summaryrefslogtreecommitdiff
path: root/deps/v8/test
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test')
-rw-r--r--deps/v8/test/base-unittests/DEPS8
-rw-r--r--deps/v8/test/base-unittests/base-unittests.gyp41
-rw-r--r--deps/v8/test/base-unittests/base-unittests.status6
-rw-r--r--deps/v8/test/base-unittests/cpu-unittest.cc49
-rw-r--r--deps/v8/test/base-unittests/platform/condition-variable-unittest.cc (renamed from deps/v8/test/cctest/test-condition-variable.cc)153
-rw-r--r--deps/v8/test/base-unittests/platform/mutex-unittest.cc91
-rw-r--r--deps/v8/test/base-unittests/platform/platform-unittest.cc115
-rw-r--r--deps/v8/test/base-unittests/platform/time-unittest.cc186
-rw-r--r--deps/v8/test/base-unittests/testcfg.py51
-rw-r--r--deps/v8/test/base-unittests/utils/random-number-generator-unittest.cc53
-rw-r--r--deps/v8/test/benchmarks/benchmarks.status4
-rw-r--r--deps/v8/test/benchmarks/testcfg.py9
-rw-r--r--deps/v8/test/cctest/DEPS3
-rw-r--r--deps/v8/test/cctest/cctest.cc25
-rw-r--r--deps/v8/test/cctest/cctest.gyp83
-rw-r--r--deps/v8/test/cctest/cctest.h139
-rw-r--r--deps/v8/test/cctest/cctest.status161
-rw-r--r--deps/v8/test/cctest/compiler/call-tester.h384
-rw-r--r--deps/v8/test/cctest/compiler/codegen-tester.cc578
-rw-r--r--deps/v8/test/cctest/compiler/codegen-tester.h353
-rw-r--r--deps/v8/test/cctest/compiler/function-tester.h194
-rw-r--r--deps/v8/test/cctest/compiler/graph-builder-tester.cc65
-rw-r--r--deps/v8/test/cctest/compiler/graph-builder-tester.h114
-rw-r--r--deps/v8/test/cctest/compiler/graph-tester.h42
-rw-r--r--deps/v8/test/cctest/compiler/instruction-selector-tester.h127
-rw-r--r--deps/v8/test/cctest/compiler/simplified-graph-builder.cc78
-rw-r--r--deps/v8/test/cctest/compiler/simplified-graph-builder.h73
-rw-r--r--deps/v8/test/cctest/compiler/test-branch-combine.cc462
-rw-r--r--deps/v8/test/cctest/compiler/test-changes-lowering.cc397
-rw-r--r--deps/v8/test/cctest/compiler/test-codegen-deopt.cc344
-rw-r--r--deps/v8/test/cctest/compiler/test-gap-resolver.cc173
-rw-r--r--deps/v8/test/cctest/compiler/test-graph-reducer.cc661
-rw-r--r--deps/v8/test/cctest/compiler/test-instruction-selector-arm.cc1863
-rw-r--r--deps/v8/test/cctest/compiler/test-instruction-selector-ia32.cc66
-rw-r--r--deps/v8/test/cctest/compiler/test-instruction-selector.cc22
-rw-r--r--deps/v8/test/cctest/compiler/test-instruction.cc350
-rw-r--r--deps/v8/test/cctest/compiler/test-js-constant-cache.cc284
-rw-r--r--deps/v8/test/cctest/compiler/test-js-context-specialization.cc309
-rw-r--r--deps/v8/test/cctest/compiler/test-js-typed-lowering.cc1342
-rw-r--r--deps/v8/test/cctest/compiler/test-linkage.cc113
-rw-r--r--deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc779
-rw-r--r--deps/v8/test/cctest/compiler/test-node-algorithm.cc330
-rw-r--r--deps/v8/test/cctest/compiler/test-node-cache.cc160
-rw-r--r--deps/v8/test/cctest/compiler/test-node.cc815
-rw-r--r--deps/v8/test/cctest/compiler/test-operator.cc244
-rw-r--r--deps/v8/test/cctest/compiler/test-phi-reducer.cc225
-rw-r--r--deps/v8/test/cctest/compiler/test-pipeline.cc40
-rw-r--r--deps/v8/test/cctest/compiler/test-representation-change.cc276
-rw-r--r--deps/v8/test/cctest/compiler/test-run-deopt.cc58
-rw-r--r--deps/v8/test/cctest/compiler/test-run-intrinsics.cc211
-rw-r--r--deps/v8/test/cctest/compiler/test-run-jsbranches.cc262
-rw-r--r--deps/v8/test/cctest/compiler/test-run-jscalls.cc235
-rw-r--r--deps/v8/test/cctest/compiler/test-run-jsexceptions.cc45
-rw-r--r--deps/v8/test/cctest/compiler/test-run-jsops.cc524
-rw-r--r--deps/v8/test/cctest/compiler/test-run-machops.cc4077
-rw-r--r--deps/v8/test/cctest/compiler/test-run-variables.cc121
-rw-r--r--deps/v8/test/cctest/compiler/test-schedule.cc159
-rw-r--r--deps/v8/test/cctest/compiler/test-scheduler.cc1809
-rw-r--r--deps/v8/test/cctest/compiler/test-simplified-lowering.cc1372
-rw-r--r--deps/v8/test/cctest/compiler/test-structured-ifbuilder-fuzzer.cc667
-rw-r--r--deps/v8/test/cctest/compiler/test-structured-machine-assembler.cc1055
-rw-r--r--deps/v8/test/cctest/compiler/value-helper.h131
-rw-r--r--deps/v8/test/cctest/gay-fixed.cc4
-rw-r--r--deps/v8/test/cctest/gay-precision.cc4
-rw-r--r--deps/v8/test/cctest/gay-shortest.cc4
-rw-r--r--deps/v8/test/cctest/print-extension.cc2
-rw-r--r--deps/v8/test/cctest/print-extension.h2
-rw-r--r--deps/v8/test/cctest/profiler-extension.cc4
-rw-r--r--deps/v8/test/cctest/profiler-extension.h2
-rw-r--r--deps/v8/test/cctest/test-accessors.cc58
-rw-r--r--deps/v8/test/cctest/test-alloc.cc27
-rw-r--r--deps/v8/test/cctest/test-api.cc1898
-rw-r--r--deps/v8/test/cctest/test-assembler-arm.cc66
-rw-r--r--deps/v8/test/cctest/test-assembler-arm64.cc3975
-rw-r--r--deps/v8/test/cctest/test-assembler-ia32.cc68
-rw-r--r--deps/v8/test/cctest/test-assembler-mips.cc14
-rw-r--r--deps/v8/test/cctest/test-assembler-mips64.cc1375
-rw-r--r--deps/v8/test/cctest/test-assembler-x64.cc105
-rw-r--r--deps/v8/test/cctest/test-assembler-x87.cc315
-rw-r--r--deps/v8/test/cctest/test-ast.cc8
-rw-r--r--deps/v8/test/cctest/test-atomicops.cc7
-rw-r--r--deps/v8/test/cctest/test-bignum-dtoa.cc16
-rw-r--r--deps/v8/test/cctest/test-bignum.cc8
-rw-r--r--deps/v8/test/cctest/test-checks.cc26
-rw-r--r--deps/v8/test/cctest/test-circular-queue.cc27
-rw-r--r--deps/v8/test/cctest/test-code-stubs-arm.cc23
-rw-r--r--deps/v8/test/cctest/test-code-stubs-arm64.cc25
-rw-r--r--deps/v8/test/cctest/test-code-stubs-ia32.cc19
-rw-r--r--deps/v8/test/cctest/test-code-stubs-mips.cc25
-rw-r--r--deps/v8/test/cctest/test-code-stubs-mips64.cc188
-rw-r--r--deps/v8/test/cctest/test-code-stubs-x64.cc19
-rw-r--r--deps/v8/test/cctest/test-code-stubs-x87.cc148
-rw-r--r--deps/v8/test/cctest/test-code-stubs.cc16
-rw-r--r--deps/v8/test/cctest/test-code-stubs.h2
-rw-r--r--deps/v8/test/cctest/test-compiler.cc45
-rw-r--r--deps/v8/test/cctest/test-constantpool.cc305
-rw-r--r--deps/v8/test/cctest/test-conversions.cc15
-rw-r--r--deps/v8/test/cctest/test-cpu-profiler.cc353
-rw-r--r--deps/v8/test/cctest/test-dataflow.cc6
-rw-r--r--deps/v8/test/cctest/test-date.cc8
-rw-r--r--deps/v8/test/cctest/test-debug.cc1243
-rw-r--r--deps/v8/test/cctest/test-declarative-accessors.cc6
-rw-r--r--deps/v8/test/cctest/test-decls.cc219
-rw-r--r--deps/v8/test/cctest/test-deoptimization.cc49
-rw-r--r--deps/v8/test/cctest/test-dictionary.cc29
-rw-r--r--deps/v8/test/cctest/test-disasm-arm.cc16
-rw-r--r--deps/v8/test/cctest/test-disasm-arm64.cc19
-rw-r--r--deps/v8/test/cctest/test-disasm-ia32.cc177
-rw-r--r--deps/v8/test/cctest/test-disasm-mips.cc16
-rw-r--r--deps/v8/test/cctest/test-disasm-mips64.cc674
-rw-r--r--deps/v8/test/cctest/test-disasm-x64.cc29
-rw-r--r--deps/v8/test/cctest/test-disasm-x87.cc410
-rw-r--r--deps/v8/test/cctest/test-diy-fp.cc8
-rw-r--r--deps/v8/test/cctest/test-double.cc14
-rw-r--r--deps/v8/test/cctest/test-dtoa.cc16
-rw-r--r--deps/v8/test/cctest/test-fast-dtoa.cc18
-rw-r--r--deps/v8/test/cctest/test-fixed-dtoa.cc12
-rw-r--r--deps/v8/test/cctest/test-flags.cc4
-rw-r--r--deps/v8/test/cctest/test-func-name-inference.cc10
-rw-r--r--deps/v8/test/cctest/test-fuzz-arm64.cc8
-rw-r--r--deps/v8/test/cctest/test-gc-tracer.cc125
-rw-r--r--deps/v8/test/cctest/test-global-handles.cc114
-rw-r--r--deps/v8/test/cctest/test-global-object.cc4
-rw-r--r--deps/v8/test/cctest/test-hashing.cc26
-rw-r--r--deps/v8/test/cctest/test-hashmap.cc7
-rw-r--r--deps/v8/test/cctest/test-heap-profiler.cc224
-rw-r--r--deps/v8/test/cctest/test-heap.cc840
-rw-r--r--deps/v8/test/cctest/test-hydrogen-types.cc168
-rw-r--r--deps/v8/test/cctest/test-javascript-arm64.cc24
-rw-r--r--deps/v8/test/cctest/test-js-arm64-variables.cc24
-rw-r--r--deps/v8/test/cctest/test-libplatform-default-platform.cc30
-rw-r--r--deps/v8/test/cctest/test-libplatform-task-queue.cc9
-rw-r--r--deps/v8/test/cctest/test-libplatform-worker-thread.cc13
-rw-r--r--deps/v8/test/cctest/test-libplatform.h21
-rw-r--r--deps/v8/test/cctest/test-list.cc4
-rw-r--r--deps/v8/test/cctest/test-liveedit.cc24
-rw-r--r--deps/v8/test/cctest/test-lockers.cc47
-rw-r--r--deps/v8/test/cctest/test-log-stack-tracer.cc38
-rw-r--r--deps/v8/test/cctest/test-log.cc45
-rw-r--r--deps/v8/test/cctest/test-macro-assembler-arm.cc23
-rw-r--r--deps/v8/test/cctest/test-macro-assembler-ia32.cc42
-rw-r--r--deps/v8/test/cctest/test-macro-assembler-mips.cc17
-rw-r--r--deps/v8/test/cctest/test-macro-assembler-mips64.cc217
-rw-r--r--deps/v8/test/cctest/test-macro-assembler-x64.cc165
-rw-r--r--deps/v8/test/cctest/test-macro-assembler-x87.cc150
-rw-r--r--deps/v8/test/cctest/test-mark-compact.cc49
-rw-r--r--deps/v8/test/cctest/test-mementos.cc13
-rw-r--r--deps/v8/test/cctest/test-microtask-delivery.cc4
-rw-r--r--deps/v8/test/cctest/test-mutex.cc118
-rw-r--r--deps/v8/test/cctest/test-object-observe.cc15
-rw-r--r--deps/v8/test/cctest/test-ordered-hash-table.cc132
-rw-r--r--deps/v8/test/cctest/test-ostreams.cc148
-rw-r--r--deps/v8/test/cctest/test-parsing.cc1324
-rw-r--r--deps/v8/test/cctest/test-platform-linux.cc13
-rw-r--r--deps/v8/test/cctest/test-platform-tls.cc93
-rw-r--r--deps/v8/test/cctest/test-platform-win32.cc16
-rw-r--r--deps/v8/test/cctest/test-platform.cc6
-rw-r--r--deps/v8/test/cctest/test-profile-generator.cc31
-rw-r--r--deps/v8/test/cctest/test-random-number-generator.cc49
-rw-r--r--deps/v8/test/cctest/test-regexp.cc437
-rw-r--r--deps/v8/test/cctest/test-reloc-info.cc4
-rw-r--r--deps/v8/test/cctest/test-representation.cc7
-rw-r--r--deps/v8/test/cctest/test-semaphore.cc61
-rw-r--r--deps/v8/test/cctest/test-serialize.cc370
-rw-r--r--deps/v8/test/cctest/test-socket.cc176
-rw-r--r--deps/v8/test/cctest/test-spaces.cc30
-rw-r--r--deps/v8/test/cctest/test-strings.cc17
-rw-r--r--deps/v8/test/cctest/test-strtod.cc16
-rw-r--r--deps/v8/test/cctest/test-symbols.cc13
-rw-r--r--deps/v8/test/cctest/test-thread-termination.cc117
-rw-r--r--deps/v8/test/cctest/test-threads.cc57
-rw-r--r--deps/v8/test/cctest/test-time.cc197
-rw-r--r--deps/v8/test/cctest/test-types.cc456
-rw-r--r--deps/v8/test/cctest/test-unbound-queue.cc7
-rw-r--r--deps/v8/test/cctest/test-unique.cc10
-rw-r--r--deps/v8/test/cctest/test-unscopables-hidden-prototype.cc103
-rw-r--r--deps/v8/test/cctest/test-utils-arm64.cc34
-rw-r--r--deps/v8/test/cctest/test-utils-arm64.h36
-rw-r--r--deps/v8/test/cctest/test-utils.cc59
-rw-r--r--deps/v8/test/cctest/test-version.cc6
-rw-r--r--deps/v8/test/cctest/test-weakmaps.cc45
-rw-r--r--deps/v8/test/cctest/test-weaksets.cc28
-rw-r--r--deps/v8/test/cctest/test-weaktypedarrays.cc28
-rw-r--r--deps/v8/test/cctest/trace-extension.cc6
-rw-r--r--deps/v8/test/cctest/trace-extension.h2
-rw-r--r--deps/v8/test/compiler-unittests/DEPS6
-rw-r--r--deps/v8/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc27
-rw-r--r--deps/v8/test/compiler-unittests/change-lowering-unittest.cc257
-rw-r--r--deps/v8/test/compiler-unittests/compiler-unittests.cc86
-rw-r--r--deps/v8/test/compiler-unittests/compiler-unittests.gyp61
-rw-r--r--deps/v8/test/compiler-unittests/compiler-unittests.h69
-rw-r--r--deps/v8/test/compiler-unittests/compiler-unittests.status6
-rw-r--r--deps/v8/test/compiler-unittests/instruction-selector-unittest.cc92
-rw-r--r--deps/v8/test/compiler-unittests/instruction-selector-unittest.h129
-rw-r--r--deps/v8/test/compiler-unittests/node-matchers.cc454
-rw-r--r--deps/v8/test/compiler-unittests/node-matchers.h71
-rw-r--r--deps/v8/test/compiler-unittests/testcfg.py51
-rw-r--r--deps/v8/test/fuzz-natives/base.js6
-rw-r--r--deps/v8/test/fuzz-natives/fuzz-natives.status21
-rw-r--r--deps/v8/test/fuzz-natives/testcfg.py17
-rw-r--r--deps/v8/test/intl/intl.status6
-rw-r--r--deps/v8/test/mjsunit/allocation-site-info.js729
-rw-r--r--deps/v8/test/mjsunit/apply.js8
-rw-r--r--deps/v8/test/mjsunit/array-construct-transition.js18
-rw-r--r--deps/v8/test/mjsunit/array-constructor-feedback.js326
-rw-r--r--deps/v8/test/mjsunit/array-feedback.js303
-rw-r--r--deps/v8/test/mjsunit/array-literal-feedback.js103
-rw-r--r--deps/v8/test/mjsunit/array-literal-transitions.js203
-rw-r--r--deps/v8/test/mjsunit/array-natives-elements.js70
-rw-r--r--deps/v8/test/mjsunit/array-push-unshift-read-only-length.js107
-rw-r--r--deps/v8/test/mjsunit/array-shift2.js18
-rw-r--r--deps/v8/test/mjsunit/array-shift3.js15
-rw-r--r--deps/v8/test/mjsunit/assert-opt-and-deopt.js2
-rw-r--r--deps/v8/test/mjsunit/binary-op-newspace.js2
-rw-r--r--deps/v8/test/mjsunit/bounds-checks-elimination.js123
-rw-r--r--deps/v8/test/mjsunit/builtins.js11
-rw-r--r--deps/v8/test/mjsunit/compiler/inline-arguments.js26
-rw-r--r--deps/v8/test/mjsunit/compiler/math-floor-global.js2
-rw-r--r--deps/v8/test/mjsunit/compiler/math-floor-local.js2
-rw-r--r--deps/v8/test/mjsunit/const-eval-init.js33
-rw-r--r--deps/v8/test/mjsunit/const-redecl.js82
-rw-r--r--deps/v8/test/mjsunit/constant-folding-2.js11
-rw-r--r--deps/v8/test/mjsunit/cross-realm-filtering.js141
-rw-r--r--deps/v8/test/mjsunit/debug-break-native.js42
-rw-r--r--deps/v8/test/mjsunit/debug-compile-event.js26
-rw-r--r--deps/v8/test/mjsunit/debug-compile-optimized.js18
-rw-r--r--deps/v8/test/mjsunit/debug-is-active.js28
-rw-r--r--deps/v8/test/mjsunit/debug-mirror-cache.js3
-rw-r--r--deps/v8/test/mjsunit/debug-script.js2
-rw-r--r--deps/v8/test/mjsunit/debug-scripts-request.js2
-rw-r--r--deps/v8/test/mjsunit/debug-stepin-positions.js3
-rw-r--r--deps/v8/test/mjsunit/debug-toggle-mirror-cache.js (renamed from deps/v8/test/cctest/test-cpu-x64.cc)26
-rw-r--r--deps/v8/test/mjsunit/define-property-gc.js2
-rw-r--r--deps/v8/test/mjsunit/deserialize-reference.js8
-rw-r--r--deps/v8/test/mjsunit/dictionary-properties.js48
-rw-r--r--deps/v8/test/mjsunit/elements-kind-depends.js2
-rw-r--r--deps/v8/test/mjsunit/elements-kind.js337
-rw-r--r--deps/v8/test/mjsunit/elements-transition-hoisting.js20
-rw-r--r--deps/v8/test/mjsunit/elements-transition.js164
-rw-r--r--deps/v8/test/mjsunit/error-tostring-omit.js18
-rw-r--r--deps/v8/test/mjsunit/es6/array-iterator.js (renamed from deps/v8/test/mjsunit/harmony/array-iterator.js)95
-rw-r--r--deps/v8/test/mjsunit/es6/collection-iterator.js200
-rw-r--r--deps/v8/test/mjsunit/es6/collections.js (renamed from deps/v8/test/mjsunit/harmony/collections.js)454
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises-throw-in-reject.js61
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises-undefined-reject.js57
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/async-task-event.js61
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/events.js124
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/reentry.js (renamed from deps/v8/test/mjsunit/es6/debug-promises-reentry.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/reject-after-resolve.js37
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/reject-caught-all.js72
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/reject-caught-late.js34
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/reject-caught-uncaught.js36
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/reject-in-constructor.js39
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-all.js69
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-late.js76
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js69
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js77
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js87
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js77
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/throw-caught-all.js (renamed from deps/v8/test/mjsunit/es6/debug-promises-caught-all.js)40
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/throw-caught-late.js (renamed from deps/v8/test/mjsunit/es6/debug-promises-caught-late.js)8
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/throw-caught-uncaught.js (renamed from deps/v8/test/mjsunit/es6/debug-promises-caught-uncaught.js)12
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/throw-in-constructor.js (renamed from deps/v8/test/mjsunit/es6/debug-promises-throw-in-constructor.js)10
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-all.js (renamed from deps/v8/test/mjsunit/es6/debug-promises-uncaught-all.js)43
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-uncaught.js (renamed from deps/v8/test/mjsunit/es6/debug-promises-uncaught-uncaught.js)42
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js90
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/throw-with-undefined-reject.js88
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/try-reject-in-constructor.js42
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/try-throw-reject-in-constructor.js44
-rw-r--r--deps/v8/test/mjsunit/es6/debug-stepin-collections-foreach.js118
-rw-r--r--deps/v8/test/mjsunit/es6/iteration-semantics.js (renamed from deps/v8/test/mjsunit/harmony/iteration-semantics.js)88
-rw-r--r--deps/v8/test/mjsunit/es6/iteration-syntax.js (renamed from deps/v8/test/mjsunit/harmony/iteration-syntax.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/math-cbrt.js2
-rw-r--r--deps/v8/test/mjsunit/es6/math-clz32.js2
-rw-r--r--deps/v8/test/mjsunit/es6/math-expm1.js2
-rw-r--r--deps/v8/test/mjsunit/es6/math-fround.js43
-rw-r--r--deps/v8/test/mjsunit/es6/math-hyperbolic.js2
-rw-r--r--deps/v8/test/mjsunit/es6/math-hypot.js2
-rw-r--r--deps/v8/test/mjsunit/es6/math-log1p.js47
-rw-r--r--deps/v8/test/mjsunit/es6/math-log2-log10.js2
-rw-r--r--deps/v8/test/mjsunit/es6/math-sign.js2
-rw-r--r--deps/v8/test/mjsunit/es6/math-trunc.js2
-rw-r--r--deps/v8/test/mjsunit/es6/mirror-collections.js144
-rw-r--r--deps/v8/test/mjsunit/es6/mirror-promises.js27
-rw-r--r--deps/v8/test/mjsunit/es6/mirror-symbols.js38
-rw-r--r--deps/v8/test/mjsunit/es6/promises.js42
-rw-r--r--deps/v8/test/mjsunit/es6/regress/regress-2186.js (renamed from deps/v8/test/mjsunit/harmony/regress/regress-2186.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/regress/regress-cr372788.js (renamed from deps/v8/test/cctest/test-cpu-ia32.cc)25
-rw-r--r--deps/v8/test/mjsunit/es6/regress/regress-crbug-248025.js (renamed from deps/v8/test/mjsunit/harmony/regress/regress-crbug-248025.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/regress/regress-crbug-346141.js (renamed from deps/v8/test/mjsunit/harmony/regress/regress-crbug-346141.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/string-html.js159
-rw-r--r--deps/v8/test/mjsunit/es6/string-iterator.js89
-rw-r--r--deps/v8/test/mjsunit/es6/symbols.js (renamed from deps/v8/test/mjsunit/harmony/symbols.js)46
-rw-r--r--deps/v8/test/mjsunit/es6/typed-array-iterator.js39
-rw-r--r--deps/v8/test/mjsunit/es6/unscopables.js664
-rw-r--r--deps/v8/test/mjsunit/es6/weak_collections.js333
-rw-r--r--deps/v8/test/mjsunit/es7/object-observe-debug-event.js51
-rw-r--r--deps/v8/test/mjsunit/es7/object-observe-runtime.js18
-rw-r--r--deps/v8/test/mjsunit/es7/object-observe.js13
-rw-r--r--deps/v8/test/mjsunit/fast-non-keyed.js6
-rw-r--r--deps/v8/test/mjsunit/fast-prototype.js13
-rw-r--r--deps/v8/test/mjsunit/global-const-var-conflicts.js13
-rw-r--r--deps/v8/test/mjsunit/harmony/array-fill.js4
-rw-r--r--deps/v8/test/mjsunit/harmony/arrow-functions.js48
-rw-r--r--deps/v8/test/mjsunit/harmony/block-conflicts.js133
-rw-r--r--deps/v8/test/mjsunit/harmony/block-const-assign.js3
-rw-r--r--deps/v8/test/mjsunit/harmony/block-early-errors.js3
-rw-r--r--deps/v8/test/mjsunit/harmony/block-for.js42
-rw-r--r--deps/v8/test/mjsunit/harmony/block-leave.js1
-rw-r--r--deps/v8/test/mjsunit/harmony/block-let-crankshaft.js258
-rw-r--r--deps/v8/test/mjsunit/harmony/block-let-declaration.js28
-rw-r--r--deps/v8/test/mjsunit/harmony/block-let-semantics.js1
-rw-r--r--deps/v8/test/mjsunit/harmony/block-scoping.js12
-rw-r--r--deps/v8/test/mjsunit/harmony/debug-blockscopes.js13
-rw-r--r--deps/v8/test/mjsunit/harmony/debug-evaluate-blockscopes.js1
-rw-r--r--deps/v8/test/mjsunit/harmony/empty-for.js (renamed from deps/v8/test/mjsunit/regress/regress-2336.js)59
-rw-r--r--deps/v8/test/mjsunit/harmony/generators-debug-liveedit.js119
-rw-r--r--deps/v8/test/mjsunit/harmony/generators-iteration.js52
-rw-r--r--deps/v8/test/mjsunit/harmony/generators-parsing.js45
-rw-r--r--deps/v8/test/mjsunit/harmony/generators-poisoned-properties.js42
-rw-r--r--deps/v8/test/mjsunit/harmony/generators-runtime.js24
-rw-r--r--deps/v8/test/mjsunit/harmony/private.js20
-rw-r--r--deps/v8/test/mjsunit/harmony/proxies-example-membrane.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/proxies-hash.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/proxies-json.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/proxies-symbols.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/proxies-with-unscopables.js153
-rw-r--r--deps/v8/test/mjsunit/harmony/proxies.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/regress/regress-3426.js7
-rw-r--r--deps/v8/test/mjsunit/harmony/set-prototype-of.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/string-codepointat.js91
-rw-r--r--deps/v8/test/mjsunit/harmony/string-fromcodepoint.js62
-rw-r--r--deps/v8/test/mjsunit/harmony/typeof.js35
-rw-r--r--deps/v8/test/mjsunit/json-stringify-recursive.js2
-rw-r--r--deps/v8/test/mjsunit/keyed-load-dictionary-stub.js20
-rw-r--r--deps/v8/test/mjsunit/math-abs.js2
-rw-r--r--deps/v8/test/mjsunit/math-floor-part1.js2
-rw-r--r--deps/v8/test/mjsunit/math-floor-part2.js2
-rw-r--r--deps/v8/test/mjsunit/math-floor-part3.js2
-rw-r--r--deps/v8/test/mjsunit/math-floor-part4.js2
-rw-r--r--deps/v8/test/mjsunit/migrations.js311
-rw-r--r--deps/v8/test/mjsunit/mirror-object.js16
-rw-r--r--deps/v8/test/mjsunit/mirror-script.js2
-rw-r--r--deps/v8/test/mjsunit/mjsunit.js27
-rw-r--r--deps/v8/test/mjsunit/mjsunit.status264
-rw-r--r--deps/v8/test/mjsunit/object-define-property.js20
-rw-r--r--deps/v8/test/mjsunit/object-toprimitive.js2
-rw-r--r--deps/v8/test/mjsunit/opt-elements-kind.js23
-rw-r--r--deps/v8/test/mjsunit/osr-elements-kind.js103
-rw-r--r--deps/v8/test/mjsunit/outobject-double-for-in.js66
-rw-r--r--deps/v8/test/mjsunit/override-read-only-property.js2
-rw-r--r--deps/v8/test/mjsunit/own-symbols.js55
-rw-r--r--deps/v8/test/mjsunit/packed-elements.js18
-rw-r--r--deps/v8/test/mjsunit/polymorph-arrays.js12
-rw-r--r--deps/v8/test/mjsunit/proto-accessor.js2
-rw-r--r--deps/v8/test/mjsunit/readonly.js3
-rw-r--r--deps/v8/test/mjsunit/regress-3456.js13
-rw-r--r--deps/v8/test/mjsunit/regress/debug-prepare-step-in.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1170.js11
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1199637.js16
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1213575.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1530.js48
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1708.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2790.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-320532.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-3281.js7
-rw-r--r--deps/v8/test/mjsunit/regress/regress-3307.js24
-rw-r--r--deps/v8/test/mjsunit/regress/regress-3315.js26
-rw-r--r--deps/v8/test/mjsunit/regress/regress-3334.js13
-rw-r--r--deps/v8/test/mjsunit/regress/regress-334.js8
-rw-r--r--deps/v8/test/mjsunit/regress/regress-3359.js12
-rw-r--r--deps/v8/test/mjsunit/regress/regress-3380.js16
-rw-r--r--deps/v8/test/mjsunit/regress/regress-3392.js18
-rw-r--r--deps/v8/test/mjsunit/regress/regress-3404.js27
-rw-r--r--deps/v8/test/mjsunit/regress/regress-3462.js48
-rw-r--r--deps/v8/test/mjsunit/regress/regress-3476.js24
-rw-r--r--deps/v8/test/mjsunit/regress/regress-370827.js21
-rw-r--r--deps/v8/test/mjsunit/regress/regress-373283.js18
-rw-r--r--deps/v8/test/mjsunit/regress/regress-377290.js17
-rw-r--r--deps/v8/test/mjsunit/regress/regress-379770.js26
-rw-r--r--deps/v8/test/mjsunit/regress/regress-380049.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-380092.js22
-rw-r--r--deps/v8/test/mjsunit/regress/regress-381313.js42
-rw-r--r--deps/v8/test/mjsunit/regress/regress-392114.js (renamed from deps/v8/test/cctest/test-cpu.cc)53
-rw-r--r--deps/v8/test/mjsunit/regress/regress-99167.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-cntl-descriptors-enum.js4
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-245480.js38
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-350864.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-374838.js20
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-380512.js12
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-381534.js40
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-382513.js11
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-385002.js15
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-387599.js19
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-387627.js13
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-387636.js14
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-390918.js18
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-390925.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-393988.js8
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-401915.js20
-rw-r--r--deps/v8/test/mjsunit/regress/regress-create-exception.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-debug-context-load.js8
-rw-r--r--deps/v8/test/mjsunit/regress/regress-double-property.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-escape-preserve-smi-representation.js13
-rw-r--r--deps/v8/test/mjsunit/regress/regress-freeze-setter.js (renamed from deps/v8/test/mjsunit/regress/regress-global-freeze-const.js)4
-rw-r--r--deps/v8/test/mjsunit/regress/regress-function-constructor-receiver.js17
-rw-r--r--deps/v8/test/mjsunit/regress/regress-mask-array-length.js10
-rw-r--r--deps/v8/test/mjsunit/regress/regress-regexp-nocase.js (renamed from deps/v8/test/cctest/test-platform-macos.cc)11
-rw-r--r--deps/v8/test/mjsunit/regress/regress-set-flags-stress-compact.js10
-rw-r--r--deps/v8/test/mjsunit/regress/regress-update-field-type-attributes.js12
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/apply.js9
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/arraybuffergetbytelength.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/arraybufferinitialize.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/arraybufferisview.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/arraybufferneuter.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/arraybuffersliceimpl.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/arraybufferviewgetbytelength.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/arraybufferviewgetbyteoffset.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/arrayconcat.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/availablelocalesof.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/basicjsonstringify.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/booleanize.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/boundfunctiongetbindings.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/break.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/breakiteratoradopttext.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/breakiteratorbreaktype.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/breakiteratorcurrent.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/breakiteratorfirst.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/breakiteratornext.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/canonicalizelanguagetag.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/changebreakonexception.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/charfromcode.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/checkexecutionstate.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/checkisbootstrapping.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/clearbreakpoint.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/clearfunctiontypefeedback.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/clearstepping.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/collectstacktrace.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/compilestring.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/constructdouble.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/createbreakiterator.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/createcollator.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/createglobalprivatesymbol.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/createjsfunctionproxy.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/createjsproxy.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/createprivateownsymbol.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/createprivatesymbol.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/createsymbol.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewgetbuffer.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewgetfloat32.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewgetfloat64.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewgetint16.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewgetint32.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewgetint8.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewgetuint16.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewgetuint32.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewgetuint8.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewinitialize.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewsetfloat32.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewsetfloat64.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewsetint16.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewsetint32.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewsetint8.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewsetuint16.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewsetuint32.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dataviewsetuint8.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/datecacheversion.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/datecurrenttime.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/datelocaltimezone.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/datemakeday.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/dateparsestring.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/datesetvalue.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/datetoutc.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugasynctaskevent.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugbreak.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugcallbacksupportsstepping.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugconstructedby.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugdisassembleconstructor.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugdisassemblefunction.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugevaluate.js12
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugevaluateglobal.js10
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debuggetproperty.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debuggetpropertydetails.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debuggetprototype.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugindexedinterceptorelementvalue.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugnamedinterceptorpropertyvalue.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugpoppromise.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugpreparestepinifstepping.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugprintscopes.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugpromiseevent.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugpromiserejectevent.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugpropertyattributesfromdetails.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugpropertyindexfromdetails.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugpropertytypefromdetails.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugpushpromise.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugreferencedby.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/debugtrace.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/defineaccessorpropertyunchecked.js9
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/defineapiaccessorproperty.js9
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/definedatapropertyunchecked.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/deleteproperty.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/deoptimizefunction.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/doublehi.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/doublelo.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/enqueuemicrotask.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/estimatenumberofelements.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/executeindebugcontext.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/finisharrayprototypesetup.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/fix.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/flattenstring.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functionbindarguments.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functiongetinferredname.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functiongetname.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functiongetscript.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functiongetscriptsourceposition.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functiongetsourcecode.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functionisapifunction.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functionisarrow.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functionisbuiltin.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functionisgenerator.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functionmarknameshouldprintasanonymous.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functionnameshouldprintasanonymous.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functionremoveprototype.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functionsetinstanceclassname.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functionsetlength.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functionsetname.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/functionsetprototype.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getallscopesdetails.js10
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getargumentsproperty.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getarraykeys.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getbreaklocations.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getcalltrap.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getconstructordelegate.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getconstructtrap.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getdataproperty.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getdefaulticulocale.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getdefaultreceiver.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getframecount.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getframedetails.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getfunctioncodepositionfromsource.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getfunctiondelegate.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getfunctionscopecount.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getfunctionscopedetails.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/gethandler.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getheapusage.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getimplfrominitializedintlobject.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getindexedinterceptorelementnames.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getinterceptorinfo.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getlanguagetagvariants.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getnamedinterceptorpropertynames.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getobjectcontextnotifierperformchange.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getobjectcontextobjectgetnotifier.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getobjectcontextobjectobserve.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getobservationstate.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getoptimizationcount.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getownelementnames.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getownproperty.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getownpropertynames.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getproperty.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getpropertynames.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getpropertynamesfast.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getprototype.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getrootnan.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getscopecount.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getscopedetails.js10
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getscript.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getstepinpositions.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/gettemplatefield.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getthreadcount.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getthreaddetails.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getv8version.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getweakmapentries.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/getweaksetvalues.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/globalprint.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/globalproxy.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/haselement.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/hasownproperty.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/hasproperty.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/havesamemap.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/internalcompare.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/internaldateformat.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/internaldateparse.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/internalnumberformat.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/internalnumberparse.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/internalsetprototype.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isattachedglobal.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isbreakonexception.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isconcurrentrecompilationsupported.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isextensible.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isinitializedintlobject.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isinitializedintlobjectoftype.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isinprototypechain.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isjsfunctionproxy.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isjsglobalproxy.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isjsmodule.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isjsproxy.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isobserved.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isoptimized.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/ispropertyenumerable.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/issloppymodefunction.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/istemplate.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/isvalidsmi.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/keyedgetproperty.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/liveeditcheckanddropactivations.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/liveeditcomparestrings.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/liveeditfunctionsetscript.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/loadmutabledouble.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/lookupaccessor.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mapclear.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mapdelete.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mapget.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mapgetsize.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/maphas.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mapinitialize.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mapiteratorinitialize.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mapiteratornext.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mapset.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/markasinitializedintlobjectoftype.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mathacos.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mathasin.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mathatan.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mathatan2.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mathexprt.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mathfloorrt.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mathfround.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mathlogrt.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/mathsqrtrt.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/maxsmi.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/movearraycontents.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/neveroptimizefunction.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/newarguments.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/newobjectfrombound.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/newstring.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/newstringwrapper.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/newsymbolwrapper.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/notifycontextdisposed.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numberadd.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numberand.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbercompare.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numberdiv.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numberequals.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numberimul.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbermod.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbermul.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numberor.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbersar.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbershl.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbershr.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbersub.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbertoexponential.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbertofixed.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbertointeger.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbertointegermapminuszero.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbertojsint32.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbertojsuint32.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbertoprecision.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbertoradixstring.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numbertostringrt.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numberunaryminus.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/numberxor.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/objectfreeze.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/objectwascreatedincurrentorigin.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/observationweakmapcreate.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/observerobjectandrecordhavesameorigin.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/optimizeobjectforaddingmultipleproperties.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/ownkeys.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/parsejson.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/preventextensions.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/pushifabsent.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/quotejsonstring.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/regexpcompile.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/regexpconstructresult.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/regexpexecmultiple.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/regexpexecrt.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/regexpinitializeobject.js9
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/removearrayholes.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/rempio2.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/roundnumber.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/runmicrotasks.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/runninginsimulator.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setadd.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setclear.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setcode.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setdebugeventlistener.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setdelete.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setdisablebreak.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setflags.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setfunctionbreakpoint.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setgetsize.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/sethas.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setinitialize.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setisobserved.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setiteratorinitialize.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setiteratornext.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setprototype.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/setscopevariablevalue.js10
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/smilexicographiccompare.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/sparsejoinwithseparator.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/specialarrayfunctions.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringbuilderconcat.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringbuilderjoin.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringcharcodeatrt.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringequals.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringindexof.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringlastindexof.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringlocalecompare.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringmatch.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringnormalize.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringparsefloat.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringparseint.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringreplaceglobalregexpwithstring.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringreplaceonecharwithstring.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringsplit.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringtoarray.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringtolowercase.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringtonumber.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringtouppercase.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/stringtrim.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/symboldescription.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/symbolisprivate.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/symbolregistry.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/tobool.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/tofastproperties.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/traceenter.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/traceexit.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/truncatestring.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/trymigrateinstance.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/typedarraygetbuffer.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/typedarraygetlength.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/typedarrayinitialize.js9
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/typedarrayinitializefromarraylike.js8
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/typedarraymaxsizeinheap.js4
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/typedarraysetfastcases.js7
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/typeof.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/unblockconcurrentrecompilation.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/uriescape.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/uriunescape.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/weakcollectiondelete.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/weakcollectionget.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/weakcollectionhas.js6
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/weakcollectioninitialize.js5
-rw-r--r--deps/v8/test/mjsunit/runtime-gen/weakcollectionset.js7
-rw-r--r--deps/v8/test/mjsunit/sin-cos.js97
-rw-r--r--deps/v8/test/mjsunit/stack-traces-overflow.js23
-rw-r--r--deps/v8/test/mjsunit/stack-traces.js20
-rw-r--r--deps/v8/test/mjsunit/tools/profviz-test.default460
-rw-r--r--deps/v8/test/mjsunit/tools/tickprocessor-test.default20
-rw-r--r--deps/v8/test/mjsunit/tools/tickprocessor-test.func-info7
-rw-r--r--deps/v8/test/mjsunit/tools/tickprocessor-test.gc-state7
-rw-r--r--deps/v8/test/mjsunit/tools/tickprocessor-test.ignore-unknown15
-rw-r--r--deps/v8/test/mjsunit/tools/tickprocessor-test.separate-ic20
-rw-r--r--deps/v8/test/mjsunit/tools/tickprocessor.js6
-rw-r--r--deps/v8/test/mjsunit/value-wrapper-accessor.js10
-rw-r--r--deps/v8/test/mjsunit/with-readonly.js2
-rw-r--r--deps/v8/test/mozilla/mozilla.status36
-rw-r--r--deps/v8/test/preparser/duplicate-property.pyt2
-rw-r--r--deps/v8/test/promises-aplus/testcfg.py6
-rw-r--r--deps/v8/test/test262/test262.status25
-rw-r--r--deps/v8/test/test262/testcfg.py4
-rw-r--r--deps/v8/test/webkit/fast/js/Object-defineProperty-expected.txt4
-rw-r--r--deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt44
-rw-r--r--deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js44
-rw-r--r--deps/v8/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt18
-rw-r--r--deps/v8/test/webkit/fast/js/read-modify-eval-expected.txt2
-rw-r--r--deps/v8/test/webkit/fast/js/string-anchor-expected.txt4
-rw-r--r--deps/v8/test/webkit/fast/js/string-fontcolor-expected.txt4
-rw-r--r--deps/v8/test/webkit/fast/js/string-fontsize-expected.txt4
-rw-r--r--deps/v8/test/webkit/fast/js/string-link-expected.txt4
-rw-r--r--deps/v8/test/webkit/for-in-cached-expected.txt4
-rw-r--r--deps/v8/test/webkit/for-in-cached.js4
-rw-r--r--deps/v8/test/webkit/object-literal-direct-put-expected.txt4
-rw-r--r--deps/v8/test/webkit/object-literal-direct-put.js4
-rw-r--r--deps/v8/test/webkit/object-literal-syntax-expected.txt24
-rw-r--r--deps/v8/test/webkit/object-literal-syntax.js24
-rw-r--r--deps/v8/test/webkit/string-replacement-outofmemory-expected.txt9
-rw-r--r--deps/v8/test/webkit/string-replacement-outofmemory.js2
-rw-r--r--deps/v8/test/webkit/webkit.status19
777 files changed, 47090 insertions, 9629 deletions
diff --git a/deps/v8/test/base-unittests/DEPS b/deps/v8/test/base-unittests/DEPS
new file mode 100644
index 000000000..90b080063
--- /dev/null
+++ b/deps/v8/test/base-unittests/DEPS
@@ -0,0 +1,8 @@
+include_rules = [
+ "-include",
+ "+include/v8config.h",
+ "+include/v8stdint.h",
+ "-src",
+ "+src/base",
+ "+testing/gtest",
+]
diff --git a/deps/v8/test/base-unittests/base-unittests.gyp b/deps/v8/test/base-unittests/base-unittests.gyp
new file mode 100644
index 000000000..339269db1
--- /dev/null
+++ b/deps/v8/test/base-unittests/base-unittests.gyp
@@ -0,0 +1,41 @@
+# 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.
+
+{
+ 'variables': {
+ 'v8_code': 1,
+ },
+ 'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
+ 'targets': [
+ {
+ 'target_name': 'base-unittests',
+ 'type': 'executable',
+ 'dependencies': [
+ '../../testing/gtest.gyp:gtest',
+ '../../testing/gtest.gyp:gtest_main',
+ '../../tools/gyp/v8.gyp:v8_libbase',
+ ],
+ 'include_dirs': [
+ '../..',
+ ],
+ 'sources': [ ### gcmole(all) ###
+ 'cpu-unittest.cc',
+ 'platform/condition-variable-unittest.cc',
+ 'platform/mutex-unittest.cc',
+ 'platform/platform-unittest.cc',
+ 'platform/time-unittest.cc',
+ 'utils/random-number-generator-unittest.cc',
+ ],
+ 'conditions': [
+ ['os_posix == 1', {
+ # TODO(svenpanne): This is a temporary work-around to fix the warnings
+ # that show up because we use -std=gnu++0x instead of -std=c++11.
+ 'cflags!': [
+ '-pedantic',
+ ],
+ }],
+ ],
+ },
+ ],
+}
diff --git a/deps/v8/test/base-unittests/base-unittests.status b/deps/v8/test/base-unittests/base-unittests.status
new file mode 100644
index 000000000..d439913cc
--- /dev/null
+++ b/deps/v8/test/base-unittests/base-unittests.status
@@ -0,0 +1,6 @@
+# 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.
+
+[
+]
diff --git a/deps/v8/test/base-unittests/cpu-unittest.cc b/deps/v8/test/base-unittests/cpu-unittest.cc
new file mode 100644
index 000000000..5c58f8623
--- /dev/null
+++ b/deps/v8/test/base-unittests/cpu-unittest.cc
@@ -0,0 +1,49 @@
+// 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 "src/base/cpu.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+TEST(CPUTest, FeatureImplications) {
+ CPU cpu;
+
+ // ia32 and x64 features
+ EXPECT_TRUE(!cpu.has_sse() || cpu.has_mmx());
+ EXPECT_TRUE(!cpu.has_sse2() || cpu.has_sse());
+ EXPECT_TRUE(!cpu.has_sse3() || cpu.has_sse2());
+ EXPECT_TRUE(!cpu.has_ssse3() || cpu.has_sse3());
+ EXPECT_TRUE(!cpu.has_sse41() || cpu.has_sse3());
+ EXPECT_TRUE(!cpu.has_sse42() || cpu.has_sse41());
+
+ // arm features
+ EXPECT_TRUE(!cpu.has_vfp3_d32() || cpu.has_vfp3());
+}
+
+
+TEST(CPUTest, RequiredFeatures) {
+ CPU cpu;
+
+#if V8_HOST_ARCH_ARM
+ EXPECT_TRUE(cpu.has_fpu());
+#endif
+
+#if V8_HOST_ARCH_IA32
+ EXPECT_TRUE(cpu.has_fpu());
+ EXPECT_TRUE(cpu.has_sahf());
+#endif
+
+#if V8_HOST_ARCH_X64
+ EXPECT_TRUE(cpu.has_fpu());
+ EXPECT_TRUE(cpu.has_cmov());
+ EXPECT_TRUE(cpu.has_mmx());
+ EXPECT_TRUE(cpu.has_sse());
+ EXPECT_TRUE(cpu.has_sse2());
+#endif
+}
+
+} // namespace base
+} // namespace v8
diff --git a/deps/v8/test/cctest/test-condition-variable.cc b/deps/v8/test/base-unittests/platform/condition-variable-unittest.cc
index a7bd6500d..ea1efd0d5 100644
--- a/deps/v8/test/cctest/test-condition-variable.cc
+++ b/deps/v8/test/base-unittests/platform/condition-variable-unittest.cc
@@ -1,40 +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.
-
-#include "v8.h"
-
-#include "cctest.h"
-#include "platform/condition-variable.h"
-#include "platform/time.h"
-
-using namespace ::v8::internal;
-
-
-TEST(WaitForAfterNofityOnSameThread) {
+// 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 "src/base/platform/condition-variable.h"
+
+#include "src/base/platform/platform.h"
+#include "src/base/platform/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+TEST(ConditionVariable, WaitForAfterNofityOnSameThread) {
for (int n = 0; n < 10; ++n) {
Mutex mutex;
ConditionVariable cv;
@@ -42,19 +19,22 @@ TEST(WaitForAfterNofityOnSameThread) {
LockGuard<Mutex> lock_guard(&mutex);
cv.NotifyOne();
- CHECK_EQ(false, cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n)));
+ EXPECT_FALSE(cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n)));
cv.NotifyAll();
- CHECK_EQ(false, cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n)));
+ EXPECT_FALSE(cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n)));
}
}
+namespace {
+
class ThreadWithMutexAndConditionVariable V8_FINAL : public Thread {
public:
ThreadWithMutexAndConditionVariable()
- : Thread("ThreadWithMutexAndConditionVariable"),
- running_(false), finished_(false) {}
+ : Thread(Options("ThreadWithMutexAndConditionVariable")),
+ running_(false),
+ finished_(false) {}
virtual ~ThreadWithMutexAndConditionVariable() {}
virtual void Run() V8_OVERRIDE {
@@ -74,15 +54,17 @@ class ThreadWithMutexAndConditionVariable V8_FINAL : public Thread {
Mutex mutex_;
};
+}
+
-TEST(MultipleThreadsWithSeparateConditionVariables) {
+TEST(ConditionVariable, MultipleThreadsWithSeparateConditionVariables) {
static const int kThreadCount = 128;
ThreadWithMutexAndConditionVariable threads[kThreadCount];
for (int n = 0; n < kThreadCount; ++n) {
LockGuard<Mutex> lock_guard(&threads[n].mutex_);
- CHECK(!threads[n].running_);
- CHECK(!threads[n].finished_);
+ EXPECT_FALSE(threads[n].running_);
+ EXPECT_FALSE(threads[n].finished_);
threads[n].Start();
// Wait for nth thread to start.
while (!threads[n].running_) {
@@ -92,14 +74,14 @@ TEST(MultipleThreadsWithSeparateConditionVariables) {
for (int n = kThreadCount - 1; n >= 0; --n) {
LockGuard<Mutex> lock_guard(&threads[n].mutex_);
- CHECK(threads[n].running_);
- CHECK(!threads[n].finished_);
+ EXPECT_TRUE(threads[n].running_);
+ EXPECT_FALSE(threads[n].finished_);
}
for (int n = 0; n < kThreadCount; ++n) {
LockGuard<Mutex> lock_guard(&threads[n].mutex_);
- CHECK(threads[n].running_);
- CHECK(!threads[n].finished_);
+ EXPECT_TRUE(threads[n].running_);
+ EXPECT_FALSE(threads[n].finished_);
// Tell the nth thread to quit.
threads[n].running_ = false;
threads[n].cv_.NotifyOne();
@@ -111,24 +93,29 @@ TEST(MultipleThreadsWithSeparateConditionVariables) {
while (!threads[n].finished_) {
threads[n].cv_.Wait(&threads[n].mutex_);
}
- CHECK(!threads[n].running_);
- CHECK(threads[n].finished_);
+ EXPECT_FALSE(threads[n].running_);
+ EXPECT_TRUE(threads[n].finished_);
}
for (int n = 0; n < kThreadCount; ++n) {
threads[n].Join();
LockGuard<Mutex> lock_guard(&threads[n].mutex_);
- CHECK(!threads[n].running_);
- CHECK(threads[n].finished_);
+ EXPECT_FALSE(threads[n].running_);
+ EXPECT_TRUE(threads[n].finished_);
}
}
+namespace {
+
class ThreadWithSharedMutexAndConditionVariable V8_FINAL : public Thread {
public:
ThreadWithSharedMutexAndConditionVariable()
- : Thread("ThreadWithSharedMutexAndConditionVariable"),
- running_(false), finished_(false), cv_(NULL), mutex_(NULL) {}
+ : Thread(Options("ThreadWithSharedMutexAndConditionVariable")),
+ running_(false),
+ finished_(false),
+ cv_(NULL),
+ mutex_(NULL) {}
virtual ~ThreadWithSharedMutexAndConditionVariable() {}
virtual void Run() V8_OVERRIDE {
@@ -148,8 +135,10 @@ class ThreadWithSharedMutexAndConditionVariable V8_FINAL : public Thread {
Mutex* mutex_;
};
+}
+
-TEST(MultipleThreadsWithSharedSeparateConditionVariables) {
+TEST(ConditionVariable, MultipleThreadsWithSharedSeparateConditionVariables) {
static const int kThreadCount = 128;
ThreadWithSharedMutexAndConditionVariable threads[kThreadCount];
ConditionVariable cv;
@@ -164,8 +153,8 @@ TEST(MultipleThreadsWithSharedSeparateConditionVariables) {
{
LockGuard<Mutex> lock_guard(&mutex);
for (int n = 0; n < kThreadCount; ++n) {
- CHECK(!threads[n].running_);
- CHECK(!threads[n].finished_);
+ EXPECT_FALSE(threads[n].running_);
+ EXPECT_FALSE(threads[n].finished_);
threads[n].Start();
}
}
@@ -184,8 +173,8 @@ TEST(MultipleThreadsWithSharedSeparateConditionVariables) {
{
LockGuard<Mutex> lock_guard(&mutex);
for (int n = 0; n < kThreadCount; ++n) {
- CHECK(threads[n].running_);
- CHECK(!threads[n].finished_);
+ EXPECT_TRUE(threads[n].running_);
+ EXPECT_FALSE(threads[n].finished_);
}
}
@@ -193,8 +182,8 @@ TEST(MultipleThreadsWithSharedSeparateConditionVariables) {
{
LockGuard<Mutex> lock_guard(&mutex);
for (int n = kThreadCount - 1; n >= 0; --n) {
- CHECK(threads[n].running_);
- CHECK(!threads[n].finished_);
+ EXPECT_TRUE(threads[n].running_);
+ EXPECT_FALSE(threads[n].finished_);
// Tell the nth thread to quit.
threads[n].running_ = false;
}
@@ -215,8 +204,8 @@ TEST(MultipleThreadsWithSharedSeparateConditionVariables) {
{
LockGuard<Mutex> lock_guard(&mutex);
for (int n = kThreadCount - 1; n >= 0; --n) {
- CHECK(!threads[n].running_);
- CHECK(threads[n].finished_);
+ EXPECT_FALSE(threads[n].running_);
+ EXPECT_TRUE(threads[n].finished_);
}
}
@@ -227,18 +216,21 @@ TEST(MultipleThreadsWithSharedSeparateConditionVariables) {
}
+namespace {
+
class LoopIncrementThread V8_FINAL : public Thread {
public:
- LoopIncrementThread(int rem,
- int* counter,
- int limit,
- int thread_count,
- ConditionVariable* cv,
- Mutex* mutex)
- : Thread("LoopIncrementThread"), rem_(rem), counter_(counter),
- limit_(limit), thread_count_(thread_count), cv_(cv), mutex_(mutex) {
- CHECK_LT(rem, thread_count);
- CHECK_EQ(0, limit % thread_count);
+ LoopIncrementThread(int rem, int* counter, int limit, int thread_count,
+ ConditionVariable* cv, Mutex* mutex)
+ : Thread(Options("LoopIncrementThread")),
+ rem_(rem),
+ counter_(counter),
+ limit_(limit),
+ thread_count_(thread_count),
+ cv_(cv),
+ mutex_(mutex) {
+ EXPECT_LT(rem, thread_count);
+ EXPECT_EQ(0, limit % thread_count);
}
virtual void Run() V8_OVERRIDE {
@@ -251,9 +243,9 @@ class LoopIncrementThread V8_FINAL : public Thread {
count = *counter_;
}
if (count >= limit_) break;
- CHECK_EQ(*counter_, count);
+ EXPECT_EQ(*counter_, count);
if (last_count != -1) {
- CHECK_EQ(last_count + (thread_count_ - 1), count);
+ EXPECT_EQ(last_count + (thread_count_ - 1), count);
}
count++;
*counter_ = count;
@@ -271,13 +263,15 @@ class LoopIncrementThread V8_FINAL : public Thread {
Mutex* mutex_;
};
+}
+
-TEST(LoopIncrement) {
+TEST(ConditionVariable, LoopIncrement) {
static const int kMaxThreadCount = 16;
Mutex mutex;
ConditionVariable cv;
for (int thread_count = 1; thread_count < kMaxThreadCount; ++thread_count) {
- int limit = thread_count * 100;
+ int limit = thread_count * 10;
int counter = 0;
// Setup the threads.
@@ -299,6 +293,9 @@ TEST(LoopIncrement) {
}
delete[] threads;
- CHECK_EQ(limit, counter);
+ EXPECT_EQ(limit, counter);
}
}
+
+} // namespace base
+} // namespace v8
diff --git a/deps/v8/test/base-unittests/platform/mutex-unittest.cc b/deps/v8/test/base-unittests/platform/mutex-unittest.cc
new file mode 100644
index 000000000..5af5efb5a
--- /dev/null
+++ b/deps/v8/test/base-unittests/platform/mutex-unittest.cc
@@ -0,0 +1,91 @@
+// 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 "src/base/platform/mutex.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+TEST(Mutex, LockGuardMutex) {
+ Mutex mutex;
+ { LockGuard<Mutex> lock_guard(&mutex); }
+ { LockGuard<Mutex> lock_guard(&mutex); }
+}
+
+
+TEST(Mutex, LockGuardRecursiveMutex) {
+ RecursiveMutex recursive_mutex;
+ { LockGuard<RecursiveMutex> lock_guard(&recursive_mutex); }
+ {
+ LockGuard<RecursiveMutex> lock_guard1(&recursive_mutex);
+ LockGuard<RecursiveMutex> lock_guard2(&recursive_mutex);
+ }
+}
+
+
+TEST(Mutex, LockGuardLazyMutex) {
+ LazyMutex lazy_mutex = LAZY_MUTEX_INITIALIZER;
+ { LockGuard<Mutex> lock_guard(lazy_mutex.Pointer()); }
+ { LockGuard<Mutex> lock_guard(lazy_mutex.Pointer()); }
+}
+
+
+TEST(Mutex, LockGuardLazyRecursiveMutex) {
+ LazyRecursiveMutex lazy_recursive_mutex = LAZY_RECURSIVE_MUTEX_INITIALIZER;
+ { LockGuard<RecursiveMutex> lock_guard(lazy_recursive_mutex.Pointer()); }
+ {
+ LockGuard<RecursiveMutex> lock_guard1(lazy_recursive_mutex.Pointer());
+ LockGuard<RecursiveMutex> lock_guard2(lazy_recursive_mutex.Pointer());
+ }
+}
+
+
+TEST(Mutex, MultipleMutexes) {
+ Mutex mutex1;
+ Mutex mutex2;
+ Mutex mutex3;
+ // Order 1
+ mutex1.Lock();
+ mutex2.Lock();
+ mutex3.Lock();
+ mutex1.Unlock();
+ mutex2.Unlock();
+ mutex3.Unlock();
+ // Order 2
+ mutex1.Lock();
+ mutex2.Lock();
+ mutex3.Lock();
+ mutex3.Unlock();
+ mutex2.Unlock();
+ mutex1.Unlock();
+}
+
+
+TEST(Mutex, MultipleRecursiveMutexes) {
+ RecursiveMutex recursive_mutex1;
+ RecursiveMutex recursive_mutex2;
+ // Order 1
+ recursive_mutex1.Lock();
+ recursive_mutex2.Lock();
+ EXPECT_TRUE(recursive_mutex1.TryLock());
+ EXPECT_TRUE(recursive_mutex2.TryLock());
+ recursive_mutex1.Unlock();
+ recursive_mutex1.Unlock();
+ recursive_mutex2.Unlock();
+ recursive_mutex2.Unlock();
+ // Order 2
+ recursive_mutex1.Lock();
+ EXPECT_TRUE(recursive_mutex1.TryLock());
+ recursive_mutex2.Lock();
+ EXPECT_TRUE(recursive_mutex2.TryLock());
+ recursive_mutex2.Unlock();
+ recursive_mutex1.Unlock();
+ recursive_mutex2.Unlock();
+ recursive_mutex1.Unlock();
+}
+
+} // namespace base
+} // namespace v8
diff --git a/deps/v8/test/base-unittests/platform/platform-unittest.cc b/deps/v8/test/base-unittests/platform/platform-unittest.cc
new file mode 100644
index 000000000..3530ff807
--- /dev/null
+++ b/deps/v8/test/base-unittests/platform/platform-unittest.cc
@@ -0,0 +1,115 @@
+// 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 "src/base/platform/platform.h"
+
+#if V8_OS_POSIX
+#include <unistd.h> // NOLINT
+#endif
+
+#if V8_OS_WIN
+#include "src/base/win32-headers.h"
+#endif
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+TEST(OS, GetCurrentProcessId) {
+#if V8_OS_POSIX
+ EXPECT_EQ(static_cast<int>(getpid()), OS::GetCurrentProcessId());
+#endif
+
+#if V8_OS_WIN
+ EXPECT_EQ(static_cast<int>(::GetCurrentProcessId()),
+ OS::GetCurrentProcessId());
+#endif
+}
+
+
+TEST(OS, NumberOfProcessorsOnline) {
+ EXPECT_GT(OS::NumberOfProcessorsOnline(), 0);
+}
+
+
+namespace {
+
+class SelfJoinThread V8_FINAL : public Thread {
+ public:
+ SelfJoinThread() : Thread(Options("SelfJoinThread")) {}
+ virtual void Run() V8_OVERRIDE { Join(); }
+};
+
+}
+
+
+TEST(Thread, SelfJoin) {
+ SelfJoinThread thread;
+ thread.Start();
+ thread.Join();
+}
+
+
+namespace {
+
+class ThreadLocalStorageTest : public Thread, public ::testing::Test {
+ public:
+ ThreadLocalStorageTest() : Thread(Options("ThreadLocalStorageTest")) {
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); ++i) {
+ keys_[i] = Thread::CreateThreadLocalKey();
+ }
+ }
+ ~ThreadLocalStorageTest() {
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); ++i) {
+ Thread::DeleteThreadLocalKey(keys_[i]);
+ }
+ }
+
+ virtual void Run() V8_FINAL V8_OVERRIDE {
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ CHECK(!Thread::HasThreadLocal(keys_[i]));
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ Thread::SetThreadLocal(keys_[i], GetValue(i));
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ CHECK(Thread::HasThreadLocal(keys_[i]));
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ CHECK_EQ(GetValue(i), Thread::GetThreadLocal(keys_[i]));
+ CHECK_EQ(GetValue(i), Thread::GetExistingThreadLocal(keys_[i]));
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ Thread::SetThreadLocal(keys_[i], GetValue(ARRAY_SIZE(keys_) - i - 1));
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ CHECK(Thread::HasThreadLocal(keys_[i]));
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ CHECK_EQ(GetValue(ARRAY_SIZE(keys_) - i - 1),
+ Thread::GetThreadLocal(keys_[i]));
+ CHECK_EQ(GetValue(ARRAY_SIZE(keys_) - i - 1),
+ Thread::GetExistingThreadLocal(keys_[i]));
+ }
+ }
+
+ private:
+ static void* GetValue(size_t x) {
+ return reinterpret_cast<void*>(static_cast<uintptr_t>(x + 1));
+ }
+
+ Thread::LocalStorageKey keys_[256];
+};
+
+}
+
+
+TEST_F(ThreadLocalStorageTest, DoTest) {
+ Run();
+ Start();
+ Join();
+}
+
+} // namespace base
+} // namespace v8
diff --git a/deps/v8/test/base-unittests/platform/time-unittest.cc b/deps/v8/test/base-unittests/platform/time-unittest.cc
new file mode 100644
index 000000000..409323a8d
--- /dev/null
+++ b/deps/v8/test/base-unittests/platform/time-unittest.cc
@@ -0,0 +1,186 @@
+// 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 "src/base/platform/time.h"
+
+#if V8_OS_MACOSX
+#include <mach/mach_time.h>
+#endif
+#if V8_OS_POSIX
+#include <sys/time.h>
+#endif
+
+#if V8_OS_WIN
+#include "src/base/win32-headers.h"
+#endif
+
+#include "src/base/platform/elapsed-timer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+TEST(TimeDelta, FromAndIn) {
+ EXPECT_EQ(TimeDelta::FromDays(2), TimeDelta::FromHours(48));
+ EXPECT_EQ(TimeDelta::FromHours(3), TimeDelta::FromMinutes(180));
+ EXPECT_EQ(TimeDelta::FromMinutes(2), TimeDelta::FromSeconds(120));
+ EXPECT_EQ(TimeDelta::FromSeconds(2), TimeDelta::FromMilliseconds(2000));
+ EXPECT_EQ(TimeDelta::FromMilliseconds(2), TimeDelta::FromMicroseconds(2000));
+ EXPECT_EQ(static_cast<int>(13), TimeDelta::FromDays(13).InDays());
+ EXPECT_EQ(static_cast<int>(13), TimeDelta::FromHours(13).InHours());
+ EXPECT_EQ(static_cast<int>(13), TimeDelta::FromMinutes(13).InMinutes());
+ EXPECT_EQ(static_cast<int64_t>(13), TimeDelta::FromSeconds(13).InSeconds());
+ EXPECT_DOUBLE_EQ(13.0, TimeDelta::FromSeconds(13).InSecondsF());
+ EXPECT_EQ(static_cast<int64_t>(13),
+ TimeDelta::FromMilliseconds(13).InMilliseconds());
+ EXPECT_DOUBLE_EQ(13.0, TimeDelta::FromMilliseconds(13).InMillisecondsF());
+ EXPECT_EQ(static_cast<int64_t>(13),
+ TimeDelta::FromMicroseconds(13).InMicroseconds());
+}
+
+
+#if V8_OS_MACOSX
+TEST(TimeDelta, MachTimespec) {
+ TimeDelta null = TimeDelta();
+ EXPECT_EQ(null, TimeDelta::FromMachTimespec(null.ToMachTimespec()));
+ TimeDelta delta1 = TimeDelta::FromMilliseconds(42);
+ EXPECT_EQ(delta1, TimeDelta::FromMachTimespec(delta1.ToMachTimespec()));
+ TimeDelta delta2 = TimeDelta::FromDays(42);
+ EXPECT_EQ(delta2, TimeDelta::FromMachTimespec(delta2.ToMachTimespec()));
+}
+#endif
+
+
+TEST(Time, JsTime) {
+ Time t = Time::FromJsTime(700000.3);
+ EXPECT_DOUBLE_EQ(700000.3, t.ToJsTime());
+}
+
+
+#if V8_OS_POSIX
+TEST(Time, Timespec) {
+ Time null;
+ EXPECT_TRUE(null.IsNull());
+ EXPECT_EQ(null, Time::FromTimespec(null.ToTimespec()));
+ Time now = Time::Now();
+ EXPECT_EQ(now, Time::FromTimespec(now.ToTimespec()));
+ Time now_sys = Time::NowFromSystemTime();
+ EXPECT_EQ(now_sys, Time::FromTimespec(now_sys.ToTimespec()));
+ Time unix_epoch = Time::UnixEpoch();
+ EXPECT_EQ(unix_epoch, Time::FromTimespec(unix_epoch.ToTimespec()));
+ Time max = Time::Max();
+ EXPECT_TRUE(max.IsMax());
+ EXPECT_EQ(max, Time::FromTimespec(max.ToTimespec()));
+}
+
+
+TEST(Time, Timeval) {
+ Time null;
+ EXPECT_TRUE(null.IsNull());
+ EXPECT_EQ(null, Time::FromTimeval(null.ToTimeval()));
+ Time now = Time::Now();
+ EXPECT_EQ(now, Time::FromTimeval(now.ToTimeval()));
+ Time now_sys = Time::NowFromSystemTime();
+ EXPECT_EQ(now_sys, Time::FromTimeval(now_sys.ToTimeval()));
+ Time unix_epoch = Time::UnixEpoch();
+ EXPECT_EQ(unix_epoch, Time::FromTimeval(unix_epoch.ToTimeval()));
+ Time max = Time::Max();
+ EXPECT_TRUE(max.IsMax());
+ EXPECT_EQ(max, Time::FromTimeval(max.ToTimeval()));
+}
+#endif
+
+
+#if V8_OS_WIN
+TEST(Time, Filetime) {
+ Time null;
+ EXPECT_TRUE(null.IsNull());
+ EXPECT_EQ(null, Time::FromFiletime(null.ToFiletime()));
+ Time now = Time::Now();
+ EXPECT_EQ(now, Time::FromFiletime(now.ToFiletime()));
+ Time now_sys = Time::NowFromSystemTime();
+ EXPECT_EQ(now_sys, Time::FromFiletime(now_sys.ToFiletime()));
+ Time unix_epoch = Time::UnixEpoch();
+ EXPECT_EQ(unix_epoch, Time::FromFiletime(unix_epoch.ToFiletime()));
+ Time max = Time::Max();
+ EXPECT_TRUE(max.IsMax());
+ EXPECT_EQ(max, Time::FromFiletime(max.ToFiletime()));
+}
+#endif
+
+
+namespace {
+
+template <typename T>
+static void ResolutionTest(T (*Now)(), TimeDelta target_granularity) {
+ // We're trying to measure that intervals increment in a VERY small amount
+ // of time -- according to the specified target granularity. Unfortunately,
+ // if we happen to have a context switch in the middle of our test, the
+ // context switch could easily exceed our limit. So, we iterate on this
+ // several times. As long as we're able to detect the fine-granularity
+ // timers at least once, then the test has succeeded.
+ static const TimeDelta kExpirationTimeout = TimeDelta::FromSeconds(1);
+ ElapsedTimer timer;
+ timer.Start();
+ TimeDelta delta;
+ do {
+ T start = Now();
+ T now = start;
+ // Loop until we can detect that the clock has changed. Non-HighRes timers
+ // will increment in chunks, i.e. 15ms. By spinning until we see a clock
+ // change, we detect the minimum time between measurements.
+ do {
+ now = Now();
+ delta = now - start;
+ } while (now <= start);
+ EXPECT_NE(static_cast<int64_t>(0), delta.InMicroseconds());
+ } while (delta > target_granularity && !timer.HasExpired(kExpirationTimeout));
+ EXPECT_LE(delta, target_granularity);
+}
+
+}
+
+
+TEST(Time, NowResolution) {
+ // We assume that Time::Now() has at least 16ms resolution.
+ static const TimeDelta kTargetGranularity = TimeDelta::FromMilliseconds(16);
+ ResolutionTest<Time>(&Time::Now, kTargetGranularity);
+}
+
+
+TEST(TimeTicks, NowResolution) {
+ // We assume that TimeTicks::Now() has at least 16ms resolution.
+ static const TimeDelta kTargetGranularity = TimeDelta::FromMilliseconds(16);
+ ResolutionTest<TimeTicks>(&TimeTicks::Now, kTargetGranularity);
+}
+
+
+TEST(TimeTicks, HighResolutionNowResolution) {
+ if (!TimeTicks::IsHighResolutionClockWorking()) return;
+
+ // We assume that TimeTicks::HighResolutionNow() has sub-ms resolution.
+ static const TimeDelta kTargetGranularity = TimeDelta::FromMilliseconds(1);
+ ResolutionTest<TimeTicks>(&TimeTicks::HighResolutionNow, kTargetGranularity);
+}
+
+
+TEST(TimeTicks, IsMonotonic) {
+ TimeTicks previous_normal_ticks;
+ TimeTicks previous_highres_ticks;
+ ElapsedTimer timer;
+ timer.Start();
+ while (!timer.HasExpired(TimeDelta::FromMilliseconds(100))) {
+ TimeTicks normal_ticks = TimeTicks::Now();
+ TimeTicks highres_ticks = TimeTicks::HighResolutionNow();
+ EXPECT_GE(normal_ticks, previous_normal_ticks);
+ EXPECT_GE((normal_ticks - previous_normal_ticks).InMicroseconds(), 0);
+ EXPECT_GE(highres_ticks, previous_highres_ticks);
+ EXPECT_GE((highres_ticks - previous_highres_ticks).InMicroseconds(), 0);
+ previous_normal_ticks = normal_ticks;
+ previous_highres_ticks = highres_ticks;
+ }
+}
+
+} // namespace base
+} // namespace v8
diff --git a/deps/v8/test/base-unittests/testcfg.py b/deps/v8/test/base-unittests/testcfg.py
new file mode 100644
index 000000000..0ed46dcdb
--- /dev/null
+++ b/deps/v8/test/base-unittests/testcfg.py
@@ -0,0 +1,51 @@
+# 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.
+
+import os
+import shutil
+
+from testrunner.local import commands
+from testrunner.local import testsuite
+from testrunner.local import utils
+from testrunner.objects import testcase
+
+
+class BaseUnitTestsSuite(testsuite.TestSuite):
+ def __init__(self, name, root):
+ super(BaseUnitTestsSuite, self).__init__(name, root)
+
+ def ListTests(self, context):
+ shell = os.path.abspath(os.path.join(context.shell_dir, self.shell()))
+ if utils.IsWindows():
+ shell += ".exe"
+ output = commands.Execute(context.command_prefix +
+ [shell, "--gtest_list_tests"] +
+ context.extra_flags)
+ if output.exit_code != 0:
+ print output.stdout
+ print output.stderr
+ return []
+ tests = []
+ test_case = ''
+ for test_desc in output.stdout.strip().split():
+ if test_desc.endswith('.'):
+ test_case = test_desc
+ else:
+ test = testcase.TestCase(self, test_case + test_desc, dependency=None)
+ tests.append(test)
+ tests.sort()
+ return tests
+
+ def GetFlagsForTestCase(self, testcase, context):
+ return (testcase.flags + ["--gtest_filter=" + testcase.path] +
+ ["--gtest_random_seed=%s" % context.random_seed] +
+ ["--gtest_print_time=0"] +
+ context.mode_flags)
+
+ def shell(self):
+ return "base-unittests"
+
+
+def GetSuite(name, root):
+ return BaseUnitTestsSuite(name, root)
diff --git a/deps/v8/test/base-unittests/utils/random-number-generator-unittest.cc b/deps/v8/test/base-unittests/utils/random-number-generator-unittest.cc
new file mode 100644
index 000000000..7c533db4f
--- /dev/null
+++ b/deps/v8/test/base-unittests/utils/random-number-generator-unittest.cc
@@ -0,0 +1,53 @@
+// 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 <climits>
+
+#include "src/base/utils/random-number-generator.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+class RandomNumberGeneratorTest : public ::testing::TestWithParam<int> {};
+
+
+static const int kMaxRuns = 12345;
+
+
+TEST_P(RandomNumberGeneratorTest, NextIntWithMaxValue) {
+ RandomNumberGenerator rng(GetParam());
+ for (int max = 1; max <= kMaxRuns; ++max) {
+ int n = rng.NextInt(max);
+ EXPECT_LE(0, n);
+ EXPECT_LT(n, max);
+ }
+}
+
+
+TEST_P(RandomNumberGeneratorTest, NextBooleanReturnsFalseOrTrue) {
+ RandomNumberGenerator rng(GetParam());
+ for (int k = 0; k < kMaxRuns; ++k) {
+ bool b = rng.NextBool();
+ EXPECT_TRUE(b == false || b == true);
+ }
+}
+
+
+TEST_P(RandomNumberGeneratorTest, NextDoubleReturnsValueBetween0And1) {
+ RandomNumberGenerator rng(GetParam());
+ for (int k = 0; k < kMaxRuns; ++k) {
+ double d = rng.NextDouble();
+ EXPECT_LE(0.0, d);
+ EXPECT_LT(d, 1.0);
+ }
+}
+
+
+INSTANTIATE_TEST_CASE_P(RandomSeeds, RandomNumberGeneratorTest,
+ ::testing::Values(INT_MIN, -1, 0, 1, 42, 100,
+ 1234567890, 987654321, INT_MAX));
+
+} // namespace base
+} // namespace v8
diff --git a/deps/v8/test/benchmarks/benchmarks.status b/deps/v8/test/benchmarks/benchmarks.status
index d651b3c0f..1afd5eca2 100644
--- a/deps/v8/test/benchmarks/benchmarks.status
+++ b/deps/v8/test/benchmarks/benchmarks.status
@@ -25,9 +25,11 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-# Too slow in Debug mode.
[
[ALWAYS, {
+ # Too slow in Debug mode.
'octane/mandreel': [PASS, ['mode == debug', SKIP]],
+ # TODO(mstarzinger,ishell): Timeout with TF in predictable mode.
+ 'octane/richards': [PASS, NO_VARIANTS],
}], # ALWAYS
]
diff --git a/deps/v8/test/benchmarks/testcfg.py b/deps/v8/test/benchmarks/testcfg.py
index c94a35ffd..8c573ba30 100644
--- a/deps/v8/test/benchmarks/testcfg.py
+++ b/deps/v8/test/benchmarks/testcfg.py
@@ -31,6 +31,7 @@ import shutil
import subprocess
import tarfile
+from testrunner.local import statusfile
from testrunner.local import testsuite
from testrunner.objects import testcase
@@ -183,8 +184,12 @@ class BenchmarksTestSuite(testsuite.TestSuite):
os.chdir(old_cwd)
def VariantFlags(self, testcase, default_flags):
- # Both --nocrankshaft and --stressopt are very slow.
- return [[]]
+ if testcase.outcomes and statusfile.OnlyStandardVariant(testcase.outcomes):
+ return [[]]
+ # Both --nocrankshaft and --stressopt are very slow. Add TF but without
+ # always opt to match the way the benchmarks are run for performance
+ # testing.
+ return [[], ["--turbo-filter=*"]]
def GetSuite(name, root):
diff --git a/deps/v8/test/cctest/DEPS b/deps/v8/test/cctest/DEPS
new file mode 100644
index 000000000..3e73aa244
--- /dev/null
+++ b/deps/v8/test/cctest/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+src",
+]
diff --git a/deps/v8/test/cctest/cctest.cc b/deps/v8/test/cctest/cctest.cc
index b1cf5abb4..2bb08b0ec 100644
--- a/deps/v8/test/cctest/cctest.cc
+++ b/deps/v8/test/cctest/cctest.cc
@@ -25,13 +25,14 @@
// (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 "cctest.h"
+#include "include/v8.h"
+#include "test/cctest/cctest.h"
-#include "print-extension.h"
-#include "profiler-extension.h"
-#include "trace-extension.h"
-#include "debug.h"
+#include "include/libplatform/libplatform.h"
+#include "src/debug.h"
+#include "test/cctest/print-extension.h"
+#include "test/cctest/profiler-extension.h"
+#include "test/cctest/trace-extension.h"
enum InitializationState {kUnset, kUnintialized, kInitialized};
static InitializationState initialization_state_ = kUnset;
@@ -138,7 +139,8 @@ static void SuggestTestHarness(int tests) {
int main(int argc, char* argv[]) {
v8::V8::InitializeICU();
- i::Isolate::SetCrashIfDefaultIsolateInitialized();
+ v8::Platform* platform = v8::platform::CreateDefaultPlatform();
+ v8::V8::InitializePlatform(platform);
v8::internal::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
@@ -157,6 +159,10 @@ int main(int argc, char* argv[]) {
for (int i = 1; i < argc; i++) {
char* arg = argv[i];
if (strcmp(arg, "--list") == 0) {
+ // TODO(svenpanne) Serializer::enabled() and Serializer::code_address_map_
+ // are fundamentally broken, so we can't unconditionally initialize and
+ // dispose V8.
+ v8::V8::Initialize();
PrintTestList(CcTest::last());
print_run_count = false;
@@ -200,7 +206,10 @@ int main(int argc, char* argv[]) {
if (print_run_count && tests_run != 1)
printf("Ran %i tests.\n", tests_run);
CcTest::TearDown();
- if (!disable_automatic_dispose_) v8::V8::Dispose();
+ // TODO(svenpanne) See comment above.
+ // if (!disable_automatic_dispose_) v8::V8::Dispose();
+ v8::V8::ShutdownPlatform();
+ delete platform;
return 0;
}
diff --git a/deps/v8/test/cctest/cctest.gyp b/deps/v8/test/cctest/cctest.gyp
index 745b4c51d..42946f5bf 100644
--- a/deps/v8/test/cctest/cctest.gyp
+++ b/deps/v8/test/cctest/cctest.gyp
@@ -37,12 +37,53 @@
'type': 'executable',
'dependencies': [
'resources',
+ '../../tools/gyp/v8.gyp:v8_libplatform',
],
'include_dirs': [
- '../../src',
+ '../..',
],
'sources': [ ### gcmole(all) ###
'<(generated_file)',
+ 'compiler/codegen-tester.cc',
+ 'compiler/codegen-tester.h',
+ 'compiler/function-tester.h',
+ 'compiler/graph-builder-tester.cc',
+ 'compiler/graph-builder-tester.h',
+ 'compiler/graph-tester.h',
+ 'compiler/simplified-graph-builder.cc',
+ 'compiler/simplified-graph-builder.h',
+ 'compiler/test-branch-combine.cc',
+ 'compiler/test-changes-lowering.cc',
+ 'compiler/test-codegen-deopt.cc',
+ 'compiler/test-gap-resolver.cc',
+ 'compiler/test-graph-reducer.cc',
+ 'compiler/test-instruction-selector.cc',
+ 'compiler/test-instruction.cc',
+ 'compiler/test-js-context-specialization.cc',
+ 'compiler/test-js-constant-cache.cc',
+ 'compiler/test-js-typed-lowering.cc',
+ 'compiler/test-linkage.cc',
+ 'compiler/test-machine-operator-reducer.cc',
+ 'compiler/test-node-algorithm.cc',
+ 'compiler/test-node-cache.cc',
+ 'compiler/test-node.cc',
+ 'compiler/test-operator.cc',
+ 'compiler/test-phi-reducer.cc',
+ 'compiler/test-pipeline.cc',
+ 'compiler/test-representation-change.cc',
+ 'compiler/test-run-deopt.cc',
+ 'compiler/test-run-intrinsics.cc',
+ 'compiler/test-run-jsbranches.cc',
+ 'compiler/test-run-jscalls.cc',
+ 'compiler/test-run-jsexceptions.cc',
+ 'compiler/test-run-jsops.cc',
+ 'compiler/test-run-machops.cc',
+ 'compiler/test-run-variables.cc',
+ 'compiler/test-schedule.cc',
+ 'compiler/test-scheduler.cc',
+ 'compiler/test-simplified-lowering.cc',
+ 'compiler/test-structured-ifbuilder-fuzzer.cc',
+ 'compiler/test-structured-machine-assembler.cc',
'cctest.cc',
'gay-fixed.cc',
'gay-precision.cc',
@@ -56,12 +97,11 @@
'test-atomicops.cc',
'test-bignum.cc',
'test-bignum-dtoa.cc',
+ 'test-checks.cc',
'test-circular-queue.cc',
'test-compiler.cc',
- 'test-condition-variable.cc',
'test-constantpool.cc',
'test-conversions.cc',
- 'test-cpu.cc',
'test-cpu-profiler.cc',
'test-dataflow.cc',
'test-date.cc',
@@ -77,12 +117,15 @@
'test-fixed-dtoa.cc',
'test-flags.cc',
'test-func-name-inference.cc',
+ 'test-gc-tracer.cc',
'test-global-handles.cc',
'test-global-object.cc',
'test-hashing.cc',
'test-hashmap.cc',
'test-heap.cc',
'test-heap-profiler.cc',
+ 'test-hydrogen-types.cc',
+ 'test-libplatform-default-platform.cc',
'test-libplatform-task-queue.cc',
'test-libplatform-worker-thread.cc',
'test-list.cc',
@@ -92,12 +135,11 @@
'test-microtask-delivery.cc',
'test-mark-compact.cc',
'test-mementos.cc',
- 'test-mutex.cc',
'test-object-observe.cc',
'test-ordered-hash-table.cc',
+ 'test-ostreams.cc',
'test-parsing.cc',
'test-platform.cc',
- 'test-platform-tls.cc',
'test-profile-generator.cc',
'test-random-number-generator.cc',
'test-regexp.cc',
@@ -105,17 +147,16 @@
'test-representation.cc',
'test-semaphore.cc',
'test-serialize.cc',
- 'test-socket.cc',
'test-spaces.cc',
'test-strings.cc',
'test-symbols.cc',
'test-strtod.cc',
'test-thread-termination.cc',
'test-threads.cc',
- 'test-time.cc',
'test-types.cc',
'test-unbound-queue.cc',
'test-unique.cc',
+ 'test-unscopables-hidden-prototype.cc',
'test-utils.cc',
'test-version.cc',
'test-weakmaps.cc',
@@ -126,10 +167,10 @@
'conditions': [
['v8_target_arch=="ia32"', {
'sources': [ ### gcmole(arch:ia32) ###
+ 'compiler/test-instruction-selector-ia32.cc',
'test-assembler-ia32.cc',
'test-code-stubs.cc',
'test-code-stubs-ia32.cc',
- 'test-cpu-ia32.cc',
'test-disasm-ia32.cc',
'test-macro-assembler-ia32.cc',
'test-log-stack-tracer.cc'
@@ -140,7 +181,6 @@
'test-assembler-x64.cc',
'test-code-stubs.cc',
'test-code-stubs-x64.cc',
- 'test-cpu-x64.cc',
'test-disasm-x64.cc',
'test-macro-assembler-x64.cc',
'test-log-stack-tracer.cc'
@@ -148,6 +188,7 @@
}],
['v8_target_arch=="arm"', {
'sources': [ ### gcmole(arch:arm) ###
+ 'compiler/test-instruction-selector-arm.cc',
'test-assembler-arm.cc',
'test-code-stubs.cc',
'test-code-stubs-arm.cc',
@@ -176,14 +217,28 @@
'test-macro-assembler-mips.cc'
],
}],
- [ 'OS=="linux" or OS=="qnx"', {
+ ['v8_target_arch=="mips64el"', {
'sources': [
- 'test-platform-linux.cc',
+ 'test-assembler-mips64.cc',
+ 'test-code-stubs.cc',
+ 'test-code-stubs-mips64.cc',
+ 'test-disasm-mips64.cc',
+ 'test-macro-assembler-mips64.cc'
],
}],
- [ 'OS=="mac"', {
+ ['v8_target_arch=="x87"', {
+ 'sources': [ ### gcmole(arch:x87) ###
+ 'test-assembler-x87.cc',
+ 'test-code-stubs.cc',
+ 'test-code-stubs-x87.cc',
+ 'test-disasm-x87.cc',
+ 'test-macro-assembler-x87.cc',
+ 'test-log-stack-tracer.cc'
+ ],
+ }],
+ [ 'OS=="linux" or OS=="qnx"', {
'sources': [
- 'test-platform-macos.cc',
+ 'test-platform-linux.cc',
],
}],
[ 'OS=="win"', {
@@ -206,7 +261,7 @@
},
{
'dependencies': [
- '../../tools/gyp/v8.gyp:v8_nosnapshot.<(v8_target_arch)',
+ '../../tools/gyp/v8.gyp:v8_nosnapshot',
],
}],
],
diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h
index 36e1b96eb..2ab973c52 100644
--- a/deps/v8/test/cctest/cctest.h
+++ b/deps/v8/test/cctest/cctest.h
@@ -28,7 +28,9 @@
#ifndef CCTEST_H_
#define CCTEST_H_
-#include "v8.h"
+#include "src/v8.h"
+
+#include "src/isolate-inl.h"
#ifndef TEST
#define TEST(Name) \
@@ -83,7 +85,6 @@ typedef v8::internal::EnumSet<CcTestExtensionIds> CcTestExtensionFlags;
// Use this to expose protected methods in i::Heap.
class TestHeap : public i::Heap {
public:
- using i::Heap::AllocateArgumentsObject;
using i::Heap::AllocateByteArray;
using i::Heap::AllocateFixedArray;
using i::Heap::AllocateHeapNumber;
@@ -113,6 +114,11 @@ class CcTest {
return isolate_;
}
+ static i::Isolate* InitIsolateOnce() {
+ if (!initialize_called_) InitializeVM();
+ return i_isolate();
+ }
+
static i::Isolate* i_isolate() {
return reinterpret_cast<i::Isolate*>(isolate());
}
@@ -125,6 +131,10 @@ class CcTest {
return reinterpret_cast<TestHeap*>(i_isolate()->heap());
}
+ static v8::base::RandomNumberGenerator* random_number_generator() {
+ return InitIsolateOnce()->random_number_generator();
+ }
+
static v8::Local<v8::Object> global() {
return isolate()->GetCurrentContext()->Global();
}
@@ -177,7 +187,7 @@ class CcTest {
// thread fuzzing test. In the thread fuzzing test it will
// pseudorandomly select a successor thread and switch execution
// to that thread, suspending the current test.
-class ApiTestFuzzer: public v8::internal::Thread {
+class ApiTestFuzzer: public v8::base::Thread {
public:
void CallTest();
@@ -199,11 +209,10 @@ class ApiTestFuzzer: public v8::internal::Thread {
private:
explicit ApiTestFuzzer(int num)
- : Thread("ApiTestFuzzer"),
+ : Thread(Options("ApiTestFuzzer")),
test_number_(num),
gate_(0),
- active_(true) {
- }
+ active_(true) {}
~ApiTestFuzzer() {}
static bool fuzzing_;
@@ -212,11 +221,11 @@ class ApiTestFuzzer: public v8::internal::Thread {
static int active_tests_;
static bool NextThread();
int test_number_;
- v8::internal::Semaphore gate_;
+ v8::base::Semaphore gate_;
bool active_;
void ContextSwitch();
static int GetNextTestNumber();
- static v8::internal::Semaphore all_tests_done_;
+ static v8::base::Semaphore all_tests_done_;
};
@@ -311,6 +320,15 @@ class LocalContext {
v8::Isolate* isolate_;
};
+
+static inline uint16_t* AsciiToTwoByteString(const char* source) {
+ int array_length = i::StrLength(source) + 1;
+ uint16_t* converted = i::NewArray<uint16_t>(array_length);
+ for (int i = 0; i < array_length; i++) converted[i] = source[i];
+ return converted;
+}
+
+
static inline v8::Local<v8::Value> v8_num(double x) {
return v8::Number::New(v8::Isolate::GetCurrent(), x);
}
@@ -363,14 +381,20 @@ static inline v8::Local<v8::Value> CompileRun(v8::Local<v8::String> source) {
}
-static inline v8::Local<v8::Value> PreCompileCompileRun(const char* source) {
+static inline v8::Local<v8::Value> ParserCacheCompileRun(const char* source) {
// Compile once just to get the preparse data, then compile the second time
// using the data.
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::ScriptCompiler::Source script_source(v8_str(source));
v8::ScriptCompiler::Compile(isolate, &script_source,
- v8::ScriptCompiler::kProduceDataToCache);
- return v8::ScriptCompiler::Compile(isolate, &script_source)->Run();
+ v8::ScriptCompiler::kProduceParserCache);
+
+ // Check whether we received cached data, and if so use it.
+ v8::ScriptCompiler::CompileOptions options =
+ script_source.GetCachedData() ? v8::ScriptCompiler::kConsumeParserCache
+ : v8::ScriptCompiler::kNoCompileOptions;
+
+ return v8::ScriptCompiler::Compile(isolate, &script_source, options)->Run();
}
@@ -403,10 +427,49 @@ static inline v8::Local<v8::Value> CompileRunWithOrigin(
}
-// Pick a slightly different port to allow tests to be run in parallel.
-static inline int FlagDependentPortOffset() {
- return ::v8::internal::FLAG_crankshaft == false ? 100 :
- ::v8::internal::FLAG_always_opt ? 200 : 0;
+
+static inline void ExpectString(const char* code, const char* expected) {
+ v8::Local<v8::Value> result = CompileRun(code);
+ CHECK(result->IsString());
+ v8::String::Utf8Value utf8(result);
+ CHECK_EQ(expected, *utf8);
+}
+
+
+static inline void ExpectInt32(const char* code, int expected) {
+ v8::Local<v8::Value> result = CompileRun(code);
+ CHECK(result->IsInt32());
+ CHECK_EQ(expected, result->Int32Value());
+}
+
+
+static inline void ExpectBoolean(const char* code, bool expected) {
+ v8::Local<v8::Value> result = CompileRun(code);
+ CHECK(result->IsBoolean());
+ CHECK_EQ(expected, result->BooleanValue());
+}
+
+
+static inline void ExpectTrue(const char* code) {
+ ExpectBoolean(code, true);
+}
+
+
+static inline void ExpectFalse(const char* code) {
+ ExpectBoolean(code, false);
+}
+
+
+static inline void ExpectObject(const char* code,
+ v8::Local<v8::Value> expected) {
+ v8::Local<v8::Value> result = CompileRun(code);
+ CHECK(result->SameValue(expected));
+}
+
+
+static inline void ExpectUndefined(const char* code) {
+ v8::Local<v8::Value> result = CompileRun(code);
+ CHECK(result->IsUndefined());
}
@@ -431,6 +494,26 @@ static inline void SimulateFullSpace(v8::internal::PagedSpace* space) {
}
+// Helper function that simulates many incremental marking steps until
+// marking is completed.
+static inline void SimulateIncrementalMarking(i::Heap* heap) {
+ i::MarkCompactCollector* collector = heap->mark_compact_collector();
+ i::IncrementalMarking* marking = heap->incremental_marking();
+ if (collector->sweeping_in_progress()) {
+ collector->EnsureSweepingCompleted();
+ }
+ CHECK(marking->IsMarking() || marking->IsStopped());
+ if (marking->IsStopped()) {
+ marking->Start();
+ }
+ CHECK(marking->IsMarking());
+ while (!marking->IsComplete()) {
+ marking->Step(i::MB, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD);
+ }
+ CHECK(marking->IsComplete());
+}
+
+
// Helper class for new allocations tracking and checking.
// To use checking of JS allocations tracking in a test,
// just create an instance of this class.
@@ -453,4 +536,30 @@ class HeapObjectsTracker {
};
+class InitializedHandleScope {
+ public:
+ InitializedHandleScope()
+ : main_isolate_(CcTest::InitIsolateOnce()),
+ handle_scope_(main_isolate_) {}
+
+ // Prefixing the below with main_ reduces a lot of naming clashes.
+ i::Isolate* main_isolate() { return main_isolate_; }
+
+ private:
+ i::Isolate* main_isolate_;
+ i::HandleScope handle_scope_;
+};
+
+
+class HandleAndZoneScope : public InitializedHandleScope {
+ public:
+ HandleAndZoneScope() : main_zone_(main_isolate()) {}
+
+ // Prefixing the below with main_ reduces a lot of naming clashes.
+ i::Zone* main_zone() { return &main_zone_; }
+
+ private:
+ i::Zone main_zone_;
+};
+
#endif // ifndef CCTEST_H_
diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status
index fb73f7a6d..60baaca08 100644
--- a/deps/v8/test/cctest/cctest.status
+++ b/deps/v8/test/cctest/cctest.status
@@ -31,6 +31,7 @@
'test-api/Bug*': [FAIL],
##############################################################################
+
# BUG(382): Weird test. Can't guarantee that it never times out.
'test-api/ApplyInterruption': [PASS, TIMEOUT],
@@ -67,14 +68,102 @@
# This tests only the type system, so there is no point in running several
# variants.
+ 'test-hydrogen-types/*': [PASS, NO_VARIANTS],
'test-types/*': [PASS, NO_VARIANTS],
- # BUG(2999).
- 'test-cpu-profiler/CollectCpuProfile': [PASS, FLAKY],
- # BUG(3287).
- 'test-cpu-profiler/SampleWhenFrameIsNotSetup': [PASS, FLAKY],
- # BUG(3308).
- 'test-cpu-profiler/JsNativeJsRuntimeJsSample': [PASS, FLAKY],
+ # The cpu profiler tests are notoriously flaky.
+ # BUG(2999). (test/cpu-profiler/CollectCpuProfile)
+ # BUG(3287). (test-cpu-profiler/SampleWhenFrameIsNotSetup)
+ 'test-cpu-profiler/*': [PASS, FLAKY],
+
+ ##############################################################################
+ # TurboFan compiler failures.
+
+ # TODO(mstarzinger): These need investigation and are not categorized yet.
+ 'test-cpu-profiler/*': [SKIP],
+ 'test-heap/NextCodeLinkIsWeak': [PASS, NO_VARIANTS],
+
+ # TODO(mstarzinger/verwaest): This access check API is borked.
+ 'test-api/TurnOnAccessCheck': [PASS, NO_VARIANTS],
+ 'test-api/TurnOnAccessCheckAndRecompile': [PASS, NO_VARIANTS],
+
+ # TODO(mstarzinger): Sometimes the try-catch blacklist fails.
+ 'test-debug/DebugEvaluateWithoutStack': [PASS, NO_VARIANTS],
+ 'test-debug/MessageQueues': [PASS, NO_VARIANTS],
+ 'test-debug/NestedBreakEventContextData': [PASS, NO_VARIANTS],
+ 'test-debug/SendClientDataToHandler': [PASS, NO_VARIANTS],
+
+ # TODO(dcarney): C calls are broken all over the place.
+ 'test-run-machops/RunCall*': [SKIP],
+ 'test-run-machops/RunLoadImmIndex': [SKIP],
+ 'test-run-machops/RunSpillLotsOfThingsWithCall': [SKIP],
+
+ # Some tests are just too slow to run for now.
+ 'test-api/Threading*': [PASS, NO_VARIANTS],
+ 'test-api/RequestInterruptTestWithMathAbs': [PASS, NO_VARIANTS],
+ 'test-heap/IncrementalMarkingStepMakesBigProgressWithLargeObjects': [PASS, NO_VARIANTS],
+ 'test-heap-profiler/ManyLocalsInSharedContext': [PASS, NO_VARIANTS],
+ 'test-debug/ThreadedDebugging': [PASS, NO_VARIANTS],
+ 'test-debug/DebugBreakLoop': [PASS, NO_VARIANTS],
+
+ # Support for lazy deoptimization is missing.
+ 'test-deoptimization/DeoptimizeCompare': [PASS, NO_VARIANTS],
+
+ # Support for breakpoints requires using LoadICs and StoreICs.
+ 'test-debug/BreakPointICStore': [PASS, NO_VARIANTS],
+ 'test-debug/BreakPointICLoad': [PASS, NO_VARIANTS],
+ 'test-debug/BreakPointICCall': [PASS, NO_VARIANTS],
+ 'test-debug/BreakPointICCallWithGC': [PASS, NO_VARIANTS],
+ 'test-debug/BreakPointConstructCallWithGC': [PASS, NO_VARIANTS],
+ 'test-debug/BreakPointReturn': [PASS, NO_VARIANTS],
+ 'test-debug/BreakPointThroughJavaScript': [PASS, NO_VARIANTS],
+ 'test-debug/ScriptBreakPointByNameThroughJavaScript': [PASS, NO_VARIANTS],
+ 'test-debug/ScriptBreakPointByIdThroughJavaScript': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepLinear': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepKeyedLoadLoop': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepKeyedStoreLoop': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepNamedLoadLoop': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepNamedStoreLoop': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepLinearMixedICs': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepDeclarations': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepLocals': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepIf': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepSwitch': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepWhile': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepDoWhile': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepFor': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepForContinue': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepForBreak': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepForIn': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepWith': [PASS, NO_VARIANTS],
+ 'test-debug/DebugConditional': [PASS, NO_VARIANTS],
+ 'test-debug/StepInOutSimple': [PASS, NO_VARIANTS],
+ 'test-debug/StepInOutTree': [PASS, NO_VARIANTS],
+ 'test-debug/StepInOutBranch': [PASS, NO_VARIANTS],
+ 'test-debug/DebugBreak': [PASS, NO_VARIANTS],
+ 'test-debug/DebugBreakStackInspection': [PASS, NO_VARIANTS],
+ 'test-debug/BreakMessageWhenMessageHandlerIsReset': [PASS, NO_VARIANTS],
+ 'test-debug/NoDebugBreakInAfterCompileMessageHandler': [PASS, NO_VARIANTS],
+ 'test-debug/DisableBreak': [PASS, NO_VARIANTS],
+ 'test-debug/RegExpDebugBreak': [PASS, NO_VARIANTS],
+ 'test-debug/DebugBreakFunctionApply': [PASS, NO_VARIANTS],
+ 'test-debug/DeoptimizeDuringDebugBreak': [PASS, NO_VARIANTS],
+
+ # Support for %GetFrameDetails is missing and requires checkpoints.
+ 'test-api/Regress385349': [PASS, NO_VARIANTS],
+ 'test-debug/DebuggerStatement': [PASS, NO_VARIANTS],
+ 'test-debug/DebuggerStatementBreakpoint': [PASS, NO_VARIANTS],
+ 'test-debug/DebugEvaluateWithCodeGenerationDisallowed': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepNatives': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepFunctionCall': [PASS, NO_VARIANTS],
+ 'test-debug/DebugStepFunctionApply': [PASS, NO_VARIANTS],
+ 'test-debug/ScriptNameAndData': [PASS, NO_VARIANTS],
+ 'test-debug/ContextData': [PASS, NO_VARIANTS],
+ 'test-debug/DebugBreakInMessageHandler': [PASS, NO_VARIANTS],
+ 'test-debug/CallFunctionInDebugger': [PASS, NO_VARIANTS],
+ 'test-debug/CallingContextIsNotDebugContext': [PASS, NO_VARIANTS],
+ 'test-debug/DebugEventContext': [PASS, NO_VARIANTS],
+ 'test-debug/DebugBreakInline': [PASS, NO_VARIANTS],
############################################################################
# Slow tests.
@@ -90,6 +179,10 @@
'test-api/Bug618': [PASS],
+ # BUG(v8:3385).
+ 'test-serialize/DeserializeFromSecondSerialization': [PASS, FAIL],
+ 'test-serialize/DeserializeFromSecondSerializationAndRunScript2': [PASS, FAIL],
+
# BUG(v8:2999).
'test-cpu-profiler/CollectCpuProfile': [PASS, FAIL],
@@ -101,6 +194,12 @@
# BUG(v8:3247).
'test-mark-compact/NoPromotion': [SKIP],
+
+ # BUG(v8:3446).
+ 'test-mark-compact/Promotion': [PASS, FAIL],
+
+ # BUG(v8:3434).
+ ' test-api/LoadICFastApi_DirectCall_GCMoveStubWithProfiler': [SKIP]
}], # 'arch == arm64'
['arch == arm64 and simulator_run == True', {
@@ -132,7 +231,7 @@
##############################################################################
['no_snap == True', {
# BUG(3215)
- 'test-lockers/MultithreadedParallelIsolates': [PASS, FAIL],
+ 'test-lockers/MultithreadedParallelIsolates': [PASS, FAIL, TIMEOUT],
}], # 'no_snap == True'
##############################################################################
@@ -148,16 +247,19 @@
# BUG(2999).
'test-cpu-profiler/CollectCpuProfile': [PASS, FAIL],
- 'test-cpu-profiler/JsNativeJsSample': [PASS, FLAKY],
-
- # BUG(3055).
- 'test-cpu-profiler/JsNative1JsNative2JsSample': [PASS, ['mode == release', FAIL], ['mode == debug', FLAKY]],
# BUG(3005).
'test-alloc/CodeRange': [PASS, FAIL],
# BUG(3215). Crashes on windows.
'test-lockers/MultithreadedParallelIsolates': [SKIP],
+
+ # BUG(3331). Fails on windows.
+ 'test-heap/NoWeakHashTableLeakWithIncrementalMarking': [SKIP],
+
+ # BUG(v8:3433). Crashes on windows.
+ 'test-cpu-profiler/FunctionApplySample': [SKIP],
+
}], # 'system == windows'
##############################################################################
@@ -187,6 +289,10 @@
'test-api/Threading2': [PASS, SLOW],
'test-api/Threading3': [PASS, SLOW],
'test-api/Threading4': [PASS, SLOW],
+
+ # Crashes due to OOM in simulator.
+ 'test-types/Distributivity1': [PASS, FLAKY],
+ 'test-types/Distributivity2': [PASS, FLAKY],
}], # 'arch == arm'
##############################################################################
@@ -203,6 +309,39 @@
}], # 'arch == mipsel or arch == mips'
##############################################################################
+['arch == mips64el', {
+
+ # BUG(2657): Test sometimes times out on MIPS simulator.
+ 'test-thread-termination/TerminateMultipleV8ThreadsDefaultIsolate': [PASS, TIMEOUT],
+
+ # BUG(v8:3154).
+ 'test-heap/ReleaseOverReservedPages': [PASS, FAIL],
+
+ # BUG(1075): Unresolved crashes on MIPS also.
+ 'test-serialize/Deserialize': [SKIP],
+ 'test-serialize/DeserializeFromSecondSerializationAndRunScript2': [SKIP],
+ 'test-serialize/DeserializeAndRunScript2': [SKIP],
+ 'test-serialize/DeserializeFromSecondSerialization': [SKIP],
+}], # 'arch == mips64el'
+
+##############################################################################
+['arch == x87', {
+
+ # TODO (weiliang): Enable below tests after fixing the double register
+ # allocation limit in X87 port.
+ 'test-serialize/Serialize': [PASS, ['mode == debug', SKIP]],
+ 'test-serialize/Deserialize': [PASS, ['mode == debug', SKIP]],
+ 'test-serialize/SerializeTwice': [PASS, ['mode == debug', SKIP]],
+ 'test-serialize/ContextSerialization': [PASS, ['mode == debug', SKIP]],
+ 'test-serialize/ContextDeserialization': [PASS, ['mode == debug', SKIP]],
+ 'test-serialize/PartialDeserialization': [PASS, ['mode == debug', SKIP]],
+ 'test-serialize/PartialSerialization': [PASS, ['mode == debug', SKIP]],
+ 'test-serialize/DeserializeAndRunScript2': [PASS, ['mode == debug', SKIP]],
+ 'test-serialize/DeserializeFromSecondSerializationAndRunScript2': [PASS, ['mode == debug', SKIP]],
+ 'test-serialize/DeserializeFromSecondSerialization': [PASS, ['mode == debug', SKIP]],
+}], # 'arch == x87'
+
+##############################################################################
['arch == android_arm or arch == android_ia32', {
# Tests crash as there is no /tmp directory in Android.
diff --git a/deps/v8/test/cctest/compiler/call-tester.h b/deps/v8/test/cctest/compiler/call-tester.h
new file mode 100644
index 000000000..40189ab40
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/call-tester.h
@@ -0,0 +1,384 @@
+// 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_CCTEST_COMPILER_CALL_TESTER_H_
+#define V8_CCTEST_COMPILER_CALL_TESTER_H_
+
+#include "src/v8.h"
+
+#include "src/simulator.h"
+
+#if V8_TARGET_ARCH_IA32
+#if __GNUC__
+#define V8_CDECL __attribute__((cdecl))
+#else
+#define V8_CDECL __cdecl
+#endif
+#else
+#define V8_CDECL
+#endif
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+template <typename R>
+struct ReturnValueTraits {
+ static R Cast(uintptr_t r) { return reinterpret_cast<R>(r); }
+ static MachineType Representation() {
+ // TODO(dcarney): detect when R is of a subclass of Object* instead of this
+ // type check.
+ while (false) {
+ *(static_cast<Object* volatile*>(0)) = static_cast<R>(0);
+ }
+ return kMachineTagged;
+ }
+};
+
+template <>
+struct ReturnValueTraits<int32_t*> {
+ static int32_t* Cast(uintptr_t r) { return reinterpret_cast<int32_t*>(r); }
+ static MachineType Representation() {
+ return MachineOperatorBuilder::pointer_rep();
+ }
+};
+
+template <>
+struct ReturnValueTraits<void> {
+ static void Cast(uintptr_t r) {}
+ static MachineType Representation() {
+ return MachineOperatorBuilder::pointer_rep();
+ }
+};
+
+template <>
+struct ReturnValueTraits<bool> {
+ static bool Cast(uintptr_t r) { return static_cast<bool>(r); }
+ static MachineType Representation() {
+ return MachineOperatorBuilder::pointer_rep();
+ }
+};
+
+template <>
+struct ReturnValueTraits<int32_t> {
+ static int32_t Cast(uintptr_t r) { return static_cast<int32_t>(r); }
+ static MachineType Representation() { return kMachineWord32; }
+};
+
+template <>
+struct ReturnValueTraits<uint32_t> {
+ static uint32_t Cast(uintptr_t r) { return static_cast<uint32_t>(r); }
+ static MachineType Representation() { return kMachineWord32; }
+};
+
+template <>
+struct ReturnValueTraits<int64_t> {
+ static int64_t Cast(uintptr_t r) { return static_cast<int64_t>(r); }
+ static MachineType Representation() { return kMachineWord64; }
+};
+
+template <>
+struct ReturnValueTraits<uint64_t> {
+ static uint64_t Cast(uintptr_t r) { return static_cast<uint64_t>(r); }
+ static MachineType Representation() { return kMachineWord64; }
+};
+
+template <>
+struct ReturnValueTraits<int16_t> {
+ static int16_t Cast(uintptr_t r) { return static_cast<int16_t>(r); }
+ static MachineType Representation() {
+ return MachineOperatorBuilder::pointer_rep();
+ }
+};
+
+template <>
+struct ReturnValueTraits<int8_t> {
+ static int8_t Cast(uintptr_t r) { return static_cast<int8_t>(r); }
+ static MachineType Representation() {
+ return MachineOperatorBuilder::pointer_rep();
+ }
+};
+
+template <>
+struct ReturnValueTraits<double> {
+ static double Cast(uintptr_t r) {
+ UNREACHABLE();
+ return 0.0;
+ }
+ static MachineType Representation() { return kMachineFloat64; }
+};
+
+
+template <typename R>
+struct ParameterTraits {
+ static uintptr_t Cast(R r) { return static_cast<uintptr_t>(r); }
+};
+
+template <>
+struct ParameterTraits<int*> {
+ static uintptr_t Cast(int* r) { return reinterpret_cast<uintptr_t>(r); }
+};
+
+template <typename T>
+struct ParameterTraits<T*> {
+ static uintptr_t Cast(void* r) { return reinterpret_cast<uintptr_t>(r); }
+};
+
+class CallHelper {
+ public:
+ explicit CallHelper(Isolate* isolate) : isolate_(isolate) { USE(isolate_); }
+ virtual ~CallHelper() {}
+
+ static MachineCallDescriptorBuilder* ToCallDescriptorBuilder(
+ Zone* zone, MachineType return_type, MachineType p0 = kMachineLast,
+ MachineType p1 = kMachineLast, MachineType p2 = kMachineLast,
+ MachineType p3 = kMachineLast, MachineType p4 = kMachineLast) {
+ const int kSize = 5;
+ MachineType* params = zone->NewArray<MachineType>(kSize);
+ params[0] = p0;
+ params[1] = p1;
+ params[2] = p2;
+ params[3] = p3;
+ params[4] = p4;
+ int parameter_count = 0;
+ for (int i = 0; i < kSize; ++i) {
+ if (params[i] == kMachineLast) {
+ break;
+ }
+ parameter_count++;
+ }
+ return new (zone)
+ MachineCallDescriptorBuilder(return_type, parameter_count, params);
+ }
+
+ protected:
+ virtual void VerifyParameters(int parameter_count,
+ MachineType* parameters) = 0;
+ virtual byte* Generate() = 0;
+
+ private:
+#if USE_SIMULATOR && V8_TARGET_ARCH_ARM64
+ uintptr_t CallSimulator(byte* f, Simulator::CallArgument* args) {
+ Simulator* simulator = Simulator::current(isolate_);
+ return static_cast<uintptr_t>(simulator->CallInt64(f, args));
+ }
+
+ template <typename R, typename F>
+ R DoCall(F* f) {
+ Simulator::CallArgument args[] = {Simulator::CallArgument::End()};
+ return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+ }
+ template <typename R, typename F, typename P1>
+ R DoCall(F* f, P1 p1) {
+ Simulator::CallArgument args[] = {Simulator::CallArgument(p1),
+ Simulator::CallArgument::End()};
+ return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+ }
+ template <typename R, typename F, typename P1, typename P2>
+ R DoCall(F* f, P1 p1, P2 p2) {
+ Simulator::CallArgument args[] = {Simulator::CallArgument(p1),
+ Simulator::CallArgument(p2),
+ Simulator::CallArgument::End()};
+ return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+ }
+ template <typename R, typename F, typename P1, typename P2, typename P3>
+ R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
+ Simulator::CallArgument args[] = {
+ Simulator::CallArgument(p1), Simulator::CallArgument(p2),
+ Simulator::CallArgument(p3), Simulator::CallArgument::End()};
+ return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+ }
+ template <typename R, typename F, typename P1, typename P2, typename P3,
+ typename P4>
+ R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) {
+ Simulator::CallArgument args[] = {
+ Simulator::CallArgument(p1), Simulator::CallArgument(p2),
+ Simulator::CallArgument(p3), Simulator::CallArgument(p4),
+ Simulator::CallArgument::End()};
+ return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+ }
+#elif USE_SIMULATOR && V8_TARGET_ARCH_ARM
+ uintptr_t CallSimulator(byte* f, int32_t p1 = 0, int32_t p2 = 0,
+ int32_t p3 = 0, int32_t p4 = 0) {
+ Simulator* simulator = Simulator::current(isolate_);
+ return static_cast<uintptr_t>(simulator->Call(f, 4, p1, p2, p3, p4));
+ }
+ template <typename R, typename F>
+ R DoCall(F* f) {
+ return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f)));
+ }
+ template <typename R, typename F, typename P1>
+ R DoCall(F* f, P1 p1) {
+ return ReturnValueTraits<R>::Cast(
+ CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1)));
+ }
+ template <typename R, typename F, typename P1, typename P2>
+ R DoCall(F* f, P1 p1, P2 p2) {
+ return ReturnValueTraits<R>::Cast(
+ CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
+ ParameterTraits<P2>::Cast(p2)));
+ }
+ template <typename R, typename F, typename P1, typename P2, typename P3>
+ R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
+ return ReturnValueTraits<R>::Cast(CallSimulator(
+ FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
+ ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3)));
+ }
+ template <typename R, typename F, typename P1, typename P2, typename P3,
+ typename P4>
+ R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) {
+ return ReturnValueTraits<R>::Cast(CallSimulator(
+ FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
+ ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3),
+ ParameterTraits<P4>::Cast(p4)));
+ }
+#else
+ template <typename R, typename F>
+ R DoCall(F* f) {
+ return f();
+ }
+ template <typename R, typename F, typename P1>
+ R DoCall(F* f, P1 p1) {
+ return f(p1);
+ }
+ template <typename R, typename F, typename P1, typename P2>
+ R DoCall(F* f, P1 p1, P2 p2) {
+ return f(p1, p2);
+ }
+ template <typename R, typename F, typename P1, typename P2, typename P3>
+ R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
+ return f(p1, p2, p3);
+ }
+ template <typename R, typename F, typename P1, typename P2, typename P3,
+ typename P4>
+ R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) {
+ return f(p1, p2, p3, p4);
+ }
+#endif
+
+#ifndef DEBUG
+ void VerifyParameters0() {}
+
+ template <typename P1>
+ void VerifyParameters1() {}
+
+ template <typename P1, typename P2>
+ void VerifyParameters2() {}
+
+ template <typename P1, typename P2, typename P3>
+ void VerifyParameters3() {}
+
+ template <typename P1, typename P2, typename P3, typename P4>
+ void VerifyParameters4() {}
+#else
+ void VerifyParameters0() { VerifyParameters(0, NULL); }
+
+ template <typename P1>
+ void VerifyParameters1() {
+ MachineType parameters[] = {ReturnValueTraits<P1>::Representation()};
+ VerifyParameters(ARRAY_SIZE(parameters), parameters);
+ }
+
+ template <typename P1, typename P2>
+ void VerifyParameters2() {
+ MachineType parameters[] = {ReturnValueTraits<P1>::Representation(),
+ ReturnValueTraits<P2>::Representation()};
+ VerifyParameters(ARRAY_SIZE(parameters), parameters);
+ }
+
+ template <typename P1, typename P2, typename P3>
+ void VerifyParameters3() {
+ MachineType parameters[] = {ReturnValueTraits<P1>::Representation(),
+ ReturnValueTraits<P2>::Representation(),
+ ReturnValueTraits<P3>::Representation()};
+ VerifyParameters(ARRAY_SIZE(parameters), parameters);
+ }
+
+ template <typename P1, typename P2, typename P3, typename P4>
+ void VerifyParameters4() {
+ MachineType parameters[] = {ReturnValueTraits<P1>::Representation(),
+ ReturnValueTraits<P2>::Representation(),
+ ReturnValueTraits<P3>::Representation(),
+ ReturnValueTraits<P4>::Representation()};
+ VerifyParameters(ARRAY_SIZE(parameters), parameters);
+ }
+#endif
+
+ // TODO(dcarney): replace Call() in CallHelper2 with these.
+ template <typename R>
+ R Call0() {
+ typedef R V8_CDECL FType();
+ VerifyParameters0();
+ return DoCall<R>(FUNCTION_CAST<FType*>(Generate()));
+ }
+
+ template <typename R, typename P1>
+ R Call1(P1 p1) {
+ typedef R V8_CDECL FType(P1);
+ VerifyParameters1<P1>();
+ return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1);
+ }
+
+ template <typename R, typename P1, typename P2>
+ R Call2(P1 p1, P2 p2) {
+ typedef R V8_CDECL FType(P1, P2);
+ VerifyParameters2<P1, P2>();
+ return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2);
+ }
+
+ template <typename R, typename P1, typename P2, typename P3>
+ R Call3(P1 p1, P2 p2, P3 p3) {
+ typedef R V8_CDECL FType(P1, P2, P3);
+ VerifyParameters3<P1, P2, P3>();
+ return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3);
+ }
+
+ template <typename R, typename P1, typename P2, typename P3, typename P4>
+ R Call4(P1 p1, P2 p2, P3 p3, P4 p4) {
+ typedef R V8_CDECL FType(P1, P2, P3, P4);
+ VerifyParameters4<P1, P2, P3, P4>();
+ return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4);
+ }
+
+ template <typename R, typename C>
+ friend class CallHelper2;
+ Isolate* isolate_;
+};
+
+
+// TODO(dcarney): replace CallHelper with CallHelper2 and rename.
+template <typename R, typename C>
+class CallHelper2 {
+ public:
+ R Call() { return helper()->template Call0<R>(); }
+
+ template <typename P1>
+ R Call(P1 p1) {
+ return helper()->template Call1<R>(p1);
+ }
+
+ template <typename P1, typename P2>
+ R Call(P1 p1, P2 p2) {
+ return helper()->template Call2<R>(p1, p2);
+ }
+
+ template <typename P1, typename P2, typename P3>
+ R Call(P1 p1, P2 p2, P3 p3) {
+ return helper()->template Call3<R>(p1, p2, p3);
+ }
+
+ template <typename P1, typename P2, typename P3, typename P4>
+ R Call(P1 p1, P2 p2, P3 p3, P4 p4) {
+ return helper()->template Call4<R>(p1, p2, p3, p4);
+ }
+
+ private:
+ CallHelper* helper() { return static_cast<C*>(this); }
+};
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
+
+#endif // V8_CCTEST_COMPILER_CALL_TESTER_H_
diff --git a/deps/v8/test/cctest/compiler/codegen-tester.cc b/deps/v8/test/cctest/compiler/codegen-tester.cc
new file mode 100644
index 000000000..24b2c6e9f
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/codegen-tester.cc
@@ -0,0 +1,578 @@
+// 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 "src/v8.h"
+
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/codegen-tester.h"
+#include "test/cctest/compiler/value-helper.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+TEST(CompareWrapper) {
+ // Who tests the testers?
+ // If CompareWrapper is broken, then test expectations will be broken.
+ RawMachineAssemblerTester<int32_t> m;
+ CompareWrapper wWord32Equal(IrOpcode::kWord32Equal);
+ CompareWrapper wInt32LessThan(IrOpcode::kInt32LessThan);
+ CompareWrapper wInt32LessThanOrEqual(IrOpcode::kInt32LessThanOrEqual);
+ CompareWrapper wUint32LessThan(IrOpcode::kUint32LessThan);
+ CompareWrapper wUint32LessThanOrEqual(IrOpcode::kUint32LessThanOrEqual);
+
+ {
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ int32_t a = *pl;
+ int32_t b = *pr;
+ CHECK_EQ(a == b, wWord32Equal.Int32Compare(a, b));
+ CHECK_EQ(a < b, wInt32LessThan.Int32Compare(a, b));
+ CHECK_EQ(a <= b, wInt32LessThanOrEqual.Int32Compare(a, b));
+ }
+ }
+ }
+
+ {
+ FOR_UINT32_INPUTS(pl) {
+ FOR_UINT32_INPUTS(pr) {
+ uint32_t a = *pl;
+ uint32_t b = *pr;
+ CHECK_EQ(a == b, wWord32Equal.Int32Compare(a, b));
+ CHECK_EQ(a < b, wUint32LessThan.Int32Compare(a, b));
+ CHECK_EQ(a <= b, wUint32LessThanOrEqual.Int32Compare(a, b));
+ }
+ }
+ }
+
+ CHECK_EQ(true, wWord32Equal.Int32Compare(0, 0));
+ CHECK_EQ(true, wWord32Equal.Int32Compare(257, 257));
+ CHECK_EQ(true, wWord32Equal.Int32Compare(65539, 65539));
+ CHECK_EQ(true, wWord32Equal.Int32Compare(-1, -1));
+ CHECK_EQ(true, wWord32Equal.Int32Compare(0xffffffff, 0xffffffff));
+
+ CHECK_EQ(false, wWord32Equal.Int32Compare(0, 1));
+ CHECK_EQ(false, wWord32Equal.Int32Compare(257, 256));
+ CHECK_EQ(false, wWord32Equal.Int32Compare(65539, 65537));
+ CHECK_EQ(false, wWord32Equal.Int32Compare(-1, -2));
+ CHECK_EQ(false, wWord32Equal.Int32Compare(0xffffffff, 0xfffffffe));
+
+ CHECK_EQ(false, wInt32LessThan.Int32Compare(0, 0));
+ CHECK_EQ(false, wInt32LessThan.Int32Compare(357, 357));
+ CHECK_EQ(false, wInt32LessThan.Int32Compare(75539, 75539));
+ CHECK_EQ(false, wInt32LessThan.Int32Compare(-1, -1));
+ CHECK_EQ(false, wInt32LessThan.Int32Compare(0xffffffff, 0xffffffff));
+
+ CHECK_EQ(true, wInt32LessThan.Int32Compare(0, 1));
+ CHECK_EQ(true, wInt32LessThan.Int32Compare(456, 457));
+ CHECK_EQ(true, wInt32LessThan.Int32Compare(85537, 85539));
+ CHECK_EQ(true, wInt32LessThan.Int32Compare(-2, -1));
+ CHECK_EQ(true, wInt32LessThan.Int32Compare(0xfffffffe, 0xffffffff));
+
+ CHECK_EQ(false, wInt32LessThan.Int32Compare(1, 0));
+ CHECK_EQ(false, wInt32LessThan.Int32Compare(457, 456));
+ CHECK_EQ(false, wInt32LessThan.Int32Compare(85539, 85537));
+ CHECK_EQ(false, wInt32LessThan.Int32Compare(-1, -2));
+ CHECK_EQ(false, wInt32LessThan.Int32Compare(0xffffffff, 0xfffffffe));
+
+ CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(0, 0));
+ CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(357, 357));
+ CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(75539, 75539));
+ CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(-1, -1));
+ CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(0xffffffff, 0xffffffff));
+
+ CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(0, 1));
+ CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(456, 457));
+ CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(85537, 85539));
+ CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(-2, -1));
+ CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(0xfffffffe, 0xffffffff));
+
+ CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(1, 0));
+ CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(457, 456));
+ CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(85539, 85537));
+ CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(-1, -2));
+ CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(0xffffffff, 0xfffffffe));
+
+ // Unsigned comparisons.
+ CHECK_EQ(false, wUint32LessThan.Int32Compare(0, 0));
+ CHECK_EQ(false, wUint32LessThan.Int32Compare(357, 357));
+ CHECK_EQ(false, wUint32LessThan.Int32Compare(75539, 75539));
+ CHECK_EQ(false, wUint32LessThan.Int32Compare(-1, -1));
+ CHECK_EQ(false, wUint32LessThan.Int32Compare(0xffffffff, 0xffffffff));
+ CHECK_EQ(false, wUint32LessThan.Int32Compare(0xffffffff, 0));
+ CHECK_EQ(false, wUint32LessThan.Int32Compare(-2999, 0));
+
+ CHECK_EQ(true, wUint32LessThan.Int32Compare(0, 1));
+ CHECK_EQ(true, wUint32LessThan.Int32Compare(456, 457));
+ CHECK_EQ(true, wUint32LessThan.Int32Compare(85537, 85539));
+ CHECK_EQ(true, wUint32LessThan.Int32Compare(-11, -10));
+ CHECK_EQ(true, wUint32LessThan.Int32Compare(0xfffffffe, 0xffffffff));
+ CHECK_EQ(true, wUint32LessThan.Int32Compare(0, 0xffffffff));
+ CHECK_EQ(true, wUint32LessThan.Int32Compare(0, -2996));
+
+ CHECK_EQ(false, wUint32LessThan.Int32Compare(1, 0));
+ CHECK_EQ(false, wUint32LessThan.Int32Compare(457, 456));
+ CHECK_EQ(false, wUint32LessThan.Int32Compare(85539, 85537));
+ CHECK_EQ(false, wUint32LessThan.Int32Compare(-10, -21));
+ CHECK_EQ(false, wUint32LessThan.Int32Compare(0xffffffff, 0xfffffffe));
+
+ CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0, 0));
+ CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(357, 357));
+ CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(75539, 75539));
+ CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(-1, -1));
+ CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0xffffffff, 0xffffffff));
+
+ CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0, 1));
+ CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(456, 457));
+ CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(85537, 85539));
+ CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(-300, -299));
+ CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(-300, -300));
+ CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0xfffffffe, 0xffffffff));
+ CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0, -2995));
+
+ CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(1, 0));
+ CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(457, 456));
+ CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(85539, 85537));
+ CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(-130, -170));
+ CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(0xffffffff, 0xfffffffe));
+ CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(-2997, 0));
+
+ CompareWrapper wFloat64Equal(IrOpcode::kFloat64Equal);
+ CompareWrapper wFloat64LessThan(IrOpcode::kFloat64LessThan);
+ CompareWrapper wFloat64LessThanOrEqual(IrOpcode::kFloat64LessThanOrEqual);
+
+ // Check NaN handling.
+ double nan = v8::base::OS::nan_value();
+ double inf = V8_INFINITY;
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, 0.0));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, 1.0));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, inf));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, -inf));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, nan));
+
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(0.0, nan));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(1.0, nan));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, nan));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, nan));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, nan));
+
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, 0.0));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, 1.0));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, inf));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, -inf));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, nan));
+
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(0.0, nan));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(1.0, nan));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, nan));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(-inf, nan));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, nan));
+
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, 0.0));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, 1.0));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, inf));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, -inf));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, nan));
+
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(0.0, nan));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(1.0, nan));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, nan));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(-inf, nan));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, nan));
+
+ // Check inf handling.
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, 0.0));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, 1.0));
+ CHECK_EQ(true, wFloat64Equal.Float64Compare(inf, inf));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, -inf));
+
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(0.0, inf));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(1.0, inf));
+ CHECK_EQ(true, wFloat64Equal.Float64Compare(inf, inf));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, inf));
+
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, 0.0));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, 1.0));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, inf));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, -inf));
+
+ CHECK_EQ(true, wFloat64LessThan.Float64Compare(0.0, inf));
+ CHECK_EQ(true, wFloat64LessThan.Float64Compare(1.0, inf));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, inf));
+ CHECK_EQ(true, wFloat64LessThan.Float64Compare(-inf, inf));
+
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, 0.0));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, 1.0));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(inf, inf));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, -inf));
+
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(0.0, inf));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(1.0, inf));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(inf, inf));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, inf));
+
+ // Check -inf handling.
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, 0.0));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, 1.0));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, inf));
+ CHECK_EQ(true, wFloat64Equal.Float64Compare(-inf, -inf));
+
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(0.0, -inf));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(1.0, -inf));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, -inf));
+ CHECK_EQ(true, wFloat64Equal.Float64Compare(-inf, -inf));
+
+ CHECK_EQ(true, wFloat64LessThan.Float64Compare(-inf, 0.0));
+ CHECK_EQ(true, wFloat64LessThan.Float64Compare(-inf, 1.0));
+ CHECK_EQ(true, wFloat64LessThan.Float64Compare(-inf, inf));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(-inf, -inf));
+
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(0.0, -inf));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(1.0, -inf));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, -inf));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(-inf, -inf));
+
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, 0.0));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, 1.0));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, inf));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, -inf));
+
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(0.0, -inf));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(1.0, -inf));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, -inf));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, -inf));
+
+ // Check basic values.
+ CHECK_EQ(true, wFloat64Equal.Float64Compare(0, 0));
+ CHECK_EQ(true, wFloat64Equal.Float64Compare(257.1, 257.1));
+ CHECK_EQ(true, wFloat64Equal.Float64Compare(65539.1, 65539.1));
+ CHECK_EQ(true, wFloat64Equal.Float64Compare(-1.1, -1.1));
+
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(0, 1));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(257.2, 256.2));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(65539.2, 65537.2));
+ CHECK_EQ(false, wFloat64Equal.Float64Compare(-1.2, -2.2));
+
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(0, 0));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(357.3, 357.3));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(75539.3, 75539.3));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(-1.3, -1.3));
+
+ CHECK_EQ(true, wFloat64LessThan.Float64Compare(0, 1));
+ CHECK_EQ(true, wFloat64LessThan.Float64Compare(456.4, 457.4));
+ CHECK_EQ(true, wFloat64LessThan.Float64Compare(85537.4, 85539.4));
+ CHECK_EQ(true, wFloat64LessThan.Float64Compare(-2.4, -1.4));
+
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(1, 0));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(457.5, 456.5));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(85539.5, 85537.5));
+ CHECK_EQ(false, wFloat64LessThan.Float64Compare(-1.5, -2.5));
+
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(0, 0));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(357.6, 357.6));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(75539.6, 75539.6));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-1.6, -1.6));
+
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(0, 1));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(456.7, 457.7));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(85537.7, 85539.7));
+ CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-2.7, -1.7));
+
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(1, 0));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(457.8, 456.8));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(85539.8, 85537.8));
+ CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(-1.8, -2.8));
+}
+
+
+void Int32BinopInputShapeTester::TestAllInputShapes() {
+ std::vector<int32_t> inputs = ValueHelper::int32_vector();
+ int num_int_inputs = static_cast<int>(inputs.size());
+ if (num_int_inputs > 16) num_int_inputs = 16; // limit to 16 inputs
+
+ for (int i = -2; i < num_int_inputs; i++) { // for all left shapes
+ for (int j = -2; j < num_int_inputs; j++) { // for all right shapes
+ if (i >= 0 && j >= 0) break; // No constant/constant combos
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
+ Node* p0 = m.Parameter(0);
+ Node* p1 = m.Parameter(1);
+ Node* n0;
+ Node* n1;
+
+ // left = Parameter | Load | Constant
+ if (i == -2) {
+ n0 = p0;
+ } else if (i == -1) {
+ n0 = m.LoadFromPointer(&input_a, kMachineWord32);
+ } else {
+ n0 = m.Int32Constant(inputs[i]);
+ }
+
+ // right = Parameter | Load | Constant
+ if (j == -2) {
+ n1 = p1;
+ } else if (j == -1) {
+ n1 = m.LoadFromPointer(&input_b, kMachineWord32);
+ } else {
+ n1 = m.Int32Constant(inputs[j]);
+ }
+
+ gen->gen(&m, n0, n1);
+
+ if (false) printf("Int32BinopInputShapeTester i=%d, j=%d\n", i, j);
+ if (i >= 0) {
+ input_a = inputs[i];
+ RunRight(&m);
+ } else if (j >= 0) {
+ input_b = inputs[j];
+ RunLeft(&m);
+ } else {
+ Run(&m);
+ }
+ }
+ }
+}
+
+
+void Int32BinopInputShapeTester::Run(RawMachineAssemblerTester<int32_t>* m) {
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ input_a = *pl;
+ input_b = *pr;
+ int32_t expect = gen->expected(input_a, input_b);
+ if (false) printf(" cmp(a=%d, b=%d) ?== %d\n", input_a, input_b, expect);
+ CHECK_EQ(expect, m->Call(input_a, input_b));
+ }
+ }
+}
+
+
+void Int32BinopInputShapeTester::RunLeft(
+ RawMachineAssemblerTester<int32_t>* m) {
+ FOR_UINT32_INPUTS(i) {
+ input_a = *i;
+ int32_t expect = gen->expected(input_a, input_b);
+ if (false) printf(" cmp(a=%d, b=%d) ?== %d\n", input_a, input_b, expect);
+ CHECK_EQ(expect, m->Call(input_a, input_b));
+ }
+}
+
+
+void Int32BinopInputShapeTester::RunRight(
+ RawMachineAssemblerTester<int32_t>* m) {
+ FOR_UINT32_INPUTS(i) {
+ input_b = *i;
+ int32_t expect = gen->expected(input_a, input_b);
+ if (false) printf(" cmp(a=%d, b=%d) ?== %d\n", input_a, input_b, expect);
+ CHECK_EQ(expect, m->Call(input_a, input_b));
+ }
+}
+
+
+TEST(ParametersEqual) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
+ Node* p1 = m.Parameter(1);
+ CHECK_NE(NULL, p1);
+ Node* p0 = m.Parameter(0);
+ CHECK_NE(NULL, p0);
+ CHECK_EQ(p0, m.Parameter(0));
+ CHECK_EQ(p1, m.Parameter(1));
+}
+
+
+#if V8_TURBOFAN_TARGET
+
+void RunSmiConstant(int32_t v) {
+// TODO(dcarney): on x64 Smis are generated with the SmiConstantRegister
+#if !V8_TARGET_ARCH_X64
+ if (Smi::IsValid(v)) {
+ RawMachineAssemblerTester<Object*> m;
+ m.Return(m.NumberConstant(v));
+ CHECK_EQ(Smi::FromInt(v), m.Call());
+ }
+#endif
+}
+
+
+void RunNumberConstant(double v) {
+ RawMachineAssemblerTester<Object*> m;
+#if V8_TARGET_ARCH_X64
+ // TODO(dcarney): on x64 Smis are generated with the SmiConstantRegister
+ Handle<Object> number = m.isolate()->factory()->NewNumber(v);
+ if (number->IsSmi()) return;
+#endif
+ m.Return(m.NumberConstant(v));
+ Object* result = m.Call();
+ m.CheckNumber(v, result);
+}
+
+
+TEST(RunEmpty) {
+ RawMachineAssemblerTester<int32_t> m;
+ m.Return(m.Int32Constant(0));
+ CHECK_EQ(0, m.Call());
+}
+
+
+TEST(RunInt32Constants) {
+ FOR_INT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m;
+ m.Return(m.Int32Constant(*i));
+ CHECK_EQ(*i, m.Call());
+ }
+}
+
+
+TEST(RunSmiConstants) {
+ for (int32_t i = 1; i < Smi::kMaxValue && i != 0; i = i << 1) {
+ RunSmiConstant(i);
+ RunSmiConstant(3 * i);
+ RunSmiConstant(5 * i);
+ RunSmiConstant(-i);
+ RunSmiConstant(i | 1);
+ RunSmiConstant(i | 3);
+ }
+ RunSmiConstant(Smi::kMaxValue);
+ RunSmiConstant(Smi::kMaxValue - 1);
+ RunSmiConstant(Smi::kMinValue);
+ RunSmiConstant(Smi::kMinValue + 1);
+
+ FOR_INT32_INPUTS(i) { RunSmiConstant(*i); }
+}
+
+
+TEST(RunNumberConstants) {
+ {
+ FOR_FLOAT64_INPUTS(i) { RunNumberConstant(*i); }
+ }
+ {
+ FOR_INT32_INPUTS(i) { RunNumberConstant(*i); }
+ }
+
+ for (int32_t i = 1; i < Smi::kMaxValue && i != 0; i = i << 1) {
+ RunNumberConstant(i);
+ RunNumberConstant(-i);
+ RunNumberConstant(i | 1);
+ RunNumberConstant(i | 3);
+ }
+ RunNumberConstant(Smi::kMaxValue);
+ RunNumberConstant(Smi::kMaxValue - 1);
+ RunNumberConstant(Smi::kMinValue);
+ RunNumberConstant(Smi::kMinValue + 1);
+}
+
+
+TEST(RunEmptyString) {
+ RawMachineAssemblerTester<Object*> m;
+ m.Return(m.StringConstant("empty"));
+ m.CheckString("empty", m.Call());
+}
+
+
+TEST(RunHeapConstant) {
+ RawMachineAssemblerTester<Object*> m;
+ m.Return(m.StringConstant("empty"));
+ m.CheckString("empty", m.Call());
+}
+
+
+TEST(RunHeapNumberConstant) {
+ RawMachineAssemblerTester<Object*> m;
+ Handle<Object> number = m.isolate()->factory()->NewHeapNumber(100.5);
+ m.Return(m.HeapConstant(number));
+ Object* result = m.Call();
+ CHECK_EQ(result, *number);
+}
+
+
+TEST(RunParam1) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Parameter(0));
+
+ FOR_INT32_INPUTS(i) {
+ int32_t result = m.Call(*i);
+ CHECK_EQ(*i, result);
+ }
+}
+
+
+TEST(RunParam2_1) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
+ Node* p0 = m.Parameter(0);
+ Node* p1 = m.Parameter(1);
+ m.Return(p0);
+ USE(p1);
+
+ FOR_INT32_INPUTS(i) {
+ int32_t result = m.Call(*i, -9999);
+ CHECK_EQ(*i, result);
+ }
+}
+
+
+TEST(RunParam2_2) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
+ Node* p0 = m.Parameter(0);
+ Node* p1 = m.Parameter(1);
+ m.Return(p1);
+ USE(p0);
+
+ FOR_INT32_INPUTS(i) {
+ int32_t result = m.Call(-7777, *i);
+ CHECK_EQ(*i, result);
+ }
+}
+
+
+TEST(RunParam3) {
+ for (int i = 0; i < 3; i++) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ Node* nodes[] = {m.Parameter(0), m.Parameter(1), m.Parameter(2)};
+ m.Return(nodes[i]);
+
+ int p[] = {-99, -77, -88};
+ FOR_INT32_INPUTS(j) {
+ p[i] = *j;
+ int32_t result = m.Call(p[0], p[1], p[2]);
+ CHECK_EQ(*j, result);
+ }
+ }
+}
+
+
+TEST(RunBinopTester) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(bt.param0);
+
+ FOR_INT32_INPUTS(i) { CHECK_EQ(*i, bt.call(*i, 777)); }
+ }
+
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(bt.param1);
+
+ FOR_INT32_INPUTS(i) { CHECK_EQ(*i, bt.call(666, *i)); }
+ }
+
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Float64BinopTester bt(&m);
+ bt.AddReturn(bt.param0);
+
+ FOR_FLOAT64_INPUTS(i) { CHECK_EQ(*i, bt.call(*i, 9.0)); }
+ }
+
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Float64BinopTester bt(&m);
+ bt.AddReturn(bt.param1);
+
+ FOR_FLOAT64_INPUTS(i) { CHECK_EQ(*i, bt.call(-11.25, *i)); }
+ }
+}
+
+#endif // V8_TURBOFAN_TARGET
diff --git a/deps/v8/test/cctest/compiler/codegen-tester.h b/deps/v8/test/cctest/compiler/codegen-tester.h
new file mode 100644
index 000000000..300381b49
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/codegen-tester.h
@@ -0,0 +1,353 @@
+// 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_CCTEST_COMPILER_CODEGEN_TESTER_H_
+#define V8_CCTEST_COMPILER_CODEGEN_TESTER_H_
+
+#include "src/v8.h"
+
+#include "src/compiler/pipeline.h"
+#include "src/compiler/raw-machine-assembler.h"
+#include "src/compiler/structured-machine-assembler.h"
+#include "src/simulator.h"
+#include "test/cctest/compiler/call-tester.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+template <typename MachineAssembler>
+class MachineAssemblerTester : public HandleAndZoneScope,
+ public CallHelper,
+ public MachineAssembler {
+ public:
+ MachineAssemblerTester(MachineType return_type, MachineType p0,
+ MachineType p1, MachineType p2, MachineType p3,
+ MachineType p4)
+ : HandleAndZoneScope(),
+ CallHelper(main_isolate()),
+ MachineAssembler(new (main_zone()) Graph(main_zone()),
+ ToCallDescriptorBuilder(main_zone(), return_type, p0,
+ p1, p2, p3, p4),
+ MachineOperatorBuilder::pointer_rep()) {}
+
+ Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) {
+ return this->Load(rep, this->PointerConstant(address),
+ this->Int32Constant(offset));
+ }
+
+ void StoreToPointer(void* address, MachineType rep, Node* node) {
+ this->Store(rep, this->PointerConstant(address), node);
+ }
+
+ Node* StringConstant(const char* string) {
+ return this->HeapConstant(
+ this->isolate()->factory()->InternalizeUtf8String(string));
+ }
+
+ void CheckNumber(double expected, Object* number) {
+ CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number));
+ }
+
+ void CheckString(const char* expected, Object* string) {
+ CHECK(
+ this->isolate()->factory()->InternalizeUtf8String(expected)->SameValue(
+ string));
+ }
+
+ void GenerateCode() { Generate(); }
+
+ protected:
+ virtual void VerifyParameters(int parameter_count,
+ MachineType* parameter_types) {
+ CHECK_EQ(this->parameter_count(), parameter_count);
+ const MachineType* expected_types = this->parameter_types();
+ for (int i = 0; i < parameter_count; i++) {
+ CHECK_EQ(expected_types[i], parameter_types[i]);
+ }
+ }
+
+ virtual byte* Generate() {
+ if (code_.is_null()) {
+ Schedule* schedule = this->Export();
+ CallDescriptor* call_descriptor = this->call_descriptor();
+ Graph* graph = this->graph();
+ CompilationInfo info(graph->zone()->isolate(), graph->zone());
+ Linkage linkage(&info, call_descriptor);
+ Pipeline pipeline(&info);
+ code_ = pipeline.GenerateCodeForMachineGraph(&linkage, graph, schedule);
+ }
+ return this->code_.ToHandleChecked()->entry();
+ }
+
+ private:
+ MaybeHandle<Code> code_;
+};
+
+
+template <typename ReturnType>
+class RawMachineAssemblerTester
+ : public MachineAssemblerTester<RawMachineAssembler>,
+ public CallHelper2<ReturnType, RawMachineAssemblerTester<ReturnType> > {
+ public:
+ RawMachineAssemblerTester(MachineType p0 = kMachineLast,
+ MachineType p1 = kMachineLast,
+ MachineType p2 = kMachineLast,
+ MachineType p3 = kMachineLast,
+ MachineType p4 = kMachineLast)
+ : MachineAssemblerTester<RawMachineAssembler>(
+ ReturnValueTraits<ReturnType>::Representation(), p0, p1, p2, p3,
+ p4) {}
+
+ template <typename Ci, typename Fn>
+ void Run(const Ci& ci, const Fn& fn) {
+ typename Ci::const_iterator i;
+ for (i = ci.begin(); i != ci.end(); ++i) {
+ CHECK_EQ(fn(*i), this->Call(*i));
+ }
+ }
+
+ template <typename Ci, typename Cj, typename Fn>
+ void Run(const Ci& ci, const Cj& cj, const Fn& fn) {
+ typename Ci::const_iterator i;
+ typename Cj::const_iterator j;
+ for (i = ci.begin(); i != ci.end(); ++i) {
+ for (j = cj.begin(); j != cj.end(); ++j) {
+ CHECK_EQ(fn(*i, *j), this->Call(*i, *j));
+ }
+ }
+ }
+};
+
+
+template <typename ReturnType>
+class StructuredMachineAssemblerTester
+ : public MachineAssemblerTester<StructuredMachineAssembler>,
+ public CallHelper2<ReturnType,
+ StructuredMachineAssemblerTester<ReturnType> > {
+ public:
+ StructuredMachineAssemblerTester(MachineType p0 = kMachineLast,
+ MachineType p1 = kMachineLast,
+ MachineType p2 = kMachineLast,
+ MachineType p3 = kMachineLast,
+ MachineType p4 = kMachineLast)
+ : MachineAssemblerTester<StructuredMachineAssembler>(
+ ReturnValueTraits<ReturnType>::Representation(), p0, p1, p2, p3,
+ p4) {}
+};
+
+
+static const bool USE_RESULT_BUFFER = true;
+static const bool USE_RETURN_REGISTER = false;
+static const int32_t CHECK_VALUE = 0x99BEEDCE;
+
+
+// TODO(titzer): use the C-style calling convention, or any register-based
+// calling convention for binop tests.
+template <typename CType, MachineType rep, bool use_result_buffer>
+class BinopTester {
+ public:
+ explicit BinopTester(RawMachineAssemblerTester<int32_t>* tester)
+ : T(tester),
+ param0(T->LoadFromPointer(&p0, rep)),
+ param1(T->LoadFromPointer(&p1, rep)),
+ p0(static_cast<CType>(0)),
+ p1(static_cast<CType>(0)),
+ result(static_cast<CType>(0)) {}
+
+ RawMachineAssemblerTester<int32_t>* T;
+ Node* param0;
+ Node* param1;
+
+ CType call(CType a0, CType a1) {
+ p0 = a0;
+ p1 = a1;
+ if (use_result_buffer) {
+ CHECK_EQ(CHECK_VALUE, T->Call());
+ return result;
+ } else {
+ return T->Call();
+ }
+ }
+
+ void AddReturn(Node* val) {
+ if (use_result_buffer) {
+ T->Store(rep, T->PointerConstant(&result), T->Int32Constant(0), val);
+ T->Return(T->Int32Constant(CHECK_VALUE));
+ } else {
+ T->Return(val);
+ }
+ }
+
+ template <typename Ci, typename Cj, typename Fn>
+ void Run(const Ci& ci, const Cj& cj, const Fn& fn) {
+ typename Ci::const_iterator i;
+ typename Cj::const_iterator j;
+ for (i = ci.begin(); i != ci.end(); ++i) {
+ for (j = cj.begin(); j != cj.end(); ++j) {
+ CHECK_EQ(fn(*i, *j), this->call(*i, *j));
+ }
+ }
+ }
+
+ protected:
+ CType p0;
+ CType p1;
+ CType result;
+};
+
+
+// A helper class for testing code sequences that take two int parameters and
+// return an int value.
+class Int32BinopTester
+ : public BinopTester<int32_t, kMachineWord32, USE_RETURN_REGISTER> {
+ public:
+ explicit Int32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
+ : BinopTester<int32_t, kMachineWord32, USE_RETURN_REGISTER>(tester) {}
+
+ int32_t call(uint32_t a0, uint32_t a1) {
+ p0 = static_cast<int32_t>(a0);
+ p1 = static_cast<int32_t>(a1);
+ return T->Call();
+ }
+};
+
+
+// A helper class for testing code sequences that take two double parameters and
+// return a double value.
+// TODO(titzer): figure out how to return doubles correctly on ia32.
+class Float64BinopTester
+ : public BinopTester<double, kMachineFloat64, USE_RESULT_BUFFER> {
+ public:
+ explicit Float64BinopTester(RawMachineAssemblerTester<int32_t>* tester)
+ : BinopTester<double, kMachineFloat64, USE_RESULT_BUFFER>(tester) {}
+};
+
+
+// A helper class for testing code sequences that take two pointer parameters
+// and return a pointer value.
+// TODO(titzer): pick word size of pointers based on V8_TARGET.
+template <typename Type>
+class PointerBinopTester
+ : public BinopTester<Type*, kMachineWord32, USE_RETURN_REGISTER> {
+ public:
+ explicit PointerBinopTester(RawMachineAssemblerTester<int32_t>* tester)
+ : BinopTester<Type*, kMachineWord32, USE_RETURN_REGISTER>(tester) {}
+};
+
+
+// A helper class for testing code sequences that take two tagged parameters and
+// return a tagged value.
+template <typename Type>
+class TaggedBinopTester
+ : public BinopTester<Type*, kMachineTagged, USE_RETURN_REGISTER> {
+ public:
+ explicit TaggedBinopTester(RawMachineAssemblerTester<int32_t>* tester)
+ : BinopTester<Type*, kMachineTagged, USE_RETURN_REGISTER>(tester) {}
+};
+
+// A helper class for testing compares. Wraps a machine opcode and provides
+// evaluation routines and the operators.
+class CompareWrapper {
+ public:
+ explicit CompareWrapper(IrOpcode::Value op) : opcode(op) {}
+
+ Node* MakeNode(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) {
+ return m->NewNode(op(m->machine()), a, b);
+ }
+
+ Operator* op(MachineOperatorBuilder* machine) {
+ switch (opcode) {
+ case IrOpcode::kWord32Equal:
+ return machine->Word32Equal();
+ case IrOpcode::kInt32LessThan:
+ return machine->Int32LessThan();
+ case IrOpcode::kInt32LessThanOrEqual:
+ return machine->Int32LessThanOrEqual();
+ case IrOpcode::kUint32LessThan:
+ return machine->Uint32LessThan();
+ case IrOpcode::kUint32LessThanOrEqual:
+ return machine->Uint32LessThanOrEqual();
+ case IrOpcode::kFloat64Equal:
+ return machine->Float64Equal();
+ case IrOpcode::kFloat64LessThan:
+ return machine->Float64LessThan();
+ case IrOpcode::kFloat64LessThanOrEqual:
+ return machine->Float64LessThanOrEqual();
+ default:
+ UNREACHABLE();
+ }
+ return NULL;
+ }
+
+ bool Int32Compare(int32_t a, int32_t b) {
+ switch (opcode) {
+ case IrOpcode::kWord32Equal:
+ return a == b;
+ case IrOpcode::kInt32LessThan:
+ return a < b;
+ case IrOpcode::kInt32LessThanOrEqual:
+ return a <= b;
+ case IrOpcode::kUint32LessThan:
+ return static_cast<uint32_t>(a) < static_cast<uint32_t>(b);
+ case IrOpcode::kUint32LessThanOrEqual:
+ return static_cast<uint32_t>(a) <= static_cast<uint32_t>(b);
+ default:
+ UNREACHABLE();
+ }
+ return false;
+ }
+
+ bool Float64Compare(double a, double b) {
+ switch (opcode) {
+ case IrOpcode::kFloat64Equal:
+ return a == b;
+ case IrOpcode::kFloat64LessThan:
+ return a < b;
+ case IrOpcode::kFloat64LessThanOrEqual:
+ return a <= b;
+ default:
+ UNREACHABLE();
+ }
+ return false;
+ }
+
+ IrOpcode::Value opcode;
+};
+
+
+// A small closure class to generate code for a function of two inputs that
+// produces a single output so that it can be used in many different contexts.
+// The {expected()} method should compute the expected output for a given
+// pair of inputs.
+template <typename T>
+class BinopGen {
+ public:
+ virtual void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) = 0;
+ virtual T expected(T a, T b) = 0;
+ virtual ~BinopGen() {}
+};
+
+// A helper class to generate various combination of input shape combinations
+// and run the generated code to ensure it produces the correct results.
+class Int32BinopInputShapeTester {
+ public:
+ explicit Int32BinopInputShapeTester(BinopGen<int32_t>* g) : gen(g) {}
+
+ void TestAllInputShapes();
+
+ private:
+ BinopGen<int32_t>* gen;
+ int32_t input_a;
+ int32_t input_b;
+
+ void Run(RawMachineAssemblerTester<int32_t>* m);
+ void RunLeft(RawMachineAssemblerTester<int32_t>* m);
+ void RunRight(RawMachineAssemblerTester<int32_t>* m);
+};
+} // namespace compiler
+} // namespace internal
+} // namespace v8
+
+#endif // V8_CCTEST_COMPILER_CODEGEN_TESTER_H_
diff --git a/deps/v8/test/cctest/compiler/function-tester.h b/deps/v8/test/cctest/compiler/function-tester.h
new file mode 100644
index 000000000..2ed2fe998
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/function-tester.h
@@ -0,0 +1,194 @@
+// 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_CCTEST_COMPILER_FUNCTION_TESTER_H_
+#define V8_CCTEST_COMPILER_FUNCTION_TESTER_H_
+
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/compiler.h"
+#include "src/compiler/pipeline.h"
+#include "src/execution.h"
+#include "src/full-codegen.h"
+#include "src/handles.h"
+#include "src/objects-inl.h"
+#include "src/parser.h"
+#include "src/rewriter.h"
+#include "src/scopes.h"
+
+#define USE_CRANKSHAFT 0
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class FunctionTester : public InitializedHandleScope {
+ public:
+ explicit FunctionTester(const char* source)
+ : isolate(main_isolate()),
+ function((FLAG_allow_natives_syntax = true, NewFunction(source))) {
+ Compile(function);
+ }
+
+ Isolate* isolate;
+ Handle<JSFunction> function;
+
+ Handle<JSFunction> Compile(Handle<JSFunction> function) {
+#if V8_TURBOFAN_TARGET
+ CompilationInfoWithZone info(function);
+
+ CHECK(Parser::Parse(&info));
+ StrictMode strict_mode = info.function()->strict_mode();
+ info.SetStrictMode(strict_mode);
+ info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
+ CHECK(Rewriter::Rewrite(&info));
+ CHECK(Scope::Analyze(&info));
+ CHECK_NE(NULL, info.scope());
+
+ EnsureDeoptimizationSupport(&info);
+
+ Pipeline pipeline(&info);
+ Handle<Code> code = pipeline.GenerateCode();
+
+ CHECK(!code.is_null());
+ function->ReplaceCode(*code);
+#elif USE_CRANKSHAFT
+ Handle<Code> unoptimized = Handle<Code>(function->code());
+ Handle<Code> code = Compiler::GetOptimizedCode(function, unoptimized,
+ Compiler::NOT_CONCURRENT);
+ CHECK(!code.is_null());
+#if ENABLE_DISASSEMBLER
+ if (FLAG_print_opt_code) {
+ CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
+ code->Disassemble("test code", tracing_scope.file());
+ }
+#endif
+ function->ReplaceCode(*code);
+#endif
+ return function;
+ }
+
+ static void EnsureDeoptimizationSupport(CompilationInfo* info) {
+ bool should_recompile = !info->shared_info()->has_deoptimization_support();
+ if (should_recompile) {
+ CompilationInfoWithZone unoptimized(info->shared_info());
+ // Note that we use the same AST that we will use for generating the
+ // optimized code.
+ unoptimized.SetFunction(info->function());
+ unoptimized.PrepareForCompilation(info->scope());
+ unoptimized.SetContext(info->context());
+ if (should_recompile) unoptimized.EnableDeoptimizationSupport();
+ bool succeeded = FullCodeGenerator::MakeCode(&unoptimized);
+ CHECK(succeeded);
+ Handle<SharedFunctionInfo> shared = info->shared_info();
+ shared->EnableDeoptimizationSupport(*unoptimized.code());
+ }
+ }
+
+ MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b) {
+ Handle<Object> args[] = {a, b};
+ return Execution::Call(isolate, function, undefined(), 2, args, false);
+ }
+
+ void CheckThrows(Handle<Object> a, Handle<Object> b) {
+ TryCatch try_catch;
+ MaybeHandle<Object> no_result = Call(a, b);
+ CHECK(isolate->has_pending_exception());
+ CHECK(try_catch.HasCaught());
+ CHECK(no_result.is_null());
+ // TODO(mstarzinger): Temporary workaround for issue chromium:362388.
+ isolate->OptionalRescheduleException(true);
+ }
+
+ v8::Handle<v8::Message> CheckThrowsReturnMessage(Handle<Object> a,
+ Handle<Object> b) {
+ TryCatch try_catch;
+ MaybeHandle<Object> no_result = Call(a, b);
+ CHECK(isolate->has_pending_exception());
+ CHECK(try_catch.HasCaught());
+ CHECK(no_result.is_null());
+ // TODO(mstarzinger): Calling OptionalRescheduleException is a dirty hack,
+ // it's the only way to make Message() not to assert because an external
+ // exception has been caught by the try_catch.
+ isolate->OptionalRescheduleException(true);
+ return try_catch.Message();
+ }
+
+ void CheckCall(Handle<Object> expected, Handle<Object> a, Handle<Object> b) {
+ Handle<Object> result = Call(a, b).ToHandleChecked();
+ CHECK(expected->SameValue(*result));
+ }
+
+ void CheckCall(Handle<Object> expected, Handle<Object> a) {
+ CheckCall(expected, a, undefined());
+ }
+
+ void CheckCall(Handle<Object> expected) {
+ CheckCall(expected, undefined(), undefined());
+ }
+
+ void CheckCall(double expected, double a, double b) {
+ CheckCall(Val(expected), Val(a), Val(b));
+ }
+
+ void CheckTrue(Handle<Object> a, Handle<Object> b) {
+ CheckCall(true_value(), a, b);
+ }
+
+ void CheckTrue(Handle<Object> a) { CheckCall(true_value(), a, undefined()); }
+
+ void CheckTrue(double a, double b) {
+ CheckCall(true_value(), Val(a), Val(b));
+ }
+
+ void CheckFalse(Handle<Object> a, Handle<Object> b) {
+ CheckCall(false_value(), a, b);
+ }
+
+ void CheckFalse(Handle<Object> a) {
+ CheckCall(false_value(), a, undefined());
+ }
+
+ void CheckFalse(double a, double b) {
+ CheckCall(false_value(), Val(a), Val(b));
+ }
+
+ Handle<JSFunction> NewFunction(const char* source) {
+ return v8::Utils::OpenHandle(
+ *v8::Handle<v8::Function>::Cast(CompileRun(source)));
+ }
+
+ Handle<JSObject> NewObject(const char* source) {
+ return v8::Utils::OpenHandle(
+ *v8::Handle<v8::Object>::Cast(CompileRun(source)));
+ }
+
+ Handle<String> Val(const char* string) {
+ return isolate->factory()->InternalizeUtf8String(string);
+ }
+
+ Handle<Object> Val(double value) {
+ return isolate->factory()->NewNumber(value);
+ }
+
+ Handle<Object> infinity() { return isolate->factory()->infinity_value(); }
+
+ Handle<Object> minus_infinity() { return Val(-V8_INFINITY); }
+
+ Handle<Object> nan() { return isolate->factory()->nan_value(); }
+
+ Handle<Object> undefined() { return isolate->factory()->undefined_value(); }
+
+ Handle<Object> null() { return isolate->factory()->null_value(); }
+
+ Handle<Object> true_value() { return isolate->factory()->true_value(); }
+
+ Handle<Object> false_value() { return isolate->factory()->false_value(); }
+};
+}
+}
+} // namespace v8::internal::compiler
+
+#endif // V8_CCTEST_COMPILER_FUNCTION_TESTER_H_
diff --git a/deps/v8/test/cctest/compiler/graph-builder-tester.cc b/deps/v8/test/cctest/compiler/graph-builder-tester.cc
new file mode 100644
index 000000000..fb6e4a28c
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/graph-builder-tester.cc
@@ -0,0 +1,65 @@
+// 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 "test/cctest/compiler/graph-builder-tester.h"
+#include "src/compiler/pipeline.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+MachineCallHelper::MachineCallHelper(Zone* zone,
+ MachineCallDescriptorBuilder* builder)
+ : CallHelper(zone->isolate()),
+ call_descriptor_builder_(builder),
+ parameters_(NULL),
+ graph_(NULL) {}
+
+
+void MachineCallHelper::InitParameters(GraphBuilder* builder,
+ CommonOperatorBuilder* common) {
+ DCHECK_EQ(NULL, parameters_);
+ graph_ = builder->graph();
+ if (parameter_count() == 0) return;
+ parameters_ = graph_->zone()->NewArray<Node*>(parameter_count());
+ for (int i = 0; i < parameter_count(); ++i) {
+ parameters_[i] = builder->NewNode(common->Parameter(i), graph_->start());
+ }
+}
+
+
+byte* MachineCallHelper::Generate() {
+ DCHECK(parameter_count() == 0 || parameters_ != NULL);
+ if (!Pipeline::SupportedBackend()) return NULL;
+ if (code_.is_null()) {
+ Zone* zone = graph_->zone();
+ CompilationInfo info(zone->isolate(), zone);
+ Linkage linkage(&info, call_descriptor_builder_->BuildCallDescriptor(zone));
+ Pipeline pipeline(&info);
+ code_ = pipeline.GenerateCodeForMachineGraph(&linkage, graph_);
+ }
+ return code_.ToHandleChecked()->entry();
+}
+
+
+void MachineCallHelper::VerifyParameters(int parameter_count,
+ MachineType* parameter_types) {
+ CHECK_EQ(this->parameter_count(), parameter_count);
+ const MachineType* expected_types =
+ call_descriptor_builder_->parameter_types();
+ for (int i = 0; i < parameter_count; i++) {
+ CHECK_EQ(expected_types[i], parameter_types[i]);
+ }
+}
+
+
+Node* MachineCallHelper::Parameter(int offset) {
+ DCHECK_NE(NULL, parameters_);
+ DCHECK(0 <= offset && offset < parameter_count());
+ return parameters_[offset];
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/compiler/graph-builder-tester.h b/deps/v8/test/cctest/compiler/graph-builder-tester.h
new file mode 100644
index 000000000..64d9b8a73
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/graph-builder-tester.h
@@ -0,0 +1,114 @@
+// 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_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_
+#define V8_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_
+
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph-builder.h"
+#include "src/compiler/machine-node-factory.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/simplified-node-factory.h"
+#include "src/compiler/simplified-operator.h"
+#include "test/cctest/compiler/call-tester.h"
+#include "test/cctest/compiler/simplified-graph-builder.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// A class that just passes node creation on to the Graph.
+class DirectGraphBuilder : public GraphBuilder {
+ public:
+ explicit DirectGraphBuilder(Graph* graph) : GraphBuilder(graph) {}
+ virtual ~DirectGraphBuilder() {}
+
+ protected:
+ virtual Node* MakeNode(Operator* op, int value_input_count,
+ Node** value_inputs) {
+ return graph()->NewNode(op, value_input_count, value_inputs);
+ }
+};
+
+
+class MachineCallHelper : public CallHelper {
+ public:
+ MachineCallHelper(Zone* zone, MachineCallDescriptorBuilder* builder);
+
+ Node* Parameter(int offset);
+
+ void GenerateCode() { Generate(); }
+
+ protected:
+ virtual byte* Generate();
+ virtual void VerifyParameters(int parameter_count, MachineType* parameters);
+ void InitParameters(GraphBuilder* builder, CommonOperatorBuilder* common);
+
+ protected:
+ int parameter_count() const {
+ return call_descriptor_builder_->parameter_count();
+ }
+
+ private:
+ MachineCallDescriptorBuilder* call_descriptor_builder_;
+ Node** parameters_;
+ // TODO(dcarney): shouldn't need graph stored.
+ Graph* graph_;
+ MaybeHandle<Code> code_;
+};
+
+
+class GraphAndBuilders {
+ public:
+ explicit GraphAndBuilders(Zone* zone)
+ : main_graph_(new (zone) Graph(zone)),
+ main_common_(zone),
+ main_machine_(zone),
+ main_simplified_(zone) {}
+
+ protected:
+ // Prefixed with main_ to avoid naiming conflicts.
+ Graph* main_graph_;
+ CommonOperatorBuilder main_common_;
+ MachineOperatorBuilder main_machine_;
+ SimplifiedOperatorBuilder main_simplified_;
+};
+
+
+template <typename ReturnType>
+class GraphBuilderTester
+ : public HandleAndZoneScope,
+ private GraphAndBuilders,
+ public MachineCallHelper,
+ public SimplifiedGraphBuilder,
+ public CallHelper2<ReturnType, GraphBuilderTester<ReturnType> > {
+ public:
+ explicit GraphBuilderTester(MachineType p0 = kMachineLast,
+ MachineType p1 = kMachineLast,
+ MachineType p2 = kMachineLast,
+ MachineType p3 = kMachineLast,
+ MachineType p4 = kMachineLast)
+ : GraphAndBuilders(main_zone()),
+ MachineCallHelper(
+ main_zone(),
+ ToCallDescriptorBuilder(
+ main_zone(), ReturnValueTraits<ReturnType>::Representation(),
+ p0, p1, p2, p3, p4)),
+ SimplifiedGraphBuilder(main_graph_, &main_common_, &main_machine_,
+ &main_simplified_) {
+ Begin(parameter_count());
+ InitParameters(this, &main_common_);
+ }
+ virtual ~GraphBuilderTester() {}
+
+ Factory* factory() const { return isolate()->factory(); }
+};
+} // namespace compiler
+} // namespace internal
+} // namespace v8
+
+#endif // V8_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_
diff --git a/deps/v8/test/cctest/compiler/graph-tester.h b/deps/v8/test/cctest/compiler/graph-tester.h
new file mode 100644
index 000000000..e56924540
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/graph-tester.h
@@ -0,0 +1,42 @@
+// 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_CCTEST_COMPILER_GRAPH_TESTER_H_
+#define V8_CCTEST_COMPILER_GRAPH_TESTER_H_
+
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class GraphTester : public HandleAndZoneScope, public Graph {
+ public:
+ GraphTester() : Graph(main_zone()) {}
+};
+
+
+class GraphWithStartNodeTester : public GraphTester {
+ public:
+ explicit GraphWithStartNodeTester(int num_parameters = 0)
+ : builder_(main_zone()),
+ start_node_(NewNode(builder_.Start(num_parameters))) {
+ SetStart(start_node_);
+ }
+
+ Node* start_node() { return start_node_; }
+
+ private:
+ CommonOperatorBuilder builder_;
+ Node* start_node_;
+};
+}
+}
+} // namespace v8::internal::compiler
+
+#endif // V8_CCTEST_COMPILER_GRAPH_TESTER_H_
diff --git a/deps/v8/test/cctest/compiler/instruction-selector-tester.h b/deps/v8/test/cctest/compiler/instruction-selector-tester.h
new file mode 100644
index 000000000..60adaec82
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/instruction-selector-tester.h
@@ -0,0 +1,127 @@
+// 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_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_
+#define V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_
+
+#include <deque>
+#include <set>
+
+#include "src/compiler/instruction-selector.h"
+#include "src/compiler/raw-machine-assembler.h"
+#include "src/ostreams.h"
+#include "test/cctest/cctest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+typedef std::set<int> VirtualRegisterSet;
+
+enum InstructionSelectorTesterMode { kTargetMode, kInternalMode };
+
+class InstructionSelectorTester : public HandleAndZoneScope,
+ public RawMachineAssembler {
+ public:
+ enum Mode { kTargetMode, kInternalMode };
+
+ static const int kParameterCount = 3;
+ static MachineType* BuildParameterArray(Zone* zone) {
+ MachineType* array = zone->NewArray<MachineType>(kParameterCount);
+ for (int i = 0; i < kParameterCount; ++i) {
+ array[i] = kMachineWord32;
+ }
+ return array;
+ }
+
+ InstructionSelectorTester()
+ : RawMachineAssembler(
+ new (main_zone()) Graph(main_zone()), new (main_zone())
+ MachineCallDescriptorBuilder(kMachineWord32, kParameterCount,
+ BuildParameterArray(main_zone())),
+ MachineOperatorBuilder::pointer_rep()) {}
+
+ void SelectInstructions(CpuFeature feature) {
+ SelectInstructions(InstructionSelector::Features(feature));
+ }
+
+ void SelectInstructions(CpuFeature feature1, CpuFeature feature2) {
+ SelectInstructions(InstructionSelector::Features(feature1, feature2));
+ }
+
+ void SelectInstructions(Mode mode = kTargetMode) {
+ SelectInstructions(InstructionSelector::Features(), mode);
+ }
+
+ void SelectInstructions(InstructionSelector::Features features,
+ Mode mode = kTargetMode) {
+ OFStream out(stdout);
+ Schedule* schedule = Export();
+ CHECK_NE(0, graph()->NodeCount());
+ CompilationInfo info(main_isolate(), main_zone());
+ Linkage linkage(&info, call_descriptor());
+ InstructionSequence sequence(&linkage, graph(), schedule);
+ SourcePositionTable source_positions(graph());
+ InstructionSelector selector(&sequence, &source_positions, features);
+ selector.SelectInstructions();
+ out << "--- Code sequence after instruction selection --- " << endl
+ << sequence;
+ for (InstructionSequence::const_iterator i = sequence.begin();
+ i != sequence.end(); ++i) {
+ Instruction* instr = *i;
+ if (instr->opcode() < 0) continue;
+ if (mode == kTargetMode) {
+ switch (ArchOpcodeField::decode(instr->opcode())) {
+#define CASE(Name) \
+ case k##Name: \
+ break;
+ TARGET_ARCH_OPCODE_LIST(CASE)
+#undef CASE
+ default:
+ continue;
+ }
+ }
+ code.push_back(instr);
+ }
+ for (int vreg = 0; vreg < sequence.VirtualRegisterCount(); ++vreg) {
+ if (sequence.IsDouble(vreg)) {
+ CHECK(!sequence.IsReference(vreg));
+ doubles.insert(vreg);
+ }
+ if (sequence.IsReference(vreg)) {
+ CHECK(!sequence.IsDouble(vreg));
+ references.insert(vreg);
+ }
+ }
+ immediates.assign(sequence.immediates().begin(),
+ sequence.immediates().end());
+ }
+
+ int32_t ToInt32(const InstructionOperand* operand) const {
+ size_t i = operand->index();
+ CHECK(i < immediates.size());
+ CHECK_EQ(InstructionOperand::IMMEDIATE, operand->kind());
+ return immediates[i].ToInt32();
+ }
+
+ std::deque<Instruction*> code;
+ VirtualRegisterSet doubles;
+ VirtualRegisterSet references;
+ std::deque<Constant> immediates;
+};
+
+
+static inline void CheckSameVreg(InstructionOperand* exp,
+ InstructionOperand* val) {
+ CHECK_EQ(InstructionOperand::UNALLOCATED, exp->kind());
+ CHECK_EQ(InstructionOperand::UNALLOCATED, val->kind());
+ CHECK_EQ(UnallocatedOperand::cast(exp)->virtual_register(),
+ UnallocatedOperand::cast(val)->virtual_register());
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
+
+#endif // V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_
diff --git a/deps/v8/test/cctest/compiler/simplified-graph-builder.cc b/deps/v8/test/cctest/compiler/simplified-graph-builder.cc
new file mode 100644
index 000000000..c688399ea
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/simplified-graph-builder.cc
@@ -0,0 +1,78 @@
+// 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 "test/cctest/compiler/simplified-graph-builder.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+SimplifiedGraphBuilder::SimplifiedGraphBuilder(
+ Graph* graph, CommonOperatorBuilder* common,
+ MachineOperatorBuilder* machine, SimplifiedOperatorBuilder* simplified)
+ : StructuredGraphBuilder(graph, common),
+ machine_(machine),
+ simplified_(simplified) {}
+
+
+void SimplifiedGraphBuilder::Begin(int num_parameters) {
+ DCHECK(graph()->start() == NULL);
+ Node* start = graph()->NewNode(common()->Start(num_parameters));
+ graph()->SetStart(start);
+ set_environment(new (zone()) Environment(this, start));
+}
+
+
+void SimplifiedGraphBuilder::Return(Node* value) {
+ Node* control = NewNode(common()->Return(), value);
+ UpdateControlDependencyToLeaveFunction(control);
+}
+
+
+void SimplifiedGraphBuilder::End() {
+ environment()->UpdateControlDependency(exit_control());
+ graph()->SetEnd(NewNode(common()->End()));
+}
+
+
+SimplifiedGraphBuilder::Environment::Environment(
+ SimplifiedGraphBuilder* builder, Node* control_dependency)
+ : StructuredGraphBuilder::Environment(builder, control_dependency) {}
+
+
+Node* SimplifiedGraphBuilder::Environment::Top() {
+ DCHECK(!values()->empty());
+ return values()->back();
+}
+
+
+void SimplifiedGraphBuilder::Environment::Push(Node* node) {
+ values()->push_back(node);
+}
+
+
+Node* SimplifiedGraphBuilder::Environment::Pop() {
+ DCHECK(!values()->empty());
+ Node* back = values()->back();
+ values()->pop_back();
+ return back;
+}
+
+
+void SimplifiedGraphBuilder::Environment::Poke(size_t depth, Node* node) {
+ DCHECK(depth < values()->size());
+ size_t index = values()->size() - depth - 1;
+ values()->at(index) = node;
+}
+
+
+Node* SimplifiedGraphBuilder::Environment::Peek(size_t depth) {
+ DCHECK(depth < values()->size());
+ size_t index = values()->size() - depth - 1;
+ return values()->at(index);
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/compiler/simplified-graph-builder.h b/deps/v8/test/cctest/compiler/simplified-graph-builder.h
new file mode 100644
index 000000000..fa9161e17
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/simplified-graph-builder.h
@@ -0,0 +1,73 @@
+// 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_CCTEST_COMPILER_SIMPLIFIED_GRAPH_BUILDER_H_
+#define V8_CCTEST_COMPILER_SIMPLIFIED_GRAPH_BUILDER_H_
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph-builder.h"
+#include "src/compiler/machine-node-factory.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/simplified-node-factory.h"
+#include "src/compiler/simplified-operator.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/call-tester.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class SimplifiedGraphBuilder
+ : public StructuredGraphBuilder,
+ public MachineNodeFactory<SimplifiedGraphBuilder>,
+ public SimplifiedNodeFactory<SimplifiedGraphBuilder> {
+ public:
+ SimplifiedGraphBuilder(Graph* graph, CommonOperatorBuilder* common,
+ MachineOperatorBuilder* machine,
+ SimplifiedOperatorBuilder* simplified);
+ virtual ~SimplifiedGraphBuilder() {}
+
+ class Environment : public StructuredGraphBuilder::Environment {
+ public:
+ Environment(SimplifiedGraphBuilder* builder, Node* control_dependency);
+
+ // TODO(dcarney): encode somehow and merge into StructuredGraphBuilder.
+ // SSA renaming operations.
+ Node* Top();
+ void Push(Node* node);
+ Node* Pop();
+ void Poke(size_t depth, Node* node);
+ Node* Peek(size_t depth);
+ };
+
+ Isolate* isolate() const { return zone()->isolate(); }
+ Zone* zone() const { return StructuredGraphBuilder::zone(); }
+ CommonOperatorBuilder* common() const {
+ return StructuredGraphBuilder::common();
+ }
+ MachineOperatorBuilder* machine() const { return machine_; }
+ SimplifiedOperatorBuilder* simplified() const { return simplified_; }
+ Environment* environment() {
+ return reinterpret_cast<Environment*>(
+ StructuredGraphBuilder::environment());
+ }
+
+ // Initialize graph and builder.
+ void Begin(int num_parameters);
+
+ void Return(Node* value);
+
+ // Close the graph.
+ void End();
+
+ private:
+ MachineOperatorBuilder* machine_;
+ SimplifiedOperatorBuilder* simplified_;
+};
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
+
+#endif // V8_CCTEST_COMPILER_SIMPLIFIED_GRAPH_BUILDER_H_
diff --git a/deps/v8/test/cctest/compiler/test-branch-combine.cc b/deps/v8/test/cctest/compiler/test-branch-combine.cc
new file mode 100644
index 000000000..61dffdca8
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-branch-combine.cc
@@ -0,0 +1,462 @@
+// 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 "src/v8.h"
+
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/codegen-tester.h"
+#include "test/cctest/compiler/value-helper.h"
+
+#if V8_TURBOFAN_TARGET
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+typedef RawMachineAssembler::Label MLabel;
+
+static IrOpcode::Value int32cmp_opcodes[] = {
+ IrOpcode::kWord32Equal, IrOpcode::kInt32LessThan,
+ IrOpcode::kInt32LessThanOrEqual, IrOpcode::kUint32LessThan,
+ IrOpcode::kUint32LessThanOrEqual};
+
+
+TEST(BranchCombineWord32EqualZero_1) {
+ // Test combining a branch with x == 0
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ int32_t eq_constant = -1033;
+ int32_t ne_constant = 825118;
+ Node* p0 = m.Parameter(0);
+
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(p0, m.Int32Constant(0)), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(eq_constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(ne_constant));
+
+ FOR_INT32_INPUTS(i) {
+ int32_t a = *i;
+ int32_t expect = a == 0 ? eq_constant : ne_constant;
+ CHECK_EQ(expect, m.Call(a));
+ }
+}
+
+
+TEST(BranchCombineWord32EqualZero_chain) {
+ // Test combining a branch with a chain of x == 0 == 0 == 0 ...
+ int32_t eq_constant = -1133;
+ int32_t ne_constant = 815118;
+
+ for (int k = 0; k < 6; k++) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ Node* p0 = m.Parameter(0);
+ MLabel blocka, blockb;
+ Node* cond = p0;
+ for (int j = 0; j < k; j++) {
+ cond = m.Word32Equal(cond, m.Int32Constant(0));
+ }
+ m.Branch(cond, &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(eq_constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(ne_constant));
+
+ FOR_INT32_INPUTS(i) {
+ int32_t a = *i;
+ int32_t expect = (k & 1) == 1 ? (a == 0 ? eq_constant : ne_constant)
+ : (a == 0 ? ne_constant : eq_constant);
+ CHECK_EQ(expect, m.Call(a));
+ }
+ }
+}
+
+
+TEST(BranchCombineInt32LessThanZero_1) {
+ // Test combining a branch with x < 0
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ int32_t eq_constant = -1433;
+ int32_t ne_constant = 845118;
+ Node* p0 = m.Parameter(0);
+
+ MLabel blocka, blockb;
+ m.Branch(m.Int32LessThan(p0, m.Int32Constant(0)), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(eq_constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(ne_constant));
+
+ FOR_INT32_INPUTS(i) {
+ int32_t a = *i;
+ int32_t expect = a < 0 ? eq_constant : ne_constant;
+ CHECK_EQ(expect, m.Call(a));
+ }
+}
+
+
+TEST(BranchCombineUint32LessThan100_1) {
+ // Test combining a branch with x < 100
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ int32_t eq_constant = 1471;
+ int32_t ne_constant = 88845718;
+ Node* p0 = m.Parameter(0);
+
+ MLabel blocka, blockb;
+ m.Branch(m.Uint32LessThan(p0, m.Int32Constant(100)), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(eq_constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(ne_constant));
+
+ FOR_UINT32_INPUTS(i) {
+ uint32_t a = *i;
+ int32_t expect = a < 100 ? eq_constant : ne_constant;
+ CHECK_EQ(expect, m.Call(a));
+ }
+}
+
+
+TEST(BranchCombineUint32LessThanOrEqual100_1) {
+ // Test combining a branch with x <= 100
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ int32_t eq_constant = 1479;
+ int32_t ne_constant = 77845719;
+ Node* p0 = m.Parameter(0);
+
+ MLabel blocka, blockb;
+ m.Branch(m.Uint32LessThanOrEqual(p0, m.Int32Constant(100)), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(eq_constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(ne_constant));
+
+ FOR_UINT32_INPUTS(i) {
+ uint32_t a = *i;
+ int32_t expect = a <= 100 ? eq_constant : ne_constant;
+ CHECK_EQ(expect, m.Call(a));
+ }
+}
+
+
+TEST(BranchCombineZeroLessThanInt32_1) {
+ // Test combining a branch with 0 < x
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ int32_t eq_constant = -2033;
+ int32_t ne_constant = 225118;
+ Node* p0 = m.Parameter(0);
+
+ MLabel blocka, blockb;
+ m.Branch(m.Int32LessThan(m.Int32Constant(0), p0), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(eq_constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(ne_constant));
+
+ FOR_INT32_INPUTS(i) {
+ int32_t a = *i;
+ int32_t expect = 0 < a ? eq_constant : ne_constant;
+ CHECK_EQ(expect, m.Call(a));
+ }
+}
+
+
+TEST(BranchCombineInt32GreaterThanZero_1) {
+ // Test combining a branch with x > 0
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ int32_t eq_constant = -1073;
+ int32_t ne_constant = 825178;
+ Node* p0 = m.Parameter(0);
+
+ MLabel blocka, blockb;
+ m.Branch(m.Int32GreaterThan(p0, m.Int32Constant(0)), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(eq_constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(ne_constant));
+
+ FOR_INT32_INPUTS(i) {
+ int32_t a = *i;
+ int32_t expect = a > 0 ? eq_constant : ne_constant;
+ CHECK_EQ(expect, m.Call(a));
+ }
+}
+
+
+TEST(BranchCombineWord32EqualP) {
+ // Test combining a branch with an Word32Equal.
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
+ int32_t eq_constant = -1035;
+ int32_t ne_constant = 825018;
+ Node* p0 = m.Parameter(0);
+ Node* p1 = m.Parameter(1);
+
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(p0, p1), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(eq_constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(ne_constant));
+
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ int32_t a = *i;
+ int32_t b = *j;
+ int32_t expect = a == b ? eq_constant : ne_constant;
+ CHECK_EQ(expect, m.Call(a, b));
+ }
+ }
+}
+
+
+TEST(BranchCombineWord32EqualI) {
+ int32_t eq_constant = -1135;
+ int32_t ne_constant = 925718;
+
+ for (int left = 0; left < 2; left++) {
+ FOR_INT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ int32_t a = *i;
+
+ Node* p0 = m.Int32Constant(a);
+ Node* p1 = m.Parameter(0);
+
+ MLabel blocka, blockb;
+ if (left == 1) m.Branch(m.Word32Equal(p0, p1), &blocka, &blockb);
+ if (left == 0) m.Branch(m.Word32Equal(p1, p0), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(eq_constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(ne_constant));
+
+ FOR_INT32_INPUTS(j) {
+ int32_t b = *j;
+ int32_t expect = a == b ? eq_constant : ne_constant;
+ CHECK_EQ(expect, m.Call(b));
+ }
+ }
+ }
+}
+
+
+TEST(BranchCombineInt32CmpP) {
+ int32_t eq_constant = -1235;
+ int32_t ne_constant = 725018;
+
+ for (int op = 0; op < 2; op++) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
+ Node* p0 = m.Parameter(0);
+ Node* p1 = m.Parameter(1);
+
+ MLabel blocka, blockb;
+ if (op == 0) m.Branch(m.Int32LessThan(p0, p1), &blocka, &blockb);
+ if (op == 1) m.Branch(m.Int32LessThanOrEqual(p0, p1), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(eq_constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(ne_constant));
+
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ int32_t a = *i;
+ int32_t b = *j;
+ int32_t expect = 0;
+ if (op == 0) expect = a < b ? eq_constant : ne_constant;
+ if (op == 1) expect = a <= b ? eq_constant : ne_constant;
+ CHECK_EQ(expect, m.Call(a, b));
+ }
+ }
+ }
+}
+
+
+TEST(BranchCombineInt32CmpI) {
+ int32_t eq_constant = -1175;
+ int32_t ne_constant = 927711;
+
+ for (int op = 0; op < 2; op++) {
+ FOR_INT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ int32_t a = *i;
+ Node* p0 = m.Int32Constant(a);
+ Node* p1 = m.Parameter(0);
+
+ MLabel blocka, blockb;
+ if (op == 0) m.Branch(m.Int32LessThan(p0, p1), &blocka, &blockb);
+ if (op == 1) m.Branch(m.Int32LessThanOrEqual(p0, p1), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(eq_constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(ne_constant));
+
+ FOR_INT32_INPUTS(j) {
+ int32_t b = *j;
+ int32_t expect = 0;
+ if (op == 0) expect = a < b ? eq_constant : ne_constant;
+ if (op == 1) expect = a <= b ? eq_constant : ne_constant;
+ CHECK_EQ(expect, m.Call(b));
+ }
+ }
+ }
+}
+
+
+// Now come the sophisticated tests for many input shape combinations.
+
+// Materializes a boolean (1 or 0) from a comparison.
+class CmpMaterializeBoolGen : public BinopGen<int32_t> {
+ public:
+ CompareWrapper w;
+ bool invert;
+
+ CmpMaterializeBoolGen(IrOpcode::Value opcode, bool i)
+ : w(opcode), invert(i) {}
+
+ virtual void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) {
+ Node* cond = w.MakeNode(m, a, b);
+ if (invert) cond = m->Word32Equal(cond, m->Int32Constant(0));
+ m->Return(cond);
+ }
+ virtual int32_t expected(int32_t a, int32_t b) {
+ if (invert) return !w.Int32Compare(a, b) ? 1 : 0;
+ return w.Int32Compare(a, b) ? 1 : 0;
+ }
+};
+
+
+// Generates a branch and return one of two values from a comparison.
+class CmpBranchGen : public BinopGen<int32_t> {
+ public:
+ CompareWrapper w;
+ bool invert;
+ bool true_first;
+ int32_t eq_constant;
+ int32_t ne_constant;
+
+ CmpBranchGen(IrOpcode::Value opcode, bool i, bool t, int32_t eq, int32_t ne)
+ : w(opcode), invert(i), true_first(t), eq_constant(eq), ne_constant(ne) {}
+
+ virtual void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) {
+ MLabel blocka, blockb;
+ Node* cond = w.MakeNode(m, a, b);
+ if (invert) cond = m->Word32Equal(cond, m->Int32Constant(0));
+ m->Branch(cond, &blocka, &blockb);
+ if (true_first) {
+ m->Bind(&blocka);
+ m->Return(m->Int32Constant(eq_constant));
+ m->Bind(&blockb);
+ m->Return(m->Int32Constant(ne_constant));
+ } else {
+ m->Bind(&blockb);
+ m->Return(m->Int32Constant(ne_constant));
+ m->Bind(&blocka);
+ m->Return(m->Int32Constant(eq_constant));
+ }
+ }
+ virtual int32_t expected(int32_t a, int32_t b) {
+ if (invert) return !w.Int32Compare(a, b) ? eq_constant : ne_constant;
+ return w.Int32Compare(a, b) ? eq_constant : ne_constant;
+ }
+};
+
+
+TEST(BranchCombineInt32CmpAllInputShapes_materialized) {
+ for (size_t i = 0; i < ARRAY_SIZE(int32cmp_opcodes); i++) {
+ CmpMaterializeBoolGen gen(int32cmp_opcodes[i], false);
+ Int32BinopInputShapeTester tester(&gen);
+ tester.TestAllInputShapes();
+ }
+}
+
+
+TEST(BranchCombineInt32CmpAllInputShapes_inverted_materialized) {
+ for (size_t i = 0; i < ARRAY_SIZE(int32cmp_opcodes); i++) {
+ CmpMaterializeBoolGen gen(int32cmp_opcodes[i], true);
+ Int32BinopInputShapeTester tester(&gen);
+ tester.TestAllInputShapes();
+ }
+}
+
+
+TEST(BranchCombineInt32CmpAllInputShapes_branch_true) {
+ for (int i = 0; i < static_cast<int>(ARRAY_SIZE(int32cmp_opcodes)); i++) {
+ CmpBranchGen gen(int32cmp_opcodes[i], false, false, 995 + i, -1011 - i);
+ Int32BinopInputShapeTester tester(&gen);
+ tester.TestAllInputShapes();
+ }
+}
+
+
+TEST(BranchCombineInt32CmpAllInputShapes_branch_false) {
+ for (int i = 0; i < static_cast<int>(ARRAY_SIZE(int32cmp_opcodes)); i++) {
+ CmpBranchGen gen(int32cmp_opcodes[i], false, true, 795 + i, -2011 - i);
+ Int32BinopInputShapeTester tester(&gen);
+ tester.TestAllInputShapes();
+ }
+}
+
+
+TEST(BranchCombineInt32CmpAllInputShapes_inverse_branch_true) {
+ for (int i = 0; i < static_cast<int>(ARRAY_SIZE(int32cmp_opcodes)); i++) {
+ CmpBranchGen gen(int32cmp_opcodes[i], true, false, 695 + i, -3011 - i);
+ Int32BinopInputShapeTester tester(&gen);
+ tester.TestAllInputShapes();
+ }
+}
+
+
+TEST(BranchCombineInt32CmpAllInputShapes_inverse_branch_false) {
+ for (int i = 0; i < static_cast<int>(ARRAY_SIZE(int32cmp_opcodes)); i++) {
+ CmpBranchGen gen(int32cmp_opcodes[i], true, true, 595 + i, -4011 - i);
+ Int32BinopInputShapeTester tester(&gen);
+ tester.TestAllInputShapes();
+ }
+}
+
+
+TEST(BranchCombineFloat64Compares) {
+ double inf = V8_INFINITY;
+ double nan = v8::base::OS::nan_value();
+ double inputs[] = {0.0, 1.0, -1.0, -inf, inf, nan};
+
+ int32_t eq_constant = -1733;
+ int32_t ne_constant = 915118;
+
+ double input_a = 0.0;
+ double input_b = 0.0;
+
+ CompareWrapper cmps[] = {CompareWrapper(IrOpcode::kFloat64Equal),
+ CompareWrapper(IrOpcode::kFloat64LessThan),
+ CompareWrapper(IrOpcode::kFloat64LessThanOrEqual)};
+
+ for (size_t c = 0; c < ARRAY_SIZE(cmps); c++) {
+ CompareWrapper cmp = cmps[c];
+ for (int invert = 0; invert < 2; invert++) {
+ RawMachineAssemblerTester<int32_t> m;
+ Node* a = m.LoadFromPointer(&input_a, kMachineFloat64);
+ Node* b = m.LoadFromPointer(&input_b, kMachineFloat64);
+
+ MLabel blocka, blockb;
+ Node* cond = cmp.MakeNode(&m, a, b);
+ if (invert) cond = m.Word32Equal(cond, m.Int32Constant(0));
+ m.Branch(cond, &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(eq_constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(ne_constant));
+
+ for (size_t i = 0; i < ARRAY_SIZE(inputs); i++) {
+ for (size_t j = 0; j < ARRAY_SIZE(inputs); j += 2) {
+ input_a = inputs[i];
+ input_b = inputs[i];
+ int32_t expected =
+ invert ? (cmp.Float64Compare(input_a, input_b) ? ne_constant
+ : eq_constant)
+ : (cmp.Float64Compare(input_a, input_b) ? eq_constant
+ : ne_constant);
+ CHECK_EQ(expected, m.Call());
+ }
+ }
+ }
+ }
+}
+#endif // V8_TURBOFAN_TARGET
diff --git a/deps/v8/test/cctest/compiler/test-changes-lowering.cc b/deps/v8/test/cctest/compiler/test-changes-lowering.cc
new file mode 100644
index 000000000..148f4b34f
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-changes-lowering.cc
@@ -0,0 +1,397 @@
+// 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 <limits>
+
+#include "src/compiler/control-builders.h"
+#include "src/compiler/generic-node-inl.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/pipeline.h"
+#include "src/compiler/simplified-lowering.h"
+#include "src/compiler/simplified-node-factory.h"
+#include "src/compiler/typer.h"
+#include "src/compiler/verifier.h"
+#include "src/execution.h"
+#include "src/parser.h"
+#include "src/rewriter.h"
+#include "src/scopes.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/codegen-tester.h"
+#include "test/cctest/compiler/graph-builder-tester.h"
+#include "test/cctest/compiler/value-helper.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+template <typename ReturnType>
+class ChangesLoweringTester : public GraphBuilderTester<ReturnType> {
+ public:
+ explicit ChangesLoweringTester(MachineType p0 = kMachineLast)
+ : GraphBuilderTester<ReturnType>(p0),
+ typer(this->zone()),
+ source_positions(this->graph()),
+ jsgraph(this->graph(), this->common(), &typer),
+ lowering(&jsgraph, &source_positions),
+ function(Handle<JSFunction>::null()) {}
+
+ Typer typer;
+ SourcePositionTable source_positions;
+ JSGraph jsgraph;
+ SimplifiedLowering lowering;
+ Handle<JSFunction> function;
+
+ Node* start() { return this->graph()->start(); }
+
+ template <typename T>
+ T* CallWithPotentialGC() {
+ // TODO(titzer): we need to wrap the code in a JSFunction and call it via
+ // Execution::Call() so that the GC knows about the frame, can walk it,
+ // relocate the code object if necessary, etc.
+ // This is pretty ugly and at the least should be moved up to helpers.
+ if (function.is_null()) {
+ function =
+ v8::Utils::OpenHandle(*v8::Handle<v8::Function>::Cast(CompileRun(
+ "(function() { 'use strict'; return 2.7123; })")));
+ CompilationInfoWithZone info(function);
+ CHECK(Parser::Parse(&info));
+ StrictMode strict_mode = info.function()->strict_mode();
+ info.SetStrictMode(strict_mode);
+ info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
+ CHECK(Rewriter::Rewrite(&info));
+ CHECK(Scope::Analyze(&info));
+ CHECK_NE(NULL, info.scope());
+ Pipeline pipeline(&info);
+ Linkage linkage(&info);
+ Handle<Code> code =
+ pipeline.GenerateCodeForMachineGraph(&linkage, this->graph());
+ CHECK(!code.is_null());
+ function->ReplaceCode(*code);
+ }
+ Handle<Object>* args = NULL;
+ MaybeHandle<Object> result =
+ Execution::Call(this->isolate(), function, factory()->undefined_value(),
+ 0, args, false);
+ return T::cast(*result.ToHandleChecked());
+ }
+
+ void StoreFloat64(Node* node, double* ptr) {
+ Node* ptr_node = this->PointerConstant(ptr);
+ this->Store(kMachineFloat64, ptr_node, node);
+ }
+
+ Node* LoadInt32(int32_t* ptr) {
+ Node* ptr_node = this->PointerConstant(ptr);
+ return this->Load(kMachineWord32, ptr_node);
+ }
+
+ Node* LoadUint32(uint32_t* ptr) {
+ Node* ptr_node = this->PointerConstant(ptr);
+ return this->Load(kMachineWord32, ptr_node);
+ }
+
+ Node* LoadFloat64(double* ptr) {
+ Node* ptr_node = this->PointerConstant(ptr);
+ return this->Load(kMachineFloat64, ptr_node);
+ }
+
+ void CheckNumber(double expected, Object* number) {
+ CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number));
+ }
+
+ void BuildAndLower(Operator* op) {
+ // We build a graph by hand here, because the raw machine assembler
+ // does not add the correct control and effect nodes.
+ Node* p0 = this->Parameter(0);
+ Node* change = this->graph()->NewNode(op, p0);
+ Node* ret = this->graph()->NewNode(this->common()->Return(), change,
+ this->start(), this->start());
+ Node* end = this->graph()->NewNode(this->common()->End(), ret);
+ this->graph()->SetEnd(end);
+ this->lowering.LowerChange(change, this->start(), this->start());
+ Verifier::Run(this->graph());
+ }
+
+ void BuildStoreAndLower(Operator* op, Operator* store_op, void* location) {
+ // We build a graph by hand here, because the raw machine assembler
+ // does not add the correct control and effect nodes.
+ Node* p0 = this->Parameter(0);
+ Node* change = this->graph()->NewNode(op, p0);
+ Node* store = this->graph()->NewNode(
+ store_op, this->PointerConstant(location), this->Int32Constant(0),
+ change, this->start(), this->start());
+ Node* ret = this->graph()->NewNode(
+ this->common()->Return(), this->Int32Constant(0), store, this->start());
+ Node* end = this->graph()->NewNode(this->common()->End(), ret);
+ this->graph()->SetEnd(end);
+ this->lowering.LowerChange(change, this->start(), this->start());
+ Verifier::Run(this->graph());
+ }
+
+ void BuildLoadAndLower(Operator* op, Operator* load_op, void* location) {
+ // We build a graph by hand here, because the raw machine assembler
+ // does not add the correct control and effect nodes.
+ Node* load =
+ this->graph()->NewNode(load_op, this->PointerConstant(location),
+ this->Int32Constant(0), this->start());
+ Node* change = this->graph()->NewNode(op, load);
+ Node* ret = this->graph()->NewNode(this->common()->Return(), change,
+ this->start(), this->start());
+ Node* end = this->graph()->NewNode(this->common()->End(), ret);
+ this->graph()->SetEnd(end);
+ this->lowering.LowerChange(change, this->start(), this->start());
+ Verifier::Run(this->graph());
+ }
+
+ Factory* factory() { return this->isolate()->factory(); }
+ Heap* heap() { return this->isolate()->heap(); }
+};
+
+
+TEST(RunChangeTaggedToInt32) {
+ // Build and lower a graph by hand.
+ ChangesLoweringTester<int32_t> t(kMachineTagged);
+ t.BuildAndLower(t.simplified()->ChangeTaggedToInt32());
+
+ if (Pipeline::SupportedTarget()) {
+ FOR_INT32_INPUTS(i) {
+ int32_t input = *i;
+
+ if (Smi::IsValid(input)) {
+ int32_t result = t.Call(Smi::FromInt(input));
+ CHECK_EQ(input, result);
+ }
+
+ {
+ Handle<Object> number = t.factory()->NewNumber(input);
+ int32_t result = t.Call(*number);
+ CHECK_EQ(input, result);
+ }
+
+ {
+ Handle<HeapNumber> number = t.factory()->NewHeapNumber(input);
+ int32_t result = t.Call(*number);
+ CHECK_EQ(input, result);
+ }
+ }
+ }
+}
+
+
+TEST(RunChangeTaggedToUint32) {
+ // Build and lower a graph by hand.
+ ChangesLoweringTester<uint32_t> t(kMachineTagged);
+ t.BuildAndLower(t.simplified()->ChangeTaggedToUint32());
+
+ if (Pipeline::SupportedTarget()) {
+ FOR_UINT32_INPUTS(i) {
+ uint32_t input = *i;
+
+ if (Smi::IsValid(input)) {
+ uint32_t result = t.Call(Smi::FromInt(input));
+ CHECK_EQ(static_cast<int32_t>(input), static_cast<int32_t>(result));
+ }
+
+ {
+ Handle<Object> number = t.factory()->NewNumber(input);
+ uint32_t result = t.Call(*number);
+ CHECK_EQ(static_cast<int32_t>(input), static_cast<int32_t>(result));
+ }
+
+ {
+ Handle<HeapNumber> number = t.factory()->NewHeapNumber(input);
+ uint32_t result = t.Call(*number);
+ CHECK_EQ(static_cast<int32_t>(input), static_cast<int32_t>(result));
+ }
+ }
+ }
+}
+
+
+TEST(RunChangeTaggedToFloat64) {
+ ChangesLoweringTester<int32_t> t(kMachineTagged);
+ double result;
+
+ t.BuildStoreAndLower(t.simplified()->ChangeTaggedToFloat64(),
+ t.machine()->Store(kMachineFloat64, kNoWriteBarrier),
+ &result);
+
+ if (Pipeline::SupportedTarget()) {
+ FOR_INT32_INPUTS(i) {
+ int32_t input = *i;
+
+ if (Smi::IsValid(input)) {
+ t.Call(Smi::FromInt(input));
+ CHECK_EQ(input, static_cast<int32_t>(result));
+ }
+
+ {
+ Handle<Object> number = t.factory()->NewNumber(input);
+ t.Call(*number);
+ CHECK_EQ(input, static_cast<int32_t>(result));
+ }
+
+ {
+ Handle<HeapNumber> number = t.factory()->NewHeapNumber(input);
+ t.Call(*number);
+ CHECK_EQ(input, static_cast<int32_t>(result));
+ }
+ }
+ }
+
+ if (Pipeline::SupportedTarget()) {
+ FOR_FLOAT64_INPUTS(i) {
+ double input = *i;
+ {
+ Handle<Object> number = t.factory()->NewNumber(input);
+ t.Call(*number);
+ CHECK_EQ(input, result);
+ }
+
+ {
+ Handle<HeapNumber> number = t.factory()->NewHeapNumber(input);
+ t.Call(*number);
+ CHECK_EQ(input, result);
+ }
+ }
+ }
+}
+
+
+TEST(RunChangeBoolToBit) {
+ ChangesLoweringTester<int32_t> t(kMachineTagged);
+ t.BuildAndLower(t.simplified()->ChangeBoolToBit());
+
+ if (Pipeline::SupportedTarget()) {
+ Object* true_obj = t.heap()->true_value();
+ int32_t result = t.Call(true_obj);
+ CHECK_EQ(1, result);
+ }
+
+ if (Pipeline::SupportedTarget()) {
+ Object* false_obj = t.heap()->false_value();
+ int32_t result = t.Call(false_obj);
+ CHECK_EQ(0, result);
+ }
+}
+
+
+TEST(RunChangeBitToBool) {
+ ChangesLoweringTester<Object*> t(kMachineWord32);
+ t.BuildAndLower(t.simplified()->ChangeBitToBool());
+
+ if (Pipeline::SupportedTarget()) {
+ Object* result = t.Call(1);
+ Object* true_obj = t.heap()->true_value();
+ CHECK_EQ(true_obj, result);
+ }
+
+ if (Pipeline::SupportedTarget()) {
+ Object* result = t.Call(0);
+ Object* false_obj = t.heap()->false_value();
+ CHECK_EQ(false_obj, result);
+ }
+}
+
+
+bool TODO_INT32_TO_TAGGED_WILL_WORK(int32_t v) {
+ // TODO(titzer): enable all UI32 -> Tagged checking when inline allocation
+ // works.
+ return Smi::IsValid(v);
+}
+
+
+bool TODO_UINT32_TO_TAGGED_WILL_WORK(uint32_t v) {
+ // TODO(titzer): enable all UI32 -> Tagged checking when inline allocation
+ // works.
+ return v <= static_cast<uint32_t>(Smi::kMaxValue);
+}
+
+
+TEST(RunChangeInt32ToTagged) {
+ ChangesLoweringTester<Object*> t;
+ int32_t input;
+ t.BuildLoadAndLower(t.simplified()->ChangeInt32ToTagged(),
+ t.machine()->Load(kMachineWord32), &input);
+
+ if (Pipeline::SupportedTarget()) {
+ FOR_INT32_INPUTS(i) {
+ input = *i;
+ Object* result = t.CallWithPotentialGC<Object>();
+ if (TODO_INT32_TO_TAGGED_WILL_WORK(input)) {
+ t.CheckNumber(static_cast<double>(input), result);
+ }
+ }
+ }
+
+ if (Pipeline::SupportedTarget()) {
+ FOR_INT32_INPUTS(i) {
+ input = *i;
+ SimulateFullSpace(CcTest::heap()->new_space());
+ Object* result = t.CallWithPotentialGC<Object>();
+ if (TODO_INT32_TO_TAGGED_WILL_WORK(input)) {
+ t.CheckNumber(static_cast<double>(input), result);
+ }
+ }
+ }
+}
+
+
+TEST(RunChangeUint32ToTagged) {
+ ChangesLoweringTester<Object*> t;
+ uint32_t input;
+ t.BuildLoadAndLower(t.simplified()->ChangeUint32ToTagged(),
+ t.machine()->Load(kMachineWord32), &input);
+
+ if (Pipeline::SupportedTarget()) {
+ FOR_UINT32_INPUTS(i) {
+ input = *i;
+ Object* result = t.CallWithPotentialGC<Object>();
+ double expected = static_cast<double>(input);
+ if (TODO_UINT32_TO_TAGGED_WILL_WORK(input)) {
+ t.CheckNumber(expected, result);
+ }
+ }
+ }
+
+ if (Pipeline::SupportedTarget()) {
+ FOR_UINT32_INPUTS(i) {
+ input = *i;
+ SimulateFullSpace(CcTest::heap()->new_space());
+ Object* result = t.CallWithPotentialGC<Object>();
+ double expected = static_cast<double>(static_cast<uint32_t>(input));
+ if (TODO_UINT32_TO_TAGGED_WILL_WORK(input)) {
+ t.CheckNumber(expected, result);
+ }
+ }
+ }
+}
+
+
+// TODO(titzer): lowering of Float64->Tagged needs inline allocation.
+#define TODO_FLOAT64_TO_TAGGED false
+
+TEST(RunChangeFloat64ToTagged) {
+ ChangesLoweringTester<Object*> t;
+ double input;
+ t.BuildLoadAndLower(t.simplified()->ChangeFloat64ToTagged(),
+ t.machine()->Load(kMachineFloat64), &input);
+
+ // TODO(titzer): need inline allocation to change float to tagged.
+ if (TODO_FLOAT64_TO_TAGGED && Pipeline::SupportedTarget()) {
+ FOR_FLOAT64_INPUTS(i) {
+ input = *i;
+ Object* result = t.CallWithPotentialGC<Object>();
+ t.CheckNumber(input, result);
+ }
+ }
+
+ if (TODO_FLOAT64_TO_TAGGED && Pipeline::SupportedTarget()) {
+ FOR_FLOAT64_INPUTS(i) {
+ input = *i;
+ SimulateFullSpace(CcTest::heap()->new_space());
+ Object* result = t.CallWithPotentialGC<Object>();
+ t.CheckNumber(input, result);
+ }
+ }
+}
diff --git a/deps/v8/test/cctest/compiler/test-codegen-deopt.cc b/deps/v8/test/cctest/compiler/test-codegen-deopt.cc
new file mode 100644
index 000000000..b953ee53c
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-codegen-deopt.cc
@@ -0,0 +1,344 @@
+// 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 "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/compiler/code-generator.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/instruction-selector.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/node.h"
+#include "src/compiler/operator.h"
+#include "src/compiler/raw-machine-assembler.h"
+#include "src/compiler/register-allocator.h"
+#include "src/compiler/schedule.h"
+
+#include "src/full-codegen.h"
+#include "src/parser.h"
+#include "src/rewriter.h"
+
+#include "test/cctest/compiler/function-tester.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+
+#if V8_TURBOFAN_TARGET
+
+typedef RawMachineAssembler::Label MLabel;
+
+static Handle<JSFunction> NewFunction(const char* source) {
+ return v8::Utils::OpenHandle(
+ *v8::Handle<v8::Function>::Cast(CompileRun(source)));
+}
+
+
+class DeoptCodegenTester {
+ public:
+ explicit DeoptCodegenTester(HandleAndZoneScope* scope, const char* src)
+ : scope_(scope),
+ function(NewFunction(src)),
+ info(function, scope->main_zone()),
+ bailout_id(-1) {
+ CHECK(Parser::Parse(&info));
+ StrictMode strict_mode = info.function()->strict_mode();
+ info.SetStrictMode(strict_mode);
+ info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
+ CHECK(Rewriter::Rewrite(&info));
+ CHECK(Scope::Analyze(&info));
+ CHECK_NE(NULL, info.scope());
+
+ FunctionTester::EnsureDeoptimizationSupport(&info);
+
+ DCHECK(info.shared_info()->has_deoptimization_support());
+
+ graph = new (scope_->main_zone()) Graph(scope_->main_zone());
+ }
+
+ virtual ~DeoptCodegenTester() { delete code; }
+
+ void GenerateCodeFromSchedule(Schedule* schedule) {
+ OFStream os(stdout);
+ os << *schedule;
+
+ // Initialize the codegen and generate code.
+ Linkage* linkage = new (scope_->main_zone()) Linkage(&info);
+ code = new v8::internal::compiler::InstructionSequence(linkage, graph,
+ schedule);
+ SourcePositionTable source_positions(graph);
+ InstructionSelector selector(code, &source_positions);
+ selector.SelectInstructions();
+
+ os << "----- Instruction sequence before register allocation -----\n"
+ << *code;
+
+ RegisterAllocator allocator(code);
+ CHECK(allocator.Allocate());
+
+ os << "----- Instruction sequence after register allocation -----\n"
+ << *code;
+
+ compiler::CodeGenerator generator(code);
+ result_code = generator.GenerateCode();
+
+#ifdef DEBUG
+ result_code->Print();
+#endif
+ }
+
+ Zone* zone() { return scope_->main_zone(); }
+
+ HandleAndZoneScope* scope_;
+ Handle<JSFunction> function;
+ CompilationInfo info;
+ BailoutId bailout_id;
+ Handle<Code> result_code;
+ v8::internal::compiler::InstructionSequence* code;
+ Graph* graph;
+};
+
+
+class TrivialDeoptCodegenTester : public DeoptCodegenTester {
+ public:
+ explicit TrivialDeoptCodegenTester(HandleAndZoneScope* scope)
+ : DeoptCodegenTester(scope,
+ "function foo() { deopt(); return 42; }; foo") {}
+
+ void GenerateCode() {
+ GenerateCodeFromSchedule(BuildGraphAndSchedule(graph));
+ }
+
+ Schedule* BuildGraphAndSchedule(Graph* graph) {
+ Isolate* isolate = info.isolate();
+ CommonOperatorBuilder common(zone());
+
+ // Manually construct a schedule for the function below:
+ // function foo() {
+ // deopt();
+ // }
+
+ MachineType parameter_reps[] = {kMachineTagged};
+ MachineCallDescriptorBuilder descriptor_builder(kMachineTagged, 1,
+ parameter_reps);
+
+ RawMachineAssembler m(graph, &descriptor_builder);
+
+ Handle<Object> undef_object =
+ Handle<Object>(isolate->heap()->undefined_value(), isolate);
+ PrintableUnique<Object> undef_constant =
+ PrintableUnique<Object>::CreateUninitialized(zone(), undef_object);
+ Node* undef_node = m.NewNode(common.HeapConstant(undef_constant));
+
+ Handle<JSFunction> deopt_function =
+ NewFunction("function deopt() { %DeoptimizeFunction(foo); }; deopt");
+ PrintableUnique<Object> deopt_fun_constant =
+ PrintableUnique<Object>::CreateUninitialized(zone(), deopt_function);
+ Node* deopt_fun_node = m.NewNode(common.HeapConstant(deopt_fun_constant));
+
+ MLabel deopt, cont;
+ Node* call = m.CallJS0(deopt_fun_node, undef_node, &cont, &deopt);
+
+ m.Bind(&cont);
+ m.NewNode(common.Continuation(), call);
+ m.Return(undef_node);
+
+ m.Bind(&deopt);
+ m.NewNode(common.LazyDeoptimization(), call);
+
+ bailout_id = GetCallBailoutId();
+ Node* parameters = m.NewNode(common.StateValues(1), undef_node);
+ Node* locals = m.NewNode(common.StateValues(0));
+ Node* stack = m.NewNode(common.StateValues(0));
+
+ Node* state_node =
+ m.NewNode(common.FrameState(bailout_id), parameters, locals, stack);
+ m.Deoptimize(state_node);
+
+ // Schedule the graph:
+ Schedule* schedule = m.Export();
+
+ cont_block = cont.block();
+ deopt_block = deopt.block();
+
+ return schedule;
+ }
+
+ BailoutId GetCallBailoutId() {
+ ZoneList<Statement*>* body = info.function()->body();
+ for (int i = 0; i < body->length(); i++) {
+ if (body->at(i)->IsExpressionStatement() &&
+ body->at(i)->AsExpressionStatement()->expression()->IsCall()) {
+ return body->at(i)->AsExpressionStatement()->expression()->id();
+ }
+ }
+ CHECK(false);
+ return BailoutId(-1);
+ }
+
+ BasicBlock* cont_block;
+ BasicBlock* deopt_block;
+};
+
+
+TEST(TurboTrivialDeoptCodegen) {
+ HandleAndZoneScope scope;
+ InitializedHandleScope handles;
+
+ FLAG_allow_natives_syntax = true;
+ FLAG_turbo_deoptimization = true;
+
+ TrivialDeoptCodegenTester t(&scope);
+ t.GenerateCode();
+
+ DeoptimizationInputData* data =
+ DeoptimizationInputData::cast(t.result_code->deoptimization_data());
+
+ Label* cont_label = t.code->GetLabel(t.cont_block);
+ Label* deopt_label = t.code->GetLabel(t.deopt_block);
+
+ // Check the patch table. It should patch the continuation address to the
+ // deoptimization block address.
+ CHECK_EQ(1, data->ReturnAddressPatchCount());
+ CHECK_EQ(cont_label->pos(), data->ReturnAddressPc(0)->value());
+ CHECK_EQ(deopt_label->pos(), data->PatchedAddressPc(0)->value());
+
+ // Check that we deoptimize to the right AST id.
+ CHECK_EQ(1, data->DeoptCount());
+ CHECK_EQ(1, data->DeoptCount());
+ CHECK_EQ(t.bailout_id.ToInt(), data->AstId(0).ToInt());
+}
+
+
+TEST(TurboTrivialDeoptCodegenAndRun) {
+ HandleAndZoneScope scope;
+ InitializedHandleScope handles;
+
+ FLAG_allow_natives_syntax = true;
+ FLAG_turbo_deoptimization = true;
+
+ TrivialDeoptCodegenTester t(&scope);
+ t.GenerateCode();
+
+ t.function->ReplaceCode(*t.result_code);
+ t.info.context()->native_context()->AddOptimizedCode(*t.result_code);
+
+ Isolate* isolate = scope.main_isolate();
+ Handle<Object> result;
+ bool has_pending_exception =
+ !Execution::Call(isolate, t.function,
+ isolate->factory()->undefined_value(), 0, NULL,
+ false).ToHandle(&result);
+ CHECK(!has_pending_exception);
+ CHECK(result->SameValue(Smi::FromInt(42)));
+}
+
+
+class TrivialRuntimeDeoptCodegenTester : public DeoptCodegenTester {
+ public:
+ explicit TrivialRuntimeDeoptCodegenTester(HandleAndZoneScope* scope)
+ : DeoptCodegenTester(
+ scope,
+ "function foo() { %DeoptimizeFunction(foo); return 42; }; foo") {}
+
+ void GenerateCode() {
+ GenerateCodeFromSchedule(BuildGraphAndSchedule(graph));
+ }
+
+ Schedule* BuildGraphAndSchedule(Graph* graph) {
+ Isolate* isolate = info.isolate();
+ CommonOperatorBuilder common(zone());
+
+ // Manually construct a schedule for the function below:
+ // function foo() {
+ // %DeoptimizeFunction(foo);
+ // }
+
+ MachineType parameter_reps[] = {kMachineTagged};
+ MachineCallDescriptorBuilder descriptor_builder(kMachineTagged, 2,
+ parameter_reps);
+
+ RawMachineAssembler m(graph, &descriptor_builder);
+
+ Handle<Object> undef_object =
+ Handle<Object>(isolate->heap()->undefined_value(), isolate);
+ PrintableUnique<Object> undef_constant =
+ PrintableUnique<Object>::CreateUninitialized(zone(), undef_object);
+ Node* undef_node = m.NewNode(common.HeapConstant(undef_constant));
+
+ PrintableUnique<Object> this_fun_constant =
+ PrintableUnique<Object>::CreateUninitialized(zone(), function);
+ Node* this_fun_node = m.NewNode(common.HeapConstant(this_fun_constant));
+
+ MLabel deopt, cont;
+ Node* call = m.CallRuntime1(Runtime::kDeoptimizeFunction, this_fun_node,
+ &cont, &deopt);
+
+ m.Bind(&cont);
+ m.NewNode(common.Continuation(), call);
+ m.Return(undef_node);
+
+ m.Bind(&deopt);
+ m.NewNode(common.LazyDeoptimization(), call);
+
+ bailout_id = GetCallBailoutId();
+ Node* parameters = m.NewNode(common.StateValues(1), undef_node);
+ Node* locals = m.NewNode(common.StateValues(0));
+ Node* stack = m.NewNode(common.StateValues(0));
+
+ Node* state_node =
+ m.NewNode(common.FrameState(bailout_id), parameters, locals, stack);
+ m.Deoptimize(state_node);
+
+ // Schedule the graph:
+ Schedule* schedule = m.Export();
+
+ cont_block = cont.block();
+ deopt_block = deopt.block();
+
+ return schedule;
+ }
+
+ BailoutId GetCallBailoutId() {
+ ZoneList<Statement*>* body = info.function()->body();
+ for (int i = 0; i < body->length(); i++) {
+ if (body->at(i)->IsExpressionStatement() &&
+ body->at(i)->AsExpressionStatement()->expression()->IsCallRuntime()) {
+ return body->at(i)->AsExpressionStatement()->expression()->id();
+ }
+ }
+ CHECK(false);
+ return BailoutId(-1);
+ }
+
+ BasicBlock* cont_block;
+ BasicBlock* deopt_block;
+};
+
+
+TEST(TurboTrivialRuntimeDeoptCodegenAndRun) {
+ HandleAndZoneScope scope;
+ InitializedHandleScope handles;
+
+ FLAG_allow_natives_syntax = true;
+ FLAG_turbo_deoptimization = true;
+
+ TrivialRuntimeDeoptCodegenTester t(&scope);
+ t.GenerateCode();
+
+ t.function->ReplaceCode(*t.result_code);
+ t.info.context()->native_context()->AddOptimizedCode(*t.result_code);
+
+ Isolate* isolate = scope.main_isolate();
+ Handle<Object> result;
+ bool has_pending_exception =
+ !Execution::Call(isolate, t.function,
+ isolate->factory()->undefined_value(), 0, NULL,
+ false).ToHandle(&result);
+ CHECK(!has_pending_exception);
+ CHECK(result->SameValue(Smi::FromInt(42)));
+}
+
+#endif
diff --git a/deps/v8/test/cctest/compiler/test-gap-resolver.cc b/deps/v8/test/cctest/compiler/test-gap-resolver.cc
new file mode 100644
index 000000000..00c220945
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-gap-resolver.cc
@@ -0,0 +1,173 @@
+// 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 "src/compiler/gap-resolver.h"
+
+#include "src/base/utils/random-number-generator.h"
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+// The state of our move interpreter is the mapping of operands to values. Note
+// that the actual values don't really matter, all we care about is equality.
+class InterpreterState {
+ public:
+ typedef std::vector<MoveOperands> Moves;
+
+ void ExecuteInParallel(Moves moves) {
+ InterpreterState copy(*this);
+ for (Moves::iterator it = moves.begin(); it != moves.end(); ++it) {
+ if (!it->IsRedundant()) write(it->destination(), copy.read(it->source()));
+ }
+ }
+
+ bool operator==(const InterpreterState& other) const {
+ return values_ == other.values_;
+ }
+
+ bool operator!=(const InterpreterState& other) const {
+ return values_ != other.values_;
+ }
+
+ private:
+ // Internally, the state is a normalized permutation of (kind,index) pairs.
+ typedef std::pair<InstructionOperand::Kind, int> Key;
+ typedef Key Value;
+ typedef std::map<Key, Value> OperandMap;
+
+ Value read(const InstructionOperand* op) const {
+ OperandMap::const_iterator it = values_.find(KeyFor(op));
+ return (it == values_.end()) ? ValueFor(op) : it->second;
+ }
+
+ void write(const InstructionOperand* op, Value v) {
+ if (v == ValueFor(op)) {
+ values_.erase(KeyFor(op));
+ } else {
+ values_[KeyFor(op)] = v;
+ }
+ }
+
+ static Key KeyFor(const InstructionOperand* op) {
+ return Key(op->kind(), op->index());
+ }
+
+ static Value ValueFor(const InstructionOperand* op) {
+ return Value(op->kind(), op->index());
+ }
+
+ friend OStream& operator<<(OStream& os, const InterpreterState& is) {
+ for (OperandMap::const_iterator it = is.values_.begin();
+ it != is.values_.end(); ++it) {
+ if (it != is.values_.begin()) os << " ";
+ InstructionOperand source(it->first.first, it->first.second);
+ InstructionOperand destination(it->second.first, it->second.second);
+ os << MoveOperands(&source, &destination);
+ }
+ return os;
+ }
+
+ OperandMap values_;
+};
+
+
+// An abstract interpreter for moves, swaps and parallel moves.
+class MoveInterpreter : public GapResolver::Assembler {
+ public:
+ virtual void AssembleMove(InstructionOperand* source,
+ InstructionOperand* destination) V8_OVERRIDE {
+ InterpreterState::Moves moves;
+ moves.push_back(MoveOperands(source, destination));
+ state_.ExecuteInParallel(moves);
+ }
+
+ virtual void AssembleSwap(InstructionOperand* source,
+ InstructionOperand* destination) V8_OVERRIDE {
+ InterpreterState::Moves moves;
+ moves.push_back(MoveOperands(source, destination));
+ moves.push_back(MoveOperands(destination, source));
+ state_.ExecuteInParallel(moves);
+ }
+
+ void AssembleParallelMove(const ParallelMove* pm) {
+ InterpreterState::Moves moves(pm->move_operands()->begin(),
+ pm->move_operands()->end());
+ state_.ExecuteInParallel(moves);
+ }
+
+ InterpreterState state() const { return state_; }
+
+ private:
+ InterpreterState state_;
+};
+
+
+class ParallelMoveCreator : public HandleAndZoneScope {
+ public:
+ ParallelMoveCreator() : rng_(CcTest::random_number_generator()) {}
+
+ ParallelMove* Create(int size) {
+ ParallelMove* parallel_move = new (main_zone()) ParallelMove(main_zone());
+ std::set<InstructionOperand*, InstructionOperandComparator> seen;
+ for (int i = 0; i < size; ++i) {
+ MoveOperands mo(CreateRandomOperand(), CreateRandomOperand());
+ if (!mo.IsRedundant() && seen.find(mo.destination()) == seen.end()) {
+ parallel_move->AddMove(mo.source(), mo.destination(), main_zone());
+ seen.insert(mo.destination());
+ }
+ }
+ return parallel_move;
+ }
+
+ private:
+ struct InstructionOperandComparator {
+ bool operator()(const InstructionOperand* x,
+ const InstructionOperand* y) const {
+ return (x->kind() < y->kind()) ||
+ (x->kind() == y->kind() && x->index() < y->index());
+ }
+ };
+
+ InstructionOperand* CreateRandomOperand() {
+ int index = rng_->NextInt(6);
+ switch (rng_->NextInt(5)) {
+ case 0:
+ return ConstantOperand::Create(index, main_zone());
+ case 1:
+ return StackSlotOperand::Create(index, main_zone());
+ case 2:
+ return DoubleStackSlotOperand::Create(index, main_zone());
+ case 3:
+ return RegisterOperand::Create(index, main_zone());
+ case 4:
+ return DoubleRegisterOperand::Create(index, main_zone());
+ }
+ UNREACHABLE();
+ return NULL;
+ }
+
+ private:
+ v8::base::RandomNumberGenerator* rng_;
+};
+
+
+TEST(FuzzResolver) {
+ ParallelMoveCreator pmc;
+ for (int size = 0; size < 20; ++size) {
+ for (int repeat = 0; repeat < 50; ++repeat) {
+ ParallelMove* pm = pmc.Create(size);
+
+ // Note: The gap resolver modifies the ParallelMove, so interpret first.
+ MoveInterpreter mi1;
+ mi1.AssembleParallelMove(pm);
+
+ MoveInterpreter mi2;
+ GapResolver resolver(&mi2);
+ resolver.Resolve(pm);
+
+ CHECK(mi1.state() == mi2.state());
+ }
+ }
+}
diff --git a/deps/v8/test/cctest/compiler/test-graph-reducer.cc b/deps/v8/test/cctest/compiler/test-graph-reducer.cc
new file mode 100644
index 000000000..189b3db18
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-graph-reducer.cc
@@ -0,0 +1,661 @@
+// 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 "src/v8.h"
+
+#include "graph-tester.h"
+#include "src/compiler/generic-node-inl.h"
+#include "src/compiler/graph-reducer.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+const uint8_t OPCODE_A0 = 10;
+const uint8_t OPCODE_A1 = 11;
+const uint8_t OPCODE_A2 = 12;
+const uint8_t OPCODE_B0 = 20;
+const uint8_t OPCODE_B1 = 21;
+const uint8_t OPCODE_B2 = 22;
+const uint8_t OPCODE_C0 = 30;
+const uint8_t OPCODE_C1 = 31;
+const uint8_t OPCODE_C2 = 32;
+
+static SimpleOperator OPA0(OPCODE_A0, Operator::kNoWrite, 0, 0, "opa0");
+static SimpleOperator OPA1(OPCODE_A1, Operator::kNoWrite, 1, 0, "opa1");
+static SimpleOperator OPA2(OPCODE_A2, Operator::kNoWrite, 2, 0, "opa2");
+static SimpleOperator OPB0(OPCODE_B0, Operator::kNoWrite, 0, 0, "opa0");
+static SimpleOperator OPB1(OPCODE_B1, Operator::kNoWrite, 1, 0, "opa1");
+static SimpleOperator OPB2(OPCODE_B2, Operator::kNoWrite, 2, 0, "opa2");
+static SimpleOperator OPC0(OPCODE_C0, Operator::kNoWrite, 0, 0, "opc0");
+static SimpleOperator OPC1(OPCODE_C1, Operator::kNoWrite, 1, 0, "opc1");
+static SimpleOperator OPC2(OPCODE_C2, Operator::kNoWrite, 2, 0, "opc2");
+
+
+// Replaces all "A" operators with "B" operators without creating new nodes.
+class InPlaceABReducer : public Reducer {
+ public:
+ virtual Reduction Reduce(Node* node) {
+ switch (node->op()->opcode()) {
+ case OPCODE_A0:
+ CHECK_EQ(0, node->InputCount());
+ node->set_op(&OPB0);
+ return Replace(node);
+ case OPCODE_A1:
+ CHECK_EQ(1, node->InputCount());
+ node->set_op(&OPB1);
+ return Replace(node);
+ case OPCODE_A2:
+ CHECK_EQ(2, node->InputCount());
+ node->set_op(&OPB2);
+ return Replace(node);
+ }
+ return NoChange();
+ }
+};
+
+
+// Replaces all "A" operators with "B" operators by allocating new nodes.
+class NewABReducer : public Reducer {
+ public:
+ explicit NewABReducer(Graph* graph) : graph_(graph) {}
+ virtual Reduction Reduce(Node* node) {
+ switch (node->op()->opcode()) {
+ case OPCODE_A0:
+ CHECK_EQ(0, node->InputCount());
+ return Replace(graph_->NewNode(&OPB0));
+ case OPCODE_A1:
+ CHECK_EQ(1, node->InputCount());
+ return Replace(graph_->NewNode(&OPB1, node->InputAt(0)));
+ case OPCODE_A2:
+ CHECK_EQ(2, node->InputCount());
+ return Replace(
+ graph_->NewNode(&OPB2, node->InputAt(0), node->InputAt(1)));
+ }
+ return NoChange();
+ }
+ Graph* graph_;
+};
+
+
+// Replaces all "B" operators with "C" operators without creating new nodes.
+class InPlaceBCReducer : public Reducer {
+ public:
+ virtual Reduction Reduce(Node* node) {
+ switch (node->op()->opcode()) {
+ case OPCODE_B0:
+ CHECK_EQ(0, node->InputCount());
+ node->set_op(&OPC0);
+ return Replace(node);
+ case OPCODE_B1:
+ CHECK_EQ(1, node->InputCount());
+ node->set_op(&OPC1);
+ return Replace(node);
+ case OPCODE_B2:
+ CHECK_EQ(2, node->InputCount());
+ node->set_op(&OPC2);
+ return Replace(node);
+ }
+ return NoChange();
+ }
+};
+
+
+// Wraps all "OPA0" nodes in "OPB1" operators by allocating new nodes.
+class A0Wrapper V8_FINAL : public Reducer {
+ public:
+ explicit A0Wrapper(Graph* graph) : graph_(graph) {}
+ virtual Reduction Reduce(Node* node) V8_OVERRIDE {
+ switch (node->op()->opcode()) {
+ case OPCODE_A0:
+ CHECK_EQ(0, node->InputCount());
+ return Replace(graph_->NewNode(&OPB1, node));
+ }
+ return NoChange();
+ }
+ Graph* graph_;
+};
+
+
+// Wraps all "OPB0" nodes in two "OPC1" operators by allocating new nodes.
+class B0Wrapper V8_FINAL : public Reducer {
+ public:
+ explicit B0Wrapper(Graph* graph) : graph_(graph) {}
+ virtual Reduction Reduce(Node* node) V8_OVERRIDE {
+ switch (node->op()->opcode()) {
+ case OPCODE_B0:
+ CHECK_EQ(0, node->InputCount());
+ return Replace(graph_->NewNode(&OPC1, graph_->NewNode(&OPC1, node)));
+ }
+ return NoChange();
+ }
+ Graph* graph_;
+};
+
+
+// Replaces all "OPA1" nodes with the first input.
+class A1Forwarder : public Reducer {
+ virtual Reduction Reduce(Node* node) {
+ switch (node->op()->opcode()) {
+ case OPCODE_A1:
+ CHECK_EQ(1, node->InputCount());
+ return Replace(node->InputAt(0));
+ }
+ return NoChange();
+ }
+};
+
+
+// Replaces all "OPB1" nodes with the first input.
+class B1Forwarder : public Reducer {
+ virtual Reduction Reduce(Node* node) {
+ switch (node->op()->opcode()) {
+ case OPCODE_B1:
+ CHECK_EQ(1, node->InputCount());
+ return Replace(node->InputAt(0));
+ }
+ return NoChange();
+ }
+};
+
+
+// Swaps the inputs to "OP2A" and "OP2B" nodes based on ids.
+class AB2Sorter : public Reducer {
+ virtual Reduction Reduce(Node* node) {
+ switch (node->op()->opcode()) {
+ case OPCODE_A2:
+ case OPCODE_B2:
+ CHECK_EQ(2, node->InputCount());
+ Node* x = node->InputAt(0);
+ Node* y = node->InputAt(1);
+ if (x->id() > y->id()) {
+ node->ReplaceInput(0, y);
+ node->ReplaceInput(1, x);
+ return Replace(node);
+ }
+ }
+ return NoChange();
+ }
+};
+
+
+// Simply records the nodes visited.
+class ReducerRecorder : public Reducer {
+ public:
+ explicit ReducerRecorder(Zone* zone)
+ : set(NodeSet::key_compare(), NodeSet::allocator_type(zone)) {}
+ virtual Reduction Reduce(Node* node) {
+ set.insert(node);
+ return NoChange();
+ }
+ void CheckContains(Node* node) {
+ CHECK_EQ(1, static_cast<int>(set.count(node)));
+ }
+ NodeSet set;
+};
+
+
+TEST(ReduceGraphFromEnd1) {
+ GraphTester graph;
+
+ Node* n1 = graph.NewNode(&OPA0);
+ Node* end = graph.NewNode(&OPA1, n1);
+ graph.SetEnd(end);
+
+ GraphReducer reducer(&graph);
+ ReducerRecorder recorder(graph.zone());
+ reducer.AddReducer(&recorder);
+ reducer.ReduceGraph();
+ recorder.CheckContains(n1);
+ recorder.CheckContains(end);
+}
+
+
+TEST(ReduceGraphFromEnd2) {
+ GraphTester graph;
+
+ Node* n1 = graph.NewNode(&OPA0);
+ Node* n2 = graph.NewNode(&OPA1, n1);
+ Node* n3 = graph.NewNode(&OPA1, n1);
+ Node* end = graph.NewNode(&OPA2, n2, n3);
+ graph.SetEnd(end);
+
+ GraphReducer reducer(&graph);
+ ReducerRecorder recorder(graph.zone());
+ reducer.AddReducer(&recorder);
+ reducer.ReduceGraph();
+ recorder.CheckContains(n1);
+ recorder.CheckContains(n2);
+ recorder.CheckContains(n3);
+ recorder.CheckContains(end);
+}
+
+
+TEST(ReduceInPlace1) {
+ GraphTester graph;
+
+ Node* n1 = graph.NewNode(&OPA0);
+ Node* end = graph.NewNode(&OPA1, n1);
+ graph.SetEnd(end);
+
+ GraphReducer reducer(&graph);
+ InPlaceABReducer r;
+ reducer.AddReducer(&r);
+
+ // Tests A* => B* with in-place updates.
+ for (int i = 0; i < 3; i++) {
+ int before = graph.NodeCount();
+ reducer.ReduceGraph();
+ CHECK_EQ(before, graph.NodeCount());
+ CHECK_EQ(&OPB0, n1->op());
+ CHECK_EQ(&OPB1, end->op());
+ CHECK_EQ(n1, end->InputAt(0));
+ }
+}
+
+
+TEST(ReduceInPlace2) {
+ GraphTester graph;
+
+ Node* n1 = graph.NewNode(&OPA0);
+ Node* n2 = graph.NewNode(&OPA1, n1);
+ Node* n3 = graph.NewNode(&OPA1, n1);
+ Node* end = graph.NewNode(&OPA2, n2, n3);
+ graph.SetEnd(end);
+
+ GraphReducer reducer(&graph);
+ InPlaceABReducer r;
+ reducer.AddReducer(&r);
+
+ // Tests A* => B* with in-place updates.
+ for (int i = 0; i < 3; i++) {
+ int before = graph.NodeCount();
+ reducer.ReduceGraph();
+ CHECK_EQ(before, graph.NodeCount());
+ CHECK_EQ(&OPB0, n1->op());
+ CHECK_EQ(&OPB1, n2->op());
+ CHECK_EQ(n1, n2->InputAt(0));
+ CHECK_EQ(&OPB1, n3->op());
+ CHECK_EQ(n1, n3->InputAt(0));
+ CHECK_EQ(&OPB2, end->op());
+ CHECK_EQ(n2, end->InputAt(0));
+ CHECK_EQ(n3, end->InputAt(1));
+ }
+}
+
+
+TEST(ReduceNew1) {
+ GraphTester graph;
+
+ Node* n1 = graph.NewNode(&OPA0);
+ Node* n2 = graph.NewNode(&OPA1, n1);
+ Node* n3 = graph.NewNode(&OPA1, n1);
+ Node* end = graph.NewNode(&OPA2, n2, n3);
+ graph.SetEnd(end);
+
+ GraphReducer reducer(&graph);
+ NewABReducer r(&graph);
+ reducer.AddReducer(&r);
+
+ // Tests A* => B* while creating new nodes.
+ for (int i = 0; i < 3; i++) {
+ int before = graph.NodeCount();
+ reducer.ReduceGraph();
+ if (i == 0) {
+ CHECK_NE(before, graph.NodeCount());
+ } else {
+ CHECK_EQ(before, graph.NodeCount());
+ }
+ Node* nend = graph.end();
+ CHECK_NE(end, nend); // end() should be updated too.
+
+ Node* nn2 = nend->InputAt(0);
+ Node* nn3 = nend->InputAt(1);
+ Node* nn1 = nn2->InputAt(0);
+
+ CHECK_EQ(nn1, nn3->InputAt(0));
+
+ CHECK_EQ(&OPB0, nn1->op());
+ CHECK_EQ(&OPB1, nn2->op());
+ CHECK_EQ(&OPB1, nn3->op());
+ CHECK_EQ(&OPB2, nend->op());
+ }
+}
+
+
+TEST(Wrapping1) {
+ GraphTester graph;
+
+ Node* end = graph.NewNode(&OPA0);
+ graph.SetEnd(end);
+ CHECK_EQ(1, graph.NodeCount());
+
+ GraphReducer reducer(&graph);
+ A0Wrapper r(&graph);
+ reducer.AddReducer(&r);
+
+ reducer.ReduceGraph();
+ CHECK_EQ(2, graph.NodeCount());
+
+ Node* nend = graph.end();
+ CHECK_NE(end, nend);
+ CHECK_EQ(&OPB1, nend->op());
+ CHECK_EQ(1, nend->InputCount());
+ CHECK_EQ(end, nend->InputAt(0));
+}
+
+
+TEST(Wrapping2) {
+ GraphTester graph;
+
+ Node* end = graph.NewNode(&OPB0);
+ graph.SetEnd(end);
+ CHECK_EQ(1, graph.NodeCount());
+
+ GraphReducer reducer(&graph);
+ B0Wrapper r(&graph);
+ reducer.AddReducer(&r);
+
+ reducer.ReduceGraph();
+ CHECK_EQ(3, graph.NodeCount());
+
+ Node* nend = graph.end();
+ CHECK_NE(end, nend);
+ CHECK_EQ(&OPC1, nend->op());
+ CHECK_EQ(1, nend->InputCount());
+
+ Node* n1 = nend->InputAt(0);
+ CHECK_NE(end, n1);
+ CHECK_EQ(&OPC1, n1->op());
+ CHECK_EQ(1, n1->InputCount());
+ CHECK_EQ(end, n1->InputAt(0));
+}
+
+
+TEST(Forwarding1) {
+ GraphTester graph;
+
+ Node* n1 = graph.NewNode(&OPA0);
+ Node* end = graph.NewNode(&OPA1, n1);
+ graph.SetEnd(end);
+
+ GraphReducer reducer(&graph);
+ A1Forwarder r;
+ reducer.AddReducer(&r);
+
+ // Tests A1(x) => x
+ for (int i = 0; i < 3; i++) {
+ int before = graph.NodeCount();
+ reducer.ReduceGraph();
+ CHECK_EQ(before, graph.NodeCount());
+ CHECK_EQ(&OPA0, n1->op());
+ CHECK_EQ(n1, graph.end());
+ }
+}
+
+
+TEST(Forwarding2) {
+ GraphTester graph;
+
+ Node* n1 = graph.NewNode(&OPA0);
+ Node* n2 = graph.NewNode(&OPA1, n1);
+ Node* n3 = graph.NewNode(&OPA1, n1);
+ Node* end = graph.NewNode(&OPA2, n2, n3);
+ graph.SetEnd(end);
+
+ GraphReducer reducer(&graph);
+ A1Forwarder r;
+ reducer.AddReducer(&r);
+
+ // Tests reducing A2(A1(x), A1(y)) => A2(x, y).
+ for (int i = 0; i < 3; i++) {
+ int before = graph.NodeCount();
+ reducer.ReduceGraph();
+ CHECK_EQ(before, graph.NodeCount());
+ CHECK_EQ(&OPA0, n1->op());
+ CHECK_EQ(n1, end->InputAt(0));
+ CHECK_EQ(n1, end->InputAt(1));
+ CHECK_EQ(&OPA2, end->op());
+ CHECK_EQ(0, n2->UseCount());
+ CHECK_EQ(0, n3->UseCount());
+ }
+}
+
+
+TEST(Forwarding3) {
+ // Tests reducing a chain of A1(A1(A1(A1(x)))) => x.
+ for (int i = 0; i < 8; i++) {
+ GraphTester graph;
+
+ Node* n1 = graph.NewNode(&OPA0);
+ Node* end = n1;
+ for (int j = 0; j < i; j++) {
+ end = graph.NewNode(&OPA1, end);
+ }
+ graph.SetEnd(end);
+
+ GraphReducer reducer(&graph);
+ A1Forwarder r;
+ reducer.AddReducer(&r);
+
+ for (int i = 0; i < 3; i++) {
+ int before = graph.NodeCount();
+ reducer.ReduceGraph();
+ CHECK_EQ(before, graph.NodeCount());
+ CHECK_EQ(&OPA0, n1->op());
+ CHECK_EQ(n1, graph.end());
+ }
+ }
+}
+
+
+TEST(ReduceForward1) {
+ GraphTester graph;
+
+ Node* n1 = graph.NewNode(&OPA0);
+ Node* n2 = graph.NewNode(&OPA1, n1);
+ Node* n3 = graph.NewNode(&OPA1, n1);
+ Node* end = graph.NewNode(&OPA2, n2, n3);
+ graph.SetEnd(end);
+
+ GraphReducer reducer(&graph);
+ InPlaceABReducer r;
+ B1Forwarder f;
+ reducer.AddReducer(&r);
+ reducer.AddReducer(&f);
+
+ // Tests first reducing A => B, then B1(x) => x.
+ for (int i = 0; i < 3; i++) {
+ int before = graph.NodeCount();
+ reducer.ReduceGraph();
+ CHECK_EQ(before, graph.NodeCount());
+ CHECK_EQ(&OPB0, n1->op());
+ CHECK_EQ(&OPB1, n2->op());
+ CHECK_EQ(n1, end->InputAt(0));
+ CHECK_EQ(&OPB1, n3->op());
+ CHECK_EQ(n1, end->InputAt(0));
+ CHECK_EQ(&OPB2, end->op());
+ CHECK_EQ(0, n2->UseCount());
+ CHECK_EQ(0, n3->UseCount());
+ }
+}
+
+
+TEST(Sorter1) {
+ HandleAndZoneScope scope;
+ AB2Sorter r;
+ for (int i = 0; i < 6; i++) {
+ GraphTester graph;
+
+ Node* n1 = graph.NewNode(&OPA0);
+ Node* n2 = graph.NewNode(&OPA1, n1);
+ Node* n3 = graph.NewNode(&OPA1, n1);
+ Node* end = NULL; // Initialize to please the compiler.
+
+ if (i == 0) end = graph.NewNode(&OPA2, n2, n3);
+ if (i == 1) end = graph.NewNode(&OPA2, n3, n2);
+ if (i == 2) end = graph.NewNode(&OPA2, n2, n1);
+ if (i == 3) end = graph.NewNode(&OPA2, n1, n2);
+ if (i == 4) end = graph.NewNode(&OPA2, n3, n1);
+ if (i == 5) end = graph.NewNode(&OPA2, n1, n3);
+
+ graph.SetEnd(end);
+
+ GraphReducer reducer(&graph);
+ reducer.AddReducer(&r);
+
+ int before = graph.NodeCount();
+ reducer.ReduceGraph();
+ CHECK_EQ(before, graph.NodeCount());
+ CHECK_EQ(&OPA0, n1->op());
+ CHECK_EQ(&OPA1, n2->op());
+ CHECK_EQ(&OPA1, n3->op());
+ CHECK_EQ(&OPA2, end->op());
+ CHECK_EQ(end, graph.end());
+ CHECK(end->InputAt(0)->id() <= end->InputAt(1)->id());
+ }
+}
+
+
+// Generate a node graph with the given permutations.
+void GenDAG(Graph* graph, int* p3, int* p2, int* p1) {
+ Node* level4 = graph->NewNode(&OPA0);
+ Node* level3[] = {graph->NewNode(&OPA1, level4),
+ graph->NewNode(&OPA1, level4)};
+
+ Node* level2[] = {graph->NewNode(&OPA1, level3[p3[0]]),
+ graph->NewNode(&OPA1, level3[p3[1]]),
+ graph->NewNode(&OPA1, level3[p3[0]]),
+ graph->NewNode(&OPA1, level3[p3[1]])};
+
+ Node* level1[] = {graph->NewNode(&OPA2, level2[p2[0]], level2[p2[1]]),
+ graph->NewNode(&OPA2, level2[p2[2]], level2[p2[3]])};
+
+ Node* end = graph->NewNode(&OPA2, level1[p1[0]], level1[p1[1]]);
+ graph->SetEnd(end);
+}
+
+
+TEST(SortForwardReduce) {
+ GraphTester graph;
+
+ // Tests combined reductions on a series of DAGs.
+ for (int j = 0; j < 2; j++) {
+ int p3[] = {j, 1 - j};
+ for (int m = 0; m < 2; m++) {
+ int p1[] = {m, 1 - m};
+ for (int k = 0; k < 24; k++) { // All permutations of 0, 1, 2, 3
+ int p2[] = {-1, -1, -1, -1};
+ int n = k;
+ for (int d = 4; d >= 1; d--) { // Construct permutation.
+ int p = n % d;
+ for (int z = 0; z < 4; z++) {
+ if (p2[z] == -1) {
+ if (p == 0) p2[z] = d - 1;
+ p--;
+ }
+ }
+ n = n / d;
+ }
+
+ GenDAG(&graph, p3, p2, p1);
+
+ GraphReducer reducer(&graph);
+ AB2Sorter r1;
+ A1Forwarder r2;
+ InPlaceABReducer r3;
+ reducer.AddReducer(&r1);
+ reducer.AddReducer(&r2);
+ reducer.AddReducer(&r3);
+
+ reducer.ReduceGraph();
+
+ Node* end = graph.end();
+ CHECK_EQ(&OPB2, end->op());
+ Node* n1 = end->InputAt(0);
+ Node* n2 = end->InputAt(1);
+ CHECK_NE(n1, n2);
+ CHECK(n1->id() < n2->id());
+ CHECK_EQ(&OPB2, n1->op());
+ CHECK_EQ(&OPB2, n2->op());
+ Node* n4 = n1->InputAt(0);
+ CHECK_EQ(&OPB0, n4->op());
+ CHECK_EQ(n4, n1->InputAt(1));
+ CHECK_EQ(n4, n2->InputAt(0));
+ CHECK_EQ(n4, n2->InputAt(1));
+ }
+ }
+ }
+}
+
+
+TEST(Order) {
+ // Test that the order of reducers doesn't matter, as they should be
+ // rerun for changed nodes.
+ for (int i = 0; i < 2; i++) {
+ GraphTester graph;
+
+ Node* n1 = graph.NewNode(&OPA0);
+ Node* end = graph.NewNode(&OPA1, n1);
+ graph.SetEnd(end);
+
+ GraphReducer reducer(&graph);
+ InPlaceABReducer abr;
+ InPlaceBCReducer bcr;
+ if (i == 0) {
+ reducer.AddReducer(&abr);
+ reducer.AddReducer(&bcr);
+ } else {
+ reducer.AddReducer(&bcr);
+ reducer.AddReducer(&abr);
+ }
+
+ // Tests A* => C* with in-place updates.
+ for (int i = 0; i < 3; i++) {
+ int before = graph.NodeCount();
+ reducer.ReduceGraph();
+ CHECK_EQ(before, graph.NodeCount());
+ CHECK_EQ(&OPC0, n1->op());
+ CHECK_EQ(&OPC1, end->op());
+ CHECK_EQ(n1, end->InputAt(0));
+ }
+ }
+}
+
+
+// Tests that a reducer is only applied once.
+class OneTimeReducer : public Reducer {
+ public:
+ OneTimeReducer(Reducer* reducer, Zone* zone)
+ : reducer_(reducer),
+ nodes_(NodeSet::key_compare(), NodeSet::allocator_type(zone)) {}
+ virtual Reduction Reduce(Node* node) {
+ CHECK_EQ(0, static_cast<int>(nodes_.count(node)));
+ nodes_.insert(node);
+ return reducer_->Reduce(node);
+ }
+ Reducer* reducer_;
+ NodeSet nodes_;
+};
+
+
+TEST(OneTimeReduce1) {
+ GraphTester graph;
+
+ Node* n1 = graph.NewNode(&OPA0);
+ Node* end = graph.NewNode(&OPA1, n1);
+ graph.SetEnd(end);
+
+ GraphReducer reducer(&graph);
+ InPlaceABReducer r;
+ OneTimeReducer once(&r, graph.zone());
+ reducer.AddReducer(&once);
+
+ // Tests A* => B* with in-place updates. Should only be applied once.
+ int before = graph.NodeCount();
+ reducer.ReduceGraph();
+ CHECK_EQ(before, graph.NodeCount());
+ CHECK_EQ(&OPB0, n1->op());
+ CHECK_EQ(&OPB1, end->op());
+ CHECK_EQ(n1, end->InputAt(0));
+}
diff --git a/deps/v8/test/cctest/compiler/test-instruction-selector-arm.cc b/deps/v8/test/cctest/compiler/test-instruction-selector-arm.cc
new file mode 100644
index 000000000..f62e09f97
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-instruction-selector-arm.cc
@@ -0,0 +1,1863 @@
+// 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 <list>
+
+#include "test/cctest/compiler/instruction-selector-tester.h"
+#include "test/cctest/compiler/value-helper.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+namespace {
+
+typedef RawMachineAssembler::Label MLabel;
+
+struct DPI {
+ Operator* op;
+ ArchOpcode arch_opcode;
+ ArchOpcode reverse_arch_opcode;
+ ArchOpcode test_arch_opcode;
+};
+
+
+// ARM data processing instructions.
+class DPIs V8_FINAL : public std::list<DPI>, private HandleAndZoneScope {
+ public:
+ DPIs() {
+ MachineOperatorBuilder machine(main_zone());
+ DPI and_ = {machine.Word32And(), kArmAnd, kArmAnd, kArmTst};
+ push_back(and_);
+ DPI or_ = {machine.Word32Or(), kArmOrr, kArmOrr, kArmOrr};
+ push_back(or_);
+ DPI xor_ = {machine.Word32Xor(), kArmEor, kArmEor, kArmTeq};
+ push_back(xor_);
+ DPI add = {machine.Int32Add(), kArmAdd, kArmAdd, kArmCmn};
+ push_back(add);
+ DPI sub = {machine.Int32Sub(), kArmSub, kArmRsb, kArmCmp};
+ push_back(sub);
+ }
+};
+
+
+struct ODPI {
+ Operator* op;
+ ArchOpcode arch_opcode;
+ ArchOpcode reverse_arch_opcode;
+};
+
+
+// ARM data processing instructions with overflow.
+class ODPIs V8_FINAL : public std::list<ODPI>, private HandleAndZoneScope {
+ public:
+ ODPIs() {
+ MachineOperatorBuilder machine(main_zone());
+ ODPI add = {machine.Int32AddWithOverflow(), kArmAdd, kArmAdd};
+ push_back(add);
+ ODPI sub = {machine.Int32SubWithOverflow(), kArmSub, kArmRsb};
+ push_back(sub);
+ }
+};
+
+
+// ARM immediates.
+class Immediates V8_FINAL : public std::list<int32_t> {
+ public:
+ Immediates() {
+ for (uint32_t imm8 = 0; imm8 < 256; ++imm8) {
+ for (uint32_t rot4 = 0; rot4 < 32; rot4 += 2) {
+ int32_t imm = (imm8 >> rot4) | (imm8 << (32 - rot4));
+ CHECK(Assembler::ImmediateFitsAddrMode1Instruction(imm));
+ push_back(imm);
+ }
+ }
+ }
+};
+
+
+struct Shift {
+ Operator* op;
+ int32_t i_low; // lowest possible immediate
+ int32_t i_high; // highest possible immediate
+ AddressingMode i_mode; // Operand2_R_<shift>_I
+ AddressingMode r_mode; // Operand2_R_<shift>_R
+};
+
+
+// ARM shifts.
+class Shifts V8_FINAL : public std::list<Shift>, private HandleAndZoneScope {
+ public:
+ Shifts() {
+ MachineOperatorBuilder machine(main_zone());
+ Shift sar = {machine.Word32Sar(), 1, 32, kMode_Operand2_R_ASR_I,
+ kMode_Operand2_R_ASR_R};
+ Shift shl = {machine.Word32Shl(), 0, 31, kMode_Operand2_R_LSL_I,
+ kMode_Operand2_R_LSL_R};
+ Shift shr = {machine.Word32Shr(), 1, 32, kMode_Operand2_R_LSR_I,
+ kMode_Operand2_R_LSR_R};
+ push_back(sar);
+ push_back(shl);
+ push_back(shr);
+ }
+};
+
+} // namespace
+
+
+TEST(InstructionSelectorDPIP) {
+ DPIs dpis;
+ for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
+ DPI dpi = *i;
+ InstructionSelectorTester m;
+ m.Return(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ }
+}
+
+
+TEST(InstructionSelectorDPIImm) {
+ DPIs dpis;
+ Immediates immediates;
+ for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
+ DPI dpi = *i;
+ for (Immediates::const_iterator j = immediates.begin();
+ j != immediates.end(); ++j) {
+ int32_t imm = *j;
+ {
+ InstructionSelectorTester m;
+ m.Return(m.NewNode(dpi.op, m.Parameter(0), m.Int32Constant(imm)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.NewNode(dpi.op, m.Int32Constant(imm), m.Parameter(0)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ }
+ }
+ }
+}
+
+
+TEST(InstructionSelectorDPIAndShiftP) {
+ DPIs dpis;
+ Shifts shifts;
+ for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
+ DPI dpi = *i;
+ for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) {
+ Shift shift = *j;
+ {
+ InstructionSelectorTester m;
+ m.Return(
+ m.NewNode(dpi.op, m.Parameter(0),
+ m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.NewNode(dpi.op,
+ m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ }
+ }
+ }
+}
+
+
+TEST(InstructionSelectorDPIAndRotateRightP) {
+ DPIs dpis;
+ for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
+ DPI dpi = *i;
+ {
+ InstructionSelectorTester m;
+ Node* value = m.Parameter(1);
+ Node* shift = m.Parameter(2);
+ Node* ror = m.Word32Or(
+ m.Word32Shr(value, shift),
+ m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)));
+ m.Return(m.NewNode(dpi.op, m.Parameter(0), ror));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ Node* value = m.Parameter(1);
+ Node* shift = m.Parameter(2);
+ Node* ror =
+ m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)),
+ m.Word32Shr(value, shift));
+ m.Return(m.NewNode(dpi.op, m.Parameter(0), ror));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ Node* value = m.Parameter(1);
+ Node* shift = m.Parameter(2);
+ Node* ror = m.Word32Or(
+ m.Word32Shr(value, shift),
+ m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)));
+ m.Return(m.NewNode(dpi.op, ror, m.Parameter(0)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ Node* value = m.Parameter(1);
+ Node* shift = m.Parameter(2);
+ Node* ror =
+ m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)),
+ m.Word32Shr(value, shift));
+ m.Return(m.NewNode(dpi.op, ror, m.Parameter(0)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
+ }
+ }
+}
+
+
+TEST(InstructionSelectorDPIAndShiftImm) {
+ DPIs dpis;
+ Shifts shifts;
+ for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
+ DPI dpi = *i;
+ for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) {
+ Shift shift = *j;
+ for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) {
+ {
+ InstructionSelectorTester m;
+ m.Return(m.NewNode(
+ dpi.op, m.Parameter(0),
+ m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.NewNode(
+ dpi.op, m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)),
+ m.Parameter(1)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
+ }
+ }
+ }
+ }
+}
+
+
+TEST(InstructionSelectorODPIP) {
+ ODPIs odpis;
+ for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) {
+ ODPI odpi = *i;
+ {
+ InstructionSelectorTester m;
+ m.Return(
+ m.Projection(1, m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(
+ m.Projection(0, m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1));
+ m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
+ m.SelectInstructions();
+ CHECK_LE(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(2, m.code[0]->OutputCount());
+ }
+ }
+}
+
+
+TEST(InstructionSelectorODPIImm) {
+ ODPIs odpis;
+ Immediates immediates;
+ for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) {
+ ODPI odpi = *i;
+ for (Immediates::const_iterator j = immediates.begin();
+ j != immediates.end(); ++j) {
+ int32_t imm = *j;
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Projection(
+ 1, m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Projection(
+ 1, m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Projection(
+ 0, m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Projection(
+ 0, m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm));
+ m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
+ m.SelectInstructions();
+ CHECK_LE(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ CHECK_EQ(2, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ Node* node = m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0));
+ m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
+ m.SelectInstructions();
+ CHECK_LE(1, m.code.size());
+ CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ CHECK_EQ(2, m.code[0]->OutputCount());
+ }
+ }
+ }
+}
+
+
+TEST(InstructionSelectorODPIAndShiftP) {
+ ODPIs odpis;
+ Shifts shifts;
+ for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) {
+ ODPI odpi = *i;
+ for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) {
+ Shift shift = *j;
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Projection(
+ 1, m.NewNode(odpi.op, m.Parameter(0),
+ m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Projection(
+ 1, m.NewNode(odpi.op,
+ m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Projection(
+ 0, m.NewNode(odpi.op, m.Parameter(0),
+ m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Projection(
+ 0, m.NewNode(odpi.op,
+ m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ Node* node =
+ m.NewNode(odpi.op, m.Parameter(0),
+ m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)));
+ m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
+ m.SelectInstructions();
+ CHECK_LE(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(2, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ Node* node = m.NewNode(
+ odpi.op, m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2));
+ m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
+ m.SelectInstructions();
+ CHECK_LE(1, m.code.size());
+ CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(2, m.code[0]->OutputCount());
+ }
+ }
+ }
+}
+
+
+TEST(InstructionSelectorODPIAndShiftImm) {
+ ODPIs odpis;
+ Shifts shifts;
+ for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) {
+ ODPI odpi = *i;
+ for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) {
+ Shift shift = *j;
+ for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) {
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Projection(1, m.NewNode(odpi.op, m.Parameter(0),
+ m.NewNode(shift.op, m.Parameter(1),
+ m.Int32Constant(imm)))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2)));
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Projection(
+ 1, m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0),
+ m.Int32Constant(imm)),
+ m.Parameter(1))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2)));
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Projection(0, m.NewNode(odpi.op, m.Parameter(0),
+ m.NewNode(shift.op, m.Parameter(1),
+ m.Int32Constant(imm)))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2)));
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Projection(
+ 0, m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0),
+ m.Int32Constant(imm)),
+ m.Parameter(1))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2)));
+ CHECK_LE(1, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ Node* node = m.NewNode(
+ odpi.op, m.Parameter(0),
+ m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)));
+ m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
+ m.SelectInstructions();
+ CHECK_LE(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2)));
+ CHECK_EQ(2, m.code[0]->OutputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ Node* node = m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0),
+ m.Int32Constant(imm)),
+ m.Parameter(1));
+ m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node)));
+ m.SelectInstructions();
+ CHECK_LE(1, m.code.size());
+ CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2)));
+ CHECK_EQ(2, m.code[0]->OutputCount());
+ }
+ }
+ }
+ }
+}
+
+
+TEST(InstructionSelectorWord32AndAndWord32XorWithMinus1P) {
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32And(m.Parameter(0),
+ m.Word32Xor(m.Int32Constant(-1), m.Parameter(1))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32And(m.Parameter(0),
+ m.Word32Xor(m.Parameter(1), m.Int32Constant(-1))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32And(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0)),
+ m.Parameter(1)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32And(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)),
+ m.Parameter(1)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ }
+}
+
+
+TEST(InstructionSelectorWord32AndAndWord32XorWithMinus1AndShiftP) {
+ Shifts shifts;
+ for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
+ Shift shift = *i;
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32And(
+ m.Parameter(0),
+ m.Word32Xor(m.Int32Constant(-1),
+ m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32And(
+ m.Parameter(0),
+ m.Word32Xor(m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)),
+ m.Int32Constant(-1))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32And(
+ m.Word32Xor(m.Int32Constant(-1),
+ m.NewNode(shift.op, m.Parameter(0), m.Parameter(1))),
+ m.Parameter(2)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32And(
+ m.Word32Xor(m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)),
+ m.Int32Constant(-1)),
+ m.Parameter(2)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ }
+ }
+}
+
+
+TEST(InstructionSelectorWord32XorWithMinus1P) {
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmMvn, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmMvn, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ }
+}
+
+
+TEST(InstructionSelectorWord32XorWithMinus1AndShiftP) {
+ Shifts shifts;
+ for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
+ Shift shift = *i;
+ {
+ InstructionSelectorTester m;
+ m.Return(
+ m.Word32Xor(m.Int32Constant(-1),
+ m.NewNode(shift.op, m.Parameter(0), m.Parameter(1))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmMvn, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Xor(m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)),
+ m.Int32Constant(-1)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmMvn, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ }
+ }
+}
+
+
+TEST(InstructionSelectorShiftP) {
+ Shifts shifts;
+ for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
+ Shift shift = *i;
+ InstructionSelectorTester m;
+ m.Return(m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ }
+}
+
+
+TEST(InstructionSelectorShiftImm) {
+ Shifts shifts;
+ for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
+ Shift shift = *i;
+ for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) {
+ InstructionSelectorTester m;
+ m.Return(m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ }
+ }
+}
+
+
+TEST(InstructionSelectorRotateRightP) {
+ {
+ InstructionSelectorTester m;
+ Node* value = m.Parameter(0);
+ Node* shift = m.Parameter(1);
+ m.Return(
+ m.Word32Or(m.Word32Shr(value, shift),
+ m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ }
+ {
+ InstructionSelectorTester m;
+ Node* value = m.Parameter(0);
+ Node* shift = m.Parameter(1);
+ m.Return(
+ m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)),
+ m.Word32Shr(value, shift)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ }
+}
+
+
+TEST(InstructionSelectorRotateRightImm) {
+ FOR_INPUTS(uint32_t, ror, i) {
+ uint32_t shift = *i;
+ {
+ InstructionSelectorTester m;
+ Node* value = m.Parameter(0);
+ m.Return(m.Word32Or(m.Word32Shr(value, m.Int32Constant(shift)),
+ m.Word32Shl(value, m.Int32Constant(32 - shift))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(1)));
+ }
+ {
+ InstructionSelectorTester m;
+ Node* value = m.Parameter(0);
+ m.Return(m.Word32Or(m.Word32Shl(value, m.Int32Constant(32 - shift)),
+ m.Word32Shr(value, m.Int32Constant(shift))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(1)));
+ }
+ }
+}
+
+
+TEST(InstructionSelectorInt32MulP) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Mul(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmMul, m.code[0]->arch_opcode());
+}
+
+
+TEST(InstructionSelectorInt32MulImm) {
+ // x * (2^k + 1) -> (x >> k) + x
+ for (int k = 1; k < 31; ++k) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode());
+ }
+ // (2^k + 1) * x -> (x >> k) + x
+ for (int k = 1; k < 31; ++k) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode());
+ }
+ // x * (2^k - 1) -> (x >> k) - x
+ for (int k = 3; k < 31; ++k) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) - 1)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmRsb, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode());
+ }
+ // (2^k - 1) * x -> (x >> k) - x
+ for (int k = 3; k < 31; ++k) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Mul(m.Int32Constant((1 << k) - 1), m.Parameter(0)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmRsb, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode());
+ }
+}
+
+
+TEST(InstructionSelectorWord32AndImm_ARMv7) {
+ for (uint32_t width = 1; width <= 32; ++width) {
+ InstructionSelectorTester m;
+ m.Return(m.Word32And(m.Parameter(0),
+ m.Int32Constant(0xffffffffu >> (32 - width))));
+ m.SelectInstructions(ARMv7);
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(0, m.ToInt32(m.code[0]->InputAt(1)));
+ CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
+ }
+ for (uint32_t lsb = 0; lsb <= 31; ++lsb) {
+ for (uint32_t width = 1; width < 32 - lsb; ++width) {
+ uint32_t msk = ~((0xffffffffu >> (32 - width)) << lsb);
+ InstructionSelectorTester m;
+ m.Return(m.Word32And(m.Parameter(0), m.Int32Constant(msk)));
+ m.SelectInstructions(ARMv7);
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmBfc, m.code[0]->arch_opcode());
+ CHECK_EQ(1, m.code[0]->OutputCount());
+ CHECK(UnallocatedOperand::cast(m.code[0]->Output())
+ ->HasSameAsInputPolicy());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
+ CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
+ }
+ }
+}
+
+
+TEST(InstructionSelectorWord32AndAndWord32ShrImm_ARMv7) {
+ for (uint32_t lsb = 0; lsb <= 31; ++lsb) {
+ for (uint32_t width = 1; width <= 32 - lsb; ++width) {
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)),
+ m.Int32Constant(0xffffffffu >> (32 - width))));
+ m.SelectInstructions(ARMv7);
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
+ CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(
+ m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
+ m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb))));
+ m.SelectInstructions(ARMv7);
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
+ CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
+ }
+ }
+ }
+}
+
+
+TEST(InstructionSelectorWord32ShrAndWord32AndImm_ARMv7) {
+ for (uint32_t lsb = 0; lsb <= 31; ++lsb) {
+ for (uint32_t width = 1; width <= 32 - lsb; ++width) {
+ uint32_t max = 1 << lsb;
+ if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
+ uint32_t jnk = CcTest::random_number_generator()->NextInt(max);
+ uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)),
+ m.Int32Constant(lsb)));
+ m.SelectInstructions(ARMv7);
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
+ CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)),
+ m.Int32Constant(lsb)));
+ m.SelectInstructions(ARMv7);
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
+ CHECK_EQ(3, m.code[0]->InputCount());
+ CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
+ CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
+ }
+ }
+ }
+}
+
+
+TEST(InstructionSelectorInt32SubAndInt32MulP) {
+ InstructionSelectorTester m;
+ m.Return(
+ m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
+ m.SelectInstructions();
+ CHECK_EQ(2, m.code.size());
+ CHECK_EQ(kArmMul, m.code[0]->arch_opcode());
+ CHECK_EQ(1, m.code[0]->OutputCount());
+ CHECK_EQ(kArmSub, m.code[1]->arch_opcode());
+ CHECK_EQ(2, m.code[1]->InputCount());
+ CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(1));
+}
+
+
+TEST(InstructionSelectorInt32SubAndInt32MulP_MLS) {
+ InstructionSelectorTester m;
+ m.Return(
+ m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
+ m.SelectInstructions(MLS);
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmMls, m.code[0]->arch_opcode());
+}
+
+
+TEST(InstructionSelectorInt32DivP) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions();
+ CHECK_EQ(4, m.code.size());
+ CHECK_EQ(kArmVcvtF64S32, m.code[0]->arch_opcode());
+ CHECK_EQ(1, m.code[0]->OutputCount());
+ CHECK_EQ(kArmVcvtF64S32, m.code[1]->arch_opcode());
+ CHECK_EQ(1, m.code[1]->OutputCount());
+ CHECK_EQ(kArmVdivF64, m.code[2]->arch_opcode());
+ CHECK_EQ(2, m.code[2]->InputCount());
+ CHECK_EQ(1, m.code[2]->OutputCount());
+ CheckSameVreg(m.code[0]->Output(), m.code[2]->InputAt(0));
+ CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1));
+ CHECK_EQ(kArmVcvtS32F64, m.code[3]->arch_opcode());
+ CHECK_EQ(1, m.code[3]->InputCount());
+ CheckSameVreg(m.code[2]->Output(), m.code[3]->InputAt(0));
+}
+
+
+TEST(InstructionSelectorInt32DivP_SUDIV) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions(SUDIV);
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmSdiv, m.code[0]->arch_opcode());
+}
+
+
+TEST(InstructionSelectorInt32UDivP) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32UDiv(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions();
+ CHECK_EQ(4, m.code.size());
+ CHECK_EQ(kArmVcvtF64U32, m.code[0]->arch_opcode());
+ CHECK_EQ(1, m.code[0]->OutputCount());
+ CHECK_EQ(kArmVcvtF64U32, m.code[1]->arch_opcode());
+ CHECK_EQ(1, m.code[1]->OutputCount());
+ CHECK_EQ(kArmVdivF64, m.code[2]->arch_opcode());
+ CHECK_EQ(2, m.code[2]->InputCount());
+ CHECK_EQ(1, m.code[2]->OutputCount());
+ CheckSameVreg(m.code[0]->Output(), m.code[2]->InputAt(0));
+ CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1));
+ CHECK_EQ(kArmVcvtU32F64, m.code[3]->arch_opcode());
+ CHECK_EQ(1, m.code[3]->InputCount());
+ CheckSameVreg(m.code[2]->Output(), m.code[3]->InputAt(0));
+}
+
+
+TEST(InstructionSelectorInt32UDivP_SUDIV) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32UDiv(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions(SUDIV);
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmUdiv, m.code[0]->arch_opcode());
+}
+
+
+TEST(InstructionSelectorInt32ModP) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions();
+ CHECK_EQ(6, m.code.size());
+ CHECK_EQ(kArmVcvtF64S32, m.code[0]->arch_opcode());
+ CHECK_EQ(1, m.code[0]->OutputCount());
+ CHECK_EQ(kArmVcvtF64S32, m.code[1]->arch_opcode());
+ CHECK_EQ(1, m.code[1]->OutputCount());
+ CHECK_EQ(kArmVdivF64, m.code[2]->arch_opcode());
+ CHECK_EQ(2, m.code[2]->InputCount());
+ CHECK_EQ(1, m.code[2]->OutputCount());
+ CheckSameVreg(m.code[0]->Output(), m.code[2]->InputAt(0));
+ CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1));
+ CHECK_EQ(kArmVcvtS32F64, m.code[3]->arch_opcode());
+ CHECK_EQ(1, m.code[3]->InputCount());
+ CheckSameVreg(m.code[2]->Output(), m.code[3]->InputAt(0));
+ CHECK_EQ(kArmMul, m.code[4]->arch_opcode());
+ CHECK_EQ(1, m.code[4]->OutputCount());
+ CHECK_EQ(2, m.code[4]->InputCount());
+ CheckSameVreg(m.code[3]->Output(), m.code[4]->InputAt(0));
+ CheckSameVreg(m.code[1]->InputAt(0), m.code[4]->InputAt(1));
+ CHECK_EQ(kArmSub, m.code[5]->arch_opcode());
+ CHECK_EQ(1, m.code[5]->OutputCount());
+ CHECK_EQ(2, m.code[5]->InputCount());
+ CheckSameVreg(m.code[0]->InputAt(0), m.code[5]->InputAt(0));
+ CheckSameVreg(m.code[4]->Output(), m.code[5]->InputAt(1));
+}
+
+
+TEST(InstructionSelectorInt32ModP_SUDIV) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions(SUDIV);
+ CHECK_EQ(3, m.code.size());
+ CHECK_EQ(kArmSdiv, m.code[0]->arch_opcode());
+ CHECK_EQ(1, m.code[0]->OutputCount());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(kArmMul, m.code[1]->arch_opcode());
+ CHECK_EQ(1, m.code[1]->OutputCount());
+ CHECK_EQ(2, m.code[1]->InputCount());
+ CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(0));
+ CheckSameVreg(m.code[0]->InputAt(1), m.code[1]->InputAt(1));
+ CHECK_EQ(kArmSub, m.code[2]->arch_opcode());
+ CHECK_EQ(1, m.code[2]->OutputCount());
+ CHECK_EQ(2, m.code[2]->InputCount());
+ CheckSameVreg(m.code[0]->InputAt(0), m.code[2]->InputAt(0));
+ CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1));
+}
+
+
+TEST(InstructionSelectorInt32ModP_MLS_SUDIV) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions(MLS, SUDIV);
+ CHECK_EQ(2, m.code.size());
+ CHECK_EQ(kArmSdiv, m.code[0]->arch_opcode());
+ CHECK_EQ(1, m.code[0]->OutputCount());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(kArmMls, m.code[1]->arch_opcode());
+ CHECK_EQ(1, m.code[1]->OutputCount());
+ CHECK_EQ(3, m.code[1]->InputCount());
+ CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(0));
+ CheckSameVreg(m.code[0]->InputAt(1), m.code[1]->InputAt(1));
+ CheckSameVreg(m.code[0]->InputAt(0), m.code[1]->InputAt(2));
+}
+
+
+TEST(InstructionSelectorInt32UModP) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions();
+ CHECK_EQ(6, m.code.size());
+ CHECK_EQ(kArmVcvtF64U32, m.code[0]->arch_opcode());
+ CHECK_EQ(1, m.code[0]->OutputCount());
+ CHECK_EQ(kArmVcvtF64U32, m.code[1]->arch_opcode());
+ CHECK_EQ(1, m.code[1]->OutputCount());
+ CHECK_EQ(kArmVdivF64, m.code[2]->arch_opcode());
+ CHECK_EQ(2, m.code[2]->InputCount());
+ CHECK_EQ(1, m.code[2]->OutputCount());
+ CheckSameVreg(m.code[0]->Output(), m.code[2]->InputAt(0));
+ CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1));
+ CHECK_EQ(kArmVcvtU32F64, m.code[3]->arch_opcode());
+ CHECK_EQ(1, m.code[3]->InputCount());
+ CheckSameVreg(m.code[2]->Output(), m.code[3]->InputAt(0));
+ CHECK_EQ(kArmMul, m.code[4]->arch_opcode());
+ CHECK_EQ(1, m.code[4]->OutputCount());
+ CHECK_EQ(2, m.code[4]->InputCount());
+ CheckSameVreg(m.code[3]->Output(), m.code[4]->InputAt(0));
+ CheckSameVreg(m.code[1]->InputAt(0), m.code[4]->InputAt(1));
+ CHECK_EQ(kArmSub, m.code[5]->arch_opcode());
+ CHECK_EQ(1, m.code[5]->OutputCount());
+ CHECK_EQ(2, m.code[5]->InputCount());
+ CheckSameVreg(m.code[0]->InputAt(0), m.code[5]->InputAt(0));
+ CheckSameVreg(m.code[4]->Output(), m.code[5]->InputAt(1));
+}
+
+
+TEST(InstructionSelectorInt32UModP_SUDIV) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions(SUDIV);
+ CHECK_EQ(3, m.code.size());
+ CHECK_EQ(kArmUdiv, m.code[0]->arch_opcode());
+ CHECK_EQ(1, m.code[0]->OutputCount());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(kArmMul, m.code[1]->arch_opcode());
+ CHECK_EQ(1, m.code[1]->OutputCount());
+ CHECK_EQ(2, m.code[1]->InputCount());
+ CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(0));
+ CheckSameVreg(m.code[0]->InputAt(1), m.code[1]->InputAt(1));
+ CHECK_EQ(kArmSub, m.code[2]->arch_opcode());
+ CHECK_EQ(1, m.code[2]->OutputCount());
+ CHECK_EQ(2, m.code[2]->InputCount());
+ CheckSameVreg(m.code[0]->InputAt(0), m.code[2]->InputAt(0));
+ CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1));
+}
+
+
+TEST(InstructionSelectorInt32UModP_MLS_SUDIV) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions(MLS, SUDIV);
+ CHECK_EQ(2, m.code.size());
+ CHECK_EQ(kArmUdiv, m.code[0]->arch_opcode());
+ CHECK_EQ(1, m.code[0]->OutputCount());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(kArmMls, m.code[1]->arch_opcode());
+ CHECK_EQ(1, m.code[1]->OutputCount());
+ CHECK_EQ(3, m.code[1]->InputCount());
+ CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(0));
+ CheckSameVreg(m.code[0]->InputAt(1), m.code[1]->InputAt(1));
+ CheckSameVreg(m.code[0]->InputAt(0), m.code[1]->InputAt(2));
+}
+
+
+TEST(InstructionSelectorWord32EqualP) {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Equal(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+}
+
+
+TEST(InstructionSelectorWord32EqualImm) {
+ Immediates immediates;
+ for (Immediates::const_iterator i = immediates.begin(); i != immediates.end();
+ ++i) {
+ int32_t imm = *i;
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(imm)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ if (imm == 0) {
+ CHECK_EQ(kArmTst, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CheckSameVreg(m.code[0]->InputAt(0), m.code[0]->InputAt(1));
+ } else {
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ }
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Equal(m.Int32Constant(imm), m.Parameter(0)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ if (imm == 0) {
+ CHECK_EQ(kArmTst, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CheckSameVreg(m.code[0]->InputAt(0), m.code[0]->InputAt(1));
+ } else {
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ }
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ }
+}
+
+
+TEST(InstructionSelectorWord32EqualAndDPIP) {
+ DPIs dpis;
+ for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
+ DPI dpi = *i;
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Equal(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)),
+ m.Int32Constant(0)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(
+ m.Word32Equal(m.Int32Constant(0),
+ m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ }
+}
+
+
+TEST(InstructionSelectorWord32EqualAndDPIImm) {
+ DPIs dpis;
+ Immediates immediates;
+ for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
+ DPI dpi = *i;
+ for (Immediates::const_iterator j = immediates.begin();
+ j != immediates.end(); ++j) {
+ int32_t imm = *j;
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Equal(
+ m.NewNode(dpi.op, m.Parameter(0), m.Int32Constant(imm)),
+ m.Int32Constant(0)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Equal(
+ m.NewNode(dpi.op, m.Int32Constant(imm), m.Parameter(0)),
+ m.Int32Constant(0)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Equal(
+ m.Int32Constant(0),
+ m.NewNode(dpi.op, m.Parameter(0), m.Int32Constant(imm))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Equal(
+ m.Int32Constant(0),
+ m.NewNode(dpi.op, m.Int32Constant(imm), m.Parameter(0))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ }
+ }
+}
+
+
+TEST(InstructionSelectorWord32EqualAndShiftP) {
+ Shifts shifts;
+ for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
+ Shift shift = *i;
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Equal(
+ m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Word32Equal(
+ m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), m.Parameter(2)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ }
+}
+
+
+TEST(InstructionSelectorBranchWithWord32EqualAndShiftP) {
+ Shifts shifts;
+ for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
+ Shift shift = *i;
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(m.Parameter(0), m.NewNode(shift.op, m.Parameter(1),
+ m.Parameter(2))),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32Equal(m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)),
+ m.Parameter(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ }
+}
+
+
+TEST(InstructionSelectorBranchWithWord32EqualAndShiftImm) {
+ Shifts shifts;
+ for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
+ Shift shift = *i;
+ for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) {
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32Equal(m.Parameter(0), m.NewNode(shift.op, m.Parameter(1),
+ m.Int32Constant(imm))),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(
+ m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)),
+ m.Parameter(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ }
+ }
+}
+
+
+TEST(InstructionSelectorBranchWithWord32EqualAndRotateRightP) {
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* input = m.Parameter(0);
+ Node* value = m.Parameter(1);
+ Node* shift = m.Parameter(2);
+ Node* ror =
+ m.Word32Or(m.Word32Shr(value, shift),
+ m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)));
+ m.Branch(m.Word32Equal(input, ror), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* input = m.Parameter(0);
+ Node* value = m.Parameter(1);
+ Node* shift = m.Parameter(2);
+ Node* ror =
+ m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)),
+ m.Word32Shr(value, shift));
+ m.Branch(m.Word32Equal(input, ror), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* input = m.Parameter(0);
+ Node* value = m.Parameter(1);
+ Node* shift = m.Parameter(2);
+ Node* ror =
+ m.Word32Or(m.Word32Shr(value, shift),
+ m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)));
+ m.Branch(m.Word32Equal(ror, input), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* input = m.Parameter(0);
+ Node* value = m.Parameter(1);
+ Node* shift = m.Parameter(2);
+ Node* ror =
+ m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)),
+ m.Word32Shr(value, shift));
+ m.Branch(m.Word32Equal(ror, input), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+}
+
+
+TEST(InstructionSelectorBranchWithWord32EqualAndRotateRightImm) {
+ FOR_INPUTS(uint32_t, ror, i) {
+ uint32_t shift = *i;
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* input = m.Parameter(0);
+ Node* value = m.Parameter(1);
+ Node* ror = m.Word32Or(m.Word32Shr(value, m.Int32Constant(shift)),
+ m.Word32Shl(value, m.Int32Constant(32 - shift)));
+ m.Branch(m.Word32Equal(input, ror), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ CHECK_LE(3, m.code[0]->InputCount());
+ CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(2)));
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* input = m.Parameter(0);
+ Node* value = m.Parameter(1);
+ Node* ror = m.Word32Or(m.Word32Shl(value, m.Int32Constant(32 - shift)),
+ m.Word32Shr(value, m.Int32Constant(shift)));
+ m.Branch(m.Word32Equal(input, ror), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ CHECK_LE(3, m.code[0]->InputCount());
+ CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(2)));
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* input = m.Parameter(0);
+ Node* value = m.Parameter(1);
+ Node* ror = m.Word32Or(m.Word32Shr(value, m.Int32Constant(shift)),
+ m.Word32Shl(value, m.Int32Constant(32 - shift)));
+ m.Branch(m.Word32Equal(ror, input), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ CHECK_LE(3, m.code[0]->InputCount());
+ CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(2)));
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* input = m.Parameter(0);
+ Node* value = m.Parameter(1);
+ Node* ror = m.Word32Or(m.Word32Shl(value, m.Int32Constant(32 - shift)),
+ m.Word32Shr(value, m.Int32Constant(shift)));
+ m.Branch(m.Word32Equal(ror, input), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ CHECK_LE(3, m.code[0]->InputCount());
+ CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(2)));
+ }
+ }
+}
+
+
+TEST(InstructionSelectorBranchWithDPIP) {
+ DPIs dpis;
+ for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
+ DPI dpi = *i;
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ m.Branch(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)), &blocka,
+ &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kNotEqual, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(m.Int32Constant(0),
+ m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1))),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kEqual, m.code[0]->flags_condition());
+ }
+ }
+}
+
+
+TEST(InstructionSelectorBranchWithODPIP) {
+ ODPIs odpis;
+ for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) {
+ ODPI odpi = *i;
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1));
+ m.Branch(m.Projection(1, node), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(0));
+ m.Bind(&blockb);
+ m.Return(m.Projection(0, node));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1));
+ m.Branch(m.Word32Equal(m.Projection(1, node), m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(0));
+ m.Bind(&blockb);
+ m.Return(m.Projection(0, node));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kNotOverflow, m.code[0]->flags_condition());
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1));
+ m.Branch(m.Word32Equal(m.Int32Constant(0), m.Projection(1, node)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(0));
+ m.Bind(&blockb);
+ m.Return(m.Projection(0, node));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kNotOverflow, m.code[0]->flags_condition());
+ }
+ }
+}
+
+
+TEST(InstructionSelectorBranchWithODPIImm) {
+ ODPIs odpis;
+ Immediates immediates;
+ for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) {
+ ODPI odpi = *i;
+ for (Immediates::const_iterator j = immediates.begin();
+ j != immediates.end(); ++j) {
+ int32_t imm = *j;
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm));
+ m.Branch(m.Projection(1, node), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(0));
+ m.Bind(&blockb);
+ m.Return(m.Projection(0, node));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_LE(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* node = m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0));
+ m.Branch(m.Projection(1, node), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(0));
+ m.Bind(&blockb);
+ m.Return(m.Projection(0, node));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition());
+ CHECK_LE(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm));
+ m.Branch(m.Word32Equal(m.Projection(1, node), m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(0));
+ m.Bind(&blockb);
+ m.Return(m.Projection(0, node));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kNotOverflow, m.code[0]->flags_condition());
+ CHECK_LE(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ }
+ {
+ InstructionSelectorTester m;
+ MLabel blocka, blockb;
+ Node* node = m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0));
+ m.Branch(m.Word32Equal(m.Projection(1, node), m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(0));
+ m.Bind(&blockb);
+ m.Return(m.Projection(0, node));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode());
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
+ CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
+ CHECK_EQ(kNotOverflow, m.code[0]->flags_condition());
+ CHECK_LE(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ }
+ }
+ }
+}
diff --git a/deps/v8/test/cctest/compiler/test-instruction-selector-ia32.cc b/deps/v8/test/cctest/compiler/test-instruction-selector-ia32.cc
new file mode 100644
index 000000000..b6509584e
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-instruction-selector-ia32.cc
@@ -0,0 +1,66 @@
+// 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 "test/cctest/compiler/instruction-selector-tester.h"
+#include "test/cctest/compiler/value-helper.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+TEST(InstructionSelectorInt32AddP) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Add(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kIA32Add, m.code[0]->arch_opcode());
+}
+
+
+TEST(InstructionSelectorInt32AddImm) {
+ FOR_INT32_INPUTS(i) {
+ int32_t imm = *i;
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Add(m.Parameter(0), m.Int32Constant(imm)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kIA32Add, m.code[0]->arch_opcode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ }
+ {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kIA32Add, m.code[0]->arch_opcode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ }
+ }
+}
+
+
+TEST(InstructionSelectorInt32SubP) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Sub(m.Parameter(0), m.Parameter(1)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kIA32Sub, m.code[0]->arch_opcode());
+ CHECK_EQ(1, m.code[0]->OutputCount());
+}
+
+
+TEST(InstructionSelectorInt32SubImm) {
+ FOR_INT32_INPUTS(i) {
+ int32_t imm = *i;
+ InstructionSelectorTester m;
+ m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm)));
+ m.SelectInstructions();
+ CHECK_EQ(1, m.code.size());
+ CHECK_EQ(kIA32Sub, m.code[0]->arch_opcode());
+ CHECK_EQ(2, m.code[0]->InputCount());
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
+ }
+}
diff --git a/deps/v8/test/cctest/compiler/test-instruction-selector.cc b/deps/v8/test/cctest/compiler/test-instruction-selector.cc
new file mode 100644
index 000000000..e59406426
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-instruction-selector.cc
@@ -0,0 +1,22 @@
+// 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 "test/cctest/compiler/instruction-selector-tester.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+#if V8_TURBOFAN_TARGET
+
+TEST(InstructionSelectionReturnZero) {
+ InstructionSelectorTester m;
+ m.Return(m.Int32Constant(0));
+ m.SelectInstructions(InstructionSelectorTester::kInternalMode);
+ CHECK_EQ(2, static_cast<int>(m.code.size()));
+ CHECK_EQ(kArchNop, m.code[0]->opcode());
+ CHECK_EQ(kArchRet, m.code[1]->opcode());
+ CHECK_EQ(1, static_cast<int>(m.code[1]->InputCount()));
+}
+
+#endif // !V8_TURBOFAN_TARGET
diff --git a/deps/v8/test/cctest/compiler/test-instruction.cc b/deps/v8/test/cctest/compiler/test-instruction.cc
new file mode 100644
index 000000000..bc9f4c772
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-instruction.cc
@@ -0,0 +1,350 @@
+// 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 "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/compiler/code-generator.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/instruction.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/node.h"
+#include "src/compiler/operator.h"
+#include "src/compiler/schedule.h"
+#include "src/compiler/scheduler.h"
+#include "src/lithium.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+typedef v8::internal::compiler::Instruction TestInstr;
+typedef v8::internal::compiler::InstructionSequence TestInstrSeq;
+
+// A testing helper for the register code abstraction.
+class InstructionTester : public HandleAndZoneScope {
+ public: // We're all friends here.
+ InstructionTester()
+ : isolate(main_isolate()),
+ graph(zone()),
+ schedule(zone()),
+ info(static_cast<HydrogenCodeStub*>(NULL), main_isolate()),
+ linkage(&info),
+ common(zone()),
+ machine(zone(), kMachineWord32),
+ code(NULL) {}
+
+ ~InstructionTester() { delete code; }
+
+ Isolate* isolate;
+ Graph graph;
+ Schedule schedule;
+ CompilationInfoWithZone info;
+ Linkage linkage;
+ CommonOperatorBuilder common;
+ MachineOperatorBuilder machine;
+ TestInstrSeq* code;
+
+ Zone* zone() { return main_zone(); }
+
+ void allocCode() {
+ if (schedule.rpo_order()->size() == 0) {
+ // Compute the RPO order.
+ Scheduler::ComputeSpecialRPO(&schedule);
+ DCHECK(schedule.rpo_order()->size() > 0);
+ }
+ code = new TestInstrSeq(&linkage, &graph, &schedule);
+ }
+
+ Node* Int32Constant(int32_t val) {
+ Node* node = graph.NewNode(common.Int32Constant(val));
+ schedule.AddNode(schedule.entry(), node);
+ return node;
+ }
+
+ Node* Float64Constant(double val) {
+ Node* node = graph.NewNode(common.Float64Constant(val));
+ schedule.AddNode(schedule.entry(), node);
+ return node;
+ }
+
+ Node* Parameter(int32_t which) {
+ Node* node = graph.NewNode(common.Parameter(which));
+ schedule.AddNode(schedule.entry(), node);
+ return node;
+ }
+
+ Node* NewNode(BasicBlock* block) {
+ Node* node = graph.NewNode(common.Int32Constant(111));
+ schedule.AddNode(block, node);
+ return node;
+ }
+
+ int NewInstr(BasicBlock* block) {
+ InstructionCode opcode = static_cast<InstructionCode>(110);
+ TestInstr* instr = TestInstr::New(zone(), opcode);
+ return code->AddInstruction(instr, block);
+ }
+
+ UnallocatedOperand* NewUnallocated(int vreg) {
+ UnallocatedOperand* unallocated =
+ new (zone()) UnallocatedOperand(UnallocatedOperand::ANY);
+ unallocated->set_virtual_register(vreg);
+ return unallocated;
+ }
+};
+
+
+TEST(InstructionBasic) {
+ InstructionTester R;
+
+ for (int i = 0; i < 10; i++) {
+ R.Int32Constant(i); // Add some nodes to the graph.
+ }
+
+ BasicBlock* last = R.schedule.entry();
+ for (int i = 0; i < 5; i++) {
+ BasicBlock* block = R.schedule.NewBasicBlock();
+ R.schedule.AddGoto(last, block);
+ last = block;
+ }
+
+ R.allocCode();
+
+ CHECK_EQ(R.graph.NodeCount(), R.code->ValueCount());
+
+ BasicBlockVector* blocks = R.schedule.rpo_order();
+ CHECK_EQ(static_cast<int>(blocks->size()), R.code->BasicBlockCount());
+
+ int index = 0;
+ for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end();
+ i++, index++) {
+ BasicBlock* block = *i;
+ CHECK_EQ(block, R.code->BlockAt(index));
+ CHECK_EQ(-1, R.code->GetLoopEnd(block));
+ }
+}
+
+
+TEST(InstructionGetBasicBlock) {
+ InstructionTester R;
+
+ BasicBlock* b0 = R.schedule.entry();
+ BasicBlock* b1 = R.schedule.NewBasicBlock();
+ BasicBlock* b2 = R.schedule.NewBasicBlock();
+ BasicBlock* b3 = R.schedule.exit();
+
+ R.schedule.AddGoto(b0, b1);
+ R.schedule.AddGoto(b1, b2);
+ R.schedule.AddGoto(b2, b3);
+
+ R.allocCode();
+
+ R.code->StartBlock(b0);
+ int i0 = R.NewInstr(b0);
+ int i1 = R.NewInstr(b0);
+ R.code->EndBlock(b0);
+ R.code->StartBlock(b1);
+ int i2 = R.NewInstr(b1);
+ int i3 = R.NewInstr(b1);
+ int i4 = R.NewInstr(b1);
+ int i5 = R.NewInstr(b1);
+ R.code->EndBlock(b1);
+ R.code->StartBlock(b2);
+ int i6 = R.NewInstr(b2);
+ int i7 = R.NewInstr(b2);
+ int i8 = R.NewInstr(b2);
+ R.code->EndBlock(b2);
+ R.code->StartBlock(b3);
+ R.code->EndBlock(b3);
+
+ CHECK_EQ(b0, R.code->GetBasicBlock(i0));
+ CHECK_EQ(b0, R.code->GetBasicBlock(i1));
+
+ CHECK_EQ(b1, R.code->GetBasicBlock(i2));
+ CHECK_EQ(b1, R.code->GetBasicBlock(i3));
+ CHECK_EQ(b1, R.code->GetBasicBlock(i4));
+ CHECK_EQ(b1, R.code->GetBasicBlock(i5));
+
+ CHECK_EQ(b2, R.code->GetBasicBlock(i6));
+ CHECK_EQ(b2, R.code->GetBasicBlock(i7));
+ CHECK_EQ(b2, R.code->GetBasicBlock(i8));
+
+ CHECK_EQ(b0, R.code->GetBasicBlock(b0->first_instruction_index()));
+ CHECK_EQ(b0, R.code->GetBasicBlock(b0->last_instruction_index()));
+
+ CHECK_EQ(b1, R.code->GetBasicBlock(b1->first_instruction_index()));
+ CHECK_EQ(b1, R.code->GetBasicBlock(b1->last_instruction_index()));
+
+ CHECK_EQ(b2, R.code->GetBasicBlock(b2->first_instruction_index()));
+ CHECK_EQ(b2, R.code->GetBasicBlock(b2->last_instruction_index()));
+
+ CHECK_EQ(b3, R.code->GetBasicBlock(b3->first_instruction_index()));
+ CHECK_EQ(b3, R.code->GetBasicBlock(b3->last_instruction_index()));
+}
+
+
+TEST(InstructionIsGapAt) {
+ InstructionTester R;
+
+ BasicBlock* b0 = R.schedule.entry();
+ R.schedule.AddReturn(b0, R.Int32Constant(1));
+
+ R.allocCode();
+ TestInstr* i0 = TestInstr::New(R.zone(), 100);
+ TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
+ R.code->StartBlock(b0);
+ R.code->AddInstruction(i0, b0);
+ R.code->AddInstruction(g, b0);
+ R.code->EndBlock(b0);
+
+ CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
+
+ CHECK_EQ(true, R.code->IsGapAt(0)); // Label
+ CHECK_EQ(true, R.code->IsGapAt(1)); // Gap
+ CHECK_EQ(false, R.code->IsGapAt(2)); // i0
+ CHECK_EQ(true, R.code->IsGapAt(3)); // Gap
+ CHECK_EQ(true, R.code->IsGapAt(4)); // Gap
+ CHECK_EQ(false, R.code->IsGapAt(5)); // g
+}
+
+
+TEST(InstructionIsGapAt2) {
+ InstructionTester R;
+
+ BasicBlock* b0 = R.schedule.entry();
+ BasicBlock* b1 = R.schedule.exit();
+ R.schedule.AddGoto(b0, b1);
+ R.schedule.AddReturn(b1, R.Int32Constant(1));
+
+ R.allocCode();
+ TestInstr* i0 = TestInstr::New(R.zone(), 100);
+ TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
+ R.code->StartBlock(b0);
+ R.code->AddInstruction(i0, b0);
+ R.code->AddInstruction(g, b0);
+ R.code->EndBlock(b0);
+
+ TestInstr* i1 = TestInstr::New(R.zone(), 102);
+ TestInstr* g1 = TestInstr::New(R.zone(), 104)->MarkAsControl();
+ R.code->StartBlock(b1);
+ R.code->AddInstruction(i1, b1);
+ R.code->AddInstruction(g1, b1);
+ R.code->EndBlock(b1);
+
+ CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
+
+ CHECK_EQ(true, R.code->IsGapAt(0)); // Label
+ CHECK_EQ(true, R.code->IsGapAt(1)); // Gap
+ CHECK_EQ(false, R.code->IsGapAt(2)); // i0
+ CHECK_EQ(true, R.code->IsGapAt(3)); // Gap
+ CHECK_EQ(true, R.code->IsGapAt(4)); // Gap
+ CHECK_EQ(false, R.code->IsGapAt(5)); // g
+
+ CHECK_EQ(true, R.code->InstructionAt(6)->IsBlockStart());
+
+ CHECK_EQ(true, R.code->IsGapAt(6)); // Label
+ CHECK_EQ(true, R.code->IsGapAt(7)); // Gap
+ CHECK_EQ(false, R.code->IsGapAt(8)); // i1
+ CHECK_EQ(true, R.code->IsGapAt(9)); // Gap
+ CHECK_EQ(true, R.code->IsGapAt(10)); // Gap
+ CHECK_EQ(false, R.code->IsGapAt(11)); // g1
+}
+
+
+TEST(InstructionAddGapMove) {
+ InstructionTester R;
+
+ BasicBlock* b0 = R.schedule.entry();
+ R.schedule.AddReturn(b0, R.Int32Constant(1));
+
+ R.allocCode();
+ TestInstr* i0 = TestInstr::New(R.zone(), 100);
+ TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
+ R.code->StartBlock(b0);
+ R.code->AddInstruction(i0, b0);
+ R.code->AddInstruction(g, b0);
+ R.code->EndBlock(b0);
+
+ CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
+
+ CHECK_EQ(true, R.code->IsGapAt(0)); // Label
+ CHECK_EQ(true, R.code->IsGapAt(1)); // Gap
+ CHECK_EQ(false, R.code->IsGapAt(2)); // i0
+ CHECK_EQ(true, R.code->IsGapAt(3)); // Gap
+ CHECK_EQ(true, R.code->IsGapAt(4)); // Gap
+ CHECK_EQ(false, R.code->IsGapAt(5)); // g
+
+ int indexes[] = {0, 1, 3, 4, -1};
+ for (int i = 0; indexes[i] >= 0; i++) {
+ int index = indexes[i];
+
+ UnallocatedOperand* op1 = R.NewUnallocated(index + 6);
+ UnallocatedOperand* op2 = R.NewUnallocated(index + 12);
+
+ R.code->AddGapMove(index, op1, op2);
+ GapInstruction* gap = R.code->GapAt(index);
+ ParallelMove* move = gap->GetParallelMove(GapInstruction::START);
+ CHECK_NE(NULL, move);
+ const ZoneList<MoveOperands>* move_operands = move->move_operands();
+ CHECK_EQ(1, move_operands->length());
+ MoveOperands* cur = &move_operands->at(0);
+ CHECK_EQ(op1, cur->source());
+ CHECK_EQ(op2, cur->destination());
+ }
+}
+
+
+TEST(InstructionOperands) {
+ Zone zone(CcTest::InitIsolateOnce());
+
+ {
+ TestInstr* i = TestInstr::New(&zone, 101);
+ CHECK_EQ(0, static_cast<int>(i->OutputCount()));
+ CHECK_EQ(0, static_cast<int>(i->InputCount()));
+ CHECK_EQ(0, static_cast<int>(i->TempCount()));
+ }
+
+ InstructionOperand* outputs[] = {
+ new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
+ new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
+ new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
+ new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)};
+
+ InstructionOperand* inputs[] = {
+ new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
+ new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
+ new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
+ new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)};
+
+ InstructionOperand* temps[] = {
+ new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
+ new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
+ new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
+ new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)};
+
+ for (size_t i = 0; i < ARRAY_SIZE(outputs); i++) {
+ for (size_t j = 0; j < ARRAY_SIZE(inputs); j++) {
+ for (size_t k = 0; k < ARRAY_SIZE(temps); k++) {
+ TestInstr* m =
+ TestInstr::New(&zone, 101, i, outputs, j, inputs, k, temps);
+ CHECK(i == m->OutputCount());
+ CHECK(j == m->InputCount());
+ CHECK(k == m->TempCount());
+
+ for (size_t z = 0; z < i; z++) {
+ CHECK_EQ(outputs[z], m->OutputAt(z));
+ }
+
+ for (size_t z = 0; z < j; z++) {
+ CHECK_EQ(inputs[z], m->InputAt(z));
+ }
+
+ for (size_t z = 0; z < k; z++) {
+ CHECK_EQ(temps[z], m->TempAt(z));
+ }
+ }
+ }
+ }
+}
diff --git a/deps/v8/test/cctest/compiler/test-js-constant-cache.cc b/deps/v8/test/cctest/compiler/test-js-constant-cache.cc
new file mode 100644
index 000000000..42a606d23
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-js-constant-cache.cc
@@ -0,0 +1,284 @@
+// 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 "src/v8.h"
+
+#include "src/compiler/js-graph.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/typer.h"
+#include "src/types.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/value-helper.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+class JSCacheTesterHelper {
+ protected:
+ explicit JSCacheTesterHelper(Zone* zone)
+ : main_graph_(zone), main_common_(zone), main_typer_(zone) {}
+ Graph main_graph_;
+ CommonOperatorBuilder main_common_;
+ Typer main_typer_;
+};
+
+
+class JSConstantCacheTester : public HandleAndZoneScope,
+ public JSCacheTesterHelper,
+ public JSGraph {
+ public:
+ JSConstantCacheTester()
+ : JSCacheTesterHelper(main_zone()),
+ JSGraph(&main_graph_, &main_common_, &main_typer_) {}
+
+ Type* upper(Node* node) { return NodeProperties::GetBounds(node).upper; }
+
+ Handle<Object> handle(Node* node) {
+ CHECK_EQ(IrOpcode::kHeapConstant, node->opcode());
+ return ValueOf<Handle<Object> >(node->op());
+ }
+
+ Factory* factory() { return main_isolate()->factory(); }
+};
+
+
+TEST(ZeroConstant1) {
+ JSConstantCacheTester T;
+
+ Node* zero = T.ZeroConstant();
+
+ CHECK_EQ(IrOpcode::kNumberConstant, zero->opcode());
+ CHECK_EQ(zero, T.Constant(0));
+ CHECK_NE(zero, T.Constant(-0.0));
+ CHECK_NE(zero, T.Constant(1.0));
+ CHECK_NE(zero, T.Constant(v8::base::OS::nan_value()));
+ CHECK_NE(zero, T.Float64Constant(0));
+ CHECK_NE(zero, T.Int32Constant(0));
+
+ Type* t = T.upper(zero);
+
+ CHECK(t->Is(Type::Number()));
+ CHECK(t->Is(Type::Integral32()));
+ CHECK(t->Is(Type::Signed32()));
+ CHECK(t->Is(Type::Unsigned32()));
+ CHECK(t->Is(Type::SignedSmall()));
+ CHECK(t->Is(Type::UnsignedSmall()));
+}
+
+
+TEST(MinusZeroConstant) {
+ JSConstantCacheTester T;
+
+ Node* minus_zero = T.Constant(-0.0);
+ Node* zero = T.ZeroConstant();
+
+ CHECK_EQ(IrOpcode::kNumberConstant, minus_zero->opcode());
+ CHECK_EQ(minus_zero, T.Constant(-0.0));
+ CHECK_NE(zero, minus_zero);
+
+ Type* t = T.upper(minus_zero);
+
+ CHECK(t->Is(Type::Number()));
+ CHECK(t->Is(Type::MinusZero()));
+ CHECK(!t->Is(Type::Integral32()));
+ CHECK(!t->Is(Type::Signed32()));
+ CHECK(!t->Is(Type::Unsigned32()));
+ CHECK(!t->Is(Type::SignedSmall()));
+ CHECK(!t->Is(Type::UnsignedSmall()));
+
+ double zero_value = ValueOf<double>(zero->op());
+ double minus_zero_value = ValueOf<double>(minus_zero->op());
+
+ CHECK_EQ(0.0, zero_value);
+ CHECK_NE(-0.0, zero_value);
+ CHECK_EQ(-0.0, minus_zero_value);
+ CHECK_NE(0.0, minus_zero_value);
+}
+
+
+TEST(ZeroConstant2) {
+ JSConstantCacheTester T;
+
+ Node* zero = T.Constant(0);
+
+ CHECK_EQ(IrOpcode::kNumberConstant, zero->opcode());
+ CHECK_EQ(zero, T.ZeroConstant());
+ CHECK_NE(zero, T.Constant(-0.0));
+ CHECK_NE(zero, T.Constant(1.0));
+ CHECK_NE(zero, T.Constant(v8::base::OS::nan_value()));
+ CHECK_NE(zero, T.Float64Constant(0));
+ CHECK_NE(zero, T.Int32Constant(0));
+
+ Type* t = T.upper(zero);
+
+ CHECK(t->Is(Type::Number()));
+ CHECK(t->Is(Type::Integral32()));
+ CHECK(t->Is(Type::Signed32()));
+ CHECK(t->Is(Type::Unsigned32()));
+ CHECK(t->Is(Type::SignedSmall()));
+ CHECK(t->Is(Type::UnsignedSmall()));
+}
+
+
+TEST(OneConstant1) {
+ JSConstantCacheTester T;
+
+ Node* one = T.OneConstant();
+
+ CHECK_EQ(IrOpcode::kNumberConstant, one->opcode());
+ CHECK_EQ(one, T.Constant(1));
+ CHECK_EQ(one, T.Constant(1.0));
+ CHECK_NE(one, T.Constant(1.01));
+ CHECK_NE(one, T.Constant(-1.01));
+ CHECK_NE(one, T.Constant(v8::base::OS::nan_value()));
+ CHECK_NE(one, T.Float64Constant(1.0));
+ CHECK_NE(one, T.Int32Constant(1));
+
+ Type* t = T.upper(one);
+
+ CHECK(t->Is(Type::Number()));
+ CHECK(t->Is(Type::Integral32()));
+ CHECK(t->Is(Type::Signed32()));
+ CHECK(t->Is(Type::Unsigned32()));
+ CHECK(t->Is(Type::SignedSmall()));
+ CHECK(t->Is(Type::UnsignedSmall()));
+}
+
+
+TEST(OneConstant2) {
+ JSConstantCacheTester T;
+
+ Node* one = T.Constant(1);
+
+ CHECK_EQ(IrOpcode::kNumberConstant, one->opcode());
+ CHECK_EQ(one, T.OneConstant());
+ CHECK_EQ(one, T.Constant(1.0));
+ CHECK_NE(one, T.Constant(1.01));
+ CHECK_NE(one, T.Constant(-1.01));
+ CHECK_NE(one, T.Constant(v8::base::OS::nan_value()));
+ CHECK_NE(one, T.Float64Constant(1.0));
+ CHECK_NE(one, T.Int32Constant(1));
+
+ Type* t = T.upper(one);
+
+ CHECK(t->Is(Type::Number()));
+ CHECK(t->Is(Type::Integral32()));
+ CHECK(t->Is(Type::Signed32()));
+ CHECK(t->Is(Type::Unsigned32()));
+ CHECK(t->Is(Type::SignedSmall()));
+ CHECK(t->Is(Type::UnsignedSmall()));
+}
+
+
+TEST(Canonicalizations) {
+ JSConstantCacheTester T;
+
+ CHECK_EQ(T.ZeroConstant(), T.ZeroConstant());
+ CHECK_EQ(T.UndefinedConstant(), T.UndefinedConstant());
+ CHECK_EQ(T.TheHoleConstant(), T.TheHoleConstant());
+ CHECK_EQ(T.TrueConstant(), T.TrueConstant());
+ CHECK_EQ(T.FalseConstant(), T.FalseConstant());
+ CHECK_EQ(T.NullConstant(), T.NullConstant());
+ CHECK_EQ(T.ZeroConstant(), T.ZeroConstant());
+ CHECK_EQ(T.OneConstant(), T.OneConstant());
+ CHECK_EQ(T.NaNConstant(), T.NaNConstant());
+}
+
+
+TEST(NoAliasing) {
+ JSConstantCacheTester T;
+
+ Node* nodes[] = {T.UndefinedConstant(), T.TheHoleConstant(), T.TrueConstant(),
+ T.FalseConstant(), T.NullConstant(), T.ZeroConstant(),
+ T.OneConstant(), T.NaNConstant(), T.Constant(21),
+ T.Constant(22.2)};
+
+ for (size_t i = 0; i < ARRAY_SIZE(nodes); i++) {
+ for (size_t j = 0; j < ARRAY_SIZE(nodes); j++) {
+ if (i != j) CHECK_NE(nodes[i], nodes[j]);
+ }
+ }
+}
+
+
+TEST(CanonicalizingNumbers) {
+ JSConstantCacheTester T;
+
+ FOR_FLOAT64_INPUTS(i) {
+ Node* node = T.Constant(*i);
+ for (int j = 0; j < 5; j++) {
+ CHECK_EQ(node, T.Constant(*i));
+ }
+ }
+}
+
+
+TEST(NumberTypes) {
+ JSConstantCacheTester T;
+
+ FOR_FLOAT64_INPUTS(i) {
+ double value = *i;
+ Node* node = T.Constant(value);
+ CHECK(T.upper(node)->Equals(Type::Of(value, T.main_zone())));
+ }
+}
+
+
+TEST(HeapNumbers) {
+ JSConstantCacheTester T;
+
+ FOR_FLOAT64_INPUTS(i) {
+ double value = *i;
+ Handle<Object> num = T.factory()->NewNumber(value);
+ Handle<HeapNumber> heap = T.factory()->NewHeapNumber(value);
+ Node* node1 = T.Constant(value);
+ Node* node2 = T.Constant(num);
+ Node* node3 = T.Constant(heap);
+ CHECK_EQ(node1, node2);
+ CHECK_EQ(node1, node3);
+ }
+}
+
+
+TEST(OddballHandle) {
+ JSConstantCacheTester T;
+
+ CHECK_EQ(T.UndefinedConstant(), T.Constant(T.factory()->undefined_value()));
+ CHECK_EQ(T.TheHoleConstant(), T.Constant(T.factory()->the_hole_value()));
+ CHECK_EQ(T.TrueConstant(), T.Constant(T.factory()->true_value()));
+ CHECK_EQ(T.FalseConstant(), T.Constant(T.factory()->false_value()));
+ CHECK_EQ(T.NullConstant(), T.Constant(T.factory()->null_value()));
+ CHECK_EQ(T.NaNConstant(), T.Constant(T.factory()->nan_value()));
+}
+
+
+TEST(OddballValues) {
+ JSConstantCacheTester T;
+
+ CHECK_EQ(*T.factory()->undefined_value(), *T.handle(T.UndefinedConstant()));
+ CHECK_EQ(*T.factory()->the_hole_value(), *T.handle(T.TheHoleConstant()));
+ CHECK_EQ(*T.factory()->true_value(), *T.handle(T.TrueConstant()));
+ CHECK_EQ(*T.factory()->false_value(), *T.handle(T.FalseConstant()));
+ CHECK_EQ(*T.factory()->null_value(), *T.handle(T.NullConstant()));
+}
+
+
+TEST(OddballTypes) {
+ JSConstantCacheTester T;
+
+ CHECK(T.upper(T.UndefinedConstant())->Is(Type::Undefined()));
+ // TODO(dcarney): figure this out.
+ // CHECK(T.upper(T.TheHoleConstant())->Is(Type::Internal()));
+ CHECK(T.upper(T.TrueConstant())->Is(Type::Boolean()));
+ CHECK(T.upper(T.FalseConstant())->Is(Type::Boolean()));
+ CHECK(T.upper(T.NullConstant())->Is(Type::Null()));
+ CHECK(T.upper(T.ZeroConstant())->Is(Type::Number()));
+ CHECK(T.upper(T.OneConstant())->Is(Type::Number()));
+ CHECK(T.upper(T.NaNConstant())->Is(Type::NaN()));
+}
+
+
+TEST(ExternalReferences) {
+ // TODO(titzer): test canonicalization of external references.
+}
diff --git a/deps/v8/test/cctest/compiler/test-js-context-specialization.cc b/deps/v8/test/cctest/compiler/test-js-context-specialization.cc
new file mode 100644
index 000000000..740d9f3d4
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-js-context-specialization.cc
@@ -0,0 +1,309 @@
+// 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 "src/compiler/js-context-specialization.h"
+#include "src/compiler/js-operator.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/simplified-node-factory.h"
+#include "src/compiler/source-position.h"
+#include "src/compiler/typer.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/function-tester.h"
+#include "test/cctest/compiler/graph-builder-tester.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+class ContextSpecializationTester
+ : public HandleAndZoneScope,
+ public DirectGraphBuilder,
+ public SimplifiedNodeFactory<ContextSpecializationTester> {
+ public:
+ ContextSpecializationTester()
+ : DirectGraphBuilder(new (main_zone()) Graph(main_zone())),
+ common_(main_zone()),
+ javascript_(main_zone()),
+ simplified_(main_zone()),
+ typer_(main_zone()),
+ jsgraph_(graph(), common(), &typer_),
+ info_(main_isolate(), main_zone()) {}
+
+ Factory* factory() { return main_isolate()->factory(); }
+ CommonOperatorBuilder* common() { return &common_; }
+ JSOperatorBuilder* javascript() { return &javascript_; }
+ SimplifiedOperatorBuilder* simplified() { return &simplified_; }
+ JSGraph* jsgraph() { return &jsgraph_; }
+ CompilationInfo* info() { return &info_; }
+
+ private:
+ CommonOperatorBuilder common_;
+ JSOperatorBuilder javascript_;
+ SimplifiedOperatorBuilder simplified_;
+ Typer typer_;
+ JSGraph jsgraph_;
+ CompilationInfo info_;
+};
+
+
+TEST(ReduceJSLoadContext) {
+ ContextSpecializationTester t;
+
+ Node* start = t.NewNode(t.common()->Start(0));
+ t.graph()->SetStart(start);
+
+ // Make a context and initialize it a bit for this test.
+ Handle<Context> native = t.factory()->NewNativeContext();
+ Handle<Context> subcontext1 = t.factory()->NewNativeContext();
+ Handle<Context> subcontext2 = t.factory()->NewNativeContext();
+ subcontext2->set_previous(*subcontext1);
+ subcontext1->set_previous(*native);
+ Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!");
+ const int slot = Context::GLOBAL_OBJECT_INDEX;
+ native->set(slot, *expected);
+
+ Node* const_context = t.jsgraph()->Constant(native);
+ Node* deep_const_context = t.jsgraph()->Constant(subcontext2);
+ Node* param_context = t.NewNode(t.common()->Parameter(0), start);
+ JSContextSpecializer spec(t.info(), t.jsgraph(), const_context);
+
+ {
+ // Mutable slot, constant context, depth = 0 => do nothing.
+ Node* load = t.NewNode(t.javascript()->LoadContext(0, 0, false),
+ const_context, const_context, start);
+ Reduction r = spec.ReduceJSLoadContext(load);
+ CHECK(!r.Changed());
+ }
+
+ {
+ // Mutable slot, non-constant context, depth = 0 => do nothing.
+ Node* load = t.NewNode(t.javascript()->LoadContext(0, 0, false),
+ param_context, param_context, start);
+ Reduction r = spec.ReduceJSLoadContext(load);
+ CHECK(!r.Changed());
+ }
+
+ {
+ // Mutable slot, constant context, depth > 0 => fold-in parent context.
+ Node* load = t.NewNode(
+ t.javascript()->LoadContext(2, Context::GLOBAL_EVAL_FUN_INDEX, false),
+ deep_const_context, deep_const_context, start);
+ Reduction r = spec.ReduceJSLoadContext(load);
+ CHECK(r.Changed());
+ Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
+ CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
+ ValueMatcher<Handle<Context> > match(new_context_input);
+ CHECK_EQ(*native, *match.Value());
+ ContextAccess access = static_cast<Operator1<ContextAccess>*>(
+ r.replacement()->op())->parameter();
+ CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, access.index());
+ CHECK_EQ(0, access.depth());
+ CHECK_EQ(false, access.immutable());
+ }
+
+ {
+ // Immutable slot, constant context, depth = 0 => specialize.
+ Node* load = t.NewNode(t.javascript()->LoadContext(0, slot, true),
+ const_context, const_context, start);
+ Reduction r = spec.ReduceJSLoadContext(load);
+ CHECK(r.Changed());
+ CHECK(r.replacement() != load);
+
+ ValueMatcher<Handle<Object> > match(r.replacement());
+ CHECK(match.HasValue());
+ CHECK_EQ(*expected, *match.Value());
+ }
+
+ // TODO(titzer): test with other kinds of contexts, e.g. a function context.
+ // TODO(sigurds): test that loads below create context are not optimized
+}
+
+
+TEST(ReduceJSStoreContext) {
+ ContextSpecializationTester t;
+
+ Node* start = t.NewNode(t.common()->Start(0));
+ t.graph()->SetStart(start);
+
+ // Make a context and initialize it a bit for this test.
+ Handle<Context> native = t.factory()->NewNativeContext();
+ Handle<Context> subcontext1 = t.factory()->NewNativeContext();
+ Handle<Context> subcontext2 = t.factory()->NewNativeContext();
+ subcontext2->set_previous(*subcontext1);
+ subcontext1->set_previous(*native);
+ Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!");
+ const int slot = Context::GLOBAL_OBJECT_INDEX;
+ native->set(slot, *expected);
+
+ Node* const_context = t.jsgraph()->Constant(native);
+ Node* deep_const_context = t.jsgraph()->Constant(subcontext2);
+ Node* param_context = t.NewNode(t.common()->Parameter(0), start);
+ JSContextSpecializer spec(t.info(), t.jsgraph(), const_context);
+
+ {
+ // Mutable slot, constant context, depth = 0 => do nothing.
+ Node* load = t.NewNode(t.javascript()->StoreContext(0, 0), const_context,
+ const_context, start);
+ Reduction r = spec.ReduceJSStoreContext(load);
+ CHECK(!r.Changed());
+ }
+
+ {
+ // Mutable slot, non-constant context, depth = 0 => do nothing.
+ Node* load = t.NewNode(t.javascript()->StoreContext(0, 0), param_context,
+ param_context, start);
+ Reduction r = spec.ReduceJSStoreContext(load);
+ CHECK(!r.Changed());
+ }
+
+ {
+ // Immutable slot, constant context, depth = 0 => do nothing.
+ Node* load = t.NewNode(t.javascript()->StoreContext(0, slot), const_context,
+ const_context, start);
+ Reduction r = spec.ReduceJSStoreContext(load);
+ CHECK(!r.Changed());
+ }
+
+ {
+ // Mutable slot, constant context, depth > 0 => fold-in parent context.
+ Node* load = t.NewNode(
+ t.javascript()->StoreContext(2, Context::GLOBAL_EVAL_FUN_INDEX),
+ deep_const_context, deep_const_context, start);
+ Reduction r = spec.ReduceJSStoreContext(load);
+ CHECK(r.Changed());
+ Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
+ CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
+ ValueMatcher<Handle<Context> > match(new_context_input);
+ CHECK_EQ(*native, *match.Value());
+ ContextAccess access = static_cast<Operator1<ContextAccess>*>(
+ r.replacement()->op())->parameter();
+ CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, access.index());
+ CHECK_EQ(0, access.depth());
+ CHECK_EQ(false, access.immutable());
+ }
+}
+
+
+// TODO(titzer): factor out common code with effects checking in typed lowering.
+static void CheckEffectInput(Node* effect, Node* use) {
+ CHECK_EQ(effect, NodeProperties::GetEffectInput(use));
+}
+
+
+TEST(SpecializeToContext) {
+ ContextSpecializationTester t;
+
+ Node* start = t.NewNode(t.common()->Start(0));
+ t.graph()->SetStart(start);
+
+ // Make a context and initialize it a bit for this test.
+ Handle<Context> native = t.factory()->NewNativeContext();
+ Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!");
+ const int slot = Context::GLOBAL_OBJECT_INDEX;
+ native->set(slot, *expected);
+ t.info()->SetContext(native);
+
+ Node* const_context = t.jsgraph()->Constant(native);
+ Node* param_context = t.NewNode(t.common()->Parameter(0), start);
+ JSContextSpecializer spec(t.info(), t.jsgraph(), const_context);
+
+ {
+ // Check that SpecializeToContext() replaces values and forwards effects
+ // correctly, and folds values from constant and non-constant contexts
+ Node* effect_in = start;
+ Node* load = t.NewNode(t.javascript()->LoadContext(0, slot, true),
+ const_context, const_context, effect_in);
+
+
+ Node* value_use = t.ChangeTaggedToInt32(load);
+ Node* other_load = t.NewNode(t.javascript()->LoadContext(0, slot, true),
+ param_context, param_context, load);
+ Node* effect_use = other_load;
+ Node* other_use = t.ChangeTaggedToInt32(other_load);
+
+ Node* add = t.NewNode(t.javascript()->Add(), value_use, other_use,
+ param_context, other_load, start);
+
+ Node* ret = t.NewNode(t.common()->Return(), add, effect_use, start);
+ Node* end = t.NewNode(t.common()->End(), ret);
+ USE(end);
+ t.graph()->SetEnd(end);
+
+ // Double check the above graph is what we expect, or the test is broken.
+ CheckEffectInput(effect_in, load);
+ CheckEffectInput(load, effect_use);
+
+ // Perform the substitution on the entire graph.
+ spec.SpecializeToContext();
+
+ // Effects should have been forwarded (not replaced with a value).
+ CheckEffectInput(effect_in, effect_use);
+
+ // Use of {other_load} should not have been replaced.
+ CHECK_EQ(other_load, other_use->InputAt(0));
+
+ Node* replacement = value_use->InputAt(0);
+ ValueMatcher<Handle<Object> > match(replacement);
+ CHECK(match.HasValue());
+ CHECK_EQ(*expected, *match.Value());
+ }
+ // TODO(titzer): clean up above test and test more complicated effects.
+}
+
+
+TEST(SpecializeJSFunction_ToConstant1) {
+ FunctionTester T(
+ "(function() { var x = 1; function inc(a)"
+ " { return a + x; } return inc; })()");
+
+ T.CheckCall(1.0, 0.0, 0.0);
+ T.CheckCall(2.0, 1.0, 0.0);
+ T.CheckCall(2.1, 1.1, 0.0);
+}
+
+
+TEST(SpecializeJSFunction_ToConstant2) {
+ FunctionTester T(
+ "(function() { var x = 1.5; var y = 2.25; var z = 3.75;"
+ " function f(a) { return a - x + y - z; } return f; })()");
+
+ T.CheckCall(-3.0, 0.0, 0.0);
+ T.CheckCall(-2.0, 1.0, 0.0);
+ T.CheckCall(-1.9, 1.1, 0.0);
+}
+
+
+TEST(SpecializeJSFunction_ToConstant3) {
+ FunctionTester T(
+ "(function() { var x = -11.5; function inc()"
+ " { return (function(a) { return a + x; }); }"
+ " return inc(); })()");
+
+ T.CheckCall(-11.5, 0.0, 0.0);
+ T.CheckCall(-10.5, 1.0, 0.0);
+ T.CheckCall(-10.4, 1.1, 0.0);
+}
+
+
+TEST(SpecializeJSFunction_ToConstant_uninit) {
+ {
+ FunctionTester T(
+ "(function() { if (false) { var x = 1; } function inc(a)"
+ " { return x; } return inc; })()"); // x is undefined!
+
+ CHECK(T.Call(T.Val(0.0), T.Val(0.0)).ToHandleChecked()->IsUndefined());
+ CHECK(T.Call(T.Val(2.0), T.Val(0.0)).ToHandleChecked()->IsUndefined());
+ CHECK(T.Call(T.Val(-2.1), T.Val(0.0)).ToHandleChecked()->IsUndefined());
+ }
+
+ {
+ FunctionTester T(
+ "(function() { if (false) { var x = 1; } function inc(a)"
+ " { return a + x; } return inc; })()"); // x is undefined!
+
+ CHECK(T.Call(T.Val(0.0), T.Val(0.0)).ToHandleChecked()->IsNaN());
+ CHECK(T.Call(T.Val(2.0), T.Val(0.0)).ToHandleChecked()->IsNaN());
+ CHECK(T.Call(T.Val(-2.1), T.Val(0.0)).ToHandleChecked()->IsNaN());
+ }
+}
diff --git a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
new file mode 100644
index 000000000..b6aa6d958
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
@@ -0,0 +1,1342 @@
+// 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 "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/compiler/graph-inl.h"
+#include "src/compiler/js-typed-lowering.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/opcodes.h"
+#include "src/compiler/typer.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+class JSTypedLoweringTester : public HandleAndZoneScope {
+ public:
+ explicit JSTypedLoweringTester(int num_parameters = 0)
+ : isolate(main_isolate()),
+ binop(NULL),
+ unop(NULL),
+ javascript(main_zone()),
+ machine(main_zone()),
+ simplified(main_zone()),
+ common(main_zone()),
+ graph(main_zone()),
+ typer(main_zone()),
+ source_positions(&graph),
+ context_node(NULL) {
+ typer.DecorateGraph(&graph);
+ Node* s = graph.NewNode(common.Start(num_parameters));
+ graph.SetStart(s);
+ }
+
+ Isolate* isolate;
+ Operator* binop;
+ Operator* unop;
+ JSOperatorBuilder javascript;
+ MachineOperatorBuilder machine;
+ SimplifiedOperatorBuilder simplified;
+ CommonOperatorBuilder common;
+ Graph graph;
+ Typer typer;
+ SourcePositionTable source_positions;
+ Node* context_node;
+
+ Node* Parameter(Type* t, int32_t index = 0) {
+ Node* n = graph.NewNode(common.Parameter(index), graph.start());
+ NodeProperties::SetBounds(n, Bounds(Type::None(), t));
+ return n;
+ }
+
+ Node* reduce(Node* node) {
+ JSGraph jsgraph(&graph, &common, &typer);
+ JSTypedLowering reducer(&jsgraph, &source_positions);
+ Reduction reduction = reducer.Reduce(node);
+ if (reduction.Changed()) return reduction.replacement();
+ return node;
+ }
+
+ Node* start() { return graph.start(); }
+
+ Node* context() {
+ if (context_node == NULL) {
+ context_node = graph.NewNode(common.Parameter(-1), graph.start());
+ }
+ return context_node;
+ }
+
+ Node* control() { return start(); }
+
+ void CheckPureBinop(IrOpcode::Value expected, Node* node) {
+ CHECK_EQ(expected, node->opcode());
+ CHECK_EQ(2, node->InputCount()); // should not have context, effect, etc.
+ }
+
+ void CheckPureBinop(Operator* expected, Node* node) {
+ CHECK_EQ(expected->opcode(), node->op()->opcode());
+ CHECK_EQ(2, node->InputCount()); // should not have context, effect, etc.
+ }
+
+ Node* ReduceUnop(Operator* op, Type* input_type) {
+ return reduce(Unop(op, Parameter(input_type)));
+ }
+
+ Node* ReduceBinop(Operator* op, Type* left_type, Type* right_type) {
+ return reduce(Binop(op, Parameter(left_type, 0), Parameter(right_type, 1)));
+ }
+
+ Node* Binop(Operator* op, Node* left, Node* right) {
+ // JS binops also require context, effect, and control
+ return graph.NewNode(op, left, right, context(), start(), control());
+ }
+
+ Node* Unop(Operator* op, Node* input) {
+ // JS unops also require context, effect, and control
+ return graph.NewNode(op, input, context(), start(), control());
+ }
+
+ Node* UseForEffect(Node* node) {
+ // TODO(titzer): use EffectPhi after fixing EffectCount
+ return graph.NewNode(javascript.ToNumber(), node, context(), node,
+ control());
+ }
+
+ void CheckEffectInput(Node* effect, Node* use) {
+ CHECK_EQ(effect, NodeProperties::GetEffectInput(use));
+ }
+
+ void CheckInt32Constant(int32_t expected, Node* result) {
+ CHECK_EQ(IrOpcode::kInt32Constant, result->opcode());
+ CHECK_EQ(expected, ValueOf<int32_t>(result->op()));
+ }
+
+ void CheckNumberConstant(double expected, Node* result) {
+ CHECK_EQ(IrOpcode::kNumberConstant, result->opcode());
+ CHECK_EQ(expected, ValueOf<double>(result->op()));
+ }
+
+ void CheckNaN(Node* result) {
+ CHECK_EQ(IrOpcode::kNumberConstant, result->opcode());
+ double value = ValueOf<double>(result->op());
+ CHECK(std::isnan(value));
+ }
+
+ void CheckTrue(Node* result) {
+ CheckHandle(isolate->factory()->true_value(), result);
+ }
+
+ void CheckFalse(Node* result) {
+ CheckHandle(isolate->factory()->false_value(), result);
+ }
+
+ void CheckHandle(Handle<Object> expected, Node* result) {
+ CHECK_EQ(IrOpcode::kHeapConstant, result->opcode());
+ Handle<Object> value = ValueOf<Handle<Object> >(result->op());
+ CHECK_EQ(*expected, *value);
+ }
+};
+
+static Type* kStringTypes[] = {Type::InternalizedString(), Type::OtherString(),
+ Type::String()};
+
+
+static Type* kInt32Types[] = {
+ Type::UnsignedSmall(), Type::OtherSignedSmall(), Type::OtherUnsigned31(),
+ Type::OtherUnsigned32(), Type::OtherSigned32(), Type::SignedSmall(),
+ Type::Signed32(), Type::Unsigned32(), Type::Integral32()};
+
+
+static Type* kNumberTypes[] = {
+ Type::UnsignedSmall(), Type::OtherSignedSmall(), Type::OtherUnsigned31(),
+ Type::OtherUnsigned32(), Type::OtherSigned32(), Type::SignedSmall(),
+ Type::Signed32(), Type::Unsigned32(), Type::Integral32(),
+ Type::MinusZero(), Type::NaN(), Type::OtherNumber(),
+ Type::Number()};
+
+
+static Type* kJSTypes[] = {Type::Undefined(), Type::Null(), Type::Boolean(),
+ Type::Number(), Type::String(), Type::Object()};
+
+
+static Type* I32Type(bool is_signed) {
+ return is_signed ? Type::Signed32() : Type::Unsigned32();
+}
+
+
+static IrOpcode::Value NumberToI32(bool is_signed) {
+ return is_signed ? IrOpcode::kNumberToInt32 : IrOpcode::kNumberToUint32;
+}
+
+
+TEST(StringBinops) {
+ JSTypedLoweringTester R;
+
+ for (size_t i = 0; i < ARRAY_SIZE(kStringTypes); ++i) {
+ Node* p0 = R.Parameter(kStringTypes[i], 0);
+
+ for (size_t j = 0; j < ARRAY_SIZE(kStringTypes); ++j) {
+ Node* p1 = R.Parameter(kStringTypes[j], 1);
+
+ Node* add = R.Binop(R.javascript.Add(), p0, p1);
+ Node* r = R.reduce(add);
+
+ R.CheckPureBinop(IrOpcode::kStringAdd, r);
+ CHECK_EQ(p0, r->InputAt(0));
+ CHECK_EQ(p1, r->InputAt(1));
+ }
+ }
+}
+
+
+TEST(AddNumber1) {
+ JSTypedLoweringTester R;
+ for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); ++i) {
+ Node* p0 = R.Parameter(kNumberTypes[i], 0);
+ Node* p1 = R.Parameter(kNumberTypes[i], 1);
+ Node* add = R.Binop(R.javascript.Add(), p0, p1);
+ Node* r = R.reduce(add);
+
+ R.CheckPureBinop(IrOpcode::kNumberAdd, r);
+ CHECK_EQ(p0, r->InputAt(0));
+ CHECK_EQ(p1, r->InputAt(1));
+ }
+}
+
+
+TEST(NumberBinops) {
+ JSTypedLoweringTester R;
+ Operator* ops[] = {
+ R.javascript.Add(), R.simplified.NumberAdd(),
+ R.javascript.Subtract(), R.simplified.NumberSubtract(),
+ R.javascript.Multiply(), R.simplified.NumberMultiply(),
+ R.javascript.Divide(), R.simplified.NumberDivide(),
+ R.javascript.Modulus(), R.simplified.NumberModulus(),
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); ++i) {
+ Node* p0 = R.Parameter(kNumberTypes[i], 0);
+
+ for (size_t j = 0; j < ARRAY_SIZE(kNumberTypes); ++j) {
+ Node* p1 = R.Parameter(kNumberTypes[j], 1);
+
+ for (size_t k = 0; k < ARRAY_SIZE(ops); k += 2) {
+ Node* add = R.Binop(ops[k], p0, p1);
+ Node* r = R.reduce(add);
+
+ R.CheckPureBinop(ops[k + 1], r);
+ CHECK_EQ(p0, r->InputAt(0));
+ CHECK_EQ(p1, r->InputAt(1));
+ }
+ }
+ }
+}
+
+
+static void CheckToI32(Node* old_input, Node* new_input, bool is_signed) {
+ Type* old_type = NodeProperties::GetBounds(old_input).upper;
+ Type* expected_type = I32Type(is_signed);
+ if (old_type->Is(expected_type)) {
+ CHECK_EQ(old_input, new_input);
+ } else if (new_input->opcode() == IrOpcode::kNumberConstant) {
+ CHECK(NodeProperties::GetBounds(new_input).upper->Is(expected_type));
+ double v = ValueOf<double>(new_input->op());
+ double e = static_cast<double>(is_signed ? FastD2I(v) : FastD2UI(v));
+ CHECK_EQ(e, v);
+ } else {
+ CHECK_EQ(NumberToI32(is_signed), new_input->opcode());
+ }
+}
+
+
+// A helper class for testing lowering of bitwise shift operators.
+class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester {
+ public:
+ static const int kNumberOps = 6;
+ Operator* ops[kNumberOps];
+ bool signedness[kNumberOps];
+
+ JSBitwiseShiftTypedLoweringTester() {
+ int i = 0;
+ set(i++, javascript.ShiftLeft(), true);
+ set(i++, machine.Word32Shl(), false);
+ set(i++, javascript.ShiftRight(), true);
+ set(i++, machine.Word32Sar(), false);
+ set(i++, javascript.ShiftRightLogical(), false);
+ set(i++, machine.Word32Shr(), false);
+ }
+
+ private:
+ void set(int idx, Operator* op, bool s) {
+ ops[idx] = op;
+ signedness[idx] = s;
+ }
+};
+
+
+TEST(Int32BitwiseShifts) {
+ JSBitwiseShiftTypedLoweringTester R;
+
+ Type* types[] = {
+ Type::SignedSmall(), Type::UnsignedSmall(), Type::OtherSigned32(),
+ Type::Unsigned32(), Type::Signed32(), Type::MinusZero(),
+ Type::NaN(), Type::OtherNumber(), Type::Undefined(),
+ Type::Null(), Type::Boolean(), Type::Number(),
+ Type::String(), Type::Object()};
+
+ for (size_t i = 0; i < ARRAY_SIZE(types); ++i) {
+ Node* p0 = R.Parameter(types[i], 0);
+
+ for (size_t j = 0; j < ARRAY_SIZE(types); ++j) {
+ Node* p1 = R.Parameter(types[j], 1);
+
+ for (int k = 0; k < R.kNumberOps; k += 2) {
+ Node* add = R.Binop(R.ops[k], p0, p1);
+ Node* r = R.reduce(add);
+
+ R.CheckPureBinop(R.ops[k + 1], r);
+ Node* r0 = r->InputAt(0);
+ Node* r1 = r->InputAt(1);
+
+ CheckToI32(p0, r0, R.signedness[k]);
+
+ R.CheckPureBinop(IrOpcode::kWord32And, r1);
+ CheckToI32(p1, r1->InputAt(0), R.signedness[k + 1]);
+ R.CheckInt32Constant(0x1F, r1->InputAt(1));
+ }
+ }
+ }
+}
+
+
+// A helper class for testing lowering of bitwise operators.
+class JSBitwiseTypedLoweringTester : public JSTypedLoweringTester {
+ public:
+ static const int kNumberOps = 6;
+ Operator* ops[kNumberOps];
+ bool signedness[kNumberOps];
+
+ JSBitwiseTypedLoweringTester() {
+ int i = 0;
+ set(i++, javascript.BitwiseOr(), true);
+ set(i++, machine.Word32Or(), true);
+ set(i++, javascript.BitwiseXor(), true);
+ set(i++, machine.Word32Xor(), true);
+ set(i++, javascript.BitwiseAnd(), true);
+ set(i++, machine.Word32And(), true);
+ }
+
+ private:
+ void set(int idx, Operator* op, bool s) {
+ ops[idx] = op;
+ signedness[idx] = s;
+ }
+};
+
+
+TEST(Int32BitwiseBinops) {
+ JSBitwiseTypedLoweringTester R;
+
+ Type* types[] = {
+ Type::SignedSmall(), Type::UnsignedSmall(), Type::OtherSigned32(),
+ Type::Unsigned32(), Type::Signed32(), Type::MinusZero(),
+ Type::NaN(), Type::OtherNumber(), Type::Undefined(),
+ Type::Null(), Type::Boolean(), Type::Number(),
+ Type::String(), Type::Object()};
+
+ for (size_t i = 0; i < ARRAY_SIZE(types); ++i) {
+ Node* p0 = R.Parameter(types[i], 0);
+
+ for (size_t j = 0; j < ARRAY_SIZE(types); ++j) {
+ Node* p1 = R.Parameter(types[j], 1);
+
+ for (int k = 0; k < R.kNumberOps; k += 2) {
+ Node* add = R.Binop(R.ops[k], p0, p1);
+ Node* r = R.reduce(add);
+
+ R.CheckPureBinop(R.ops[k + 1], r);
+
+ CheckToI32(p0, r->InputAt(0), R.signedness[k]);
+ CheckToI32(p1, r->InputAt(1), R.signedness[k + 1]);
+ }
+ }
+ }
+}
+
+
+TEST(JSToNumber1) {
+ JSTypedLoweringTester R;
+ Operator* ton = R.javascript.ToNumber();
+
+ for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); i++) { // ToNumber(number)
+ Node* r = R.ReduceUnop(ton, kNumberTypes[i]);
+ CHECK_EQ(IrOpcode::kParameter, r->opcode());
+ }
+
+ { // ToNumber(undefined)
+ Node* r = R.ReduceUnop(ton, Type::Undefined());
+ R.CheckNaN(r);
+ }
+
+ { // ToNumber(null)
+ Node* r = R.ReduceUnop(ton, Type::Null());
+ R.CheckNumberConstant(0.0, r);
+ }
+}
+
+
+TEST(JSToNumber_replacement) {
+ JSTypedLoweringTester R;
+
+ Type* types[] = {Type::Null(), Type::Undefined(), Type::Number()};
+
+ for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+ Node* n = R.Parameter(types[i]);
+ Node* c = R.graph.NewNode(R.javascript.ToNumber(), n, R.context(),
+ R.start(), R.start());
+ Node* effect_use = R.UseForEffect(c);
+ Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c);
+
+ R.CheckEffectInput(c, effect_use);
+ Node* r = R.reduce(c);
+
+ if (types[i]->Is(Type::Number())) {
+ CHECK_EQ(n, r);
+ } else {
+ CHECK_EQ(IrOpcode::kNumberConstant, r->opcode());
+ }
+
+ CHECK_EQ(n, add->InputAt(0));
+ CHECK_EQ(r, add->InputAt(1));
+ R.CheckEffectInput(R.start(), effect_use);
+ }
+}
+
+
+TEST(JSToNumberOfConstant) {
+ JSTypedLoweringTester R;
+
+ Operator* ops[] = {R.common.NumberConstant(0), R.common.NumberConstant(-1),
+ R.common.NumberConstant(0.1), R.common.Int32Constant(1177),
+ R.common.Float64Constant(0.99)};
+
+ for (size_t i = 0; i < ARRAY_SIZE(ops); i++) {
+ Node* n = R.graph.NewNode(ops[i]);
+ Node* convert = R.Unop(R.javascript.ToNumber(), n);
+ Node* r = R.reduce(convert);
+ // Note that either outcome below is correct. It only depends on whether
+ // the types of constants are eagerly computed or only computed by the
+ // typing pass.
+ if (NodeProperties::GetBounds(n).upper->Is(Type::Number())) {
+ // If number constants are eagerly typed, then reduction should
+ // remove the ToNumber.
+ CHECK_EQ(n, r);
+ } else {
+ // Otherwise, type-based lowering should only look at the type, and
+ // *not* try to constant fold.
+ CHECK_EQ(convert, r);
+ }
+ }
+}
+
+
+TEST(JSToNumberOfNumberOrOtherPrimitive) {
+ JSTypedLoweringTester R;
+ Type* others[] = {Type::Undefined(), Type::Null(), Type::Boolean(),
+ Type::String()};
+
+ for (size_t i = 0; i < ARRAY_SIZE(others); i++) {
+ Type* t = Type::Union(Type::Number(), others[i], R.main_zone());
+ Node* r = R.ReduceUnop(R.javascript.ToNumber(), t);
+ CHECK_EQ(IrOpcode::kJSToNumber, r->opcode());
+ }
+}
+
+
+TEST(JSToBoolean) {
+ JSTypedLoweringTester R;
+ Operator* op = R.javascript.ToBoolean();
+
+ { // ToBoolean(undefined)
+ Node* r = R.ReduceUnop(op, Type::Undefined());
+ R.CheckFalse(r);
+ }
+
+ { // ToBoolean(null)
+ Node* r = R.ReduceUnop(op, Type::Null());
+ R.CheckFalse(r);
+ }
+
+ { // ToBoolean(boolean)
+ Node* r = R.ReduceUnop(op, Type::Boolean());
+ CHECK_EQ(IrOpcode::kParameter, r->opcode());
+ }
+
+ { // ToBoolean(number)
+ Node* r = R.ReduceUnop(op, Type::Number());
+ CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
+ Node* i = r->InputAt(0);
+ CHECK_EQ(IrOpcode::kNumberEqual, i->opcode());
+ // ToBoolean(number) => BooleanNot(NumberEqual(x, #0))
+ }
+
+ { // ToBoolean(string)
+ Node* r = R.ReduceUnop(op, Type::String());
+ // TODO(titzer): test will break with better js-typed-lowering
+ CHECK_EQ(IrOpcode::kJSToBoolean, r->opcode());
+ }
+
+ { // ToBoolean(object)
+ Node* r = R.ReduceUnop(op, Type::DetectableObject());
+ R.CheckTrue(r);
+ }
+
+ { // ToBoolean(undetectable)
+ Node* r = R.ReduceUnop(op, Type::Undetectable());
+ R.CheckFalse(r);
+ }
+
+ { // ToBoolean(object)
+ Node* r = R.ReduceUnop(op, Type::Object());
+ CHECK_EQ(IrOpcode::kJSToBoolean, r->opcode());
+ }
+}
+
+
+TEST(JSToBoolean_replacement) {
+ JSTypedLoweringTester R;
+
+ Type* types[] = {Type::Null(), Type::Undefined(), Type::Boolean(),
+ Type::DetectableObject(), Type::Undetectable()};
+
+ for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+ Node* n = R.Parameter(types[i]);
+ Node* c = R.graph.NewNode(R.javascript.ToBoolean(), n, R.context(),
+ R.start(), R.start());
+ Node* effect_use = R.UseForEffect(c);
+ Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c);
+
+ R.CheckEffectInput(c, effect_use);
+ Node* r = R.reduce(c);
+
+ if (types[i]->Is(Type::Boolean())) {
+ CHECK_EQ(n, r);
+ } else {
+ CHECK_EQ(IrOpcode::kHeapConstant, r->opcode());
+ }
+
+ CHECK_EQ(n, add->InputAt(0));
+ CHECK_EQ(r, add->InputAt(1));
+ R.CheckEffectInput(R.start(), effect_use);
+ }
+}
+
+
+TEST(JSToString1) {
+ JSTypedLoweringTester R;
+
+ for (size_t i = 0; i < ARRAY_SIZE(kStringTypes); i++) {
+ Node* r = R.ReduceUnop(R.javascript.ToString(), kStringTypes[i]);
+ CHECK_EQ(IrOpcode::kParameter, r->opcode());
+ }
+
+ Operator* op = R.javascript.ToString();
+
+ { // ToString(undefined) => "undefined"
+ Node* r = R.ReduceUnop(op, Type::Undefined());
+ R.CheckHandle(R.isolate->factory()->undefined_string(), r);
+ }
+
+ { // ToString(null) => "null"
+ Node* r = R.ReduceUnop(op, Type::Null());
+ R.CheckHandle(R.isolate->factory()->null_string(), r);
+ }
+
+ { // ToString(boolean)
+ Node* r = R.ReduceUnop(op, Type::Boolean());
+ // TODO(titzer): could be a branch
+ CHECK_EQ(IrOpcode::kJSToString, r->opcode());
+ }
+
+ { // ToString(number)
+ Node* r = R.ReduceUnop(op, Type::Number());
+ // TODO(titzer): could remove effects
+ CHECK_EQ(IrOpcode::kJSToString, r->opcode());
+ }
+
+ { // ToString(string)
+ Node* r = R.ReduceUnop(op, Type::String());
+ CHECK_EQ(IrOpcode::kParameter, r->opcode()); // No-op
+ }
+
+ { // ToString(object)
+ Node* r = R.ReduceUnop(op, Type::Object());
+ CHECK_EQ(IrOpcode::kJSToString, r->opcode()); // No reduction.
+ }
+}
+
+
+TEST(JSToString_replacement) {
+ JSTypedLoweringTester R;
+
+ Type* types[] = {Type::Null(), Type::Undefined(), Type::String()};
+
+ for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+ Node* n = R.Parameter(types[i]);
+ Node* c = R.graph.NewNode(R.javascript.ToString(), n, R.context(),
+ R.start(), R.start());
+ Node* effect_use = R.UseForEffect(c);
+ Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c);
+
+ R.CheckEffectInput(c, effect_use);
+ Node* r = R.reduce(c);
+
+ if (types[i]->Is(Type::String())) {
+ CHECK_EQ(n, r);
+ } else {
+ CHECK_EQ(IrOpcode::kHeapConstant, r->opcode());
+ }
+
+ CHECK_EQ(n, add->InputAt(0));
+ CHECK_EQ(r, add->InputAt(1));
+ R.CheckEffectInput(R.start(), effect_use);
+ }
+}
+
+
+TEST(StringComparison) {
+ JSTypedLoweringTester R;
+
+ Operator* ops[] = {
+ R.javascript.LessThan(), R.simplified.StringLessThan(),
+ R.javascript.LessThanOrEqual(), R.simplified.StringLessThanOrEqual(),
+ R.javascript.GreaterThan(), R.simplified.StringLessThan(),
+ R.javascript.GreaterThanOrEqual(), R.simplified.StringLessThanOrEqual()};
+
+ for (size_t i = 0; i < ARRAY_SIZE(kStringTypes); i++) {
+ Node* p0 = R.Parameter(kStringTypes[i], 0);
+ for (size_t j = 0; j < ARRAY_SIZE(kStringTypes); j++) {
+ Node* p1 = R.Parameter(kStringTypes[j], 1);
+
+ for (size_t k = 0; k < ARRAY_SIZE(ops); k += 2) {
+ Node* cmp = R.Binop(ops[k], p0, p1);
+ Node* r = R.reduce(cmp);
+
+ R.CheckPureBinop(ops[k + 1], r);
+ if (k >= 4) {
+ // GreaterThan and GreaterThanOrEqual commute the inputs
+ // and use the LessThan and LessThanOrEqual operators.
+ CHECK_EQ(p1, r->InputAt(0));
+ CHECK_EQ(p0, r->InputAt(1));
+ } else {
+ CHECK_EQ(p0, r->InputAt(0));
+ CHECK_EQ(p1, r->InputAt(1));
+ }
+ }
+ }
+ }
+}
+
+
+static void CheckIsConvertedToNumber(Node* val, Node* converted) {
+ if (NodeProperties::GetBounds(val).upper->Is(Type::Number())) {
+ CHECK_EQ(val, converted);
+ } else {
+ if (converted->opcode() == IrOpcode::kNumberConstant) return;
+ CHECK_EQ(IrOpcode::kJSToNumber, converted->opcode());
+ CHECK_EQ(val, converted->InputAt(0));
+ }
+}
+
+
+TEST(NumberComparison) {
+ JSTypedLoweringTester R;
+
+ Operator* ops[] = {
+ R.javascript.LessThan(), R.simplified.NumberLessThan(),
+ R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
+ R.javascript.GreaterThan(), R.simplified.NumberLessThan(),
+ R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()};
+
+ for (size_t i = 0; i < ARRAY_SIZE(kJSTypes); i++) {
+ Type* t0 = kJSTypes[i];
+ if (t0->Is(Type::String())) continue; // skip Type::String
+ Node* p0 = R.Parameter(t0, 0);
+
+ for (size_t j = 0; j < ARRAY_SIZE(kJSTypes); j++) {
+ Type* t1 = kJSTypes[j];
+ if (t1->Is(Type::String())) continue; // skip Type::String
+ Node* p1 = R.Parameter(t1, 1);
+
+ for (size_t k = 0; k < ARRAY_SIZE(ops); k += 2) {
+ Node* cmp = R.Binop(ops[k], p0, p1);
+ Node* r = R.reduce(cmp);
+
+ R.CheckPureBinop(ops[k + 1], r);
+ if (k >= 4) {
+ // GreaterThan and GreaterThanOrEqual commute the inputs
+ // and use the LessThan and LessThanOrEqual operators.
+ CheckIsConvertedToNumber(p1, r->InputAt(0));
+ CheckIsConvertedToNumber(p0, r->InputAt(1));
+ } else {
+ CheckIsConvertedToNumber(p0, r->InputAt(0));
+ CheckIsConvertedToNumber(p1, r->InputAt(1));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(MixedComparison1) {
+ JSTypedLoweringTester R;
+
+ Type* types[] = {Type::Number(), Type::String(),
+ Type::Union(Type::Number(), Type::String(), R.main_zone())};
+
+ for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+ Node* p0 = R.Parameter(types[i], 0);
+
+ for (size_t j = 0; j < ARRAY_SIZE(types); j++) {
+ Node* p1 = R.Parameter(types[j], 1);
+ {
+ Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1);
+ Node* r = R.reduce(cmp);
+
+ if (!types[i]->Maybe(Type::String()) ||
+ !types[j]->Maybe(Type::String())) {
+ if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) {
+ R.CheckPureBinop(R.simplified.StringLessThan(), r);
+ } else {
+ R.CheckPureBinop(R.simplified.NumberLessThan(), r);
+ }
+ } else {
+ CHECK_EQ(cmp, r); // No reduction of mixed types.
+ }
+ }
+ }
+ }
+}
+
+
+TEST(ObjectComparison) {
+ JSTypedLoweringTester R;
+
+ Node* p0 = R.Parameter(Type::Object(), 0);
+ Node* p1 = R.Parameter(Type::Object(), 1);
+
+ Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1);
+ Node* effect_use = R.UseForEffect(cmp);
+
+ R.CheckEffectInput(R.start(), cmp);
+ R.CheckEffectInput(cmp, effect_use);
+
+ Node* r = R.reduce(cmp);
+
+ R.CheckPureBinop(R.simplified.NumberLessThan(), r);
+
+ Node* i0 = r->InputAt(0);
+ Node* i1 = r->InputAt(1);
+
+ CHECK_NE(p0, i0);
+ CHECK_NE(p1, i1);
+ CHECK_EQ(IrOpcode::kJSToNumber, i0->opcode());
+ CHECK_EQ(IrOpcode::kJSToNumber, i1->opcode());
+
+ // Check effect chain is correct.
+ R.CheckEffectInput(R.start(), i0);
+ R.CheckEffectInput(i0, i1);
+ R.CheckEffectInput(i1, effect_use);
+}
+
+
+TEST(UnaryNot) {
+ JSTypedLoweringTester R;
+ Operator* opnot = R.javascript.UnaryNot();
+
+ for (size_t i = 0; i < ARRAY_SIZE(kJSTypes); i++) {
+ Node* r = R.ReduceUnop(opnot, kJSTypes[i]);
+ // TODO(titzer): test will break if/when js-typed-lowering constant folds.
+ CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
+ }
+}
+
+
+TEST(RemoveToNumberEffects) {
+ JSTypedLoweringTester R;
+
+ Node* effect_use = NULL;
+ for (int i = 0; i < 10; i++) {
+ Node* p0 = R.Parameter(Type::Number());
+ Node* ton = R.Unop(R.javascript.ToNumber(), p0);
+ effect_use = NULL;
+
+ switch (i) {
+ case 0:
+ effect_use = R.graph.NewNode(R.javascript.ToNumber(), p0, R.context(),
+ ton, R.start());
+ break;
+ case 1:
+ effect_use = R.graph.NewNode(R.javascript.ToNumber(), ton, R.context(),
+ ton, R.start());
+ break;
+ case 2:
+ effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start());
+ case 3:
+ effect_use = R.graph.NewNode(R.javascript.Add(), ton, ton, R.context(),
+ ton, R.start());
+ break;
+ case 4:
+ effect_use = R.graph.NewNode(R.javascript.Add(), p0, p0, R.context(),
+ ton, R.start());
+ break;
+ case 5:
+ effect_use = R.graph.NewNode(R.common.Return(), p0, ton, R.start());
+ break;
+ case 6:
+ effect_use = R.graph.NewNode(R.common.Return(), ton, ton, R.start());
+ }
+
+ R.CheckEffectInput(R.start(), ton);
+ if (effect_use != NULL) R.CheckEffectInput(ton, effect_use);
+
+ Node* r = R.reduce(ton);
+ CHECK_EQ(p0, r);
+ CHECK_NE(R.start(), r);
+
+ if (effect_use != NULL) {
+ R.CheckEffectInput(R.start(), effect_use);
+ // Check that value uses of ToNumber() do not go to start().
+ for (int i = 0; i < effect_use->op()->InputCount(); i++) {
+ CHECK_NE(R.start(), effect_use->InputAt(i));
+ }
+ }
+ }
+
+ CHECK_EQ(NULL, effect_use); // should have done all cases above.
+}
+
+
+// Helper class for testing the reduction of a single binop.
+class BinopEffectsTester {
+ public:
+ explicit BinopEffectsTester(Operator* op, Type* t0, Type* t1)
+ : R(),
+ p0(R.Parameter(t0, 0)),
+ p1(R.Parameter(t1, 1)),
+ binop(R.Binop(op, p0, p1)),
+ effect_use(R.graph.NewNode(R.common.EffectPhi(1), binop, R.start())) {
+ // Effects should be ordered start -> binop -> effect_use
+ R.CheckEffectInput(R.start(), binop);
+ R.CheckEffectInput(binop, effect_use);
+ result = R.reduce(binop);
+ }
+
+ JSTypedLoweringTester R;
+ Node* p0;
+ Node* p1;
+ Node* binop;
+ Node* effect_use;
+ Node* result;
+
+ void CheckEffectsRemoved() { R.CheckEffectInput(R.start(), effect_use); }
+
+ void CheckEffectOrdering(Node* n0) {
+ R.CheckEffectInput(R.start(), n0);
+ R.CheckEffectInput(n0, effect_use);
+ }
+
+ void CheckEffectOrdering(Node* n0, Node* n1) {
+ R.CheckEffectInput(R.start(), n0);
+ R.CheckEffectInput(n0, n1);
+ R.CheckEffectInput(n1, effect_use);
+ }
+
+ Node* CheckConvertedInput(IrOpcode::Value opcode, int which, bool effects) {
+ return CheckConverted(opcode, result->InputAt(which), effects);
+ }
+
+ Node* CheckConverted(IrOpcode::Value opcode, Node* node, bool effects) {
+ CHECK_EQ(opcode, node->opcode());
+ if (effects) {
+ CHECK_LT(0, OperatorProperties::GetEffectInputCount(node->op()));
+ } else {
+ CHECK_EQ(0, OperatorProperties::GetEffectInputCount(node->op()));
+ }
+ return node;
+ }
+
+ Node* CheckNoOp(int which) {
+ CHECK_EQ(which == 0 ? p0 : p1, result->InputAt(which));
+ return result->InputAt(which);
+ }
+};
+
+
+// Helper function for strict and non-strict equality reductions.
+void CheckEqualityReduction(JSTypedLoweringTester* R, bool strict, Node* l,
+ Node* r, IrOpcode::Value expected) {
+ for (int j = 0; j < 2; j++) {
+ Node* p0 = j == 0 ? l : r;
+ Node* p1 = j == 1 ? l : r;
+
+ {
+ Node* eq = strict ? R->graph.NewNode(R->javascript.StrictEqual(), p0, p1)
+ : R->Binop(R->javascript.Equal(), p0, p1);
+ Node* r = R->reduce(eq);
+ R->CheckPureBinop(expected, r);
+ }
+
+ {
+ Node* ne = strict
+ ? R->graph.NewNode(R->javascript.StrictNotEqual(), p0, p1)
+ : R->Binop(R->javascript.NotEqual(), p0, p1);
+ Node* n = R->reduce(ne);
+ CHECK_EQ(IrOpcode::kBooleanNot, n->opcode());
+ Node* r = n->InputAt(0);
+ R->CheckPureBinop(expected, r);
+ }
+ }
+}
+
+
+TEST(EqualityForNumbers) {
+ JSTypedLoweringTester R;
+
+ Type* simple_number_types[] = {Type::UnsignedSmall(), Type::SignedSmall(),
+ Type::Signed32(), Type::Unsigned32(),
+ Type::Number()};
+
+
+ for (size_t i = 0; i < ARRAY_SIZE(simple_number_types); ++i) {
+ Node* p0 = R.Parameter(simple_number_types[i], 0);
+
+ for (size_t j = 0; j < ARRAY_SIZE(simple_number_types); ++j) {
+ Node* p1 = R.Parameter(simple_number_types[j], 1);
+
+ CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kNumberEqual);
+ CheckEqualityReduction(&R, false, p0, p1, IrOpcode::kNumberEqual);
+ }
+ }
+}
+
+
+TEST(StrictEqualityForRefEqualTypes) {
+ JSTypedLoweringTester R;
+
+ Type* types[] = {Type::Undefined(), Type::Null(), Type::Boolean(),
+ Type::Object(), Type::Receiver()};
+
+ Node* p0 = R.Parameter(Type::Any());
+ for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+ Node* p1 = R.Parameter(types[i]);
+ CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kReferenceEqual);
+ }
+ // TODO(titzer): Equal(RefEqualTypes)
+}
+
+
+TEST(StringEquality) {
+ JSTypedLoweringTester R;
+ Node* p0 = R.Parameter(Type::String());
+ Node* p1 = R.Parameter(Type::String());
+
+ CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kStringEqual);
+ CheckEqualityReduction(&R, false, p0, p1, IrOpcode::kStringEqual);
+}
+
+
+TEST(RemovePureNumberBinopEffects) {
+ JSTypedLoweringTester R;
+
+ Operator* ops[] = {
+ R.javascript.Equal(), R.simplified.NumberEqual(),
+ R.javascript.Add(), R.simplified.NumberAdd(),
+ R.javascript.Subtract(), R.simplified.NumberSubtract(),
+ R.javascript.Multiply(), R.simplified.NumberMultiply(),
+ R.javascript.Divide(), R.simplified.NumberDivide(),
+ R.javascript.Modulus(), R.simplified.NumberModulus(),
+ R.javascript.LessThan(), R.simplified.NumberLessThan(),
+ R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
+ };
+
+ for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
+ BinopEffectsTester B(ops[j], Type::Number(), Type::Number());
+ CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());
+
+ B.R.CheckPureBinop(B.result->opcode(), B.result);
+
+ B.CheckNoOp(0);
+ B.CheckNoOp(1);
+
+ B.CheckEffectsRemoved();
+ }
+}
+
+
+TEST(OrderNumberBinopEffects1) {
+ JSTypedLoweringTester R;
+
+ Operator* ops[] = {
+ R.javascript.Subtract(), R.simplified.NumberSubtract(),
+ R.javascript.Multiply(), R.simplified.NumberMultiply(),
+ R.javascript.Divide(), R.simplified.NumberDivide(),
+ R.javascript.Modulus(), R.simplified.NumberModulus(),
+ };
+
+ for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
+ BinopEffectsTester B(ops[j], Type::Object(), Type::String());
+ CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());
+
+ Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
+ Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true);
+
+ CHECK_EQ(B.p0, i0->InputAt(0));
+ CHECK_EQ(B.p1, i1->InputAt(0));
+
+ // Effects should be ordered start -> i0 -> i1 -> effect_use
+ B.CheckEffectOrdering(i0, i1);
+ }
+}
+
+
+TEST(OrderNumberBinopEffects2) {
+ JSTypedLoweringTester R;
+
+ Operator* ops[] = {
+ R.javascript.Add(), R.simplified.NumberAdd(),
+ R.javascript.Subtract(), R.simplified.NumberSubtract(),
+ R.javascript.Multiply(), R.simplified.NumberMultiply(),
+ R.javascript.Divide(), R.simplified.NumberDivide(),
+ R.javascript.Modulus(), R.simplified.NumberModulus(),
+ };
+
+ for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
+ BinopEffectsTester B(ops[j], Type::Number(), Type::Object());
+
+ Node* i0 = B.CheckNoOp(0);
+ Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true);
+
+ CHECK_EQ(B.p0, i0);
+ CHECK_EQ(B.p1, i1->InputAt(0));
+
+ // Effects should be ordered start -> i1 -> effect_use
+ B.CheckEffectOrdering(i1);
+ }
+
+ for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
+ BinopEffectsTester B(ops[j], Type::Object(), Type::Number());
+
+ Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
+ Node* i1 = B.CheckNoOp(1);
+
+ CHECK_EQ(B.p0, i0->InputAt(0));
+ CHECK_EQ(B.p1, i1);
+
+ // Effects should be ordered start -> i0 -> effect_use
+ B.CheckEffectOrdering(i0);
+ }
+}
+
+
+TEST(OrderCompareEffects) {
+ JSTypedLoweringTester R;
+
+ Operator* ops[] = {
+ R.javascript.GreaterThan(), R.simplified.NumberLessThan(),
+ R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
+ };
+
+ for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
+ BinopEffectsTester B(ops[j], Type::Object(), Type::String());
+ CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());
+
+ Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
+ Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true);
+
+ // Inputs should be commuted.
+ CHECK_EQ(B.p1, i0->InputAt(0));
+ CHECK_EQ(B.p0, i1->InputAt(0));
+
+ // But effects should be ordered start -> i1 -> i0 -> effect_use
+ B.CheckEffectOrdering(i1, i0);
+ }
+
+ for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
+ BinopEffectsTester B(ops[j], Type::Number(), Type::Object());
+
+ Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
+ Node* i1 = B.result->InputAt(1);
+
+ CHECK_EQ(B.p1, i0->InputAt(0)); // Should be commuted.
+ CHECK_EQ(B.p0, i1);
+
+ // Effects should be ordered start -> i1 -> effect_use
+ B.CheckEffectOrdering(i0);
+ }
+
+ for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
+ BinopEffectsTester B(ops[j], Type::Object(), Type::Number());
+
+ Node* i0 = B.result->InputAt(0);
+ Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true);
+
+ CHECK_EQ(B.p1, i0); // Should be commuted.
+ CHECK_EQ(B.p0, i1->InputAt(0));
+
+ // Effects should be ordered start -> i0 -> effect_use
+ B.CheckEffectOrdering(i1);
+ }
+}
+
+
+TEST(Int32BinopEffects) {
+ JSBitwiseTypedLoweringTester R;
+
+ for (int j = 0; j < R.kNumberOps; j += 2) {
+ bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
+ BinopEffectsTester B(R.ops[j], I32Type(signed_left), I32Type(signed_right));
+ CHECK_EQ(R.ops[j + 1]->opcode(), B.result->op()->opcode());
+
+ B.R.CheckPureBinop(B.result->opcode(), B.result);
+
+ B.CheckNoOp(0);
+ B.CheckNoOp(1);
+
+ B.CheckEffectsRemoved();
+ }
+
+ for (int j = 0; j < R.kNumberOps; j += 2) {
+ bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
+ BinopEffectsTester B(R.ops[j], Type::Number(), Type::Number());
+ CHECK_EQ(R.ops[j + 1]->opcode(), B.result->op()->opcode());
+
+ B.R.CheckPureBinop(B.result->opcode(), B.result);
+
+ B.CheckConvertedInput(NumberToI32(signed_left), 0, false);
+ B.CheckConvertedInput(NumberToI32(signed_right), 1, false);
+
+ B.CheckEffectsRemoved();
+ }
+
+ for (int j = 0; j < R.kNumberOps; j += 2) {
+ bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
+ BinopEffectsTester B(R.ops[j], Type::Number(), Type::Object());
+
+ B.R.CheckPureBinop(B.result->opcode(), B.result);
+
+ Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false);
+ Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false);
+
+ CHECK_EQ(B.p0, i0->InputAt(0));
+ Node* ii1 = B.CheckConverted(IrOpcode::kJSToNumber, i1->InputAt(0), true);
+
+ CHECK_EQ(B.p1, ii1->InputAt(0));
+
+ B.CheckEffectOrdering(ii1);
+ }
+
+ for (int j = 0; j < R.kNumberOps; j += 2) {
+ bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
+ BinopEffectsTester B(R.ops[j], Type::Object(), Type::Number());
+
+ B.R.CheckPureBinop(B.result->opcode(), B.result);
+
+ Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false);
+ Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false);
+
+ Node* ii0 = B.CheckConverted(IrOpcode::kJSToNumber, i0->InputAt(0), true);
+ CHECK_EQ(B.p1, i1->InputAt(0));
+
+ CHECK_EQ(B.p0, ii0->InputAt(0));
+
+ B.CheckEffectOrdering(ii0);
+ }
+
+ for (int j = 0; j < R.kNumberOps; j += 2) {
+ bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
+ BinopEffectsTester B(R.ops[j], Type::Object(), Type::Object());
+
+ B.R.CheckPureBinop(B.result->opcode(), B.result);
+
+ Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false);
+ Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false);
+
+ Node* ii0 = B.CheckConverted(IrOpcode::kJSToNumber, i0->InputAt(0), true);
+ Node* ii1 = B.CheckConverted(IrOpcode::kJSToNumber, i1->InputAt(0), true);
+
+ CHECK_EQ(B.p0, ii0->InputAt(0));
+ CHECK_EQ(B.p1, ii1->InputAt(0));
+
+ B.CheckEffectOrdering(ii0, ii1);
+ }
+}
+
+
+TEST(UnaryNotEffects) {
+ JSTypedLoweringTester R;
+ Operator* opnot = R.javascript.UnaryNot();
+
+ for (size_t i = 0; i < ARRAY_SIZE(kJSTypes); i++) {
+ Node* p0 = R.Parameter(kJSTypes[i], 0);
+ Node* orig = R.Unop(opnot, p0);
+ Node* effect_use = R.UseForEffect(orig);
+ Node* value_use = R.graph.NewNode(R.common.Return(), orig);
+ Node* r = R.reduce(orig);
+ // TODO(titzer): test will break if/when js-typed-lowering constant folds.
+ CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
+
+ CHECK_EQ(r, value_use->InputAt(0));
+
+ if (r->InputAt(0) == orig && orig->opcode() == IrOpcode::kJSToBoolean) {
+ // The original node was turned into a ToBoolean, which has an effect.
+ R.CheckEffectInput(R.start(), orig);
+ R.CheckEffectInput(orig, effect_use);
+ } else {
+ // effect should have been removed from this node.
+ R.CheckEffectInput(R.start(), effect_use);
+ }
+ }
+}
+
+
+TEST(Int32AddNarrowing) {
+ {
+ JSBitwiseTypedLoweringTester R;
+
+ for (int o = 0; o < R.kNumberOps; o += 2) {
+ for (size_t i = 0; i < ARRAY_SIZE(kInt32Types); i++) {
+ Node* n0 = R.Parameter(kInt32Types[i]);
+ for (size_t j = 0; j < ARRAY_SIZE(kInt32Types); j++) {
+ Node* n1 = R.Parameter(kInt32Types[j]);
+ Node* one = R.graph.NewNode(R.common.NumberConstant(1));
+
+ for (int l = 0; l < 2; l++) {
+ Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1);
+ Node* or_node =
+ R.Binop(R.ops[o], l ? add_node : one, l ? one : add_node);
+ Node* r = R.reduce(or_node);
+
+ CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode());
+ CHECK_EQ(IrOpcode::kInt32Add, add_node->opcode());
+ bool is_signed = l ? R.signedness[o] : R.signedness[o + 1];
+
+ Type* add_type = NodeProperties::GetBounds(add_node).upper;
+ CHECK(add_type->Is(I32Type(is_signed)));
+ }
+ }
+ }
+ }
+ }
+ {
+ JSBitwiseShiftTypedLoweringTester R;
+
+ for (int o = 0; o < R.kNumberOps; o += 2) {
+ for (size_t i = 0; i < ARRAY_SIZE(kInt32Types); i++) {
+ Node* n0 = R.Parameter(kInt32Types[i]);
+ for (size_t j = 0; j < ARRAY_SIZE(kInt32Types); j++) {
+ Node* n1 = R.Parameter(kInt32Types[j]);
+ Node* one = R.graph.NewNode(R.common.NumberConstant(1));
+
+ for (int l = 0; l < 2; l++) {
+ Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1);
+ Node* or_node =
+ R.Binop(R.ops[o], l ? add_node : one, l ? one : add_node);
+ Node* r = R.reduce(or_node);
+
+ CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode());
+ CHECK_EQ(IrOpcode::kInt32Add, add_node->opcode());
+ bool is_signed = l ? R.signedness[o] : R.signedness[o + 1];
+
+ Type* add_type = NodeProperties::GetBounds(add_node).upper;
+ CHECK(add_type->Is(I32Type(is_signed)));
+ }
+ }
+ }
+ }
+ }
+}
+
+
+TEST(Int32AddNarrowingNotOwned) {
+ JSBitwiseTypedLoweringTester R;
+
+ for (int o = 0; o < R.kNumberOps; o += 2) {
+ Node* n0 = R.Parameter(I32Type(R.signedness[o]));
+ Node* n1 = R.Parameter(I32Type(R.signedness[o + 1]));
+ Node* one = R.graph.NewNode(R.common.NumberConstant(1));
+
+ Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1);
+ Node* or_node = R.Binop(R.ops[o], add_node, one);
+ Node* other_use = R.Binop(R.simplified.NumberAdd(), add_node, one);
+ Node* r = R.reduce(or_node);
+ CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode());
+ // Should not be reduced to Int32Add because of the other number add.
+ CHECK_EQ(IrOpcode::kNumberAdd, add_node->opcode());
+ // Conversion to int32 should be done.
+ CheckToI32(add_node, r->InputAt(0), R.signedness[o]);
+ CheckToI32(one, r->InputAt(1), R.signedness[o + 1]);
+ // The other use should also not be touched.
+ CHECK_EQ(add_node, other_use->InputAt(0));
+ CHECK_EQ(one, other_use->InputAt(1));
+ }
+}
+
+
+TEST(Int32Comparisons) {
+ JSTypedLoweringTester R;
+
+ struct Entry {
+ Operator* js_op;
+ Operator* uint_op;
+ Operator* int_op;
+ Operator* num_op;
+ bool commute;
+ };
+
+ Entry ops[] = {
+ {R.javascript.LessThan(), R.machine.Uint32LessThan(),
+ R.machine.Int32LessThan(), R.simplified.NumberLessThan(), false},
+ {R.javascript.LessThanOrEqual(), R.machine.Uint32LessThanOrEqual(),
+ R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
+ false},
+ {R.javascript.GreaterThan(), R.machine.Uint32LessThan(),
+ R.machine.Int32LessThan(), R.simplified.NumberLessThan(), true},
+ {R.javascript.GreaterThanOrEqual(), R.machine.Uint32LessThanOrEqual(),
+ R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
+ true}};
+
+ for (size_t o = 0; o < ARRAY_SIZE(ops); o++) {
+ for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); i++) {
+ Type* t0 = kNumberTypes[i];
+ Node* p0 = R.Parameter(t0, 0);
+
+ for (size_t j = 0; j < ARRAY_SIZE(kNumberTypes); j++) {
+ Type* t1 = kNumberTypes[j];
+ Node* p1 = R.Parameter(t1, 1);
+
+ Node* cmp = R.Binop(ops[o].js_op, p0, p1);
+ Node* r = R.reduce(cmp);
+
+ Operator* expected;
+ if (t0->Is(Type::Unsigned32()) && t1->Is(Type::Unsigned32())) {
+ expected = ops[o].uint_op;
+ } else if (t0->Is(Type::Signed32()) && t1->Is(Type::Signed32())) {
+ expected = ops[o].int_op;
+ } else {
+ expected = ops[o].num_op;
+ }
+ R.CheckPureBinop(expected, r);
+ if (ops[o].commute) {
+ CHECK_EQ(p1, r->InputAt(0));
+ CHECK_EQ(p0, r->InputAt(1));
+ } else {
+ CHECK_EQ(p0, r->InputAt(0));
+ CHECK_EQ(p1, r->InputAt(1));
+ }
+ }
+ }
+ }
+}
diff --git a/deps/v8/test/cctest/compiler/test-linkage.cc b/deps/v8/test/cctest/compiler/test-linkage.cc
new file mode 100644
index 000000000..6d9453f7c
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-linkage.cc
@@ -0,0 +1,113 @@
+// 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 "src/v8.h"
+
+#include "src/compiler.h"
+#include "src/zone.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/generic-node-inl.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/node.h"
+#include "src/compiler/operator.h"
+#include "src/compiler/pipeline.h"
+#include "src/compiler/schedule.h"
+#include "test/cctest/cctest.h"
+
+#if V8_TURBOFAN_TARGET
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+static SimpleOperator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
+ 0, 0, "dummy");
+
+// So we can get a real JS function.
+static Handle<JSFunction> Compile(const char* source) {
+ Isolate* isolate = CcTest::i_isolate();
+ Handle<String> source_code = isolate->factory()
+ ->NewStringFromUtf8(CStrVector(source))
+ .ToHandleChecked();
+ Handle<SharedFunctionInfo> shared_function = Compiler::CompileScript(
+ source_code, Handle<String>(), 0, 0, false,
+ Handle<Context>(isolate->native_context()), NULL, NULL,
+ v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE);
+ return isolate->factory()->NewFunctionFromSharedFunctionInfo(
+ shared_function, isolate->native_context());
+}
+
+
+TEST(TestLinkageCreate) {
+ InitializedHandleScope handles;
+ Handle<JSFunction> function = Compile("a + b");
+ CompilationInfoWithZone info(function);
+ Linkage linkage(&info);
+}
+
+
+TEST(TestLinkageJSFunctionIncoming) {
+ InitializedHandleScope handles;
+
+ const char* sources[] = {"(function() { })", "(function(a) { })",
+ "(function(a,b) { })", "(function(a,b,c) { })"};
+
+ for (int i = 0; i < 3; i++) {
+ i::HandleScope handles(CcTest::i_isolate());
+ Handle<JSFunction> function = v8::Utils::OpenHandle(
+ *v8::Handle<v8::Function>::Cast(CompileRun(sources[i])));
+ CompilationInfoWithZone info(function);
+ Linkage linkage(&info);
+
+ CallDescriptor* descriptor = linkage.GetIncomingDescriptor();
+ CHECK_NE(NULL, descriptor);
+
+ CHECK_EQ(1 + i, descriptor->ParameterCount());
+ CHECK_EQ(1, descriptor->ReturnCount());
+ CHECK_EQ(Operator::kNoProperties, descriptor->properties());
+ CHECK_EQ(true, descriptor->IsJSFunctionCall());
+ }
+}
+
+
+TEST(TestLinkageCodeStubIncoming) {
+ Isolate* isolate = CcTest::InitIsolateOnce();
+ CompilationInfoWithZone info(static_cast<HydrogenCodeStub*>(NULL), isolate);
+ Linkage linkage(&info);
+ // TODO(titzer): test linkage creation with a bonafide code stub.
+ // this just checks current behavior.
+ CHECK_EQ(NULL, linkage.GetIncomingDescriptor());
+}
+
+
+TEST(TestLinkageJSCall) {
+ HandleAndZoneScope handles;
+ Handle<JSFunction> function = Compile("a + c");
+ CompilationInfoWithZone info(function);
+ Linkage linkage(&info);
+
+ for (int i = 0; i < 32; i++) {
+ CallDescriptor* descriptor = linkage.GetJSCallDescriptor(i);
+ CHECK_NE(NULL, descriptor);
+ CHECK_EQ(i, descriptor->ParameterCount());
+ CHECK_EQ(1, descriptor->ReturnCount());
+ CHECK_EQ(Operator::kNoProperties, descriptor->properties());
+ CHECK_EQ(true, descriptor->IsJSFunctionCall());
+ }
+}
+
+
+TEST(TestLinkageRuntimeCall) {
+ // TODO(titzer): test linkage creation for outgoing runtime calls.
+}
+
+
+TEST(TestLinkageStubCall) {
+ // TODO(titzer): test linkage creation for outgoing stub calls.
+}
+
+
+#endif // V8_TURBOFAN_TARGET
diff --git a/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc b/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc
new file mode 100644
index 000000000..c79a96a09
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc
@@ -0,0 +1,779 @@
+// 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 "test/cctest/cctest.h"
+
+#include "src/base/utils/random-number-generator.h"
+#include "src/compiler/graph-inl.h"
+#include "src/compiler/machine-operator-reducer.h"
+#include "test/cctest/compiler/value-helper.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+template <typename T>
+Operator* NewConstantOperator(CommonOperatorBuilder* common, volatile T value);
+
+template <>
+Operator* NewConstantOperator<int32_t>(CommonOperatorBuilder* common,
+ volatile int32_t value) {
+ return common->Int32Constant(value);
+}
+
+template <>
+Operator* NewConstantOperator<double>(CommonOperatorBuilder* common,
+ volatile double value) {
+ return common->Float64Constant(value);
+}
+
+
+class ReducerTester : public HandleAndZoneScope {
+ public:
+ explicit ReducerTester(int num_parameters = 0)
+ : isolate(main_isolate()),
+ binop(NULL),
+ unop(NULL),
+ machine(main_zone()),
+ common(main_zone()),
+ graph(main_zone()),
+ maxuint32(Constant<int32_t>(kMaxUInt32)) {
+ Node* s = graph.NewNode(common.Start(num_parameters));
+ graph.SetStart(s);
+ }
+
+ Isolate* isolate;
+ Operator* binop;
+ Operator* unop;
+ MachineOperatorBuilder machine;
+ CommonOperatorBuilder common;
+ Graph graph;
+ Node* maxuint32;
+
+ template <typename T>
+ Node* Constant(volatile T value) {
+ return graph.NewNode(NewConstantOperator<T>(&common, value));
+ }
+
+ // Check that the reduction of this binop applied to constants {a} and {b}
+ // yields the {expect} value.
+ template <typename T>
+ void CheckFoldBinop(volatile T expect, volatile T a, volatile T b) {
+ CheckFoldBinop<T>(expect, Constant<T>(a), Constant<T>(b));
+ }
+
+ // Check that the reduction of this binop applied to {a} and {b} yields
+ // the {expect} value.
+ template <typename T>
+ void CheckFoldBinop(volatile T expect, Node* a, Node* b) {
+ CHECK_NE(NULL, binop);
+ Node* n = graph.NewNode(binop, a, b);
+ MachineOperatorReducer reducer(&graph);
+ Reduction reduction = reducer.Reduce(n);
+ CHECK(reduction.Changed());
+ CHECK_NE(n, reduction.replacement());
+ CHECK_EQ(expect, ValueOf<T>(reduction.replacement()->op()));
+ }
+
+ // Check that the reduction of this binop applied to {a} and {b} yields
+ // the {expect} node.
+ void CheckBinop(Node* expect, Node* a, Node* b) {
+ CHECK_NE(NULL, binop);
+ Node* n = graph.NewNode(binop, a, b);
+ MachineOperatorReducer reducer(&graph);
+ Reduction reduction = reducer.Reduce(n);
+ CHECK(reduction.Changed());
+ CHECK_EQ(expect, reduction.replacement());
+ }
+
+ // Check that the reduction of this binop applied to {left} and {right} yields
+ // this binop applied to {left_expect} and {right_expect}.
+ void CheckFoldBinop(Node* left_expect, Node* right_expect, Node* left,
+ Node* right) {
+ CHECK_NE(NULL, binop);
+ Node* n = graph.NewNode(binop, left, right);
+ MachineOperatorReducer reducer(&graph);
+ Reduction reduction = reducer.Reduce(n);
+ CHECK(reduction.Changed());
+ CHECK_EQ(binop, reduction.replacement()->op());
+ CHECK_EQ(left_expect, reduction.replacement()->InputAt(0));
+ CHECK_EQ(right_expect, reduction.replacement()->InputAt(1));
+ }
+
+ // Check that the reduction of this binop applied to {left} and {right} yields
+ // the {op_expect} applied to {left_expect} and {right_expect}.
+ template <typename T>
+ void CheckFoldBinop(volatile T left_expect, Operator* op_expect,
+ Node* right_expect, Node* left, Node* right) {
+ CHECK_NE(NULL, binop);
+ Node* n = graph.NewNode(binop, left, right);
+ MachineOperatorReducer reducer(&graph);
+ Reduction r = reducer.Reduce(n);
+ CHECK(r.Changed());
+ CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode());
+ CHECK_EQ(left_expect, ValueOf<T>(r.replacement()->InputAt(0)->op()));
+ CHECK_EQ(right_expect, r.replacement()->InputAt(1));
+ }
+
+ // Check that the reduction of this binop applied to {left} and {right} yields
+ // the {op_expect} applied to {left_expect} and {right_expect}.
+ template <typename T>
+ void CheckFoldBinop(Node* left_expect, Operator* op_expect,
+ volatile T right_expect, Node* left, Node* right) {
+ CHECK_NE(NULL, binop);
+ Node* n = graph.NewNode(binop, left, right);
+ MachineOperatorReducer reducer(&graph);
+ Reduction r = reducer.Reduce(n);
+ CHECK(r.Changed());
+ CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode());
+ CHECK_EQ(left_expect, r.replacement()->InputAt(0));
+ CHECK_EQ(right_expect, ValueOf<T>(r.replacement()->InputAt(1)->op()));
+ }
+
+ // Check that if the given constant appears on the left, the reducer will
+ // swap it to be on the right.
+ template <typename T>
+ void CheckPutConstantOnRight(volatile T constant) {
+ // TODO(titzer): CHECK(binop->HasProperty(Operator::kCommutative));
+ Node* p = Parameter();
+ Node* k = Constant<T>(constant);
+ {
+ Node* n = graph.NewNode(binop, k, p);
+ MachineOperatorReducer reducer(&graph);
+ Reduction reduction = reducer.Reduce(n);
+ CHECK(!reduction.Changed() || reduction.replacement() == n);
+ CHECK_EQ(p, n->InputAt(0));
+ CHECK_EQ(k, n->InputAt(1));
+ }
+ {
+ Node* n = graph.NewNode(binop, p, k);
+ MachineOperatorReducer reducer(&graph);
+ Reduction reduction = reducer.Reduce(n);
+ CHECK(!reduction.Changed());
+ CHECK_EQ(p, n->InputAt(0));
+ CHECK_EQ(k, n->InputAt(1));
+ }
+ }
+
+ // Check that if the given constant appears on the left, the reducer will
+ // *NOT* swap it to be on the right.
+ template <typename T>
+ void CheckDontPutConstantOnRight(volatile T constant) {
+ CHECK(!binop->HasProperty(Operator::kCommutative));
+ Node* p = Parameter();
+ Node* k = Constant<T>(constant);
+ Node* n = graph.NewNode(binop, k, p);
+ MachineOperatorReducer reducer(&graph);
+ Reduction reduction = reducer.Reduce(n);
+ CHECK(!reduction.Changed());
+ CHECK_EQ(k, n->InputAt(0));
+ CHECK_EQ(p, n->InputAt(1));
+ }
+
+ Node* Parameter(int32_t index = 0) {
+ return graph.NewNode(common.Parameter(index), graph.start());
+ }
+};
+
+
+TEST(ReduceWord32And) {
+ ReducerTester R;
+ R.binop = R.machine.Word32And();
+
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ int32_t x = *pl, y = *pr;
+ R.CheckFoldBinop<int32_t>(x & y, x, y);
+ }
+ }
+
+ R.CheckPutConstantOnRight(33);
+ R.CheckPutConstantOnRight(44000);
+
+ Node* x = R.Parameter();
+ Node* zero = R.Constant<int32_t>(0);
+ Node* minus_1 = R.Constant<int32_t>(-1);
+
+ R.CheckBinop(zero, x, zero); // x & 0 => 0
+ R.CheckBinop(zero, zero, x); // 0 & x => 0
+ R.CheckBinop(x, x, minus_1); // x & -1 => 0
+ R.CheckBinop(x, minus_1, x); // -1 & x => 0
+ R.CheckBinop(x, x, x); // x & x => x
+}
+
+
+TEST(ReduceWord32Or) {
+ ReducerTester R;
+ R.binop = R.machine.Word32Or();
+
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ int32_t x = *pl, y = *pr;
+ R.CheckFoldBinop<int32_t>(x | y, x, y);
+ }
+ }
+
+ R.CheckPutConstantOnRight(36);
+ R.CheckPutConstantOnRight(44001);
+
+ Node* x = R.Parameter();
+ Node* zero = R.Constant<int32_t>(0);
+ Node* minus_1 = R.Constant<int32_t>(-1);
+
+ R.CheckBinop(x, x, zero); // x & 0 => x
+ R.CheckBinop(x, zero, x); // 0 & x => x
+ R.CheckBinop(minus_1, x, minus_1); // x & -1 => -1
+ R.CheckBinop(minus_1, minus_1, x); // -1 & x => -1
+ R.CheckBinop(x, x, x); // x & x => x
+}
+
+
+TEST(ReduceWord32Xor) {
+ ReducerTester R;
+ R.binop = R.machine.Word32Xor();
+
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ int32_t x = *pl, y = *pr;
+ R.CheckFoldBinop<int32_t>(x ^ y, x, y);
+ }
+ }
+
+ R.CheckPutConstantOnRight(39);
+ R.CheckPutConstantOnRight(4403);
+
+ Node* x = R.Parameter();
+ Node* zero = R.Constant<int32_t>(0);
+
+ R.CheckBinop(x, x, zero); // x ^ 0 => x
+ R.CheckBinop(x, zero, x); // 0 ^ x => x
+ R.CheckFoldBinop<int32_t>(0, x, x); // x ^ x => 0
+}
+
+
+TEST(ReduceWord32Shl) {
+ ReducerTester R;
+ R.binop = R.machine.Word32Shl();
+
+ // TODO(titzer): out of range shifts
+ FOR_INT32_INPUTS(i) {
+ for (int y = 0; y < 32; y++) {
+ int32_t x = *i;
+ R.CheckFoldBinop<int32_t>(x << y, x, y);
+ }
+ }
+
+ R.CheckDontPutConstantOnRight(44);
+
+ Node* x = R.Parameter();
+ Node* zero = R.Constant<int32_t>(0);
+
+ R.CheckBinop(x, x, zero); // x << 0 => x
+}
+
+
+TEST(ReduceWord32Shr) {
+ ReducerTester R;
+ R.binop = R.machine.Word32Shr();
+
+ // TODO(titzer): test out of range shifts
+ FOR_UINT32_INPUTS(i) {
+ for (uint32_t y = 0; y < 32; y++) {
+ uint32_t x = *i;
+ R.CheckFoldBinop<int32_t>(x >> y, x, y);
+ }
+ }
+
+ R.CheckDontPutConstantOnRight(44);
+
+ Node* x = R.Parameter();
+ Node* zero = R.Constant<int32_t>(0);
+
+ R.CheckBinop(x, x, zero); // x >>> 0 => x
+}
+
+
+TEST(ReduceWord32Sar) {
+ ReducerTester R;
+ R.binop = R.machine.Word32Sar();
+
+ // TODO(titzer): test out of range shifts
+ FOR_INT32_INPUTS(i) {
+ for (int32_t y = 0; y < 32; y++) {
+ int32_t x = *i;
+ R.CheckFoldBinop<int32_t>(x >> y, x, y);
+ }
+ }
+
+ R.CheckDontPutConstantOnRight(44);
+
+ Node* x = R.Parameter();
+ Node* zero = R.Constant<int32_t>(0);
+
+ R.CheckBinop(x, x, zero); // x >> 0 => x
+}
+
+
+TEST(ReduceWord32Equal) {
+ ReducerTester R;
+ R.binop = R.machine.Word32Equal();
+
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ int32_t x = *pl, y = *pr;
+ R.CheckFoldBinop<int32_t>(x == y ? 1 : 0, x, y);
+ }
+ }
+
+ R.CheckPutConstantOnRight(48);
+ R.CheckPutConstantOnRight(-48);
+
+ Node* x = R.Parameter(0);
+ Node* y = R.Parameter(1);
+ Node* zero = R.Constant<int32_t>(0);
+ Node* sub = R.graph.NewNode(R.machine.Int32Sub(), x, y);
+
+ R.CheckFoldBinop<int32_t>(1, x, x); // x == x => 1
+ R.CheckFoldBinop(x, y, sub, zero); // x - y == 0 => x == y
+ R.CheckFoldBinop(x, y, zero, sub); // 0 == x - y => x == y
+}
+
+
+TEST(ReduceInt32Add) {
+ ReducerTester R;
+ R.binop = R.machine.Int32Add();
+
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ int32_t x = *pl, y = *pr;
+ R.CheckFoldBinop<int32_t>(x + y, x, y); // TODO(titzer): signed overflow
+ }
+ }
+
+ R.CheckPutConstantOnRight(41);
+ R.CheckPutConstantOnRight(4407);
+
+ Node* x = R.Parameter();
+ Node* zero = R.Constant<int32_t>(0);
+
+ R.CheckBinop(x, x, zero); // x + 0 => x
+ R.CheckBinop(x, zero, x); // 0 + x => x
+}
+
+
+TEST(ReduceInt32Sub) {
+ ReducerTester R;
+ R.binop = R.machine.Int32Sub();
+
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ int32_t x = *pl, y = *pr;
+ R.CheckFoldBinop<int32_t>(x - y, x, y);
+ }
+ }
+
+ R.CheckDontPutConstantOnRight(412);
+
+ Node* x = R.Parameter();
+ Node* zero = R.Constant<int32_t>(0);
+
+ R.CheckBinop(x, x, zero); // x - 0 => x
+}
+
+
+TEST(ReduceInt32Mul) {
+ ReducerTester R;
+ R.binop = R.machine.Int32Mul();
+
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ int32_t x = *pl, y = *pr;
+ R.CheckFoldBinop<int32_t>(x * y, x, y); // TODO(titzer): signed overflow
+ }
+ }
+
+ R.CheckPutConstantOnRight(4111);
+ R.CheckPutConstantOnRight(-4407);
+
+ Node* x = R.Parameter();
+ Node* zero = R.Constant<int32_t>(0);
+ Node* one = R.Constant<int32_t>(1);
+ Node* minus_one = R.Constant<int32_t>(-1);
+
+ R.CheckBinop(zero, x, zero); // x * 0 => 0
+ R.CheckBinop(zero, zero, x); // 0 * x => 0
+ R.CheckBinop(x, x, one); // x * 1 => x
+ R.CheckBinop(x, one, x); // 1 * x => x
+ R.CheckFoldBinop<int32_t>(0, R.machine.Int32Sub(), x, minus_one,
+ x); // -1 * x => 0 - x
+ R.CheckFoldBinop<int32_t>(0, R.machine.Int32Sub(), x, x,
+ minus_one); // x * -1 => 0 - x
+
+ for (int32_t n = 1; n < 31; ++n) {
+ Node* multiplier = R.Constant<int32_t>(1 << n);
+ R.CheckFoldBinop<int32_t>(x, R.machine.Word32Shl(), n, x,
+ multiplier); // x * 2^n => x << n
+ R.CheckFoldBinop<int32_t>(x, R.machine.Word32Shl(), n, multiplier,
+ x); // 2^n * x => x << n
+ }
+}
+
+
+TEST(ReduceInt32Div) {
+ ReducerTester R;
+ R.binop = R.machine.Int32Div();
+
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ int32_t x = *pl, y = *pr;
+ if (y == 0) continue; // TODO(titzer): test / 0
+ int32_t r = y == -1 ? -x : x / y; // INT_MIN / -1 may explode in C
+ R.CheckFoldBinop<int32_t>(r, x, y);
+ }
+ }
+
+ R.CheckDontPutConstantOnRight(41111);
+ R.CheckDontPutConstantOnRight(-44071);
+
+ Node* x = R.Parameter();
+ Node* one = R.Constant<int32_t>(1);
+ Node* minus_one = R.Constant<int32_t>(-1);
+
+ R.CheckBinop(x, x, one); // x / 1 => x
+ // TODO(titzer): // 0 / x => 0 if x != 0
+ // TODO(titzer): // x / 2^n => x >> n and round
+ R.CheckFoldBinop<int32_t>(0, R.machine.Int32Sub(), x, x,
+ minus_one); // x / -1 => 0 - x
+}
+
+
+TEST(ReduceInt32UDiv) {
+ ReducerTester R;
+ R.binop = R.machine.Int32UDiv();
+
+ FOR_UINT32_INPUTS(pl) {
+ FOR_UINT32_INPUTS(pr) {
+ uint32_t x = *pl, y = *pr;
+ if (y == 0) continue; // TODO(titzer): test / 0
+ R.CheckFoldBinop<int32_t>(x / y, x, y);
+ }
+ }
+
+ R.CheckDontPutConstantOnRight(41311);
+ R.CheckDontPutConstantOnRight(-44371);
+
+ Node* x = R.Parameter();
+ Node* one = R.Constant<int32_t>(1);
+
+ R.CheckBinop(x, x, one); // x / 1 => x
+ // TODO(titzer): // 0 / x => 0 if x != 0
+
+ for (uint32_t n = 1; n < 32; ++n) {
+ Node* divisor = R.Constant<int32_t>(1u << n);
+ R.CheckFoldBinop<int32_t>(x, R.machine.Word32Shr(), n, x,
+ divisor); // x / 2^n => x >> n
+ }
+}
+
+
+TEST(ReduceInt32Mod) {
+ ReducerTester R;
+ R.binop = R.machine.Int32Mod();
+
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ int32_t x = *pl, y = *pr;
+ if (y == 0) continue; // TODO(titzer): test % 0
+ int32_t r = y == -1 ? 0 : x % y; // INT_MIN % -1 may explode in C
+ R.CheckFoldBinop<int32_t>(r, x, y);
+ }
+ }
+
+ R.CheckDontPutConstantOnRight(413);
+ R.CheckDontPutConstantOnRight(-4401);
+
+ Node* x = R.Parameter();
+ Node* one = R.Constant<int32_t>(1);
+
+ R.CheckFoldBinop<int32_t>(0, x, one); // x % 1 => 0
+ // TODO(titzer): // x % 2^n => x & 2^n-1 and round
+}
+
+
+TEST(ReduceInt32UMod) {
+ ReducerTester R;
+ R.binop = R.machine.Int32UMod();
+
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ uint32_t x = *pl, y = *pr;
+ if (y == 0) continue; // TODO(titzer): test x % 0
+ R.CheckFoldBinop<int32_t>(x % y, x, y);
+ }
+ }
+
+ R.CheckDontPutConstantOnRight(417);
+ R.CheckDontPutConstantOnRight(-4371);
+
+ Node* x = R.Parameter();
+ Node* one = R.Constant<int32_t>(1);
+
+ R.CheckFoldBinop<int32_t>(0, x, one); // x % 1 => 0
+
+ for (uint32_t n = 1; n < 32; ++n) {
+ Node* divisor = R.Constant<int32_t>(1u << n);
+ R.CheckFoldBinop<int32_t>(x, R.machine.Word32And(), (1u << n) - 1, x,
+ divisor); // x % 2^n => x & 2^n-1
+ }
+}
+
+
+TEST(ReduceInt32LessThan) {
+ ReducerTester R;
+ R.binop = R.machine.Int32LessThan();
+
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ int32_t x = *pl, y = *pr;
+ R.CheckFoldBinop<int32_t>(x < y ? 1 : 0, x, y);
+ }
+ }
+
+ R.CheckDontPutConstantOnRight(41399);
+ R.CheckDontPutConstantOnRight(-440197);
+
+ Node* x = R.Parameter(0);
+ Node* y = R.Parameter(1);
+ Node* zero = R.Constant<int32_t>(0);
+ Node* sub = R.graph.NewNode(R.machine.Int32Sub(), x, y);
+
+ R.CheckFoldBinop<int32_t>(0, x, x); // x < x => 0
+ R.CheckFoldBinop(x, y, sub, zero); // x - y < 0 => x < y
+ R.CheckFoldBinop(y, x, zero, sub); // 0 < x - y => y < x
+}
+
+
+TEST(ReduceInt32LessThanOrEqual) {
+ ReducerTester R;
+ R.binop = R.machine.Int32LessThanOrEqual();
+
+ FOR_INT32_INPUTS(pl) {
+ FOR_INT32_INPUTS(pr) {
+ int32_t x = *pl, y = *pr;
+ R.CheckFoldBinop<int32_t>(x <= y ? 1 : 0, x, y);
+ }
+ }
+
+ FOR_INT32_INPUTS(i) { R.CheckDontPutConstantOnRight<int32_t>(*i); }
+
+ Node* x = R.Parameter(0);
+ Node* y = R.Parameter(1);
+ Node* zero = R.Constant<int32_t>(0);
+ Node* sub = R.graph.NewNode(R.machine.Int32Sub(), x, y);
+
+ R.CheckFoldBinop<int32_t>(1, x, x); // x <= x => 1
+ R.CheckFoldBinop(x, y, sub, zero); // x - y <= 0 => x <= y
+ R.CheckFoldBinop(y, x, zero, sub); // 0 <= x - y => y <= x
+}
+
+
+TEST(ReduceUint32LessThan) {
+ ReducerTester R;
+ R.binop = R.machine.Uint32LessThan();
+
+ FOR_UINT32_INPUTS(pl) {
+ FOR_UINT32_INPUTS(pr) {
+ uint32_t x = *pl, y = *pr;
+ R.CheckFoldBinop<int32_t>(x < y ? 1 : 0, x, y);
+ }
+ }
+
+ R.CheckDontPutConstantOnRight(41399);
+ R.CheckDontPutConstantOnRight(-440197);
+
+ Node* x = R.Parameter();
+ Node* max = R.maxuint32;
+ Node* zero = R.Constant<int32_t>(0);
+
+ R.CheckFoldBinop<int32_t>(0, max, x); // M < x => 0
+ R.CheckFoldBinop<int32_t>(0, x, zero); // x < 0 => 0
+ R.CheckFoldBinop<int32_t>(0, x, x); // x < x => 0
+}
+
+
+TEST(ReduceUint32LessThanOrEqual) {
+ ReducerTester R;
+ R.binop = R.machine.Uint32LessThanOrEqual();
+
+ FOR_UINT32_INPUTS(pl) {
+ FOR_UINT32_INPUTS(pr) {
+ uint32_t x = *pl, y = *pr;
+ R.CheckFoldBinop<int32_t>(x <= y ? 1 : 0, x, y);
+ }
+ }
+
+ R.CheckDontPutConstantOnRight(41399);
+ R.CheckDontPutConstantOnRight(-440197);
+
+ Node* x = R.Parameter();
+ Node* max = R.maxuint32;
+ Node* zero = R.Constant<int32_t>(0);
+
+ R.CheckFoldBinop<int32_t>(1, x, max); // x <= M => 1
+ R.CheckFoldBinop<int32_t>(1, zero, x); // 0 <= x => 1
+ R.CheckFoldBinop<int32_t>(1, x, x); // x <= x => 1
+}
+
+
+TEST(ReduceLoadStore) {
+ ReducerTester R;
+
+ Node* base = R.Constant<int32_t>(11);
+ Node* index = R.Constant<int32_t>(4);
+ Node* load = R.graph.NewNode(R.machine.Load(kMachineWord32), base, index);
+
+ {
+ MachineOperatorReducer reducer(&R.graph);
+ Reduction reduction = reducer.Reduce(load);
+ CHECK(!reduction.Changed()); // loads should not be reduced.
+ }
+
+ {
+ Node* store = R.graph.NewNode(
+ R.machine.Store(kMachineWord32, kNoWriteBarrier), base, index, load);
+ MachineOperatorReducer reducer(&R.graph);
+ Reduction reduction = reducer.Reduce(store);
+ CHECK(!reduction.Changed()); // stores should not be reduced.
+ }
+}
+
+
+static void CheckNans(ReducerTester* R) {
+ Node* x = R->Parameter();
+ std::vector<double> nans = ValueHelper::nan_vector();
+ for (std::vector<double>::const_iterator pl = nans.begin(); pl != nans.end();
+ ++pl) {
+ for (std::vector<double>::const_iterator pr = nans.begin();
+ pr != nans.end(); ++pr) {
+ Node* nan1 = R->Constant<double>(*pl);
+ Node* nan2 = R->Constant<double>(*pr);
+ R->CheckBinop(nan1, x, nan1); // x % NaN => NaN
+ R->CheckBinop(nan1, nan1, x); // NaN % x => NaN
+ R->CheckBinop(nan1, nan2, nan1); // NaN % NaN => NaN
+ }
+ }
+}
+
+
+TEST(ReduceFloat64Add) {
+ ReducerTester R;
+ R.binop = R.machine.Float64Add();
+
+ FOR_FLOAT64_INPUTS(pl) {
+ FOR_FLOAT64_INPUTS(pr) {
+ double x = *pl, y = *pr;
+ R.CheckFoldBinop<double>(x + y, x, y);
+ }
+ }
+
+ FOR_FLOAT64_INPUTS(i) { R.CheckPutConstantOnRight(*i); }
+ // TODO(titzer): CheckNans(&R);
+}
+
+
+TEST(ReduceFloat64Sub) {
+ ReducerTester R;
+ R.binop = R.machine.Float64Sub();
+
+ FOR_FLOAT64_INPUTS(pl) {
+ FOR_FLOAT64_INPUTS(pr) {
+ double x = *pl, y = *pr;
+ R.CheckFoldBinop<double>(x - y, x, y);
+ }
+ }
+ // TODO(titzer): CheckNans(&R);
+}
+
+
+TEST(ReduceFloat64Mul) {
+ ReducerTester R;
+ R.binop = R.machine.Float64Mul();
+
+ FOR_FLOAT64_INPUTS(pl) {
+ FOR_FLOAT64_INPUTS(pr) {
+ double x = *pl, y = *pr;
+ R.CheckFoldBinop<double>(x * y, x, y);
+ }
+ }
+
+ double inf = V8_INFINITY;
+ R.CheckPutConstantOnRight(-inf);
+ R.CheckPutConstantOnRight(-0.1);
+ R.CheckPutConstantOnRight(0.1);
+ R.CheckPutConstantOnRight(inf);
+
+ Node* x = R.Parameter();
+ Node* one = R.Constant<double>(1.0);
+
+ R.CheckBinop(x, x, one); // x * 1.0 => x
+ R.CheckBinop(x, one, x); // 1.0 * x => x
+
+ CheckNans(&R);
+}
+
+
+TEST(ReduceFloat64Div) {
+ ReducerTester R;
+ R.binop = R.machine.Float64Div();
+
+ FOR_FLOAT64_INPUTS(pl) {
+ FOR_FLOAT64_INPUTS(pr) {
+ double x = *pl, y = *pr;
+ R.CheckFoldBinop<double>(x / y, x, y);
+ }
+ }
+
+ Node* x = R.Parameter();
+ Node* one = R.Constant<double>(1.0);
+
+ R.CheckBinop(x, x, one); // x / 1.0 => x
+
+ CheckNans(&R);
+}
+
+
+TEST(ReduceFloat64Mod) {
+ ReducerTester R;
+ R.binop = R.machine.Float64Mod();
+
+ FOR_FLOAT64_INPUTS(pl) {
+ FOR_FLOAT64_INPUTS(pr) {
+ double x = *pl, y = *pr;
+ R.CheckFoldBinop<double>(modulo(x, y), x, y);
+ }
+ }
+
+ CheckNans(&R);
+}
+
+
+// TODO(titzer): test MachineOperatorReducer for Word64And
+// TODO(titzer): test MachineOperatorReducer for Word64Or
+// TODO(titzer): test MachineOperatorReducer for Word64Xor
+// TODO(titzer): test MachineOperatorReducer for Word64Shl
+// TODO(titzer): test MachineOperatorReducer for Word64Shr
+// TODO(titzer): test MachineOperatorReducer for Word64Sar
+// TODO(titzer): test MachineOperatorReducer for Word64Equal
+// TODO(titzer): test MachineOperatorReducer for Word64Not
+// TODO(titzer): test MachineOperatorReducer for Int64Add
+// TODO(titzer): test MachineOperatorReducer for Int64Sub
+// TODO(titzer): test MachineOperatorReducer for Int64Mul
+// TODO(titzer): test MachineOperatorReducer for Int64UMul
+// TODO(titzer): test MachineOperatorReducer for Int64Div
+// TODO(titzer): test MachineOperatorReducer for Int64UDiv
+// TODO(titzer): test MachineOperatorReducer for Int64Mod
+// TODO(titzer): test MachineOperatorReducer for Int64UMod
+// TODO(titzer): test MachineOperatorReducer for Int64Neg
+// TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64
+// TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32
+// TODO(titzer): test MachineOperatorReducer for Float64Compare
diff --git a/deps/v8/test/cctest/compiler/test-node-algorithm.cc b/deps/v8/test/cctest/compiler/test-node-algorithm.cc
new file mode 100644
index 000000000..10f98a66a
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-node-algorithm.cc
@@ -0,0 +1,330 @@
+// Copyright 2013 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 <vector>
+
+#include "src/v8.h"
+
+#include "graph-tester.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/generic-node.h"
+#include "src/compiler/generic-node-inl.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/graph-inl.h"
+#include "src/compiler/graph-visualizer.h"
+#include "src/compiler/operator.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+static SimpleOperator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
+ 0, 0, "dummy");
+
+class PreNodeVisitor : public NullNodeVisitor {
+ public:
+ GenericGraphVisit::Control Pre(Node* node) {
+ printf("NODE ID: %d\n", node->id());
+ nodes_.push_back(node);
+ return GenericGraphVisit::CONTINUE;
+ }
+ std::vector<Node*> nodes_;
+};
+
+
+class PostNodeVisitor : public NullNodeVisitor {
+ public:
+ GenericGraphVisit::Control Post(Node* node) {
+ printf("NODE ID: %d\n", node->id());
+ nodes_.push_back(node);
+ return GenericGraphVisit::CONTINUE;
+ }
+ std::vector<Node*> nodes_;
+};
+
+
+TEST(TestUseNodeVisitEmpty) {
+ GraphWithStartNodeTester graph;
+
+ PreNodeVisitor node_visitor;
+ graph.VisitNodeUsesFromStart(&node_visitor);
+
+ CHECK_EQ(1, static_cast<int>(node_visitor.nodes_.size()));
+}
+
+
+TEST(TestUseNodePreOrderVisitSimple) {
+ GraphWithStartNodeTester graph;
+ Node* n2 = graph.NewNode(&dummy_operator, graph.start());
+ Node* n3 = graph.NewNode(&dummy_operator, n2);
+ Node* n4 = graph.NewNode(&dummy_operator, n2, n3);
+ Node* n5 = graph.NewNode(&dummy_operator, n4, n2);
+ graph.SetEnd(n5);
+
+ PreNodeVisitor node_visitor;
+ graph.VisitNodeUsesFromStart(&node_visitor);
+
+ CHECK_EQ(5, static_cast<int>(node_visitor.nodes_.size()));
+ CHECK(graph.start()->id() == node_visitor.nodes_[0]->id());
+ CHECK(n2->id() == node_visitor.nodes_[1]->id());
+ CHECK(n3->id() == node_visitor.nodes_[2]->id());
+ CHECK(n4->id() == node_visitor.nodes_[3]->id());
+ CHECK(n5->id() == node_visitor.nodes_[4]->id());
+}
+
+
+TEST(TestInputNodePreOrderVisitSimple) {
+ GraphWithStartNodeTester graph;
+ Node* n2 = graph.NewNode(&dummy_operator, graph.start());
+ Node* n3 = graph.NewNode(&dummy_operator, n2);
+ Node* n4 = graph.NewNode(&dummy_operator, n2, n3);
+ Node* n5 = graph.NewNode(&dummy_operator, n4, n2);
+ graph.SetEnd(n5);
+
+ PreNodeVisitor node_visitor;
+ graph.VisitNodeInputsFromEnd(&node_visitor);
+ CHECK_EQ(5, static_cast<int>(node_visitor.nodes_.size()));
+ CHECK(n5->id() == node_visitor.nodes_[0]->id());
+ CHECK(n4->id() == node_visitor.nodes_[1]->id());
+ CHECK(n2->id() == node_visitor.nodes_[2]->id());
+ CHECK(graph.start()->id() == node_visitor.nodes_[3]->id());
+ CHECK(n3->id() == node_visitor.nodes_[4]->id());
+}
+
+
+TEST(TestUseNodePostOrderVisitSimple) {
+ GraphWithStartNodeTester graph;
+ Node* n2 = graph.NewNode(&dummy_operator, graph.start());
+ Node* n3 = graph.NewNode(&dummy_operator, graph.start());
+ Node* n4 = graph.NewNode(&dummy_operator, n2);
+ Node* n5 = graph.NewNode(&dummy_operator, n2);
+ Node* n6 = graph.NewNode(&dummy_operator, n2);
+ Node* n7 = graph.NewNode(&dummy_operator, n3);
+ Node* end_dependencies[4] = {n4, n5, n6, n7};
+ Node* n8 = graph.NewNode(&dummy_operator, 4, end_dependencies);
+ graph.SetEnd(n8);
+
+ PostNodeVisitor node_visitor;
+ graph.VisitNodeUsesFromStart(&node_visitor);
+
+ CHECK_EQ(8, static_cast<int>(node_visitor.nodes_.size()));
+ CHECK(graph.end()->id() == node_visitor.nodes_[0]->id());
+ CHECK(n4->id() == node_visitor.nodes_[1]->id());
+ CHECK(n5->id() == node_visitor.nodes_[2]->id());
+ CHECK(n6->id() == node_visitor.nodes_[3]->id());
+ CHECK(n2->id() == node_visitor.nodes_[4]->id());
+ CHECK(n7->id() == node_visitor.nodes_[5]->id());
+ CHECK(n3->id() == node_visitor.nodes_[6]->id());
+ CHECK(graph.start()->id() == node_visitor.nodes_[7]->id());
+}
+
+
+TEST(TestUseNodePostOrderVisitLong) {
+ GraphWithStartNodeTester graph;
+ Node* n2 = graph.NewNode(&dummy_operator, graph.start());
+ Node* n3 = graph.NewNode(&dummy_operator, graph.start());
+ Node* n4 = graph.NewNode(&dummy_operator, n2);
+ Node* n5 = graph.NewNode(&dummy_operator, n2);
+ Node* n6 = graph.NewNode(&dummy_operator, n3);
+ Node* n7 = graph.NewNode(&dummy_operator, n3);
+ Node* n8 = graph.NewNode(&dummy_operator, n5);
+ Node* n9 = graph.NewNode(&dummy_operator, n5);
+ Node* n10 = graph.NewNode(&dummy_operator, n9);
+ Node* n11 = graph.NewNode(&dummy_operator, n9);
+ Node* end_dependencies[6] = {n4, n8, n10, n11, n6, n7};
+ Node* n12 = graph.NewNode(&dummy_operator, 6, end_dependencies);
+ graph.SetEnd(n12);
+
+ PostNodeVisitor node_visitor;
+ graph.VisitNodeUsesFromStart(&node_visitor);
+
+ CHECK_EQ(12, static_cast<int>(node_visitor.nodes_.size()));
+ CHECK(graph.end()->id() == node_visitor.nodes_[0]->id());
+ CHECK(n4->id() == node_visitor.nodes_[1]->id());
+ CHECK(n8->id() == node_visitor.nodes_[2]->id());
+ CHECK(n10->id() == node_visitor.nodes_[3]->id());
+ CHECK(n11->id() == node_visitor.nodes_[4]->id());
+ CHECK(n9->id() == node_visitor.nodes_[5]->id());
+ CHECK(n5->id() == node_visitor.nodes_[6]->id());
+ CHECK(n2->id() == node_visitor.nodes_[7]->id());
+ CHECK(n6->id() == node_visitor.nodes_[8]->id());
+ CHECK(n7->id() == node_visitor.nodes_[9]->id());
+ CHECK(n3->id() == node_visitor.nodes_[10]->id());
+ CHECK(graph.start()->id() == node_visitor.nodes_[11]->id());
+}
+
+
+TEST(TestUseNodePreOrderVisitCycle) {
+ GraphWithStartNodeTester graph;
+ Node* n0 = graph.start_node();
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node* n2 = graph.NewNode(&dummy_operator, n1);
+ n0->AppendInput(graph.main_zone(), n2);
+ graph.SetStart(n0);
+ graph.SetEnd(n2);
+
+ PreNodeVisitor node_visitor;
+ graph.VisitNodeUsesFromStart(&node_visitor);
+
+ CHECK_EQ(3, static_cast<int>(node_visitor.nodes_.size()));
+ CHECK(n0->id() == node_visitor.nodes_[0]->id());
+ CHECK(n1->id() == node_visitor.nodes_[1]->id());
+ CHECK(n2->id() == node_visitor.nodes_[2]->id());
+}
+
+
+struct ReenterNodeVisitor : NullNodeVisitor {
+ GenericGraphVisit::Control Pre(Node* node) {
+ printf("[%d] PRE NODE: %d\n", static_cast<int>(nodes_.size()), node->id());
+ nodes_.push_back(node->id());
+ int size = static_cast<int>(nodes_.size());
+ switch (node->id()) {
+ case 0:
+ return size < 6 ? GenericGraphVisit::REENTER : GenericGraphVisit::SKIP;
+ case 1:
+ return size < 4 ? GenericGraphVisit::DEFER
+ : GenericGraphVisit::CONTINUE;
+ default:
+ return GenericGraphVisit::REENTER;
+ }
+ }
+
+ GenericGraphVisit::Control Post(Node* node) {
+ printf("[%d] POST NODE: %d\n", static_cast<int>(nodes_.size()), node->id());
+ nodes_.push_back(-node->id());
+ return node->id() == 4 ? GenericGraphVisit::REENTER
+ : GenericGraphVisit::CONTINUE;
+ }
+
+ void PreEdge(Node* from, int index, Node* to) {
+ printf("[%d] PRE EDGE: %d-%d\n", static_cast<int>(edges_.size()),
+ from->id(), to->id());
+ edges_.push_back(std::make_pair(from->id(), to->id()));
+ }
+
+ void PostEdge(Node* from, int index, Node* to) {
+ printf("[%d] POST EDGE: %d-%d\n", static_cast<int>(edges_.size()),
+ from->id(), to->id());
+ edges_.push_back(std::make_pair(-from->id(), -to->id()));
+ }
+
+ std::vector<int> nodes_;
+ std::vector<std::pair<int, int> > edges_;
+};
+
+
+TEST(TestUseNodeReenterVisit) {
+ GraphWithStartNodeTester graph;
+ Node* n0 = graph.start_node();
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ Node* n3 = graph.NewNode(&dummy_operator, n2);
+ Node* n4 = graph.NewNode(&dummy_operator, n0);
+ Node* n5 = graph.NewNode(&dummy_operator, n4);
+ n0->AppendInput(graph.main_zone(), n3);
+ graph.SetStart(n0);
+ graph.SetEnd(n5);
+
+ ReenterNodeVisitor visitor;
+ graph.VisitNodeUsesFromStart(&visitor);
+
+ CHECK_EQ(22, static_cast<int>(visitor.nodes_.size()));
+ CHECK_EQ(24, static_cast<int>(visitor.edges_.size()));
+
+ CHECK(n0->id() == visitor.nodes_[0]);
+ CHECK(n0->id() == visitor.edges_[0].first);
+ CHECK(n1->id() == visitor.edges_[0].second);
+ CHECK(n1->id() == visitor.nodes_[1]);
+ // N1 is deferred.
+ CHECK(-n1->id() == visitor.edges_[1].second);
+ CHECK(-n0->id() == visitor.edges_[1].first);
+ CHECK(n0->id() == visitor.edges_[2].first);
+ CHECK(n2->id() == visitor.edges_[2].second);
+ CHECK(n2->id() == visitor.nodes_[2]);
+ CHECK(n2->id() == visitor.edges_[3].first);
+ CHECK(n3->id() == visitor.edges_[3].second);
+ CHECK(n3->id() == visitor.nodes_[3]);
+ // Circle back to N0, which we may reenter for now.
+ CHECK(n3->id() == visitor.edges_[4].first);
+ CHECK(n0->id() == visitor.edges_[4].second);
+ CHECK(n0->id() == visitor.nodes_[4]);
+ CHECK(n0->id() == visitor.edges_[5].first);
+ CHECK(n1->id() == visitor.edges_[5].second);
+ CHECK(n1->id() == visitor.nodes_[5]);
+ // This time N1 is no longer deferred.
+ CHECK(-n1->id() == visitor.nodes_[6]);
+ CHECK(-n1->id() == visitor.edges_[6].second);
+ CHECK(-n0->id() == visitor.edges_[6].first);
+ CHECK(n0->id() == visitor.edges_[7].first);
+ CHECK(n2->id() == visitor.edges_[7].second);
+ CHECK(n2->id() == visitor.nodes_[7]);
+ CHECK(n2->id() == visitor.edges_[8].first);
+ CHECK(n3->id() == visitor.edges_[8].second);
+ CHECK(n3->id() == visitor.nodes_[8]);
+ CHECK(n3->id() == visitor.edges_[9].first);
+ CHECK(n0->id() == visitor.edges_[9].second);
+ CHECK(n0->id() == visitor.nodes_[9]);
+ // This time we break at N0 and skip it.
+ CHECK(-n0->id() == visitor.edges_[10].second);
+ CHECK(-n3->id() == visitor.edges_[10].first);
+ CHECK(-n3->id() == visitor.nodes_[10]);
+ CHECK(-n3->id() == visitor.edges_[11].second);
+ CHECK(-n2->id() == visitor.edges_[11].first);
+ CHECK(-n2->id() == visitor.nodes_[11]);
+ CHECK(-n2->id() == visitor.edges_[12].second);
+ CHECK(-n0->id() == visitor.edges_[12].first);
+ CHECK(n0->id() == visitor.edges_[13].first);
+ CHECK(n4->id() == visitor.edges_[13].second);
+ CHECK(n4->id() == visitor.nodes_[12]);
+ CHECK(n4->id() == visitor.edges_[14].first);
+ CHECK(n5->id() == visitor.edges_[14].second);
+ CHECK(n5->id() == visitor.nodes_[13]);
+ CHECK(-n5->id() == visitor.nodes_[14]);
+ CHECK(-n5->id() == visitor.edges_[15].second);
+ CHECK(-n4->id() == visitor.edges_[15].first);
+ CHECK(-n4->id() == visitor.nodes_[15]);
+ CHECK(-n4->id() == visitor.edges_[16].second);
+ CHECK(-n0->id() == visitor.edges_[16].first);
+ CHECK(-n0->id() == visitor.nodes_[16]);
+ CHECK(-n0->id() == visitor.edges_[17].second);
+ CHECK(-n3->id() == visitor.edges_[17].first);
+ CHECK(-n3->id() == visitor.nodes_[17]);
+ CHECK(-n3->id() == visitor.edges_[18].second);
+ CHECK(-n2->id() == visitor.edges_[18].first);
+ CHECK(-n2->id() == visitor.nodes_[18]);
+ CHECK(-n2->id() == visitor.edges_[19].second);
+ CHECK(-n0->id() == visitor.edges_[19].first);
+ // N4 may be reentered.
+ CHECK(n0->id() == visitor.edges_[20].first);
+ CHECK(n4->id() == visitor.edges_[20].second);
+ CHECK(n4->id() == visitor.nodes_[19]);
+ CHECK(n4->id() == visitor.edges_[21].first);
+ CHECK(n5->id() == visitor.edges_[21].second);
+ CHECK(-n5->id() == visitor.edges_[22].second);
+ CHECK(-n4->id() == visitor.edges_[22].first);
+ CHECK(-n4->id() == visitor.nodes_[20]);
+ CHECK(-n4->id() == visitor.edges_[23].second);
+ CHECK(-n0->id() == visitor.edges_[23].first);
+ CHECK(-n0->id() == visitor.nodes_[21]);
+}
+
+
+TEST(TestPrintNodeGraphToNodeGraphviz) {
+ GraphWithStartNodeTester graph;
+ Node* n2 = graph.NewNode(&dummy_operator, graph.start());
+ Node* n3 = graph.NewNode(&dummy_operator, graph.start());
+ Node* n4 = graph.NewNode(&dummy_operator, n2);
+ Node* n5 = graph.NewNode(&dummy_operator, n2);
+ Node* n6 = graph.NewNode(&dummy_operator, n3);
+ Node* n7 = graph.NewNode(&dummy_operator, n3);
+ Node* n8 = graph.NewNode(&dummy_operator, n5);
+ Node* n9 = graph.NewNode(&dummy_operator, n5);
+ Node* n10 = graph.NewNode(&dummy_operator, n9);
+ Node* n11 = graph.NewNode(&dummy_operator, n9);
+ Node* end_dependencies[6] = {n4, n8, n10, n11, n6, n7};
+ Node* n12 = graph.NewNode(&dummy_operator, 6, end_dependencies);
+ graph.SetEnd(n12);
+
+ OFStream os(stdout);
+ os << AsDOT(graph);
+}
diff --git a/deps/v8/test/cctest/compiler/test-node-cache.cc b/deps/v8/test/cctest/compiler/test-node-cache.cc
new file mode 100644
index 000000000..23909a5f5
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-node-cache.cc
@@ -0,0 +1,160 @@
+// 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 "src/v8.h"
+
+#include "graph-tester.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/node-cache.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+TEST(Int32Constant_back_to_back) {
+ GraphTester graph;
+ Int32NodeCache cache;
+
+ for (int i = -2000000000; i < 2000000000; i += 3315177) {
+ Node** pos = cache.Find(graph.zone(), i);
+ CHECK_NE(NULL, pos);
+ for (int j = 0; j < 3; j++) {
+ Node** npos = cache.Find(graph.zone(), i);
+ CHECK_EQ(pos, npos);
+ }
+ }
+}
+
+
+TEST(Int32Constant_five) {
+ GraphTester graph;
+ Int32NodeCache cache;
+ CommonOperatorBuilder common(graph.zone());
+
+ int32_t constants[] = {static_cast<int32_t>(0x80000000), -77, 0, 1, -1};
+
+ Node* nodes[ARRAY_SIZE(constants)];
+
+ for (size_t i = 0; i < ARRAY_SIZE(constants); i++) {
+ int32_t k = constants[i];
+ Node* node = graph.NewNode(common.Int32Constant(k));
+ *cache.Find(graph.zone(), k) = nodes[i] = node;
+ }
+
+ for (size_t i = 0; i < ARRAY_SIZE(constants); i++) {
+ int32_t k = constants[i];
+ CHECK_EQ(nodes[i], *cache.Find(graph.zone(), k));
+ }
+}
+
+
+TEST(Int32Constant_hits) {
+ GraphTester graph;
+ Int32NodeCache cache;
+ const int32_t kSize = 1500;
+ Node** nodes = graph.zone()->NewArray<Node*>(kSize);
+ CommonOperatorBuilder common(graph.zone());
+
+ for (int i = 0; i < kSize; i++) {
+ int32_t v = i * -55;
+ nodes[i] = graph.NewNode(common.Int32Constant(v));
+ *cache.Find(graph.zone(), v) = nodes[i];
+ }
+
+ int hits = 0;
+ for (int i = 0; i < kSize; i++) {
+ int32_t v = i * -55;
+ Node** pos = cache.Find(graph.zone(), v);
+ if (*pos != NULL) {
+ CHECK_EQ(nodes[i], *pos);
+ hits++;
+ }
+ }
+ CHECK_LT(4, hits);
+}
+
+
+TEST(Int64Constant_back_to_back) {
+ GraphTester graph;
+ Int64NodeCache cache;
+
+ for (int64_t i = -2000000000; i < 2000000000; i += 3315177) {
+ Node** pos = cache.Find(graph.zone(), i);
+ CHECK_NE(NULL, pos);
+ for (int j = 0; j < 3; j++) {
+ Node** npos = cache.Find(graph.zone(), i);
+ CHECK_EQ(pos, npos);
+ }
+ }
+}
+
+
+TEST(Int64Constant_hits) {
+ GraphTester graph;
+ Int64NodeCache cache;
+ const int32_t kSize = 1500;
+ Node** nodes = graph.zone()->NewArray<Node*>(kSize);
+ CommonOperatorBuilder common(graph.zone());
+
+ for (int i = 0; i < kSize; i++) {
+ int64_t v = static_cast<int64_t>(i) * static_cast<int64_t>(5003001);
+ nodes[i] = graph.NewNode(common.Int32Constant(i));
+ *cache.Find(graph.zone(), v) = nodes[i];
+ }
+
+ int hits = 0;
+ for (int i = 0; i < kSize; i++) {
+ int64_t v = static_cast<int64_t>(i) * static_cast<int64_t>(5003001);
+ Node** pos = cache.Find(graph.zone(), v);
+ if (*pos != NULL) {
+ CHECK_EQ(nodes[i], *pos);
+ hits++;
+ }
+ }
+ CHECK_LT(4, hits);
+}
+
+
+TEST(PtrConstant_back_to_back) {
+ GraphTester graph;
+ PtrNodeCache cache;
+ int32_t buffer[50];
+
+ for (int32_t* p = buffer;
+ (p - buffer) < static_cast<ptrdiff_t>(ARRAY_SIZE(buffer)); p++) {
+ Node** pos = cache.Find(graph.zone(), p);
+ CHECK_NE(NULL, pos);
+ for (int j = 0; j < 3; j++) {
+ Node** npos = cache.Find(graph.zone(), p);
+ CHECK_EQ(pos, npos);
+ }
+ }
+}
+
+
+TEST(PtrConstant_hits) {
+ GraphTester graph;
+ PtrNodeCache cache;
+ const int32_t kSize = 50;
+ int32_t buffer[kSize];
+ Node* nodes[kSize];
+ CommonOperatorBuilder common(graph.zone());
+
+ for (size_t i = 0; i < ARRAY_SIZE(buffer); i++) {
+ int k = static_cast<int>(i);
+ int32_t* p = &buffer[i];
+ nodes[i] = graph.NewNode(common.Int32Constant(k));
+ *cache.Find(graph.zone(), p) = nodes[i];
+ }
+
+ int hits = 0;
+ for (size_t i = 0; i < ARRAY_SIZE(buffer); i++) {
+ int32_t* p = &buffer[i];
+ Node** pos = cache.Find(graph.zone(), p);
+ if (*pos != NULL) {
+ CHECK_EQ(nodes[i], *pos);
+ hits++;
+ }
+ }
+ CHECK_LT(4, hits);
+}
diff --git a/deps/v8/test/cctest/compiler/test-node.cc b/deps/v8/test/cctest/compiler/test-node.cc
new file mode 100644
index 000000000..6fe8573a2
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-node.cc
@@ -0,0 +1,815 @@
+// Copyright 2013 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 <functional>
+
+#include "src/v8.h"
+
+#include "graph-tester.h"
+#include "src/compiler/generic-node-inl.h"
+#include "src/compiler/node.h"
+#include "src/compiler/operator.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+static SimpleOperator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
+ 0, 0, "dummy");
+
+TEST(NodeAllocation) {
+ GraphTester graph;
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator);
+ CHECK(n2->id() != n1->id());
+}
+
+
+TEST(NodeWithOpcode) {
+ GraphTester graph;
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator);
+ CHECK(n1->op() == &dummy_operator);
+ CHECK(n2->op() == &dummy_operator);
+}
+
+
+TEST(NodeInputs1) {
+ GraphTester graph;
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ CHECK_EQ(1, n2->InputCount());
+ CHECK(n0 == n2->InputAt(0));
+}
+
+
+TEST(NodeInputs2) {
+ GraphTester graph;
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
+ CHECK_EQ(2, n2->InputCount());
+ CHECK(n0 == n2->InputAt(0));
+ CHECK(n1 == n2->InputAt(1));
+}
+
+
+TEST(NodeInputs3) {
+ GraphTester graph;
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0, n1, n1);
+ CHECK_EQ(3, n2->InputCount());
+ CHECK(n0 == n2->InputAt(0));
+ CHECK(n1 == n2->InputAt(1));
+ CHECK(n1 == n2->InputAt(2));
+}
+
+
+TEST(NodeInputIteratorEmpty) {
+ GraphTester graph;
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node::Inputs::iterator i(n1->inputs().begin());
+ int input_count = 0;
+ for (; i != n1->inputs().end(); ++i) {
+ input_count++;
+ }
+ CHECK_EQ(0, input_count);
+}
+
+
+TEST(NodeInputIteratorOne) {
+ GraphTester graph;
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node::Inputs::iterator i(n1->inputs().begin());
+ CHECK_EQ(1, n1->InputCount());
+ CHECK_EQ(n0, *i);
+ ++i;
+ CHECK(n1->inputs().end() == i);
+}
+
+
+TEST(NodeUseIteratorEmpty) {
+ GraphTester graph;
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node::Uses::iterator i(n1->uses().begin());
+ int use_count = 0;
+ for (; i != n1->uses().end(); ++i) {
+ Node::Edge edge(i.edge());
+ USE(edge);
+ use_count++;
+ }
+ CHECK_EQ(0, use_count);
+}
+
+
+TEST(NodeUseIteratorOne) {
+ GraphTester graph;
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node::Uses::iterator i(n0->uses().begin());
+ CHECK_EQ(n1, *i);
+ ++i;
+ CHECK(n0->uses().end() == i);
+}
+
+
+TEST(NodeUseIteratorReplaceNoUses) {
+ GraphTester graph;
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n3 = graph.NewNode(&dummy_operator);
+ n0->ReplaceUses(n3);
+ CHECK(n0->uses().begin() == n0->uses().end());
+}
+
+
+TEST(NodeUseIteratorReplaceUses) {
+ GraphTester graph;
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ Node* n3 = graph.NewNode(&dummy_operator);
+ Node::Uses::iterator i1(n0->uses().begin());
+ CHECK_EQ(n1, *i1);
+ ++i1;
+ CHECK_EQ(n2, *i1);
+ n0->ReplaceUses(n3);
+ Node::Uses::iterator i2(n3->uses().begin());
+ CHECK_EQ(n1, *i2);
+ ++i2;
+ CHECK_EQ(n2, *i2);
+ Node::Inputs::iterator i3(n1->inputs().begin());
+ CHECK_EQ(n3, *i3);
+ ++i3;
+ CHECK(n1->inputs().end() == i3);
+ Node::Inputs::iterator i4(n2->inputs().begin());
+ CHECK_EQ(n3, *i4);
+ ++i4;
+ CHECK(n2->inputs().end() == i4);
+}
+
+
+TEST(NodeUseIteratorReplaceUsesSelf) {
+ GraphTester graph;
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node* n3 = graph.NewNode(&dummy_operator);
+
+ n1->ReplaceInput(0, n1); // Create self-reference.
+
+ Node::Uses::iterator i1(n1->uses().begin());
+ CHECK_EQ(n1, *i1);
+
+ n1->ReplaceUses(n3);
+
+ CHECK(n1->uses().begin() == n1->uses().end());
+
+ Node::Uses::iterator i2(n3->uses().begin());
+ CHECK_EQ(n1, *i2);
+ ++i2;
+ CHECK(n1->uses().end() == i2);
+}
+
+
+TEST(ReplaceInput) {
+ GraphTester graph;
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator);
+ Node* n3 = graph.NewNode(&dummy_operator, n0, n1, n2);
+ Node::Inputs::iterator i1(n3->inputs().begin());
+ CHECK(n0 == *i1);
+ CHECK_EQ(n0, n3->InputAt(0));
+ ++i1;
+ CHECK_EQ(n1, *i1);
+ CHECK_EQ(n1, n3->InputAt(1));
+ ++i1;
+ CHECK_EQ(n2, *i1);
+ CHECK_EQ(n2, n3->InputAt(2));
+ ++i1;
+ CHECK(i1 == n3->inputs().end());
+
+ Node::Uses::iterator i2(n1->uses().begin());
+ CHECK_EQ(n3, *i2);
+ ++i2;
+ CHECK(i2 == n1->uses().end());
+
+ Node* n4 = graph.NewNode(&dummy_operator);
+ Node::Uses::iterator i3(n4->uses().begin());
+ CHECK(i3 == n4->uses().end());
+
+ n3->ReplaceInput(1, n4);
+
+ Node::Uses::iterator i4(n1->uses().begin());
+ CHECK(i4 == n1->uses().end());
+
+ Node::Uses::iterator i5(n4->uses().begin());
+ CHECK_EQ(n3, *i5);
+ ++i5;
+ CHECK(i5 == n4->uses().end());
+
+ Node::Inputs::iterator i6(n3->inputs().begin());
+ CHECK(n0 == *i6);
+ CHECK_EQ(n0, n3->InputAt(0));
+ ++i6;
+ CHECK_EQ(n4, *i6);
+ CHECK_EQ(n4, n3->InputAt(1));
+ ++i6;
+ CHECK_EQ(n2, *i6);
+ CHECK_EQ(n2, n3->InputAt(2));
+ ++i6;
+ CHECK(i6 == n3->inputs().end());
+}
+
+
+TEST(OwnedBy) {
+ GraphTester graph;
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+
+ CHECK(!n0->OwnedBy(n1));
+ CHECK(!n1->OwnedBy(n0));
+
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ CHECK(n0->OwnedBy(n2));
+ CHECK(!n2->OwnedBy(n0));
+
+ Node* n3 = graph.NewNode(&dummy_operator, n0);
+ CHECK(!n0->OwnedBy(n2));
+ CHECK(!n0->OwnedBy(n3));
+ CHECK(!n2->OwnedBy(n0));
+ CHECK(!n3->OwnedBy(n0));
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ CHECK(n0->OwnedBy(n1));
+ CHECK(!n1->OwnedBy(n0));
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ CHECK(!n0->OwnedBy(n1));
+ CHECK(!n0->OwnedBy(n2));
+ CHECK(!n1->OwnedBy(n0));
+ CHECK(!n1->OwnedBy(n2));
+ CHECK(!n2->OwnedBy(n0));
+ CHECK(!n2->OwnedBy(n1));
+
+ Node* n3 = graph.NewNode(&dummy_operator);
+ n2->ReplaceInput(0, n3);
+
+ CHECK(n0->OwnedBy(n1));
+ CHECK(!n1->OwnedBy(n0));
+ CHECK(!n1->OwnedBy(n0));
+ CHECK(!n1->OwnedBy(n2));
+ CHECK(!n2->OwnedBy(n0));
+ CHECK(!n2->OwnedBy(n1));
+ CHECK(n3->OwnedBy(n2));
+ CHECK(!n2->OwnedBy(n3));
+ }
+}
+
+
+TEST(Uses) {
+ GraphTester graph;
+
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ CHECK_EQ(1, n0->UseCount());
+ printf("A: %d vs %d\n", n0->UseAt(0)->id(), n1->id());
+ CHECK(n0->UseAt(0) == n1);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ CHECK_EQ(2, n0->UseCount());
+ printf("B: %d vs %d\n", n0->UseAt(1)->id(), n2->id());
+ CHECK(n0->UseAt(1) == n2);
+ Node* n3 = graph.NewNode(&dummy_operator, n0);
+ CHECK_EQ(3, n0->UseCount());
+ CHECK(n0->UseAt(2) == n3);
+}
+
+
+TEST(Inputs) {
+ GraphTester graph;
+
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ Node* n3 = graph.NewNode(&dummy_operator, n0, n1, n2);
+ CHECK_EQ(3, n3->InputCount());
+ CHECK(n3->InputAt(0) == n0);
+ CHECK(n3->InputAt(1) == n1);
+ CHECK(n3->InputAt(2) == n2);
+ Node* n4 = graph.NewNode(&dummy_operator, n0, n1, n2);
+ n3->AppendInput(graph.zone(), n4);
+ CHECK_EQ(4, n3->InputCount());
+ CHECK(n3->InputAt(0) == n0);
+ CHECK(n3->InputAt(1) == n1);
+ CHECK(n3->InputAt(2) == n2);
+ CHECK(n3->InputAt(3) == n4);
+ Node* n5 = graph.NewNode(&dummy_operator, n4);
+ n3->AppendInput(graph.zone(), n4);
+ CHECK_EQ(5, n3->InputCount());
+ CHECK(n3->InputAt(0) == n0);
+ CHECK(n3->InputAt(1) == n1);
+ CHECK(n3->InputAt(2) == n2);
+ CHECK(n3->InputAt(3) == n4);
+ CHECK(n3->InputAt(4) == n4);
+
+ // Make sure uses have been hooked op correctly.
+ Node::Uses uses(n4->uses());
+ Node::Uses::iterator current = uses.begin();
+ CHECK(current != uses.end());
+ CHECK(*current == n3);
+ ++current;
+ CHECK(current != uses.end());
+ CHECK(*current == n5);
+ ++current;
+ CHECK(current != uses.end());
+ CHECK(*current == n3);
+ ++current;
+ CHECK(current == uses.end());
+}
+
+
+TEST(AppendInputsAndIterator) {
+ GraphTester graph;
+
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
+
+ Node::Inputs inputs(n2->inputs());
+ Node::Inputs::iterator current = inputs.begin();
+ CHECK(current != inputs.end());
+ CHECK(*current == n0);
+ ++current;
+ CHECK(current != inputs.end());
+ CHECK(*current == n1);
+ ++current;
+ CHECK(current == inputs.end());
+
+ Node* n3 = graph.NewNode(&dummy_operator);
+ n2->AppendInput(graph.zone(), n3);
+ inputs = n2->inputs();
+ current = inputs.begin();
+ CHECK(current != inputs.end());
+ CHECK(*current == n0);
+ CHECK_EQ(0, current.index());
+ ++current;
+ CHECK(current != inputs.end());
+ CHECK(*current == n1);
+ CHECK_EQ(1, current.index());
+ ++current;
+ CHECK(current != inputs.end());
+ CHECK(*current == n3);
+ CHECK_EQ(2, current.index());
+ ++current;
+ CHECK(current == inputs.end());
+}
+
+
+TEST(NullInputsSimple) {
+ GraphTester graph;
+
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
+ CHECK_EQ(2, n2->InputCount());
+
+ CHECK(n0 == n2->InputAt(0));
+ CHECK(n1 == n2->InputAt(1));
+ CHECK_EQ(2, n0->UseCount());
+ n2->ReplaceInput(0, NULL);
+ CHECK(NULL == n2->InputAt(0));
+ CHECK(n1 == n2->InputAt(1));
+ CHECK_EQ(1, n0->UseCount());
+}
+
+
+TEST(NullInputsAppended) {
+ GraphTester graph;
+
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ Node* n3 = graph.NewNode(&dummy_operator, n0);
+ n3->AppendInput(graph.zone(), n1);
+ n3->AppendInput(graph.zone(), n2);
+ CHECK_EQ(3, n3->InputCount());
+
+ CHECK(n0 == n3->InputAt(0));
+ CHECK(n1 == n3->InputAt(1));
+ CHECK(n2 == n3->InputAt(2));
+ CHECK_EQ(1, n1->UseCount());
+ n3->ReplaceInput(1, NULL);
+ CHECK(n0 == n3->InputAt(0));
+ CHECK(NULL == n3->InputAt(1));
+ CHECK(n2 == n3->InputAt(2));
+ CHECK_EQ(0, n1->UseCount());
+}
+
+
+TEST(ReplaceUsesFromAppendedInputs) {
+ GraphTester graph;
+
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ Node* n3 = graph.NewNode(&dummy_operator);
+ n2->AppendInput(graph.zone(), n1);
+ n2->AppendInput(graph.zone(), n0);
+ CHECK_EQ(0, n3->UseCount());
+ CHECK_EQ(3, n0->UseCount());
+ n0->ReplaceUses(n3);
+ CHECK_EQ(0, n0->UseCount());
+ CHECK_EQ(3, n3->UseCount());
+
+ Node::Uses uses(n3->uses());
+ Node::Uses::iterator current = uses.begin();
+ CHECK(current != uses.end());
+ CHECK(*current == n1);
+ ++current;
+ CHECK(current != uses.end());
+ CHECK(*current == n2);
+ ++current;
+ CHECK(current != uses.end());
+ CHECK(*current == n2);
+ ++current;
+ CHECK(current == uses.end());
+}
+
+
+template <bool result>
+struct FixedPredicate {
+ bool operator()(const Node* node) const { return result; }
+};
+
+
+TEST(ReplaceUsesIfWithFixedPredicate) {
+ GraphTester graph;
+
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ Node* n3 = graph.NewNode(&dummy_operator);
+
+ CHECK_EQ(0, n2->UseCount());
+ n2->ReplaceUsesIf(FixedPredicate<true>(), n1);
+ CHECK_EQ(0, n2->UseCount());
+ n2->ReplaceUsesIf(FixedPredicate<false>(), n1);
+ CHECK_EQ(0, n2->UseCount());
+
+ CHECK_EQ(0, n3->UseCount());
+ n3->ReplaceUsesIf(FixedPredicate<true>(), n1);
+ CHECK_EQ(0, n3->UseCount());
+ n3->ReplaceUsesIf(FixedPredicate<false>(), n1);
+ CHECK_EQ(0, n3->UseCount());
+
+ CHECK_EQ(2, n0->UseCount());
+ CHECK_EQ(0, n1->UseCount());
+ n0->ReplaceUsesIf(FixedPredicate<false>(), n1);
+ CHECK_EQ(2, n0->UseCount());
+ CHECK_EQ(0, n1->UseCount());
+ n0->ReplaceUsesIf(FixedPredicate<true>(), n1);
+ CHECK_EQ(0, n0->UseCount());
+ CHECK_EQ(2, n1->UseCount());
+
+ n1->AppendInput(graph.zone(), n1);
+ CHECK_EQ(3, n1->UseCount());
+ n1->AppendInput(graph.zone(), n3);
+ CHECK_EQ(1, n3->UseCount());
+ n3->ReplaceUsesIf(FixedPredicate<true>(), n1);
+ CHECK_EQ(4, n1->UseCount());
+ CHECK_EQ(0, n3->UseCount());
+ n1->ReplaceUsesIf(FixedPredicate<false>(), n3);
+ CHECK_EQ(4, n1->UseCount());
+ CHECK_EQ(0, n3->UseCount());
+}
+
+
+TEST(ReplaceUsesIfWithEqualTo) {
+ GraphTester graph;
+
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
+
+ CHECK_EQ(0, n2->UseCount());
+ n2->ReplaceUsesIf(std::bind1st(std::equal_to<Node*>(), n1), n0);
+ CHECK_EQ(0, n2->UseCount());
+
+ CHECK_EQ(2, n0->UseCount());
+ CHECK_EQ(1, n1->UseCount());
+ n1->ReplaceUsesIf(std::bind1st(std::equal_to<Node*>(), n0), n0);
+ CHECK_EQ(2, n0->UseCount());
+ CHECK_EQ(1, n1->UseCount());
+ n0->ReplaceUsesIf(std::bind2nd(std::equal_to<Node*>(), n2), n1);
+ CHECK_EQ(1, n0->UseCount());
+ CHECK_EQ(2, n1->UseCount());
+}
+
+
+TEST(ReplaceInputMultipleUses) {
+ GraphTester graph;
+
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ n2->ReplaceInput(0, n1);
+ CHECK_EQ(0, n0->UseCount());
+ CHECK_EQ(1, n1->UseCount());
+
+ Node* n3 = graph.NewNode(&dummy_operator, n0);
+ n3->ReplaceInput(0, n1);
+ CHECK_EQ(0, n0->UseCount());
+ CHECK_EQ(2, n1->UseCount());
+}
+
+
+TEST(TrimInputCountInline) {
+ GraphTester graph;
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ n1->TrimInputCount(1);
+ CHECK_EQ(1, n1->InputCount());
+ CHECK_EQ(n0, n1->InputAt(0));
+ CHECK_EQ(1, n0->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ n1->TrimInputCount(0);
+ CHECK_EQ(0, n1->InputCount());
+ CHECK_EQ(0, n0->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
+ n2->TrimInputCount(2);
+ CHECK_EQ(2, n2->InputCount());
+ CHECK_EQ(1, n0->UseCount());
+ CHECK_EQ(1, n1->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
+ n2->TrimInputCount(1);
+ CHECK_EQ(1, n2->InputCount());
+ CHECK_EQ(1, n0->UseCount());
+ CHECK_EQ(0, n1->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
+ n2->TrimInputCount(0);
+ CHECK_EQ(0, n2->InputCount());
+ CHECK_EQ(0, n0->UseCount());
+ CHECK_EQ(0, n1->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0, n0);
+ n2->TrimInputCount(1);
+ CHECK_EQ(1, n2->InputCount());
+ CHECK_EQ(1, n0->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0, n0);
+ n2->TrimInputCount(0);
+ CHECK_EQ(0, n2->InputCount());
+ CHECK_EQ(0, n0->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+}
+
+
+TEST(TrimInputCountOutOfLine1) {
+ GraphTester graph;
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ n1->AppendInput(graph.zone(), n0);
+ n1->TrimInputCount(1);
+ CHECK_EQ(1, n1->InputCount());
+ CHECK_EQ(n0, n1->InputAt(0));
+ CHECK_EQ(1, n0->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ n1->AppendInput(graph.zone(), n0);
+ CHECK_EQ(1, n1->InputCount());
+ n1->TrimInputCount(0);
+ CHECK_EQ(0, n1->InputCount());
+ CHECK_EQ(0, n0->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator);
+ n2->AppendInput(graph.zone(), n0);
+ n2->AppendInput(graph.zone(), n1);
+ CHECK_EQ(2, n2->InputCount());
+ n2->TrimInputCount(2);
+ CHECK_EQ(2, n2->InputCount());
+ CHECK_EQ(n0, n2->InputAt(0));
+ CHECK_EQ(n1, n2->InputAt(1));
+ CHECK_EQ(1, n0->UseCount());
+ CHECK_EQ(1, n1->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator);
+ n2->AppendInput(graph.zone(), n0);
+ n2->AppendInput(graph.zone(), n1);
+ CHECK_EQ(2, n2->InputCount());
+ n2->TrimInputCount(1);
+ CHECK_EQ(1, n2->InputCount());
+ CHECK_EQ(n0, n2->InputAt(0));
+ CHECK_EQ(1, n0->UseCount());
+ CHECK_EQ(0, n1->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator);
+ n2->AppendInput(graph.zone(), n0);
+ n2->AppendInput(graph.zone(), n1);
+ CHECK_EQ(2, n2->InputCount());
+ n2->TrimInputCount(0);
+ CHECK_EQ(0, n2->InputCount());
+ CHECK_EQ(0, n0->UseCount());
+ CHECK_EQ(0, n1->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator);
+ n2->AppendInput(graph.zone(), n0);
+ n2->AppendInput(graph.zone(), n0);
+ CHECK_EQ(2, n2->InputCount());
+ CHECK_EQ(2, n0->UseCount());
+ n2->TrimInputCount(1);
+ CHECK_EQ(1, n2->InputCount());
+ CHECK_EQ(1, n0->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator);
+ n2->AppendInput(graph.zone(), n0);
+ n2->AppendInput(graph.zone(), n0);
+ CHECK_EQ(2, n2->InputCount());
+ CHECK_EQ(2, n0->UseCount());
+ n2->TrimInputCount(0);
+ CHECK_EQ(0, n2->InputCount());
+ CHECK_EQ(0, n0->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+}
+
+
+TEST(TrimInputCountOutOfLine2) {
+ GraphTester graph;
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ n2->AppendInput(graph.zone(), n1);
+ CHECK_EQ(2, n2->InputCount());
+ n2->TrimInputCount(2);
+ CHECK_EQ(2, n2->InputCount());
+ CHECK_EQ(n0, n2->InputAt(0));
+ CHECK_EQ(n1, n2->InputAt(1));
+ CHECK_EQ(1, n0->UseCount());
+ CHECK_EQ(1, n1->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ n2->AppendInput(graph.zone(), n1);
+ CHECK_EQ(2, n2->InputCount());
+ n2->TrimInputCount(1);
+ CHECK_EQ(1, n2->InputCount());
+ CHECK_EQ(n0, n2->InputAt(0));
+ CHECK_EQ(1, n0->UseCount());
+ CHECK_EQ(0, n1->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ n2->AppendInput(graph.zone(), n1);
+ CHECK_EQ(2, n2->InputCount());
+ n2->TrimInputCount(0);
+ CHECK_EQ(0, n2->InputCount());
+ CHECK_EQ(0, n0->UseCount());
+ CHECK_EQ(0, n1->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ n2->AppendInput(graph.zone(), n0);
+ CHECK_EQ(2, n2->InputCount());
+ CHECK_EQ(2, n0->UseCount());
+ n2->TrimInputCount(1);
+ CHECK_EQ(1, n2->InputCount());
+ CHECK_EQ(1, n0->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n2 = graph.NewNode(&dummy_operator, n0);
+ n2->AppendInput(graph.zone(), n0);
+ CHECK_EQ(2, n2->InputCount());
+ CHECK_EQ(2, n0->UseCount());
+ n2->TrimInputCount(0);
+ CHECK_EQ(0, n2->InputCount());
+ CHECK_EQ(0, n0->UseCount());
+ CHECK_EQ(0, n2->UseCount());
+ }
+}
+
+
+TEST(RemoveAllInputs) {
+ GraphTester graph;
+
+ for (int i = 0; i < 2; i++) {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node* n2;
+ if (i == 0) {
+ n2 = graph.NewNode(&dummy_operator, n0, n1);
+ } else {
+ n2 = graph.NewNode(&dummy_operator, n0);
+ n2->AppendInput(graph.zone(), n1); // with out-of-line input.
+ }
+
+ n0->RemoveAllInputs();
+ CHECK_EQ(0, n0->InputCount());
+
+ CHECK_EQ(2, n0->UseCount());
+ n1->RemoveAllInputs();
+ CHECK_EQ(1, n1->InputCount());
+ CHECK_EQ(1, n0->UseCount());
+ CHECK_EQ(NULL, n1->InputAt(0));
+
+ CHECK_EQ(1, n1->UseCount());
+ n2->RemoveAllInputs();
+ CHECK_EQ(2, n2->InputCount());
+ CHECK_EQ(0, n0->UseCount());
+ CHECK_EQ(0, n1->UseCount());
+ CHECK_EQ(NULL, n2->InputAt(0));
+ CHECK_EQ(NULL, n2->InputAt(1));
+ }
+
+ {
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ n1->ReplaceInput(0, n1); // self-reference.
+
+ CHECK_EQ(0, n0->UseCount());
+ CHECK_EQ(1, n1->UseCount());
+ n1->RemoveAllInputs();
+ CHECK_EQ(1, n1->InputCount());
+ CHECK_EQ(0, n1->UseCount());
+ CHECK_EQ(NULL, n1->InputAt(0));
+ }
+}
diff --git a/deps/v8/test/cctest/compiler/test-operator.cc b/deps/v8/test/cctest/compiler/test-operator.cc
new file mode 100644
index 000000000..0bf8cb755
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-operator.cc
@@ -0,0 +1,244 @@
+// Copyright 2013 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 "src/v8.h"
+
+#include "src/compiler/operator.h"
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+#define NaN (v8::base::OS::nan_value())
+#define Infinity (std::numeric_limits<double>::infinity())
+
+TEST(TestOperatorMnemonic) {
+ SimpleOperator op1(10, 0, 0, 0, "ThisOne");
+ CHECK_EQ(0, strcmp(op1.mnemonic(), "ThisOne"));
+
+ SimpleOperator op2(11, 0, 0, 0, "ThatOne");
+ CHECK_EQ(0, strcmp(op2.mnemonic(), "ThatOne"));
+
+ Operator1<int> op3(12, 0, 0, 1, "Mnemonic1", 12333);
+ CHECK_EQ(0, strcmp(op3.mnemonic(), "Mnemonic1"));
+
+ Operator1<double> op4(13, 0, 0, 1, "TheOther", 99.9);
+ CHECK_EQ(0, strcmp(op4.mnemonic(), "TheOther"));
+}
+
+
+TEST(TestSimpleOperatorHash) {
+ SimpleOperator op1(17, 0, 0, 0, "Another");
+ CHECK_EQ(17, op1.HashCode());
+
+ SimpleOperator op2(18, 0, 0, 0, "Falsch");
+ CHECK_EQ(18, op2.HashCode());
+}
+
+
+TEST(TestSimpleOperatorEquals) {
+ SimpleOperator op1a(19, 0, 0, 0, "Another1");
+ SimpleOperator op1b(19, 2, 2, 2, "Another2");
+
+ CHECK(op1a.Equals(&op1a));
+ CHECK(op1a.Equals(&op1b));
+ CHECK(op1b.Equals(&op1a));
+ CHECK(op1b.Equals(&op1b));
+
+ SimpleOperator op2a(20, 0, 0, 0, "Falsch1");
+ SimpleOperator op2b(20, 1, 1, 1, "Falsch2");
+
+ CHECK(op2a.Equals(&op2a));
+ CHECK(op2a.Equals(&op2b));
+ CHECK(op2b.Equals(&op2a));
+ CHECK(op2b.Equals(&op2b));
+
+ CHECK(!op1a.Equals(&op2a));
+ CHECK(!op1a.Equals(&op2b));
+ CHECK(!op1b.Equals(&op2a));
+ CHECK(!op1b.Equals(&op2b));
+
+ CHECK(!op2a.Equals(&op1a));
+ CHECK(!op2a.Equals(&op1b));
+ CHECK(!op2b.Equals(&op1a));
+ CHECK(!op2b.Equals(&op1b));
+}
+
+
+static SmartArrayPointer<const char> OperatorToString(Operator* op) {
+ OStringStream os;
+ os << *op;
+ return SmartArrayPointer<const char>(StrDup(os.c_str()));
+}
+
+
+TEST(TestSimpleOperatorPrint) {
+ SimpleOperator op1a(19, 0, 0, 0, "Another1");
+ SimpleOperator op1b(19, 2, 2, 2, "Another2");
+
+ CHECK_EQ("Another1", OperatorToString(&op1a).get());
+ CHECK_EQ("Another2", OperatorToString(&op1b).get());
+
+ SimpleOperator op2a(20, 0, 0, 0, "Flog1");
+ SimpleOperator op2b(20, 1, 1, 1, "Flog2");
+
+ CHECK_EQ("Flog1", OperatorToString(&op2a).get());
+ CHECK_EQ("Flog2", OperatorToString(&op2b).get());
+}
+
+
+TEST(TestOperator1intHash) {
+ Operator1<int> op1a(23, 0, 0, 0, "Wolfie", 11);
+ Operator1<int> op1b(23, 2, 2, 2, "Doggie", 11);
+
+ CHECK_EQ(op1a.HashCode(), op1b.HashCode());
+
+ Operator1<int> op2a(24, 0, 0, 0, "Arfie", 3);
+ Operator1<int> op2b(24, 0, 0, 0, "Arfie", 4);
+
+ CHECK_NE(op1a.HashCode(), op2a.HashCode());
+ CHECK_NE(op2a.HashCode(), op2b.HashCode());
+}
+
+
+TEST(TestOperator1intEquals) {
+ Operator1<int> op1a(23, 0, 0, 0, "Scratchy", 11);
+ Operator1<int> op1b(23, 2, 2, 2, "Scratchy", 11);
+
+ CHECK(op1a.Equals(&op1a));
+ CHECK(op1a.Equals(&op1b));
+ CHECK(op1b.Equals(&op1a));
+ CHECK(op1b.Equals(&op1b));
+
+ Operator1<int> op2a(24, 0, 0, 0, "Im", 3);
+ Operator1<int> op2b(24, 0, 0, 0, "Im", 4);
+
+ CHECK(op2a.Equals(&op2a));
+ CHECK(!op2a.Equals(&op2b));
+ CHECK(!op2b.Equals(&op2a));
+ CHECK(op2b.Equals(&op2b));
+
+ CHECK(!op1a.Equals(&op2a));
+ CHECK(!op1a.Equals(&op2b));
+ CHECK(!op1b.Equals(&op2a));
+ CHECK(!op1b.Equals(&op2b));
+
+ CHECK(!op2a.Equals(&op1a));
+ CHECK(!op2a.Equals(&op1b));
+ CHECK(!op2b.Equals(&op1a));
+ CHECK(!op2b.Equals(&op1b));
+
+ SimpleOperator op3(25, 0, 0, 0, "Weepy");
+
+ CHECK(!op1a.Equals(&op3));
+ CHECK(!op1b.Equals(&op3));
+ CHECK(!op2a.Equals(&op3));
+ CHECK(!op2b.Equals(&op3));
+
+ CHECK(!op3.Equals(&op1a));
+ CHECK(!op3.Equals(&op1b));
+ CHECK(!op3.Equals(&op2a));
+ CHECK(!op3.Equals(&op2b));
+}
+
+
+TEST(TestOperator1intPrint) {
+ Operator1<int> op1(12, 0, 0, 1, "Op1Test", 0);
+ CHECK_EQ("Op1Test[0]", OperatorToString(&op1).get());
+
+ Operator1<int> op2(12, 0, 0, 1, "Op1Test", 66666666);
+ CHECK_EQ("Op1Test[66666666]", OperatorToString(&op2).get());
+
+ Operator1<int> op3(12, 0, 0, 1, "FooBar", 2347);
+ CHECK_EQ("FooBar[2347]", OperatorToString(&op3).get());
+
+ Operator1<int> op4(12, 0, 0, 1, "BarFoo", -879);
+ CHECK_EQ("BarFoo[-879]", OperatorToString(&op4).get());
+}
+
+
+TEST(TestOperator1doubleHash) {
+ Operator1<double> op1a(23, 0, 0, 0, "Wolfie", 11.77);
+ Operator1<double> op1b(23, 2, 2, 2, "Doggie", 11.77);
+
+ CHECK_EQ(op1a.HashCode(), op1b.HashCode());
+
+ Operator1<double> op2a(24, 0, 0, 0, "Arfie", -6.7);
+ Operator1<double> op2b(24, 0, 0, 0, "Arfie", -6.8);
+
+ CHECK_NE(op1a.HashCode(), op2a.HashCode());
+ CHECK_NE(op2a.HashCode(), op2b.HashCode());
+}
+
+
+TEST(TestOperator1doubleEquals) {
+ Operator1<double> op1a(23, 0, 0, 0, "Scratchy", 11.77);
+ Operator1<double> op1b(23, 2, 2, 2, "Scratchy", 11.77);
+
+ CHECK(op1a.Equals(&op1a));
+ CHECK(op1a.Equals(&op1b));
+ CHECK(op1b.Equals(&op1a));
+ CHECK(op1b.Equals(&op1b));
+
+ Operator1<double> op2a(24, 0, 0, 0, "Im", 3.1);
+ Operator1<double> op2b(24, 0, 0, 0, "Im", 3.2);
+
+ CHECK(op2a.Equals(&op2a));
+ CHECK(!op2a.Equals(&op2b));
+ CHECK(!op2b.Equals(&op2a));
+ CHECK(op2b.Equals(&op2b));
+
+ CHECK(!op1a.Equals(&op2a));
+ CHECK(!op1a.Equals(&op2b));
+ CHECK(!op1b.Equals(&op2a));
+ CHECK(!op1b.Equals(&op2b));
+
+ CHECK(!op2a.Equals(&op1a));
+ CHECK(!op2a.Equals(&op1b));
+ CHECK(!op2b.Equals(&op1a));
+ CHECK(!op2b.Equals(&op1b));
+
+ SimpleOperator op3(25, 0, 0, 0, "Weepy");
+
+ CHECK(!op1a.Equals(&op3));
+ CHECK(!op1b.Equals(&op3));
+ CHECK(!op2a.Equals(&op3));
+ CHECK(!op2b.Equals(&op3));
+
+ CHECK(!op3.Equals(&op1a));
+ CHECK(!op3.Equals(&op1b));
+ CHECK(!op3.Equals(&op2a));
+ CHECK(!op3.Equals(&op2b));
+
+ Operator1<double> op4a(24, 0, 0, 0, "Bashful", NaN);
+ Operator1<double> op4b(24, 0, 0, 0, "Bashful", NaN);
+
+ CHECK(op4a.Equals(&op4a));
+ CHECK(op4a.Equals(&op4b));
+ CHECK(op4b.Equals(&op4a));
+ CHECK(op4b.Equals(&op4b));
+
+ CHECK(!op3.Equals(&op4a));
+ CHECK(!op3.Equals(&op4b));
+ CHECK(!op3.Equals(&op4a));
+ CHECK(!op3.Equals(&op4b));
+}
+
+
+TEST(TestOperator1doublePrint) {
+ Operator1<double> op1(12, 0, 0, 1, "Op1Test", 0);
+ CHECK_EQ("Op1Test[0]", OperatorToString(&op1).get());
+
+ Operator1<double> op2(12, 0, 0, 1, "Op1Test", 7.3);
+ CHECK_EQ("Op1Test[7.3]", OperatorToString(&op2).get());
+
+ Operator1<double> op3(12, 0, 0, 1, "FooBar", 2e+123);
+ CHECK_EQ("FooBar[2e+123]", OperatorToString(&op3).get());
+
+ Operator1<double> op4(12, 0, 0, 1, "BarFoo", Infinity);
+ CHECK_EQ("BarFoo[inf]", OperatorToString(&op4).get());
+
+ Operator1<double> op5(12, 0, 0, 1, "BarFoo", NaN);
+ CHECK_EQ("BarFoo[nan]", OperatorToString(&op5).get());
+}
diff --git a/deps/v8/test/cctest/compiler/test-phi-reducer.cc b/deps/v8/test/cctest/compiler/test-phi-reducer.cc
new file mode 100644
index 000000000..00e250d8a
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-phi-reducer.cc
@@ -0,0 +1,225 @@
+// 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 "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph-inl.h"
+#include "src/compiler/phi-reducer.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+class PhiReducerTester : HandleAndZoneScope {
+ public:
+ explicit PhiReducerTester(int num_parameters = 0)
+ : isolate(main_isolate()),
+ common(main_zone()),
+ graph(main_zone()),
+ self(graph.NewNode(common.Start(num_parameters))),
+ dead(graph.NewNode(common.Dead())) {
+ graph.SetStart(self);
+ }
+
+ Isolate* isolate;
+ CommonOperatorBuilder common;
+ Graph graph;
+ Node* self;
+ Node* dead;
+
+ void CheckReduce(Node* expect, Node* phi) {
+ PhiReducer reducer;
+ Reduction reduction = reducer.Reduce(phi);
+ if (expect == phi) {
+ CHECK(!reduction.Changed());
+ } else {
+ CHECK(reduction.Changed());
+ CHECK_EQ(expect, reduction.replacement());
+ }
+ }
+
+ Node* Int32Constant(int32_t val) {
+ return graph.NewNode(common.Int32Constant(val));
+ }
+
+ Node* Float64Constant(double val) {
+ return graph.NewNode(common.Float64Constant(val));
+ }
+
+ Node* Parameter(int32_t index = 0) {
+ return graph.NewNode(common.Parameter(index), graph.start());
+ }
+
+ Node* Phi(Node* a) {
+ return SetSelfReferences(graph.NewNode(common.Phi(1), a));
+ }
+
+ Node* Phi(Node* a, Node* b) {
+ return SetSelfReferences(graph.NewNode(common.Phi(2), a, b));
+ }
+
+ Node* Phi(Node* a, Node* b, Node* c) {
+ return SetSelfReferences(graph.NewNode(common.Phi(3), a, b, c));
+ }
+
+ Node* Phi(Node* a, Node* b, Node* c, Node* d) {
+ return SetSelfReferences(graph.NewNode(common.Phi(4), a, b, c, d));
+ }
+
+ Node* PhiWithControl(Node* a, Node* control) {
+ return SetSelfReferences(graph.NewNode(common.Phi(1), a, control));
+ }
+
+ Node* PhiWithControl(Node* a, Node* b, Node* control) {
+ return SetSelfReferences(graph.NewNode(common.Phi(2), a, b, control));
+ }
+
+ Node* SetSelfReferences(Node* node) {
+ Node::Inputs inputs = node->inputs();
+ for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
+ ++iter) {
+ Node* input = *iter;
+ if (input == self) node->ReplaceInput(iter.index(), node);
+ }
+ return node;
+ }
+};
+
+
+TEST(PhiReduce1) {
+ PhiReducerTester R;
+ Node* zero = R.Int32Constant(0);
+ Node* one = R.Int32Constant(1);
+ Node* oneish = R.Float64Constant(1.1);
+ Node* param = R.Parameter();
+
+ Node* singles[] = {zero, one, oneish, param};
+ for (size_t i = 0; i < ARRAY_SIZE(singles); i++) {
+ R.CheckReduce(singles[i], R.Phi(singles[i]));
+ }
+}
+
+
+TEST(PhiReduce2) {
+ PhiReducerTester R;
+ Node* zero = R.Int32Constant(0);
+ Node* one = R.Int32Constant(1);
+ Node* oneish = R.Float64Constant(1.1);
+ Node* param = R.Parameter();
+
+ Node* singles[] = {zero, one, oneish, param};
+ for (size_t i = 0; i < ARRAY_SIZE(singles); i++) {
+ Node* a = singles[i];
+ R.CheckReduce(a, R.Phi(a, a));
+ }
+
+ for (size_t i = 0; i < ARRAY_SIZE(singles); i++) {
+ Node* a = singles[i];
+ R.CheckReduce(a, R.Phi(R.self, a));
+ R.CheckReduce(a, R.Phi(a, R.self));
+ }
+
+ for (size_t i = 1; i < ARRAY_SIZE(singles); i++) {
+ Node* a = singles[i], *b = singles[0];
+ Node* phi1 = R.Phi(b, a);
+ R.CheckReduce(phi1, phi1);
+
+ Node* phi2 = R.Phi(a, b);
+ R.CheckReduce(phi2, phi2);
+ }
+}
+
+
+TEST(PhiReduce3) {
+ PhiReducerTester R;
+ Node* zero = R.Int32Constant(0);
+ Node* one = R.Int32Constant(1);
+ Node* oneish = R.Float64Constant(1.1);
+ Node* param = R.Parameter();
+
+ Node* singles[] = {zero, one, oneish, param};
+ for (size_t i = 0; i < ARRAY_SIZE(singles); i++) {
+ Node* a = singles[i];
+ R.CheckReduce(a, R.Phi(a, a, a));
+ }
+
+ for (size_t i = 0; i < ARRAY_SIZE(singles); i++) {
+ Node* a = singles[i];
+ R.CheckReduce(a, R.Phi(R.self, a, a));
+ R.CheckReduce(a, R.Phi(a, R.self, a));
+ R.CheckReduce(a, R.Phi(a, a, R.self));
+ }
+
+ for (size_t i = 1; i < ARRAY_SIZE(singles); i++) {
+ Node* a = singles[i], *b = singles[0];
+ Node* phi1 = R.Phi(b, a, a);
+ R.CheckReduce(phi1, phi1);
+
+ Node* phi2 = R.Phi(a, b, a);
+ R.CheckReduce(phi2, phi2);
+
+ Node* phi3 = R.Phi(a, a, b);
+ R.CheckReduce(phi3, phi3);
+ }
+}
+
+
+TEST(PhiReduce4) {
+ PhiReducerTester R;
+ Node* zero = R.Int32Constant(0);
+ Node* one = R.Int32Constant(1);
+ Node* oneish = R.Float64Constant(1.1);
+ Node* param = R.Parameter();
+
+ Node* singles[] = {zero, one, oneish, param};
+ for (size_t i = 0; i < ARRAY_SIZE(singles); i++) {
+ Node* a = singles[i];
+ R.CheckReduce(a, R.Phi(a, a, a, a));
+ }
+
+ for (size_t i = 0; i < ARRAY_SIZE(singles); i++) {
+ Node* a = singles[i];
+ R.CheckReduce(a, R.Phi(R.self, a, a, a));
+ R.CheckReduce(a, R.Phi(a, R.self, a, a));
+ R.CheckReduce(a, R.Phi(a, a, R.self, a));
+ R.CheckReduce(a, R.Phi(a, a, a, R.self));
+
+ R.CheckReduce(a, R.Phi(R.self, R.self, a, a));
+ R.CheckReduce(a, R.Phi(a, R.self, R.self, a));
+ R.CheckReduce(a, R.Phi(a, a, R.self, R.self));
+ R.CheckReduce(a, R.Phi(R.self, a, a, R.self));
+ }
+
+ for (size_t i = 1; i < ARRAY_SIZE(singles); i++) {
+ Node* a = singles[i], *b = singles[0];
+ Node* phi1 = R.Phi(b, a, a, a);
+ R.CheckReduce(phi1, phi1);
+
+ Node* phi2 = R.Phi(a, b, a, a);
+ R.CheckReduce(phi2, phi2);
+
+ Node* phi3 = R.Phi(a, a, b, a);
+ R.CheckReduce(phi3, phi3);
+
+ Node* phi4 = R.Phi(a, a, a, b);
+ R.CheckReduce(phi4, phi4);
+ }
+}
+
+
+TEST(PhiReduceShouldIgnoreControlNodes) {
+ PhiReducerTester R;
+ Node* zero = R.Int32Constant(0);
+ Node* one = R.Int32Constant(1);
+ Node* oneish = R.Float64Constant(1.1);
+ Node* param = R.Parameter();
+
+ Node* singles[] = {zero, one, oneish, param};
+ for (size_t i = 0; i < ARRAY_SIZE(singles); ++i) {
+ R.CheckReduce(singles[i], R.PhiWithControl(singles[i], R.dead));
+ R.CheckReduce(singles[i], R.PhiWithControl(R.self, singles[i], R.dead));
+ R.CheckReduce(singles[i], R.PhiWithControl(singles[i], R.self, R.dead));
+ }
+}
diff --git a/deps/v8/test/cctest/compiler/test-pipeline.cc b/deps/v8/test/cctest/compiler/test-pipeline.cc
new file mode 100644
index 000000000..7efedeeea
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-pipeline.cc
@@ -0,0 +1,40 @@
+// Copyright 2013 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 "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/compiler.h"
+#include "src/compiler/pipeline.h"
+#include "src/handles.h"
+#include "src/parser.h"
+#include "src/rewriter.h"
+#include "src/scopes.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+TEST(PipelineAdd) {
+ InitializedHandleScope handles;
+ const char* source = "(function(a,b) { return a + b; })";
+ Handle<JSFunction> function = v8::Utils::OpenHandle(
+ *v8::Handle<v8::Function>::Cast(CompileRun(source)));
+ CompilationInfoWithZone info(function);
+
+ CHECK(Parser::Parse(&info));
+ StrictMode strict_mode = info.function()->strict_mode();
+ info.SetStrictMode(strict_mode);
+ CHECK(Rewriter::Rewrite(&info));
+ CHECK(Scope::Analyze(&info));
+ CHECK_NE(NULL, info.scope());
+
+ Pipeline pipeline(&info);
+#if V8_TURBOFAN_TARGET
+ Handle<Code> code = pipeline.GenerateCode();
+ CHECK(Pipeline::SupportedTarget());
+ CHECK(!code.is_null());
+#else
+ USE(pipeline);
+#endif
+}
diff --git a/deps/v8/test/cctest/compiler/test-representation-change.cc b/deps/v8/test/cctest/compiler/test-representation-change.cc
new file mode 100644
index 000000000..092a5f7d9
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-representation-change.cc
@@ -0,0 +1,276 @@
+// 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 <limits>
+
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/graph-builder-tester.h"
+
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/representation-change.h"
+#include "src/compiler/typer.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+namespace v8 { // for friendiness.
+namespace internal {
+namespace compiler {
+
+class RepresentationChangerTester : public HandleAndZoneScope,
+ public GraphAndBuilders {
+ public:
+ explicit RepresentationChangerTester(int num_parameters = 0)
+ : GraphAndBuilders(main_zone()),
+ typer_(main_zone()),
+ jsgraph_(main_graph_, &main_common_, &typer_),
+ changer_(&jsgraph_, &main_simplified_, &main_machine_, main_isolate()) {
+ Node* s = graph()->NewNode(common()->Start(num_parameters));
+ graph()->SetStart(s);
+ }
+
+ Typer typer_;
+ JSGraph jsgraph_;
+ RepresentationChanger changer_;
+
+ Isolate* isolate() { return main_isolate(); }
+ Graph* graph() { return main_graph_; }
+ CommonOperatorBuilder* common() { return &main_common_; }
+ JSGraph* jsgraph() { return &jsgraph_; }
+ RepresentationChanger* changer() { return &changer_; }
+
+ // TODO(titzer): use ValueChecker / ValueUtil
+ void CheckInt32Constant(Node* n, int32_t expected) {
+ ValueMatcher<int32_t> m(n);
+ CHECK(m.HasValue());
+ CHECK_EQ(expected, m.Value());
+ }
+
+ void CheckHeapConstant(Node* n, Object* expected) {
+ ValueMatcher<Handle<Object> > m(n);
+ CHECK(m.HasValue());
+ CHECK_EQ(expected, *m.Value());
+ }
+
+ void CheckNumberConstant(Node* n, double expected) {
+ ValueMatcher<double> m(n);
+ CHECK_EQ(IrOpcode::kNumberConstant, n->opcode());
+ CHECK(m.HasValue());
+ CHECK_EQ(expected, m.Value());
+ }
+
+ Node* Parameter(int index = 0) {
+ return graph()->NewNode(common()->Parameter(index), graph()->start());
+ }
+
+ void CheckTypeError(RepTypeUnion from, RepTypeUnion to) {
+ changer()->testing_type_errors_ = true;
+ changer()->type_error_ = false;
+ Node* n = Parameter(0);
+ Node* c = changer()->GetRepresentationFor(n, from, to);
+ CHECK_EQ(n, c);
+ CHECK(changer()->type_error_);
+ }
+
+ void CheckNop(RepTypeUnion from, RepTypeUnion to) {
+ Node* n = Parameter(0);
+ Node* c = changer()->GetRepresentationFor(n, from, to);
+ CHECK_EQ(n, c);
+ }
+};
+}
+}
+} // namespace v8::internal::compiler
+
+
+static const RepType all_reps[] = {rBit, rWord32, rWord64, rFloat64, rTagged};
+
+
+// TODO(titzer): lift this to ValueHelper
+static const double double_inputs[] = {
+ 0.0, -0.0, 1.0, -1.0, 0.1, 1.4, -1.7,
+ 2, 5, 6, 982983, 888, -999.8, 3.1e7,
+ -2e66, 2.3e124, -12e73, V8_INFINITY, -V8_INFINITY};
+
+
+static const int32_t int32_inputs[] = {
+ 0, 1, -1,
+ 2, 5, 6,
+ 982983, 888, -999,
+ 65535, static_cast<int32_t>(0xFFFFFFFF), static_cast<int32_t>(0x80000000)};
+
+
+static const uint32_t uint32_inputs[] = {
+ 0, 1, static_cast<uint32_t>(-1), 2, 5, 6,
+ 982983, 888, static_cast<uint32_t>(-999), 65535, 0xFFFFFFFF, 0x80000000};
+
+
+TEST(BoolToBit_constant) {
+ RepresentationChangerTester r;
+
+ Node* true_node = r.jsgraph()->TrueConstant();
+ Node* true_bit = r.changer()->GetRepresentationFor(true_node, rTagged, rBit);
+ r.CheckInt32Constant(true_bit, 1);
+
+ Node* false_node = r.jsgraph()->FalseConstant();
+ Node* false_bit =
+ r.changer()->GetRepresentationFor(false_node, rTagged, rBit);
+ r.CheckInt32Constant(false_bit, 0);
+}
+
+
+TEST(BitToBool_constant) {
+ RepresentationChangerTester r;
+
+ for (int i = -5; i < 5; i++) {
+ Node* node = r.jsgraph()->Int32Constant(i);
+ Node* val = r.changer()->GetRepresentationFor(node, rBit, rTagged);
+ r.CheckHeapConstant(val, i == 0 ? r.isolate()->heap()->false_value()
+ : r.isolate()->heap()->true_value());
+ }
+}
+
+
+TEST(ToTagged_constant) {
+ RepresentationChangerTester r;
+
+ for (size_t i = 0; i < ARRAY_SIZE(double_inputs); i++) {
+ Node* n = r.jsgraph()->Float64Constant(double_inputs[i]);
+ Node* c = r.changer()->GetRepresentationFor(n, rFloat64, rTagged);
+ r.CheckNumberConstant(c, double_inputs[i]);
+ }
+
+ for (size_t i = 0; i < ARRAY_SIZE(int32_inputs); i++) {
+ Node* n = r.jsgraph()->Int32Constant(int32_inputs[i]);
+ Node* c = r.changer()->GetRepresentationFor(n, rWord32 | tInt32, rTagged);
+ r.CheckNumberConstant(c, static_cast<double>(int32_inputs[i]));
+ }
+
+ for (size_t i = 0; i < ARRAY_SIZE(uint32_inputs); i++) {
+ Node* n = r.jsgraph()->Int32Constant(uint32_inputs[i]);
+ Node* c = r.changer()->GetRepresentationFor(n, rWord32 | tUint32, rTagged);
+ r.CheckNumberConstant(c, static_cast<double>(uint32_inputs[i]));
+ }
+}
+
+
+static void CheckChange(IrOpcode::Value expected, RepTypeUnion from,
+ RepTypeUnion to) {
+ RepresentationChangerTester r;
+
+ Node* n = r.Parameter();
+ Node* c = r.changer()->GetRepresentationFor(n, from, to);
+
+ CHECK_NE(c, n);
+ CHECK_EQ(expected, c->opcode());
+ CHECK_EQ(n, c->InputAt(0));
+}
+
+
+TEST(SingleChanges) {
+ CheckChange(IrOpcode::kChangeBoolToBit, rTagged, rBit);
+ CheckChange(IrOpcode::kChangeBitToBool, rBit, rTagged);
+
+ CheckChange(IrOpcode::kChangeInt32ToTagged, rWord32 | tInt32, rTagged);
+ CheckChange(IrOpcode::kChangeUint32ToTagged, rWord32 | tUint32, rTagged);
+ CheckChange(IrOpcode::kChangeFloat64ToTagged, rFloat64, rTagged);
+
+ CheckChange(IrOpcode::kChangeTaggedToInt32, rTagged | tInt32, rWord32);
+ CheckChange(IrOpcode::kChangeTaggedToUint32, rTagged | tUint32, rWord32);
+ CheckChange(IrOpcode::kChangeTaggedToFloat64, rTagged, rFloat64);
+
+ // Int32,Uint32 <-> Float64 are actually machine conversions.
+ CheckChange(IrOpcode::kChangeInt32ToFloat64, rWord32 | tInt32, rFloat64);
+ CheckChange(IrOpcode::kChangeUint32ToFloat64, rWord32 | tUint32, rFloat64);
+ CheckChange(IrOpcode::kChangeFloat64ToInt32, rFloat64 | tInt32, rWord32);
+ CheckChange(IrOpcode::kChangeFloat64ToUint32, rFloat64 | tUint32, rWord32);
+}
+
+
+TEST(SignednessInWord32) {
+ RepresentationChangerTester r;
+
+ // TODO(titzer): assume that uses of a word32 without a sign mean tInt32.
+ CheckChange(IrOpcode::kChangeTaggedToInt32, rTagged, rWord32 | tInt32);
+ CheckChange(IrOpcode::kChangeTaggedToUint32, rTagged, rWord32 | tUint32);
+ CheckChange(IrOpcode::kChangeInt32ToFloat64, rWord32, rFloat64);
+ CheckChange(IrOpcode::kChangeFloat64ToInt32, rFloat64, rWord32);
+}
+
+
+TEST(Nops) {
+ RepresentationChangerTester r;
+
+ // X -> X is always a nop for any single representation X.
+ for (size_t i = 0; i < ARRAY_SIZE(all_reps); i++) {
+ r.CheckNop(all_reps[i], all_reps[i]);
+ }
+
+ // 32-bit or 64-bit words can be used as branch conditions (rBit).
+ r.CheckNop(rWord32, rBit);
+ r.CheckNop(rWord32, rBit | tBool);
+ r.CheckNop(rWord64, rBit);
+ r.CheckNop(rWord64, rBit | tBool);
+
+ // rBit (result of comparison) is implicitly a wordish thing.
+ r.CheckNop(rBit, rWord32);
+ r.CheckNop(rBit | tBool, rWord32);
+ r.CheckNop(rBit, rWord64);
+ r.CheckNop(rBit | tBool, rWord64);
+}
+
+
+TEST(TypeErrors) {
+ RepresentationChangerTester r;
+
+ // Floats cannot be implicitly converted to/from comparison conditions.
+ r.CheckTypeError(rFloat64, rBit);
+ r.CheckTypeError(rFloat64, rBit | tBool);
+ r.CheckTypeError(rBit, rFloat64);
+ r.CheckTypeError(rBit | tBool, rFloat64);
+
+ // Word64 is internal and shouldn't be implicitly converted.
+ r.CheckTypeError(rWord64, rTagged | tBool);
+ r.CheckTypeError(rWord64, rTagged);
+ r.CheckTypeError(rWord64, rTagged | tBool);
+ r.CheckTypeError(rTagged, rWord64);
+ r.CheckTypeError(rTagged | tBool, rWord64);
+
+ // Word64 / Word32 shouldn't be implicitly converted.
+ r.CheckTypeError(rWord64, rWord32);
+ r.CheckTypeError(rWord32, rWord64);
+ r.CheckTypeError(rWord64, rWord32 | tInt32);
+ r.CheckTypeError(rWord32 | tInt32, rWord64);
+ r.CheckTypeError(rWord64, rWord32 | tUint32);
+ r.CheckTypeError(rWord32 | tUint32, rWord64);
+
+ for (size_t i = 0; i < ARRAY_SIZE(all_reps); i++) {
+ for (size_t j = 0; j < ARRAY_SIZE(all_reps); j++) {
+ if (i == j) continue;
+ // Only a single from representation is allowed.
+ r.CheckTypeError(all_reps[i] | all_reps[j], rTagged);
+ }
+ }
+}
+
+
+TEST(CompleteMatrix) {
+ // TODO(titzer): test all variants in the matrix.
+ // rB
+ // tBrB
+ // tBrT
+ // rW32
+ // tIrW32
+ // tUrW32
+ // rW64
+ // tIrW64
+ // tUrW64
+ // rF64
+ // tIrF64
+ // tUrF64
+ // tArF64
+ // rT
+ // tArT
+}
diff --git a/deps/v8/test/cctest/compiler/test-run-deopt.cc b/deps/v8/test/cctest/compiler/test-run-deopt.cc
new file mode 100644
index 000000000..af173d6be
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-run-deopt.cc
@@ -0,0 +1,58 @@
+// 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 "src/v8.h"
+
+#include "test/cctest/compiler/function-tester.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+#if V8_TURBOFAN_TARGET
+
+TEST(TurboSimpleDeopt) {
+ FLAG_allow_natives_syntax = true;
+ FLAG_turbo_deoptimization = true;
+
+ FunctionTester T(
+ "(function f(a) {"
+ "var b = 1;"
+ "if (!%IsOptimized()) return 0;"
+ "%DeoptimizeFunction(f);"
+ "if (%IsOptimized()) return 0;"
+ "return a + b; })");
+
+ T.CheckCall(T.Val(2), T.Val(1));
+}
+
+
+TEST(TurboSimpleDeoptInExpr) {
+ FLAG_allow_natives_syntax = true;
+ FLAG_turbo_deoptimization = true;
+
+ FunctionTester T(
+ "(function f(a) {"
+ "var b = 1;"
+ "var c = 2;"
+ "if (!%IsOptimized()) return 0;"
+ "var d = b + (%DeoptimizeFunction(f), c);"
+ "if (%IsOptimized()) return 0;"
+ "return d + a; })");
+
+ T.CheckCall(T.Val(6), T.Val(3));
+}
+
+#endif
+
+TEST(TurboTrivialDeopt) {
+ FLAG_allow_natives_syntax = true;
+ FLAG_turbo_deoptimization = true;
+
+ FunctionTester T(
+ "(function foo() {"
+ "%DeoptimizeFunction(foo);"
+ "return 1; })");
+
+ T.CheckCall(T.Val(1));
+}
diff --git a/deps/v8/test/cctest/compiler/test-run-intrinsics.cc b/deps/v8/test/cctest/compiler/test-run-intrinsics.cc
new file mode 100644
index 000000000..a1b567618
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-run-intrinsics.cc
@@ -0,0 +1,211 @@
+// 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 "src/v8.h"
+
+#include "test/cctest/compiler/function-tester.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+
+TEST(IsSmi) {
+ FunctionTester T("(function(a) { return %_IsSmi(a); })");
+
+ T.CheckTrue(T.Val(1));
+ T.CheckFalse(T.Val(1.1));
+ T.CheckFalse(T.Val(-0.0));
+ T.CheckTrue(T.Val(-2));
+ T.CheckFalse(T.Val(-2.3));
+ T.CheckFalse(T.undefined());
+}
+
+
+TEST(IsNonNegativeSmi) {
+ FunctionTester T("(function(a) { return %_IsNonNegativeSmi(a); })");
+
+ T.CheckTrue(T.Val(1));
+ T.CheckFalse(T.Val(1.1));
+ T.CheckFalse(T.Val(-0.0));
+ T.CheckFalse(T.Val(-2));
+ T.CheckFalse(T.Val(-2.3));
+ T.CheckFalse(T.undefined());
+}
+
+
+TEST(IsMinusZero) {
+ FunctionTester T("(function(a) { return %_IsMinusZero(a); })");
+
+ T.CheckFalse(T.Val(1));
+ T.CheckFalse(T.Val(1.1));
+ T.CheckTrue(T.Val(-0.0));
+ T.CheckFalse(T.Val(-2));
+ T.CheckFalse(T.Val(-2.3));
+ T.CheckFalse(T.undefined());
+}
+
+
+TEST(IsArray) {
+ FunctionTester T("(function(a) { return %_IsArray(a); })");
+
+ T.CheckFalse(T.NewObject("(function() {})"));
+ T.CheckTrue(T.NewObject("([1])"));
+ T.CheckFalse(T.NewObject("({})"));
+ T.CheckFalse(T.NewObject("(/x/)"));
+ T.CheckFalse(T.undefined());
+ T.CheckFalse(T.null());
+ T.CheckFalse(T.Val("x"));
+ T.CheckFalse(T.Val(1));
+}
+
+
+TEST(IsObject) {
+ FunctionTester T("(function(a) { return %_IsObject(a); })");
+
+ T.CheckFalse(T.NewObject("(function() {})"));
+ T.CheckTrue(T.NewObject("([1])"));
+ T.CheckTrue(T.NewObject("({})"));
+ T.CheckTrue(T.NewObject("(/x/)"));
+ T.CheckFalse(T.undefined());
+ T.CheckTrue(T.null());
+ T.CheckFalse(T.Val("x"));
+ T.CheckFalse(T.Val(1));
+}
+
+
+TEST(IsFunction) {
+ FunctionTester T("(function(a) { return %_IsFunction(a); })");
+
+ T.CheckTrue(T.NewObject("(function() {})"));
+ T.CheckFalse(T.NewObject("([1])"));
+ T.CheckFalse(T.NewObject("({})"));
+ T.CheckFalse(T.NewObject("(/x/)"));
+ T.CheckFalse(T.undefined());
+ T.CheckFalse(T.null());
+ T.CheckFalse(T.Val("x"));
+ T.CheckFalse(T.Val(1));
+}
+
+
+TEST(IsRegExp) {
+ FunctionTester T("(function(a) { return %_IsRegExp(a); })");
+
+ T.CheckFalse(T.NewObject("(function() {})"));
+ T.CheckFalse(T.NewObject("([1])"));
+ T.CheckFalse(T.NewObject("({})"));
+ T.CheckTrue(T.NewObject("(/x/)"));
+ T.CheckFalse(T.undefined());
+ T.CheckFalse(T.null());
+ T.CheckFalse(T.Val("x"));
+ T.CheckFalse(T.Val(1));
+}
+
+
+TEST(ClassOf) {
+ FunctionTester T("(function(a) { return %_ClassOf(a); })");
+
+ T.CheckCall(T.Val("Function"), T.NewObject("(function() {})"));
+ T.CheckCall(T.Val("Array"), T.NewObject("([1])"));
+ T.CheckCall(T.Val("Object"), T.NewObject("({})"));
+ T.CheckCall(T.Val("RegExp"), T.NewObject("(/x/)"));
+ T.CheckCall(T.null(), T.undefined());
+ T.CheckCall(T.null(), T.null());
+ T.CheckCall(T.null(), T.Val("x"));
+ T.CheckCall(T.null(), T.Val(1));
+}
+
+
+TEST(ObjectEquals) {
+ FunctionTester T("(function(a,b) { return %_ObjectEquals(a,b); })");
+ CompileRun("var o = {}");
+
+ T.CheckTrue(T.NewObject("(o)"), T.NewObject("(o)"));
+ T.CheckTrue(T.Val("internal"), T.Val("internal"));
+ T.CheckTrue(T.true_value(), T.true_value());
+ T.CheckFalse(T.true_value(), T.false_value());
+ T.CheckFalse(T.NewObject("({})"), T.NewObject("({})"));
+ T.CheckFalse(T.Val("a"), T.Val("b"));
+}
+
+
+TEST(ValueOf) {
+ FunctionTester T("(function(a) { return %_ValueOf(a); })");
+
+ T.CheckCall(T.Val("a"), T.Val("a"));
+ T.CheckCall(T.Val("b"), T.NewObject("(new String('b'))"));
+ T.CheckCall(T.Val(123), T.Val(123));
+ T.CheckCall(T.Val(456), T.NewObject("(new Number(456))"));
+}
+
+
+TEST(SetValueOf) {
+ FunctionTester T("(function(a,b) { return %_SetValueOf(a,b); })");
+
+ T.CheckCall(T.Val("a"), T.NewObject("(new String)"), T.Val("a"));
+ T.CheckCall(T.Val(123), T.NewObject("(new Number)"), T.Val(123));
+ T.CheckCall(T.Val("x"), T.undefined(), T.Val("x"));
+}
+
+
+TEST(StringCharFromCode) {
+ FunctionTester T("(function(a) { return %_StringCharFromCode(a); })");
+
+ T.CheckCall(T.Val("a"), T.Val(97));
+ T.CheckCall(T.Val("\xE2\x9D\x8A"), T.Val(0x274A));
+ T.CheckCall(T.Val(""), T.undefined());
+}
+
+
+TEST(StringCharAt) {
+ FunctionTester T("(function(a,b) { return %_StringCharAt(a,b); })");
+
+ T.CheckCall(T.Val("e"), T.Val("huge fan!"), T.Val(3));
+ T.CheckCall(T.Val("f"), T.Val("\xE2\x9D\x8A fan!"), T.Val(2));
+ T.CheckCall(T.Val(""), T.Val("not a fan!"), T.Val(23));
+}
+
+
+TEST(StringCharCodeAt) {
+ FunctionTester T("(function(a,b) { return %_StringCharCodeAt(a,b); })");
+
+ T.CheckCall(T.Val('e'), T.Val("huge fan!"), T.Val(3));
+ T.CheckCall(T.Val('f'), T.Val("\xE2\x9D\x8A fan!"), T.Val(2));
+ T.CheckCall(T.nan(), T.Val("not a fan!"), T.Val(23));
+}
+
+
+TEST(StringAdd) {
+ FunctionTester T("(function(a,b) { return %_StringAdd(a,b); })");
+
+ T.CheckCall(T.Val("aaabbb"), T.Val("aaa"), T.Val("bbb"));
+ T.CheckCall(T.Val("aaa"), T.Val("aaa"), T.Val(""));
+ T.CheckCall(T.Val("bbb"), T.Val(""), T.Val("bbb"));
+}
+
+
+TEST(StringSubString) {
+ FunctionTester T("(function(a,b) { return %_SubString(a,b,b+3); })");
+
+ T.CheckCall(T.Val("aaa"), T.Val("aaabbb"), T.Val(0.0));
+ T.CheckCall(T.Val("abb"), T.Val("aaabbb"), T.Val(2));
+ T.CheckCall(T.Val("aaa"), T.Val("aaa"), T.Val(0.0));
+}
+
+
+TEST(StringCompare) {
+ FunctionTester T("(function(a,b) { return %_StringCompare(a,b); })");
+
+ T.CheckCall(T.Val(-1), T.Val("aaa"), T.Val("bbb"));
+ T.CheckCall(T.Val(0.0), T.Val("bbb"), T.Val("bbb"));
+ T.CheckCall(T.Val(+1), T.Val("ccc"), T.Val("bbb"));
+}
+
+
+TEST(CallFunction) {
+ FunctionTester T("(function(a,b) { return %_CallFunction(a, 1, 2, 3, b); })");
+ CompileRun("function f(a,b,c) { return a + b + c + this.d; }");
+
+ T.CheckCall(T.Val(129), T.NewObject("({d:123})"), T.NewObject("f"));
+ T.CheckCall(T.Val("6x"), T.NewObject("({d:'x'})"), T.NewObject("f"));
+}
diff --git a/deps/v8/test/cctest/compiler/test-run-jsbranches.cc b/deps/v8/test/cctest/compiler/test-run-jsbranches.cc
new file mode 100644
index 000000000..2eb4fa6d0
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-run-jsbranches.cc
@@ -0,0 +1,262 @@
+// 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 "src/v8.h"
+
+#include "test/cctest/compiler/function-tester.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+TEST(Conditional) {
+ FunctionTester T("(function(a) { return a ? 23 : 42; })");
+
+ T.CheckCall(T.Val(23), T.true_value(), T.undefined());
+ T.CheckCall(T.Val(42), T.false_value(), T.undefined());
+ T.CheckCall(T.Val(42), T.undefined(), T.undefined());
+ T.CheckCall(T.Val(42), T.Val(0.0), T.undefined());
+ T.CheckCall(T.Val(23), T.Val(999), T.undefined());
+ T.CheckCall(T.Val(23), T.Val("x"), T.undefined());
+}
+
+
+TEST(LogicalAnd) {
+ FunctionTester T("(function(a,b) { return a && b; })");
+
+ T.CheckCall(T.true_value(), T.true_value(), T.true_value());
+ T.CheckCall(T.false_value(), T.false_value(), T.true_value());
+ T.CheckCall(T.false_value(), T.true_value(), T.false_value());
+ T.CheckCall(T.false_value(), T.false_value(), T.false_value());
+
+ T.CheckCall(T.Val(999), T.Val(777), T.Val(999));
+ T.CheckCall(T.Val(0.0), T.Val(0.0), T.Val(999));
+ T.CheckCall(T.Val("b"), T.Val("a"), T.Val("b"));
+}
+
+
+TEST(LogicalOr) {
+ FunctionTester T("(function(a,b) { return a || b; })");
+
+ T.CheckCall(T.true_value(), T.true_value(), T.true_value());
+ T.CheckCall(T.true_value(), T.false_value(), T.true_value());
+ T.CheckCall(T.true_value(), T.true_value(), T.false_value());
+ T.CheckCall(T.false_value(), T.false_value(), T.false_value());
+
+ T.CheckCall(T.Val(777), T.Val(777), T.Val(999));
+ T.CheckCall(T.Val(999), T.Val(0.0), T.Val(999));
+ T.CheckCall(T.Val("a"), T.Val("a"), T.Val("b"));
+}
+
+
+TEST(LogicalEffect) {
+ FunctionTester T("(function(a,b) { a && (b = a); return b; })");
+
+ T.CheckCall(T.true_value(), T.true_value(), T.true_value());
+ T.CheckCall(T.true_value(), T.false_value(), T.true_value());
+ T.CheckCall(T.true_value(), T.true_value(), T.false_value());
+ T.CheckCall(T.false_value(), T.false_value(), T.false_value());
+
+ T.CheckCall(T.Val(777), T.Val(777), T.Val(999));
+ T.CheckCall(T.Val(999), T.Val(0.0), T.Val(999));
+ T.CheckCall(T.Val("a"), T.Val("a"), T.Val("b"));
+}
+
+
+TEST(IfStatement) {
+ FunctionTester T("(function(a) { if (a) { return 1; } else { return 2; } })");
+
+ T.CheckCall(T.Val(1), T.true_value(), T.undefined());
+ T.CheckCall(T.Val(2), T.false_value(), T.undefined());
+ T.CheckCall(T.Val(2), T.undefined(), T.undefined());
+ T.CheckCall(T.Val(2), T.Val(0.0), T.undefined());
+ T.CheckCall(T.Val(1), T.Val(999), T.undefined());
+ T.CheckCall(T.Val(1), T.Val("x"), T.undefined());
+}
+
+
+TEST(DoWhileStatement) {
+ FunctionTester T("(function(a,b) { do { a+=23; } while(a < b) return a; })");
+
+ T.CheckCall(T.Val(24), T.Val(1), T.Val(1));
+ T.CheckCall(T.Val(24), T.Val(1), T.Val(23));
+ T.CheckCall(T.Val(47), T.Val(1), T.Val(25));
+ T.CheckCall(T.Val("str23"), T.Val("str"), T.Val("str"));
+}
+
+
+TEST(WhileStatement) {
+ FunctionTester T("(function(a,b) { while(a < b) { a+=23; } return a; })");
+
+ T.CheckCall(T.Val(1), T.Val(1), T.Val(1));
+ T.CheckCall(T.Val(24), T.Val(1), T.Val(23));
+ T.CheckCall(T.Val(47), T.Val(1), T.Val(25));
+ T.CheckCall(T.Val("str"), T.Val("str"), T.Val("str"));
+}
+
+
+TEST(ForStatement) {
+ FunctionTester T("(function(a,b) { for (; a < b; a+=23) {} return a; })");
+
+ T.CheckCall(T.Val(1), T.Val(1), T.Val(1));
+ T.CheckCall(T.Val(24), T.Val(1), T.Val(23));
+ T.CheckCall(T.Val(47), T.Val(1), T.Val(25));
+ T.CheckCall(T.Val("str"), T.Val("str"), T.Val("str"));
+}
+
+
+static void TestForIn(const char* code) {
+ FunctionTester T(code);
+ T.CheckCall(T.undefined(), T.undefined());
+ T.CheckCall(T.undefined(), T.null());
+ T.CheckCall(T.undefined(), T.NewObject("({})"));
+ T.CheckCall(T.undefined(), T.Val(1));
+ T.CheckCall(T.Val("2"), T.Val("str"));
+ T.CheckCall(T.Val("a"), T.NewObject("({'a' : 1})"));
+ T.CheckCall(T.Val("2"), T.NewObject("([1, 2, 3])"));
+ T.CheckCall(T.Val("a"), T.NewObject("({'a' : 1, 'b' : 1})"), T.Val("b"));
+ T.CheckCall(T.Val("1"), T.NewObject("([1, 2, 3])"), T.Val("2"));
+}
+
+
+TEST(ForInStatement) {
+ // Variable assignment.
+ TestForIn(
+ "(function(a, b) {"
+ "var last;"
+ "for (var x in a) {"
+ " if (b) { delete a[b]; b = undefined; }"
+ " last = x;"
+ "}"
+ "return last;})");
+ // Indexed assignment.
+ TestForIn(
+ "(function(a, b) {"
+ "var array = [0, 1, undefined];"
+ "for (array[2] in a) {"
+ " if (b) { delete a[b]; b = undefined; }"
+ "}"
+ "return array[2];})");
+ // Named assignment.
+ TestForIn(
+ "(function(a, b) {"
+ "var obj = {'a' : undefined};"
+ "for (obj.a in a) {"
+ " if (b) { delete a[b]; b = undefined; }"
+ "}"
+ "return obj.a;})");
+}
+
+
+TEST(SwitchStatement) {
+ const char* src =
+ "(function(a,b) {"
+ " var r = '-';"
+ " switch (a) {"
+ " case 'x' : r += 'X-';"
+ " case b + 'b': r += 'B-';"
+ " default : r += 'D-';"
+ " case 'y' : r += 'Y-';"
+ " }"
+ " return r;"
+ "})";
+ FunctionTester T(src);
+
+ T.CheckCall(T.Val("-X-B-D-Y-"), T.Val("x"), T.Val("B"));
+ T.CheckCall(T.Val("-B-D-Y-"), T.Val("Bb"), T.Val("B"));
+ T.CheckCall(T.Val("-D-Y-"), T.Val("z"), T.Val("B"));
+ T.CheckCall(T.Val("-Y-"), T.Val("y"), T.Val("B"));
+
+ CompileRun("var c = 0; var o = { toString:function(){return c++} };");
+ T.CheckCall(T.Val("-D-Y-"), T.Val("1b"), T.NewObject("o"));
+ T.CheckCall(T.Val("-B-D-Y-"), T.Val("1b"), T.NewObject("o"));
+ T.CheckCall(T.Val("-D-Y-"), T.Val("1b"), T.NewObject("o"));
+}
+
+
+TEST(BlockBreakStatement) {
+ FunctionTester T("(function(a,b) { L:{ if (a) break L; b=1; } return b; })");
+
+ T.CheckCall(T.Val(7), T.true_value(), T.Val(7));
+ T.CheckCall(T.Val(1), T.false_value(), T.Val(7));
+}
+
+
+TEST(BlockReturnStatement) {
+ FunctionTester T("(function(a,b) { L:{ if (a) b=1; return b; } })");
+
+ T.CheckCall(T.Val(1), T.true_value(), T.Val(7));
+ T.CheckCall(T.Val(7), T.false_value(), T.Val(7));
+}
+
+
+TEST(NestedIfConditional) {
+ FunctionTester T("(function(a,b) { if (a) { b = (b?b:7) + 1; } return b; })");
+
+ T.CheckCall(T.Val(4), T.false_value(), T.Val(4));
+ T.CheckCall(T.Val(6), T.true_value(), T.Val(5));
+ T.CheckCall(T.Val(8), T.true_value(), T.undefined());
+}
+
+
+TEST(NestedIfLogical) {
+ const char* src =
+ "(function(a,b) {"
+ " if (a || b) { return 1; } else { return 2; }"
+ "})";
+ FunctionTester T(src);
+
+ T.CheckCall(T.Val(1), T.true_value(), T.true_value());
+ T.CheckCall(T.Val(1), T.false_value(), T.true_value());
+ T.CheckCall(T.Val(1), T.true_value(), T.false_value());
+ T.CheckCall(T.Val(2), T.false_value(), T.false_value());
+ T.CheckCall(T.Val(1), T.Val(1.0), T.Val(1.0));
+ T.CheckCall(T.Val(1), T.Val(0.0), T.Val(1.0));
+ T.CheckCall(T.Val(1), T.Val(1.0), T.Val(0.0));
+ T.CheckCall(T.Val(2), T.Val(0.0), T.Val(0.0));
+}
+
+
+TEST(NestedIfElseFor) {
+ const char* src =
+ "(function(a,b) {"
+ " if (!a) { return b - 3; } else { for (; a < b; a++); }"
+ " return a;"
+ "})";
+ FunctionTester T(src);
+
+ T.CheckCall(T.Val(1), T.false_value(), T.Val(4));
+ T.CheckCall(T.Val(2), T.true_value(), T.Val(2));
+ T.CheckCall(T.Val(3), T.Val(3), T.Val(1));
+}
+
+
+TEST(NestedWhileWhile) {
+ const char* src =
+ "(function(a) {"
+ " var i = a; while (false) while(false) return i;"
+ " return i;"
+ "})";
+ FunctionTester T(src);
+
+ T.CheckCall(T.Val(2.0), T.Val(2.0), T.Val(-1.0));
+ T.CheckCall(T.Val(65.0), T.Val(65.0), T.Val(-1.0));
+}
+
+
+TEST(NestedForIf) {
+ FunctionTester T("(function(a,b) { for (; a > 1; a--) if (b) return 1; })");
+
+ T.CheckCall(T.Val(1), T.Val(3), T.true_value());
+ T.CheckCall(T.undefined(), T.Val(2), T.false_value());
+ T.CheckCall(T.undefined(), T.Val(1), T.null());
+}
+
+
+TEST(NestedForConditional) {
+ FunctionTester T("(function(a,b) { for (; a > 1; a--) return b ? 1 : 2; })");
+
+ T.CheckCall(T.Val(1), T.Val(3), T.true_value());
+ T.CheckCall(T.Val(2), T.Val(2), T.false_value());
+ T.CheckCall(T.undefined(), T.Val(1), T.null());
+}
diff --git a/deps/v8/test/cctest/compiler/test-run-jscalls.cc b/deps/v8/test/cctest/compiler/test-run-jscalls.cc
new file mode 100644
index 000000000..2ad7e5046
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-run-jscalls.cc
@@ -0,0 +1,235 @@
+// 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 "src/v8.h"
+
+#include "test/cctest/compiler/function-tester.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+TEST(SimpleCall) {
+ FunctionTester T("(function(foo,a) { return foo(a); })");
+ Handle<JSFunction> foo = T.NewFunction("(function(a) { return a; })");
+
+ T.CheckCall(T.Val(3), foo, T.Val(3));
+ T.CheckCall(T.Val(3.1), foo, T.Val(3.1));
+ T.CheckCall(foo, foo, foo);
+ T.CheckCall(T.Val("Abba"), foo, T.Val("Abba"));
+}
+
+
+TEST(SimpleCall2) {
+ FunctionTester T("(function(foo,a) { return foo(a); })");
+ Handle<JSFunction> foo = T.NewFunction("(function(a) { return a; })");
+ T.Compile(foo);
+
+ T.CheckCall(T.Val(3), foo, T.Val(3));
+ T.CheckCall(T.Val(3.1), foo, T.Val(3.1));
+ T.CheckCall(foo, foo, foo);
+ T.CheckCall(T.Val("Abba"), foo, T.Val("Abba"));
+}
+
+
+TEST(ConstCall) {
+ FunctionTester T("(function(foo,a) { return foo(a,3); })");
+ Handle<JSFunction> foo = T.NewFunction("(function(a,b) { return a + b; })");
+ T.Compile(foo);
+
+ T.CheckCall(T.Val(6), foo, T.Val(3));
+ T.CheckCall(T.Val(6.1), foo, T.Val(3.1));
+ T.CheckCall(T.Val("function (a,b) { return a + b; }3"), foo, foo);
+ T.CheckCall(T.Val("Abba3"), foo, T.Val("Abba"));
+}
+
+
+TEST(ConstCall2) {
+ FunctionTester T("(function(foo,a) { return foo(a,\"3\"); })");
+ Handle<JSFunction> foo = T.NewFunction("(function(a,b) { return a + b; })");
+ T.Compile(foo);
+
+ T.CheckCall(T.Val("33"), foo, T.Val(3));
+ T.CheckCall(T.Val("3.13"), foo, T.Val(3.1));
+ T.CheckCall(T.Val("function (a,b) { return a + b; }3"), foo, foo);
+ T.CheckCall(T.Val("Abba3"), foo, T.Val("Abba"));
+}
+
+
+TEST(PropertyNamedCall) {
+ FunctionTester T("(function(a,b) { return a.foo(b,23); })");
+ CompileRun("function foo(y,z) { return this.x + y + z; }");
+
+ T.CheckCall(T.Val(32), T.NewObject("({ foo:foo, x:4 })"), T.Val(5));
+ T.CheckCall(T.Val("xy23"), T.NewObject("({ foo:foo, x:'x' })"), T.Val("y"));
+ T.CheckCall(T.nan(), T.NewObject("({ foo:foo, y:0 })"), T.Val(3));
+}
+
+
+TEST(PropertyKeyedCall) {
+ FunctionTester T("(function(a,b) { var f = 'foo'; return a[f](b,23); })");
+ CompileRun("function foo(y,z) { return this.x + y + z; }");
+
+ T.CheckCall(T.Val(32), T.NewObject("({ foo:foo, x:4 })"), T.Val(5));
+ T.CheckCall(T.Val("xy23"), T.NewObject("({ foo:foo, x:'x' })"), T.Val("y"));
+ T.CheckCall(T.nan(), T.NewObject("({ foo:foo, y:0 })"), T.Val(3));
+}
+
+
+TEST(GlobalCall) {
+ FunctionTester T("(function(a,b) { return foo(a,b); })");
+ CompileRun("function foo(a,b) { return a + b + this.c; }");
+ CompileRun("var c = 23;");
+
+ T.CheckCall(T.Val(32), T.Val(4), T.Val(5));
+ T.CheckCall(T.Val("xy23"), T.Val("x"), T.Val("y"));
+ T.CheckCall(T.nan(), T.undefined(), T.Val(3));
+}
+
+
+TEST(LookupCall) {
+ FunctionTester T("(function(a,b) { with (a) { return foo(a,b); } })");
+
+ CompileRun("function f1(a,b) { return a.val + b; }");
+ T.CheckCall(T.Val(5), T.NewObject("({ foo:f1, val:2 })"), T.Val(3));
+ T.CheckCall(T.Val("xy"), T.NewObject("({ foo:f1, val:'x' })"), T.Val("y"));
+
+ CompileRun("function f2(a,b) { return this.val + b; }");
+ T.CheckCall(T.Val(9), T.NewObject("({ foo:f2, val:4 })"), T.Val(5));
+ T.CheckCall(T.Val("xy"), T.NewObject("({ foo:f2, val:'x' })"), T.Val("y"));
+}
+
+
+TEST(MismatchCallTooFew) {
+ FunctionTester T("(function(a,b) { return foo(a,b); })");
+ CompileRun("function foo(a,b,c) { return a + b + c; }");
+
+ T.CheckCall(T.nan(), T.Val(23), T.Val(42));
+ T.CheckCall(T.nan(), T.Val(4.2), T.Val(2.3));
+ T.CheckCall(T.Val("abundefined"), T.Val("a"), T.Val("b"));
+}
+
+
+TEST(MismatchCallTooMany) {
+ FunctionTester T("(function(a,b) { return foo(a,b); })");
+ CompileRun("function foo(a) { return a; }");
+
+ T.CheckCall(T.Val(23), T.Val(23), T.Val(42));
+ T.CheckCall(T.Val(4.2), T.Val(4.2), T.Val(2.3));
+ T.CheckCall(T.Val("a"), T.Val("a"), T.Val("b"));
+}
+
+
+TEST(ConstructorCall) {
+ FunctionTester T("(function(a,b) { return new foo(a,b).value; })");
+ CompileRun("function foo(a,b) { return { value: a + b + this.c }; }");
+ CompileRun("foo.prototype.c = 23;");
+
+ T.CheckCall(T.Val(32), T.Val(4), T.Val(5));
+ T.CheckCall(T.Val("xy23"), T.Val("x"), T.Val("y"));
+ T.CheckCall(T.nan(), T.undefined(), T.Val(3));
+}
+
+
+// TODO(titzer): factor these out into test-runtime-calls.cc
+TEST(RuntimeCallCPP1) {
+ FLAG_allow_natives_syntax = true;
+ FunctionTester T("(function(a) { return %ToBool(a); })");
+
+ T.CheckCall(T.true_value(), T.Val(23), T.undefined());
+ T.CheckCall(T.true_value(), T.Val(4.2), T.undefined());
+ T.CheckCall(T.true_value(), T.Val("str"), T.undefined());
+ T.CheckCall(T.true_value(), T.true_value(), T.undefined());
+ T.CheckCall(T.false_value(), T.false_value(), T.undefined());
+ T.CheckCall(T.false_value(), T.undefined(), T.undefined());
+ T.CheckCall(T.false_value(), T.Val(0.0), T.undefined());
+}
+
+
+TEST(RuntimeCallCPP2) {
+ FLAG_allow_natives_syntax = true;
+ FunctionTester T("(function(a,b) { return %NumberAdd(a, b); })");
+
+ T.CheckCall(T.Val(65), T.Val(42), T.Val(23));
+ T.CheckCall(T.Val(19), T.Val(42), T.Val(-23));
+ T.CheckCall(T.Val(6.5), T.Val(4.2), T.Val(2.3));
+}
+
+
+TEST(RuntimeCallJS) {
+ FLAG_allow_natives_syntax = true;
+ FunctionTester T("(function(a) { return %ToString(a); })");
+
+ T.CheckCall(T.Val("23"), T.Val(23), T.undefined());
+ T.CheckCall(T.Val("4.2"), T.Val(4.2), T.undefined());
+ T.CheckCall(T.Val("str"), T.Val("str"), T.undefined());
+ T.CheckCall(T.Val("true"), T.true_value(), T.undefined());
+ T.CheckCall(T.Val("false"), T.false_value(), T.undefined());
+ T.CheckCall(T.Val("undefined"), T.undefined(), T.undefined());
+}
+
+
+TEST(RuntimeCallInline) {
+ FLAG_allow_natives_syntax = true;
+ FunctionTester T("(function(a) { return %_IsObject(a); })");
+
+ T.CheckCall(T.false_value(), T.Val(23), T.undefined());
+ T.CheckCall(T.false_value(), T.Val(4.2), T.undefined());
+ T.CheckCall(T.false_value(), T.Val("str"), T.undefined());
+ T.CheckCall(T.false_value(), T.true_value(), T.undefined());
+ T.CheckCall(T.false_value(), T.false_value(), T.undefined());
+ T.CheckCall(T.false_value(), T.undefined(), T.undefined());
+ T.CheckCall(T.true_value(), T.NewObject("({})"), T.undefined());
+ T.CheckCall(T.true_value(), T.NewObject("([])"), T.undefined());
+}
+
+
+TEST(RuntimeCallBooleanize) {
+ // TODO(turbofan): %Booleanize will disappear, don't hesitate to remove this
+ // test case, two-argument case is covered by the above test already.
+ FLAG_allow_natives_syntax = true;
+ FunctionTester T("(function(a,b) { return %Booleanize(a, b); })");
+
+ T.CheckCall(T.true_value(), T.Val(-1), T.Val(Token::LT));
+ T.CheckCall(T.false_value(), T.Val(-1), T.Val(Token::EQ));
+ T.CheckCall(T.false_value(), T.Val(-1), T.Val(Token::GT));
+
+ T.CheckCall(T.false_value(), T.Val(0.0), T.Val(Token::LT));
+ T.CheckCall(T.true_value(), T.Val(0.0), T.Val(Token::EQ));
+ T.CheckCall(T.false_value(), T.Val(0.0), T.Val(Token::GT));
+
+ T.CheckCall(T.false_value(), T.Val(1), T.Val(Token::LT));
+ T.CheckCall(T.false_value(), T.Val(1), T.Val(Token::EQ));
+ T.CheckCall(T.true_value(), T.Val(1), T.Val(Token::GT));
+}
+
+
+TEST(EvalCall) {
+ FunctionTester T("(function(a,b) { return eval(a); })");
+ Handle<JSObject> g(T.function->context()->global_object()->global_proxy());
+
+ T.CheckCall(T.Val(23), T.Val("17 + 6"), T.undefined());
+ T.CheckCall(T.Val("'Y'; a"), T.Val("'Y'; a"), T.Val("b-val"));
+ T.CheckCall(T.Val("b-val"), T.Val("'Y'; b"), T.Val("b-val"));
+ T.CheckCall(g, T.Val("this"), T.undefined());
+ T.CheckCall(g, T.Val("'use strict'; this"), T.undefined());
+
+ CompileRun("eval = function(x) { return x; }");
+ T.CheckCall(T.Val("17 + 6"), T.Val("17 + 6"), T.undefined());
+
+ CompileRun("eval = function(x) { return this; }");
+ T.CheckCall(g, T.Val("17 + 6"), T.undefined());
+
+ CompileRun("eval = function(x) { 'use strict'; return this; }");
+ T.CheckCall(T.undefined(), T.Val("17 + 6"), T.undefined());
+}
+
+
+TEST(ReceiverPatching) {
+ // TODO(turbofan): Note that this test only checks that the function prologue
+ // patches an undefined receiver to the global receiver. If this starts to
+ // fail once we fix the calling protocol, just remove this test.
+ FunctionTester T("(function(a) { return this; })");
+ Handle<JSObject> g(T.function->context()->global_object()->global_proxy());
+ T.CheckCall(g, T.undefined());
+}
diff --git a/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc b/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc
new file mode 100644
index 000000000..0712ab620
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc
@@ -0,0 +1,45 @@
+// 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 "src/v8.h"
+
+#include "test/cctest/compiler/function-tester.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+TEST(Throw) {
+ FunctionTester T("(function(a,b) { if (a) { throw b; } else { return b; }})");
+
+ T.CheckThrows(T.true_value(), T.NewObject("new Error"));
+ T.CheckCall(T.Val(23), T.false_value(), T.Val(23));
+}
+
+
+TEST(ThrowSourcePosition) {
+ static const char* src =
+ "(function(a, b) { \n"
+ " if (a == 1) throw 1; \n"
+ " if (a == 2) {throw 2} \n"
+ " if (a == 3) {0;throw 3}\n"
+ " throw 4; \n"
+ "}) ";
+ FunctionTester T(src);
+ v8::Handle<v8::Message> message;
+
+ message = T.CheckThrowsReturnMessage(T.Val(1), T.undefined());
+ CHECK(!message.IsEmpty());
+ CHECK_EQ(2, message->GetLineNumber());
+ CHECK_EQ(40, message->GetStartPosition());
+
+ message = T.CheckThrowsReturnMessage(T.Val(2), T.undefined());
+ CHECK(!message.IsEmpty());
+ CHECK_EQ(3, message->GetLineNumber());
+ CHECK_EQ(67, message->GetStartPosition());
+
+ message = T.CheckThrowsReturnMessage(T.Val(3), T.undefined());
+ CHECK(!message.IsEmpty());
+ CHECK_EQ(4, message->GetLineNumber());
+ CHECK_EQ(95, message->GetStartPosition());
+}
diff --git a/deps/v8/test/cctest/compiler/test-run-jsops.cc b/deps/v8/test/cctest/compiler/test-run-jsops.cc
new file mode 100644
index 000000000..eb39760ff
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-run-jsops.cc
@@ -0,0 +1,524 @@
+// 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 "src/v8.h"
+
+#include "test/cctest/compiler/function-tester.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+TEST(BinopAdd) {
+ FunctionTester T("(function(a,b) { return a + b; })");
+
+ T.CheckCall(3, 1, 2);
+ T.CheckCall(-11, -2, -9);
+ T.CheckCall(-11, -1.5, -9.5);
+ T.CheckCall(T.Val("AB"), T.Val("A"), T.Val("B"));
+ T.CheckCall(T.Val("A11"), T.Val("A"), T.Val(11));
+ T.CheckCall(T.Val("12B"), T.Val(12), T.Val("B"));
+ T.CheckCall(T.Val("38"), T.Val("3"), T.Val("8"));
+ T.CheckCall(T.Val("31"), T.Val("3"), T.NewObject("([1])"));
+ T.CheckCall(T.Val("3[object Object]"), T.Val("3"), T.NewObject("({})"));
+}
+
+
+TEST(BinopSubtract) {
+ FunctionTester T("(function(a,b) { return a - b; })");
+
+ T.CheckCall(3, 4, 1);
+ T.CheckCall(3.0, 4.5, 1.5);
+ T.CheckCall(T.Val(-9), T.Val("0"), T.Val(9));
+ T.CheckCall(T.Val(-9), T.Val(0.0), T.Val("9"));
+ T.CheckCall(T.Val(1), T.Val("3"), T.Val("2"));
+ T.CheckCall(T.nan(), T.Val("3"), T.Val("B"));
+ T.CheckCall(T.Val(2), T.Val("3"), T.NewObject("([1])"));
+ T.CheckCall(T.nan(), T.Val("3"), T.NewObject("({})"));
+}
+
+
+TEST(BinopMultiply) {
+ FunctionTester T("(function(a,b) { return a * b; })");
+
+ T.CheckCall(6, 3, 2);
+ T.CheckCall(4.5, 2.0, 2.25);
+ T.CheckCall(T.Val(6), T.Val("3"), T.Val(2));
+ T.CheckCall(T.Val(4.5), T.Val(2.0), T.Val("2.25"));
+ T.CheckCall(T.Val(6), T.Val("3"), T.Val("2"));
+ T.CheckCall(T.nan(), T.Val("3"), T.Val("B"));
+ T.CheckCall(T.Val(3), T.Val("3"), T.NewObject("([1])"));
+ T.CheckCall(T.nan(), T.Val("3"), T.NewObject("({})"));
+}
+
+
+TEST(BinopDivide) {
+ FunctionTester T("(function(a,b) { return a / b; })");
+
+ T.CheckCall(2, 8, 4);
+ T.CheckCall(2.1, 8.4, 4);
+ T.CheckCall(V8_INFINITY, 8, 0);
+ T.CheckCall(-V8_INFINITY, -8, 0);
+ T.CheckCall(T.infinity(), T.Val(8), T.Val("0"));
+ T.CheckCall(T.minus_infinity(), T.Val("-8"), T.Val(0.0));
+ T.CheckCall(T.Val(1.5), T.Val("3"), T.Val("2"));
+ T.CheckCall(T.nan(), T.Val("3"), T.Val("B"));
+ T.CheckCall(T.Val(1.5), T.Val("3"), T.NewObject("([2])"));
+ T.CheckCall(T.nan(), T.Val("3"), T.NewObject("({})"));
+}
+
+
+TEST(BinopModulus) {
+ FunctionTester T("(function(a,b) { return a % b; })");
+
+ T.CheckCall(3, 8, 5);
+ T.CheckCall(T.Val(3), T.Val("8"), T.Val(5));
+ T.CheckCall(T.Val(3), T.Val(8), T.Val("5"));
+ T.CheckCall(T.Val(1), T.Val("3"), T.Val("2"));
+ T.CheckCall(T.nan(), T.Val("3"), T.Val("B"));
+ T.CheckCall(T.Val(1), T.Val("3"), T.NewObject("([2])"));
+ T.CheckCall(T.nan(), T.Val("3"), T.NewObject("({})"));
+}
+
+
+TEST(BinopShiftLeft) {
+ FunctionTester T("(function(a,b) { return a << b; })");
+
+ T.CheckCall(4, 2, 1);
+ T.CheckCall(T.Val(4), T.Val("2"), T.Val(1));
+ T.CheckCall(T.Val(4), T.Val(2), T.Val("1"));
+}
+
+
+TEST(BinopShiftRight) {
+ FunctionTester T("(function(a,b) { return a >> b; })");
+
+ T.CheckCall(4, 8, 1);
+ T.CheckCall(-4, -8, 1);
+ T.CheckCall(T.Val(4), T.Val("8"), T.Val(1));
+ T.CheckCall(T.Val(4), T.Val(8), T.Val("1"));
+}
+
+
+TEST(BinopShiftRightLogical) {
+ FunctionTester T("(function(a,b) { return a >>> b; })");
+
+ T.CheckCall(4, 8, 1);
+ T.CheckCall(0x7ffffffc, -8, 1);
+ T.CheckCall(T.Val(4), T.Val("8"), T.Val(1));
+ T.CheckCall(T.Val(4), T.Val(8), T.Val("1"));
+}
+
+
+TEST(BinopAnd) {
+ FunctionTester T("(function(a,b) { return a & b; })");
+
+ T.CheckCall(7, 7, 15);
+ T.CheckCall(7, 15, 7);
+ T.CheckCall(T.Val(7), T.Val("15"), T.Val(7));
+ T.CheckCall(T.Val(7), T.Val(15), T.Val("7"));
+}
+
+
+TEST(BinopOr) {
+ FunctionTester T("(function(a,b) { return a | b; })");
+
+ T.CheckCall(6, 4, 2);
+ T.CheckCall(6, 2, 4);
+ T.CheckCall(T.Val(6), T.Val("2"), T.Val(4));
+ T.CheckCall(T.Val(6), T.Val(2), T.Val("4"));
+}
+
+
+TEST(BinopXor) {
+ FunctionTester T("(function(a,b) { return a ^ b; })");
+
+ T.CheckCall(7, 15, 8);
+ T.CheckCall(7, 8, 15);
+ T.CheckCall(T.Val(7), T.Val("8"), T.Val(15));
+ T.CheckCall(T.Val(7), T.Val(8), T.Val("15"));
+}
+
+
+TEST(BinopStrictEqual) {
+ FunctionTester T("(function(a,b) { return a === b; })");
+
+ T.CheckTrue(7, 7);
+ T.CheckFalse(7, 8);
+ T.CheckTrue(7.1, 7.1);
+ T.CheckFalse(7.1, 8.1);
+
+ T.CheckTrue(T.Val("7.1"), T.Val("7.1"));
+ T.CheckFalse(T.Val(7.1), T.Val("7.1"));
+ T.CheckFalse(T.Val(7), T.undefined());
+ T.CheckFalse(T.undefined(), T.Val(7));
+
+ CompileRun("var o = { desc : 'I am a singleton' }");
+ T.CheckFalse(T.NewObject("([1])"), T.NewObject("([1])"));
+ T.CheckFalse(T.NewObject("({})"), T.NewObject("({})"));
+ T.CheckTrue(T.NewObject("(o)"), T.NewObject("(o)"));
+}
+
+
+TEST(BinopEqual) {
+ FunctionTester T("(function(a,b) { return a == b; })");
+
+ T.CheckTrue(7, 7);
+ T.CheckFalse(7, 8);
+ T.CheckTrue(7.1, 7.1);
+ T.CheckFalse(7.1, 8.1);
+
+ T.CheckTrue(T.Val("7.1"), T.Val("7.1"));
+ T.CheckTrue(T.Val(7.1), T.Val("7.1"));
+
+ CompileRun("var o = { desc : 'I am a singleton' }");
+ T.CheckFalse(T.NewObject("([1])"), T.NewObject("([1])"));
+ T.CheckFalse(T.NewObject("({})"), T.NewObject("({})"));
+ T.CheckTrue(T.NewObject("(o)"), T.NewObject("(o)"));
+}
+
+
+TEST(BinopNotEqual) {
+ FunctionTester T("(function(a,b) { return a != b; })");
+
+ T.CheckFalse(7, 7);
+ T.CheckTrue(7, 8);
+ T.CheckFalse(7.1, 7.1);
+ T.CheckTrue(7.1, 8.1);
+
+ T.CheckFalse(T.Val("7.1"), T.Val("7.1"));
+ T.CheckFalse(T.Val(7.1), T.Val("7.1"));
+
+ CompileRun("var o = { desc : 'I am a singleton' }");
+ T.CheckTrue(T.NewObject("([1])"), T.NewObject("([1])"));
+ T.CheckTrue(T.NewObject("({})"), T.NewObject("({})"));
+ T.CheckFalse(T.NewObject("(o)"), T.NewObject("(o)"));
+}
+
+
+TEST(BinopLessThan) {
+ FunctionTester T("(function(a,b) { return a < b; })");
+
+ T.CheckTrue(7, 8);
+ T.CheckFalse(8, 7);
+ T.CheckTrue(-8.1, -8);
+ T.CheckFalse(-8, -8.1);
+ T.CheckFalse(0.111, 0.111);
+
+ T.CheckFalse(T.Val("7.1"), T.Val("7.1"));
+ T.CheckFalse(T.Val(7.1), T.Val("6.1"));
+ T.CheckFalse(T.Val(7.1), T.Val("7.1"));
+ T.CheckTrue(T.Val(7.1), T.Val("8.1"));
+}
+
+
+TEST(BinopLessThanEqual) {
+ FunctionTester T("(function(a,b) { return a <= b; })");
+
+ T.CheckTrue(7, 8);
+ T.CheckFalse(8, 7);
+ T.CheckTrue(-8.1, -8);
+ T.CheckFalse(-8, -8.1);
+ T.CheckTrue(0.111, 0.111);
+
+ T.CheckTrue(T.Val("7.1"), T.Val("7.1"));
+ T.CheckFalse(T.Val(7.1), T.Val("6.1"));
+ T.CheckTrue(T.Val(7.1), T.Val("7.1"));
+ T.CheckTrue(T.Val(7.1), T.Val("8.1"));
+}
+
+
+TEST(BinopGreaterThan) {
+ FunctionTester T("(function(a,b) { return a > b; })");
+
+ T.CheckFalse(7, 8);
+ T.CheckTrue(8, 7);
+ T.CheckFalse(-8.1, -8);
+ T.CheckTrue(-8, -8.1);
+ T.CheckFalse(0.111, 0.111);
+
+ T.CheckFalse(T.Val("7.1"), T.Val("7.1"));
+ T.CheckTrue(T.Val(7.1), T.Val("6.1"));
+ T.CheckFalse(T.Val(7.1), T.Val("7.1"));
+ T.CheckFalse(T.Val(7.1), T.Val("8.1"));
+}
+
+
+TEST(BinopGreaterThanOrEqual) {
+ FunctionTester T("(function(a,b) { return a >= b; })");
+
+ T.CheckFalse(7, 8);
+ T.CheckTrue(8, 7);
+ T.CheckFalse(-8.1, -8);
+ T.CheckTrue(-8, -8.1);
+ T.CheckTrue(0.111, 0.111);
+
+ T.CheckTrue(T.Val("7.1"), T.Val("7.1"));
+ T.CheckTrue(T.Val(7.1), T.Val("6.1"));
+ T.CheckTrue(T.Val(7.1), T.Val("7.1"));
+ T.CheckFalse(T.Val(7.1), T.Val("8.1"));
+}
+
+
+TEST(BinopIn) {
+ FunctionTester T("(function(a,b) { return a in b; })");
+
+ T.CheckTrue(T.Val("x"), T.NewObject("({x:23})"));
+ T.CheckFalse(T.Val("y"), T.NewObject("({x:42})"));
+ T.CheckFalse(T.Val(123), T.NewObject("({x:65})"));
+ T.CheckTrue(T.Val(1), T.NewObject("([1,2,3])"));
+}
+
+
+TEST(BinopInstanceOf) {
+ FunctionTester T("(function(a,b) { return a instanceof b; })");
+
+ T.CheckTrue(T.NewObject("(new Number(23))"), T.NewObject("Number"));
+ T.CheckFalse(T.NewObject("(new Number(23))"), T.NewObject("String"));
+ T.CheckFalse(T.NewObject("(new String('a'))"), T.NewObject("Number"));
+ T.CheckTrue(T.NewObject("(new String('b'))"), T.NewObject("String"));
+ T.CheckFalse(T.Val(1), T.NewObject("Number"));
+ T.CheckFalse(T.Val("abc"), T.NewObject("String"));
+
+ CompileRun("var bound = (function() {}).bind(undefined)");
+ T.CheckTrue(T.NewObject("(new bound())"), T.NewObject("bound"));
+ T.CheckTrue(T.NewObject("(new bound())"), T.NewObject("Object"));
+ T.CheckFalse(T.NewObject("(new bound())"), T.NewObject("Number"));
+}
+
+
+TEST(UnopNot) {
+ FunctionTester T("(function(a) { return !a; })");
+
+ T.CheckCall(T.true_value(), T.false_value(), T.undefined());
+ T.CheckCall(T.false_value(), T.true_value(), T.undefined());
+ T.CheckCall(T.true_value(), T.Val(0.0), T.undefined());
+ T.CheckCall(T.false_value(), T.Val(123), T.undefined());
+ T.CheckCall(T.false_value(), T.Val("x"), T.undefined());
+ T.CheckCall(T.true_value(), T.undefined(), T.undefined());
+ T.CheckCall(T.true_value(), T.nan(), T.undefined());
+}
+
+
+TEST(UnopCountPost) {
+ FunctionTester T("(function(a) { return a++; })");
+
+ T.CheckCall(T.Val(0.0), T.Val(0.0), T.undefined());
+ T.CheckCall(T.Val(2.3), T.Val(2.3), T.undefined());
+ T.CheckCall(T.Val(123), T.Val(123), T.undefined());
+ T.CheckCall(T.Val(7), T.Val("7"), T.undefined());
+ T.CheckCall(T.nan(), T.Val("x"), T.undefined());
+ T.CheckCall(T.nan(), T.undefined(), T.undefined());
+ T.CheckCall(T.Val(1.0), T.true_value(), T.undefined());
+ T.CheckCall(T.Val(0.0), T.false_value(), T.undefined());
+ T.CheckCall(T.nan(), T.nan(), T.undefined());
+}
+
+
+TEST(UnopCountPre) {
+ FunctionTester T("(function(a) { return ++a; })");
+
+ T.CheckCall(T.Val(1.0), T.Val(0.0), T.undefined());
+ T.CheckCall(T.Val(3.3), T.Val(2.3), T.undefined());
+ T.CheckCall(T.Val(124), T.Val(123), T.undefined());
+ T.CheckCall(T.Val(8), T.Val("7"), T.undefined());
+ T.CheckCall(T.nan(), T.Val("x"), T.undefined());
+ T.CheckCall(T.nan(), T.undefined(), T.undefined());
+ T.CheckCall(T.Val(2.0), T.true_value(), T.undefined());
+ T.CheckCall(T.Val(1.0), T.false_value(), T.undefined());
+ T.CheckCall(T.nan(), T.nan(), T.undefined());
+}
+
+
+TEST(PropertyNamedLoad) {
+ FunctionTester T("(function(a,b) { return a.x; })");
+
+ T.CheckCall(T.Val(23), T.NewObject("({x:23})"), T.undefined());
+ T.CheckCall(T.undefined(), T.NewObject("({y:23})"), T.undefined());
+}
+
+
+TEST(PropertyKeyedLoad) {
+ FunctionTester T("(function(a,b) { return a[b]; })");
+
+ T.CheckCall(T.Val(23), T.NewObject("({x:23})"), T.Val("x"));
+ T.CheckCall(T.Val(42), T.NewObject("([23,42,65])"), T.Val(1));
+ T.CheckCall(T.undefined(), T.NewObject("({x:23})"), T.Val("y"));
+ T.CheckCall(T.undefined(), T.NewObject("([23,42,65])"), T.Val(4));
+}
+
+
+TEST(PropertyNamedStore) {
+ FunctionTester T("(function(a) { a.x = 7; return a.x; })");
+
+ T.CheckCall(T.Val(7), T.NewObject("({})"), T.undefined());
+ T.CheckCall(T.Val(7), T.NewObject("({x:23})"), T.undefined());
+}
+
+
+TEST(PropertyKeyedStore) {
+ FunctionTester T("(function(a,b) { a[b] = 7; return a.x; })");
+
+ T.CheckCall(T.Val(7), T.NewObject("({})"), T.Val("x"));
+ T.CheckCall(T.Val(7), T.NewObject("({x:23})"), T.Val("x"));
+ T.CheckCall(T.Val(9), T.NewObject("({x:9})"), T.Val("y"));
+}
+
+
+TEST(PropertyNamedDelete) {
+ FunctionTester T("(function(a) { return delete a.x; })");
+
+ CompileRun("var o = Object.create({}, { x: { value:23 } });");
+ T.CheckTrue(T.NewObject("({x:42})"), T.undefined());
+ T.CheckTrue(T.NewObject("({})"), T.undefined());
+ T.CheckFalse(T.NewObject("(o)"), T.undefined());
+}
+
+
+TEST(PropertyKeyedDelete) {
+ FunctionTester T("(function(a, b) { return delete a[b]; })");
+
+ CompileRun("function getX() { return 'x'; }");
+ CompileRun("var o = Object.create({}, { x: { value:23 } });");
+ T.CheckTrue(T.NewObject("({x:42})"), T.Val("x"));
+ T.CheckFalse(T.NewObject("(o)"), T.Val("x"));
+ T.CheckFalse(T.NewObject("(o)"), T.NewObject("({toString:getX})"));
+}
+
+
+TEST(GlobalLoad) {
+ FunctionTester T("(function() { return g; })");
+
+ T.CheckThrows(T.undefined(), T.undefined());
+ CompileRun("var g = 23;");
+ T.CheckCall(T.Val(23));
+}
+
+
+TEST(GlobalStoreSloppy) {
+ FunctionTester T("(function(a,b) { g = a + b; return g; })");
+
+ T.CheckCall(T.Val(33), T.Val(22), T.Val(11));
+ CompileRun("delete g");
+ CompileRun("const g = 23");
+ T.CheckCall(T.Val(23), T.Val(55), T.Val(44));
+}
+
+
+TEST(GlobalStoreStrict) {
+ FunctionTester T("(function(a,b) { 'use strict'; g = a + b; return g; })");
+
+ T.CheckThrows(T.Val(22), T.Val(11));
+ CompileRun("var g = 'a global variable';");
+ T.CheckCall(T.Val(33), T.Val(22), T.Val(11));
+}
+
+
+TEST(ContextLoad) {
+ FunctionTester T("(function(a,b) { (function(){a}); return a + b; })");
+
+ T.CheckCall(T.Val(65), T.Val(23), T.Val(42));
+ T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b"));
+}
+
+
+TEST(ContextStore) {
+ FunctionTester T("(function(a,b) { (function(){x}); var x = a; return x; })");
+
+ T.CheckCall(T.Val(23), T.Val(23), T.undefined());
+ T.CheckCall(T.Val("a"), T.Val("a"), T.undefined());
+}
+
+
+TEST(LookupLoad) {
+ FunctionTester T("(function(a,b) { with(a) { return x + b; } })");
+
+ T.CheckCall(T.Val(24), T.NewObject("({x:23})"), T.Val(1));
+ T.CheckCall(T.Val(32), T.NewObject("({x:23, b:9})"), T.Val(2));
+ T.CheckCall(T.Val(45), T.NewObject("({__proto__:{x:42}})"), T.Val(3));
+ T.CheckCall(T.Val(69), T.NewObject("({get x() { return 65; }})"), T.Val(4));
+}
+
+
+TEST(LookupStore) {
+ FunctionTester T("(function(a,b) { var x; with(a) { x = b; } return x; })");
+
+ T.CheckCall(T.undefined(), T.NewObject("({x:23})"), T.Val(1));
+ T.CheckCall(T.Val(2), T.NewObject("({y:23})"), T.Val(2));
+ T.CheckCall(T.Val(23), T.NewObject("({b:23})"), T.Val(3));
+ T.CheckCall(T.undefined(), T.NewObject("({__proto__:{x:42}})"), T.Val(4));
+}
+
+
+TEST(BlockLoadStore) {
+ FLAG_harmony_scoping = true;
+ FunctionTester T("(function(a) { 'use strict'; { let x = a+a; return x; }})");
+
+ T.CheckCall(T.Val(46), T.Val(23));
+ T.CheckCall(T.Val("aa"), T.Val("a"));
+}
+
+
+TEST(BlockLoadStoreNested) {
+ FLAG_harmony_scoping = true;
+ const char* src =
+ "(function(a,b) {"
+ "'use strict';"
+ "{ let x = a, y = a;"
+ " { let y = b;"
+ " return x + y;"
+ " }"
+ "}})";
+ FunctionTester T(src);
+
+ T.CheckCall(T.Val(65), T.Val(23), T.Val(42));
+ T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b"));
+}
+
+
+TEST(ObjectLiteralComputed) {
+ FunctionTester T("(function(a,b) { o = { x:a+b }; return o.x; })");
+
+ T.CheckCall(T.Val(65), T.Val(23), T.Val(42));
+ T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b"));
+}
+
+
+TEST(ObjectLiteralNonString) {
+ FunctionTester T("(function(a,b) { o = { 7:a+b }; return o[7]; })");
+
+ T.CheckCall(T.Val(65), T.Val(23), T.Val(42));
+ T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b"));
+}
+
+
+TEST(ObjectLiteralPrototype) {
+ FunctionTester T("(function(a) { o = { __proto__:a }; return o.x; })");
+
+ T.CheckCall(T.Val(23), T.NewObject("({x:23})"), T.undefined());
+ T.CheckCall(T.undefined(), T.NewObject("({y:42})"), T.undefined());
+}
+
+
+TEST(ObjectLiteralGetter) {
+ FunctionTester T("(function(a) { o = { get x() {return a} }; return o.x; })");
+
+ T.CheckCall(T.Val(23), T.Val(23), T.undefined());
+ T.CheckCall(T.Val("x"), T.Val("x"), T.undefined());
+}
+
+
+TEST(ArrayLiteral) {
+ FunctionTester T("(function(a,b) { o = [1, a + b, 3]; return o[1]; })");
+
+ T.CheckCall(T.Val(65), T.Val(23), T.Val(42));
+ T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b"));
+}
+
+
+TEST(RegExpLiteral) {
+ FunctionTester T("(function(a) { o = /b/; return o.test(a); })");
+
+ T.CheckTrue(T.Val("abc"));
+ T.CheckFalse(T.Val("xyz"));
+}
diff --git a/deps/v8/test/cctest/compiler/test-run-machops.cc b/deps/v8/test/cctest/compiler/test-run-machops.cc
new file mode 100644
index 000000000..6786f3874
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-run-machops.cc
@@ -0,0 +1,4077 @@
+// 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 <functional>
+#include <limits>
+
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/codegen-tester.h"
+#include "test/cctest/compiler/value-helper.h"
+
+#if V8_TURBOFAN_TARGET
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+typedef RawMachineAssembler::Label MLabel;
+
+TEST(RunInt32Add) {
+ RawMachineAssemblerTester<int32_t> m;
+ Node* add = m.Int32Add(m.Int32Constant(0), m.Int32Constant(1));
+ m.Return(add);
+ CHECK_EQ(1, m.Call());
+}
+
+
+static Node* Int32Input(RawMachineAssemblerTester<int32_t>* m, int index) {
+ switch (index) {
+ case 0:
+ return m->Parameter(0);
+ case 1:
+ return m->Parameter(1);
+ case 2:
+ return m->Int32Constant(0);
+ case 3:
+ return m->Int32Constant(1);
+ case 4:
+ return m->Int32Constant(-1);
+ case 5:
+ return m->Int32Constant(0xff);
+ case 6:
+ return m->Int32Constant(0x01234567);
+ case 7:
+ return m->Load(kMachineWord32, m->PointerConstant(NULL));
+ default:
+ return NULL;
+ }
+}
+
+
+TEST(CodeGenInt32Binop) {
+ RawMachineAssemblerTester<void> m;
+
+ Operator* ops[] = {
+ m.machine()->Word32And(), m.machine()->Word32Or(),
+ m.machine()->Word32Xor(), m.machine()->Word32Shl(),
+ m.machine()->Word32Shr(), m.machine()->Word32Sar(),
+ m.machine()->Word32Equal(), m.machine()->Int32Add(),
+ m.machine()->Int32Sub(), m.machine()->Int32Mul(),
+ m.machine()->Int32Div(), m.machine()->Int32UDiv(),
+ m.machine()->Int32Mod(), m.machine()->Int32UMod(),
+ m.machine()->Int32LessThan(), m.machine()->Int32LessThanOrEqual(),
+ m.machine()->Uint32LessThan(), m.machine()->Uint32LessThanOrEqual(),
+ NULL};
+
+ for (int i = 0; ops[i] != NULL; i++) {
+ for (int j = 0; j < 8; j++) {
+ for (int k = 0; k < 8; k++) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
+ Node* a = Int32Input(&m, j);
+ Node* b = Int32Input(&m, k);
+ m.Return(m.NewNode(ops[i], a, b));
+ m.GenerateCode();
+ }
+ }
+ }
+}
+
+
+TEST(RunGoto) {
+ RawMachineAssemblerTester<int32_t> m;
+ int constant = 99999;
+
+ MLabel next;
+ m.Goto(&next);
+ m.Bind(&next);
+ m.Return(m.Int32Constant(constant));
+
+ CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunGotoMultiple) {
+ RawMachineAssemblerTester<int32_t> m;
+ int constant = 9999977;
+
+ MLabel labels[10];
+ for (size_t i = 0; i < ARRAY_SIZE(labels); i++) {
+ m.Goto(&labels[i]);
+ m.Bind(&labels[i]);
+ }
+ m.Return(m.Int32Constant(constant));
+
+ CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunBranch) {
+ RawMachineAssemblerTester<int32_t> m;
+ int constant = 999777;
+
+ MLabel blocka, blockb;
+ m.Branch(m.Int32Constant(0), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(0 - constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(constant));
+
+ CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunRedundantBranch1) {
+ RawMachineAssemblerTester<int32_t> m;
+ int constant = 944777;
+
+ MLabel blocka;
+ m.Branch(m.Int32Constant(0), &blocka, &blocka);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+
+ CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunRedundantBranch2) {
+ RawMachineAssemblerTester<int32_t> m;
+ int constant = 955777;
+
+ MLabel blocka, blockb;
+ m.Branch(m.Int32Constant(0), &blocka, &blocka);
+ m.Bind(&blockb);
+ m.Goto(&blocka);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+
+ CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunRedundantBranch3) {
+ RawMachineAssemblerTester<int32_t> m;
+ int constant = 966777;
+
+ MLabel blocka, blockb, blockc;
+ m.Branch(m.Int32Constant(0), &blocka, &blockc);
+ m.Bind(&blocka);
+ m.Branch(m.Int32Constant(0), &blockb, &blockb);
+ m.Bind(&blockc);
+ m.Goto(&blockb);
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(constant));
+
+ CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunDiamond2) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ int constant = 995666;
+
+ MLabel blocka, blockb, end;
+ m.Branch(m.Int32Constant(0), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Goto(&end);
+ m.Bind(&blockb);
+ m.Goto(&end);
+ m.Bind(&end);
+ m.Return(m.Int32Constant(constant));
+
+ CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunLoop) {
+ RawMachineAssemblerTester<int32_t> m;
+ int constant = 999555;
+
+ MLabel header, body, exit;
+ m.Goto(&header);
+ m.Bind(&header);
+ m.Branch(m.Int32Constant(0), &body, &exit);
+ m.Bind(&body);
+ m.Goto(&header);
+ m.Bind(&exit);
+ m.Return(m.Int32Constant(constant));
+
+ CHECK_EQ(constant, m.Call());
+}
+
+
+template <typename R>
+static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node,
+ Node* true_node, Node* false_node) {
+ MLabel blocka, blockb;
+ MLabel* end = m->Exit();
+ m->Branch(cond_node, &blocka, &blockb);
+ m->Bind(&blocka);
+ m->Goto(end);
+ m->Bind(&blockb);
+ m->Goto(end);
+
+ m->Bind(end);
+ Node* phi = m->Phi(true_node, false_node);
+ m->Return(phi);
+}
+
+
+TEST(RunDiamondPhiConst) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ int false_val = 0xFF666;
+ int true_val = 0x00DDD;
+ Node* true_node = m.Int32Constant(true_val);
+ Node* false_node = m.Int32Constant(false_val);
+ BuildDiamondPhi(&m, m.Parameter(0), true_node, false_node);
+ CHECK_EQ(false_val, m.Call(0));
+ CHECK_EQ(true_val, m.Call(1));
+}
+
+
+TEST(RunDiamondPhiNumber) {
+ RawMachineAssemblerTester<Object*> m(kMachineWord32);
+ double false_val = -11.1;
+ double true_val = 200.1;
+ Node* true_node = m.NumberConstant(true_val);
+ Node* false_node = m.NumberConstant(false_val);
+ BuildDiamondPhi(&m, m.Parameter(0), true_node, false_node);
+ m.CheckNumber(false_val, m.Call(0));
+ m.CheckNumber(true_val, m.Call(1));
+}
+
+
+TEST(RunDiamondPhiString) {
+ RawMachineAssemblerTester<Object*> m(kMachineWord32);
+ const char* false_val = "false";
+ const char* true_val = "true";
+ Node* true_node = m.StringConstant(true_val);
+ Node* false_node = m.StringConstant(false_val);
+ BuildDiamondPhi(&m, m.Parameter(0), true_node, false_node);
+ m.CheckString(false_val, m.Call(0));
+ m.CheckString(true_val, m.Call(1));
+}
+
+
+TEST(RunDiamondPhiParam) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ BuildDiamondPhi(&m, m.Parameter(0), m.Parameter(1), m.Parameter(2));
+ int32_t c1 = 0x260cb75a;
+ int32_t c2 = 0xcd3e9c8b;
+ int result = m.Call(0, c1, c2);
+ CHECK_EQ(c2, result);
+ result = m.Call(1, c1, c2);
+ CHECK_EQ(c1, result);
+}
+
+
+TEST(RunLoopPhiConst) {
+ RawMachineAssemblerTester<int32_t> m;
+ int true_val = 0x44000;
+ int false_val = 0x00888;
+
+ Node* cond_node = m.Int32Constant(0);
+ Node* true_node = m.Int32Constant(true_val);
+ Node* false_node = m.Int32Constant(false_val);
+
+ // x = false_val; while(false) { x = true_val; } return x;
+ MLabel body, header;
+ MLabel* end = m.Exit();
+
+ m.Goto(&header);
+ m.Bind(&header);
+ Node* phi = m.Phi(false_node, true_node);
+ m.Branch(cond_node, &body, end);
+ m.Bind(&body);
+ m.Goto(&header);
+ m.Bind(end);
+ m.Return(phi);
+
+ CHECK_EQ(false_val, m.Call());
+}
+
+
+TEST(RunLoopPhiParam) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+
+ MLabel blocka, blockb;
+ MLabel* end = m.Exit();
+
+ m.Goto(&blocka);
+
+ m.Bind(&blocka);
+ Node* phi = m.Phi(m.Parameter(1), m.Parameter(2));
+ Node* cond = m.Phi(m.Parameter(0), m.Int32Constant(0));
+ m.Branch(cond, &blockb, end);
+
+ m.Bind(&blockb);
+ m.Goto(&blocka);
+
+ m.Bind(end);
+ m.Return(phi);
+
+ int32_t c1 = 0xa81903b4;
+ int32_t c2 = 0x5a1207da;
+ int result = m.Call(0, c1, c2);
+ CHECK_EQ(c1, result);
+ result = m.Call(1, c1, c2);
+ CHECK_EQ(c2, result);
+}
+
+
+TEST(RunLoopPhiInduction) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ int false_val = 0x10777;
+
+ // x = false_val; while(false) { x++; } return x;
+ MLabel header, body;
+ MLabel* end = m.Exit();
+ Node* false_node = m.Int32Constant(false_val);
+
+ m.Goto(&header);
+
+ m.Bind(&header);
+ Node* phi = m.Phi(false_node, false_node);
+ m.Branch(m.Int32Constant(0), &body, end);
+
+ m.Bind(&body);
+ Node* add = m.Int32Add(phi, m.Int32Constant(1));
+ phi->ReplaceInput(1, add);
+ m.Goto(&header);
+
+ m.Bind(end);
+ m.Return(phi);
+
+ CHECK_EQ(false_val, m.Call());
+}
+
+
+TEST(RunLoopIncrement) {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+
+ // x = 0; while(x ^ param) { x++; } return x;
+ MLabel header, body;
+ MLabel* end = m.Exit();
+ Node* zero = m.Int32Constant(0);
+
+ m.Goto(&header);
+
+ m.Bind(&header);
+ Node* phi = m.Phi(zero, zero);
+ m.Branch(m.WordXor(phi, bt.param0), &body, end);
+
+ m.Bind(&body);
+ phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
+ m.Goto(&header);
+
+ m.Bind(end);
+ bt.AddReturn(phi);
+
+ CHECK_EQ(11, bt.call(11, 0));
+ CHECK_EQ(110, bt.call(110, 0));
+ CHECK_EQ(176, bt.call(176, 0));
+}
+
+
+TEST(RunLoopIncrement2) {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+
+ // x = 0; while(x < param) { x++; } return x;
+ MLabel header, body;
+ MLabel* end = m.Exit();
+ Node* zero = m.Int32Constant(0);
+
+ m.Goto(&header);
+
+ m.Bind(&header);
+ Node* phi = m.Phi(zero, zero);
+ m.Branch(m.Int32LessThan(phi, bt.param0), &body, end);
+
+ m.Bind(&body);
+ phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
+ m.Goto(&header);
+
+ m.Bind(end);
+ bt.AddReturn(phi);
+
+ CHECK_EQ(11, bt.call(11, 0));
+ CHECK_EQ(110, bt.call(110, 0));
+ CHECK_EQ(176, bt.call(176, 0));
+ CHECK_EQ(0, bt.call(-200, 0));
+}
+
+
+TEST(RunLoopIncrement3) {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+
+ // x = 0; while(x < param) { x++; } return x;
+ MLabel header, body;
+ MLabel* end = m.Exit();
+ Node* zero = m.Int32Constant(0);
+
+ m.Goto(&header);
+
+ m.Bind(&header);
+ Node* phi = m.Phi(zero, zero);
+ m.Branch(m.Uint32LessThan(phi, bt.param0), &body, end);
+
+ m.Bind(&body);
+ phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
+ m.Goto(&header);
+
+ m.Bind(end);
+ bt.AddReturn(phi);
+
+ CHECK_EQ(11, bt.call(11, 0));
+ CHECK_EQ(110, bt.call(110, 0));
+ CHECK_EQ(176, bt.call(176, 0));
+ CHECK_EQ(200, bt.call(200, 0));
+}
+
+
+TEST(RunLoopDecrement) {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+
+ // x = param; while(x) { x--; } return x;
+ MLabel header, body;
+ MLabel* end = m.Exit();
+
+ m.Goto(&header);
+
+ m.Bind(&header);
+ Node* phi = m.Phi(bt.param0, m.Int32Constant(0));
+ m.Branch(phi, &body, end);
+
+ m.Bind(&body);
+ phi->ReplaceInput(1, m.Int32Sub(phi, m.Int32Constant(1)));
+ m.Goto(&header);
+
+ m.Bind(end);
+ bt.AddReturn(phi);
+
+ CHECK_EQ(0, bt.call(11, 0));
+ CHECK_EQ(0, bt.call(110, 0));
+ CHECK_EQ(0, bt.call(197, 0));
+}
+
+
+TEST(RunLoopIncrementFloat64) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ // x = -3.0; while(x < 10) { x = x + 0.5; } return (int) x;
+ MLabel header, body;
+ MLabel* end = m.Exit();
+ Node* minus_3 = m.Float64Constant(-3.0);
+ Node* ten = m.Float64Constant(10.0);
+
+ m.Goto(&header);
+
+ m.Bind(&header);
+ Node* phi = m.Phi(minus_3, ten);
+ m.Branch(m.Float64LessThan(phi, ten), &body, end);
+
+ m.Bind(&body);
+ phi->ReplaceInput(1, m.Float64Add(phi, m.Float64Constant(0.5)));
+ m.Goto(&header);
+
+ m.Bind(end);
+ m.Return(m.ChangeFloat64ToInt32(phi));
+
+ CHECK_EQ(10, m.Call());
+}
+
+
+TEST(RunLoadInt32) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ int32_t p1 = 0; // loads directly from this location.
+ m.Return(m.LoadFromPointer(&p1, kMachineWord32));
+
+ FOR_INT32_INPUTS(i) {
+ p1 = *i;
+ CHECK_EQ(p1, m.Call());
+ }
+}
+
+
+TEST(RunLoadInt32Offset) {
+ int32_t p1 = 0; // loads directly from this location.
+
+ int32_t offsets[] = {-2000000, -100, -101, 1, 3,
+ 7, 120, 2000, 2000000000, 0xff};
+
+ for (size_t i = 0; i < ARRAY_SIZE(offsets); i++) {
+ RawMachineAssemblerTester<int32_t> m;
+ int32_t offset = offsets[i];
+ byte* pointer = reinterpret_cast<byte*>(&p1) - offset;
+ // generate load [#base + #index]
+ m.Return(m.LoadFromPointer(pointer, kMachineWord32, offset));
+
+ FOR_INT32_INPUTS(j) {
+ p1 = *j;
+ CHECK_EQ(p1, m.Call());
+ }
+ }
+}
+
+
+TEST(RunLoadStoreFloat64Offset) {
+ double p1 = 0; // loads directly from this location.
+ double p2 = 0; // and stores directly into this location.
+
+ FOR_INT32_INPUTS(i) {
+ int32_t magic = 0x2342aabb + *i * 3;
+ RawMachineAssemblerTester<int32_t> m;
+ int32_t offset = *i;
+ byte* from = reinterpret_cast<byte*>(&p1) - offset;
+ byte* to = reinterpret_cast<byte*>(&p2) - offset;
+ // generate load [#base + #index]
+ Node* load = m.Load(kMachineFloat64, m.PointerConstant(from),
+ m.Int32Constant(offset));
+ m.Store(kMachineFloat64, m.PointerConstant(to), m.Int32Constant(offset),
+ load);
+ m.Return(m.Int32Constant(magic));
+
+ FOR_FLOAT64_INPUTS(j) {
+ p1 = *j;
+ p2 = *j - 5;
+ CHECK_EQ(magic, m.Call());
+ CHECK_EQ(p1, p2);
+ }
+ }
+}
+
+
+TEST(RunInt32AddP) {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+
+ bt.AddReturn(m.Int32Add(bt.param0, bt.param1));
+
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ // Use uint32_t because signed overflow is UB in C.
+ int expected = static_cast<int32_t>(*i + *j);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+}
+
+
+TEST(RunInt32AddAndWord32SarP) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Int32Add(m.Parameter(0),
+ m.Word32Sar(m.Parameter(1), m.Parameter(2))));
+ FOR_UINT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = *i + (*j >> shift);
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Int32Add(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2)));
+ FOR_INT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *j & 0x1F;
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = (*i >> shift) + *k;
+ CHECK_EQ(expected, m.Call(*i, shift, *k));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32AddAndWord32ShlP) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Int32Add(m.Parameter(0),
+ m.Word32Shl(m.Parameter(1), m.Parameter(2))));
+ FOR_UINT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = *i + (*j << shift);
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Int32Add(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2)));
+ FOR_INT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *j & 0x1F;
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = (*i << shift) + *k;
+ CHECK_EQ(expected, m.Call(*i, shift, *k));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32AddAndWord32ShrP) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Int32Add(m.Parameter(0),
+ m.Word32Shr(m.Parameter(1), m.Parameter(2))));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = *i + (*j >> shift);
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Int32Add(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *j & 0x1F;
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = (*i >> shift) + *k;
+ CHECK_EQ(expected, m.Call(*i, shift, *k));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32AddInBranch) {
+ static const int32_t constant = 987654321;
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ bt.AddReturn(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ bt.AddReturn(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i + *j) == 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32NotEqual(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ bt.AddReturn(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ bt.AddReturn(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i + *j) != 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i + *j) == 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(m.Word32NotEqual(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i + *j) != 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<void> m;
+ Operator* shops[] = {m.machine()->Word32Sar(), m.machine()->Word32Shl(),
+ m.machine()->Word32Shr()};
+ for (size_t n = 0; n < ARRAY_SIZE(shops); n++) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(m.Int32Add(m.Parameter(0),
+ m.NewNode(shops[n], m.Parameter(1),
+ m.Parameter(2))),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ int32_t right;
+ switch (shops[n]->opcode()) {
+ default:
+ UNREACHABLE();
+ case IrOpcode::kWord32Sar:
+ right = *j >> shift;
+ break;
+ case IrOpcode::kWord32Shl:
+ right = *j << shift;
+ break;
+ case IrOpcode::kWord32Shr:
+ right = static_cast<uint32_t>(*j) >> shift;
+ break;
+ }
+ int32_t expected = ((*i + right) == 0) ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32AddInComparison) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i + *j) == 0;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Equal(m.Int32Constant(0), m.Int32Add(bt.param0, bt.param1)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i + *j) == 0;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i + *j) == 0;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Equal(m.Int32Add(m.Parameter(0), m.Int32Constant(*i)),
+ m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*j + *i) == 0;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<void> m;
+ Operator* shops[] = {m.machine()->Word32Sar(), m.machine()->Word32Shl(),
+ m.machine()->Word32Shr()};
+ for (size_t n = 0; n < ARRAY_SIZE(shops); n++) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Word32Equal(
+ m.Int32Add(m.Parameter(0),
+ m.NewNode(shops[n], m.Parameter(1), m.Parameter(2))),
+ m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ int32_t right;
+ switch (shops[n]->opcode()) {
+ default:
+ UNREACHABLE();
+ case IrOpcode::kWord32Sar:
+ right = *j >> shift;
+ break;
+ case IrOpcode::kWord32Shl:
+ right = *j << shift;
+ break;
+ case IrOpcode::kWord32Shr:
+ right = static_cast<uint32_t>(*j) >> shift;
+ break;
+ }
+ int32_t expected = (*i + right) == 0;
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32SubP) {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+
+ m.Return(m.Int32Sub(bt.param0, bt.param1));
+
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ // Use uint32_t because signed overflow is UB in C.
+ int expected = static_cast<int32_t>(*i - *j);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+}
+
+
+TEST(RunInt32SubImm) {
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)));
+ FOR_UINT32_INPUTS(j) {
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = static_cast<int32_t>(*i - *j);
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)));
+ FOR_UINT32_INPUTS(j) {
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = static_cast<int32_t>(*j - *i);
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32SubAndWord32SarP) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Int32Sub(m.Parameter(0),
+ m.Word32Sar(m.Parameter(1), m.Parameter(2))));
+ FOR_UINT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = *i - (*j >> shift);
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Int32Sub(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2)));
+ FOR_INT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *j & 0x1F;
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = (*i >> shift) - *k;
+ CHECK_EQ(expected, m.Call(*i, shift, *k));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32SubAndWord32ShlP) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Int32Sub(m.Parameter(0),
+ m.Word32Shl(m.Parameter(1), m.Parameter(2))));
+ FOR_UINT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = *i - (*j << shift);
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Int32Sub(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2)));
+ FOR_INT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *j & 0x1F;
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = (*i << shift) - *k;
+ CHECK_EQ(expected, m.Call(*i, shift, *k));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32SubAndWord32ShrP) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Int32Sub(m.Parameter(0),
+ m.Word32Shr(m.Parameter(1), m.Parameter(2))));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = *i - (*j >> shift);
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Int32Sub(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *j & 0x1F;
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t expected = (*i >> shift) - *k;
+ CHECK_EQ(expected, m.Call(*i, shift, *k));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32SubInBranch) {
+ static const int constant = 987654321;
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ bt.AddReturn(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ bt.AddReturn(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i - *j) == 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32NotEqual(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ bt.AddReturn(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ bt.AddReturn(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i - *j) != 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i - *j) == 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(m.Word32NotEqual(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i - *j) != 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<void> m;
+ Operator* shops[] = {m.machine()->Word32Sar(), m.machine()->Word32Shl(),
+ m.machine()->Word32Shr()};
+ for (size_t n = 0; n < ARRAY_SIZE(shops); n++) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(m.Int32Sub(m.Parameter(0),
+ m.NewNode(shops[n], m.Parameter(1),
+ m.Parameter(2))),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ int32_t right;
+ switch (shops[n]->opcode()) {
+ default:
+ UNREACHABLE();
+ case IrOpcode::kWord32Sar:
+ right = *j >> shift;
+ break;
+ case IrOpcode::kWord32Shl:
+ right = *j << shift;
+ break;
+ case IrOpcode::kWord32Shr:
+ right = static_cast<uint32_t>(*j) >> shift;
+ break;
+ }
+ int32_t expected = ((*i - right) == 0) ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32SubInComparison) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i - *j) == 0;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Equal(m.Int32Constant(0), m.Int32Sub(bt.param0, bt.param1)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i - *j) == 0;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i - *j) == 0;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Equal(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)),
+ m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*j - *i) == 0;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<void> m;
+ Operator* shops[] = {m.machine()->Word32Sar(), m.machine()->Word32Shl(),
+ m.machine()->Word32Shr()};
+ for (size_t n = 0; n < ARRAY_SIZE(shops); n++) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Word32Equal(
+ m.Int32Sub(m.Parameter(0),
+ m.NewNode(shops[n], m.Parameter(1), m.Parameter(2))),
+ m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ int32_t right;
+ switch (shops[n]->opcode()) {
+ default:
+ UNREACHABLE();
+ case IrOpcode::kWord32Sar:
+ right = *j >> shift;
+ break;
+ case IrOpcode::kWord32Shl:
+ right = *j << shift;
+ break;
+ case IrOpcode::kWord32Shr:
+ right = static_cast<uint32_t>(*j) >> shift;
+ break;
+ }
+ int32_t expected = (*i - right) == 0;
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32MulP) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Int32Mul(bt.param0, bt.param1));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ int expected = static_cast<int32_t>(*i * *j);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Int32Mul(bt.param0, bt.param1));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int expected = static_cast<int32_t>(*i * *j);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32MulImm) {
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Int32Mul(m.Int32Constant(*i), m.Parameter(0)));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = static_cast<int32_t>(*i * *j);
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant(*i)));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = static_cast<int32_t>(*j * *i);
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32MulAndInt32AddP) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(
+ m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ int32_t p0 = *i;
+ int32_t p1 = *j;
+ int32_t p2 = *k;
+ int expected = p0 + static_cast<int32_t>(p1 * p2);
+ CHECK_EQ(expected, m.Call(p0, p1, p2));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(
+ m.Int32Add(m.Int32Mul(m.Parameter(0), m.Parameter(1)), m.Parameter(2)));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ int32_t p0 = *i;
+ int32_t p1 = *j;
+ int32_t p2 = *k;
+ int expected = static_cast<int32_t>(p0 * p1) + p2;
+ CHECK_EQ(expected, m.Call(p0, p1, p2));
+ }
+ }
+ }
+ }
+ {
+ FOR_INT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Int32Add(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1)));
+ FOR_INT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ int32_t p0 = *j;
+ int32_t p1 = *k;
+ int expected = *i + static_cast<int32_t>(p0 * p1);
+ CHECK_EQ(expected, bt.call(p0, p1));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32MulAndInt32SubP) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(
+ m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
+ FOR_UINT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ uint32_t p0 = *i;
+ int32_t p1 = *j;
+ int32_t p2 = *k;
+ // Use uint32_t because signed overflow is UB in C.
+ int expected = p0 - static_cast<uint32_t>(p1 * p2);
+ CHECK_EQ(expected, m.Call(p0, p1, p2));
+ }
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Int32Sub(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1)));
+ FOR_INT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ int32_t p0 = *j;
+ int32_t p1 = *k;
+ // Use uint32_t because signed overflow is UB in C.
+ int expected = *i - static_cast<uint32_t>(p0 * p1);
+ CHECK_EQ(expected, bt.call(p0, p1));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32DivP) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Int32Div(bt.param0, bt.param1));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ int p0 = *i;
+ int p1 = *j;
+ if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
+ int expected = static_cast<int32_t>(p0 / p1);
+ CHECK_EQ(expected, bt.call(p0, p1));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Int32Add(bt.param0, m.Int32Div(bt.param0, bt.param1)));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ int p0 = *i;
+ int p1 = *j;
+ if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
+ int expected = static_cast<int32_t>(p0 + (p0 / p1));
+ CHECK_EQ(expected, bt.call(p0, p1));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32UDivP) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Int32UDiv(bt.param0, bt.param1));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t p0 = *i;
+ uint32_t p1 = *j;
+ if (p1 != 0) {
+ uint32_t expected = static_cast<uint32_t>(p0 / p1);
+ CHECK_EQ(expected, bt.call(p0, p1));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Int32Add(bt.param0, m.Int32UDiv(bt.param0, bt.param1)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t p0 = *i;
+ uint32_t p1 = *j;
+ if (p1 != 0) {
+ uint32_t expected = static_cast<uint32_t>(p0 + (p0 / p1));
+ CHECK_EQ(expected, bt.call(p0, p1));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32ModP) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Int32Mod(bt.param0, bt.param1));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ int p0 = *i;
+ int p1 = *j;
+ if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
+ int expected = static_cast<int32_t>(p0 % p1);
+ CHECK_EQ(expected, bt.call(p0, p1));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Int32Add(bt.param0, m.Int32Mod(bt.param0, bt.param1)));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ int p0 = *i;
+ int p1 = *j;
+ if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
+ int expected = static_cast<int32_t>(p0 + (p0 % p1));
+ CHECK_EQ(expected, bt.call(p0, p1));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32UModP) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Int32UMod(bt.param0, bt.param1));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t p0 = *i;
+ uint32_t p1 = *j;
+ if (p1 != 0) {
+ uint32_t expected = static_cast<uint32_t>(p0 % p1);
+ CHECK_EQ(expected, bt.call(p0, p1));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Int32Add(bt.param0, m.Int32UMod(bt.param0, bt.param1)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t p0 = *i;
+ uint32_t p1 = *j;
+ if (p1 != 0) {
+ uint32_t expected = static_cast<uint32_t>(p0 + (p0 % p1));
+ CHECK_EQ(expected, bt.call(p0, p1));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32AndP) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32And(bt.param0, bt.param1));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i & *j;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32And(bt.param0, m.Word32Not(bt.param1)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i & ~(*j);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32And(m.Word32Not(bt.param0), bt.param1));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = ~(*i) & *j;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32AndAndWord32ShlP) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Shl(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i << (*j & 0x1f);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Shl(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i << (0x1f & *j);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32AndAndWord32ShrP) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Shr(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i >> (*j & 0x1f);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Shr(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i >> (0x1f & *j);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32AndAndWord32SarP) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Sar(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
+ FOR_INT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i >> (*j & 0x1f);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Sar(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
+ FOR_INT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i >> (0x1f & *j);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32AndImm) {
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32And(m.Int32Constant(*i), m.Parameter(0)));
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i & *j;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32And(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i & ~(*j);
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32AndInBranch) {
+ static const int constant = 987654321;
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ bt.AddReturn(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ bt.AddReturn(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i & *j) == 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32NotEqual(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ bt.AddReturn(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ bt.AddReturn(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i & *j) != 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i & *j) == 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32NotEqual(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i & *j) != 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<void> m;
+ Operator* shops[] = {m.machine()->Word32Sar(), m.machine()->Word32Shl(),
+ m.machine()->Word32Shr()};
+ for (size_t n = 0; n < ARRAY_SIZE(shops); n++) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(m.Word32And(m.Parameter(0),
+ m.NewNode(shops[n], m.Parameter(1),
+ m.Parameter(2))),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ int32_t right;
+ switch (shops[n]->opcode()) {
+ default:
+ UNREACHABLE();
+ case IrOpcode::kWord32Sar:
+ right = *j >> shift;
+ break;
+ case IrOpcode::kWord32Shl:
+ right = *j << shift;
+ break;
+ case IrOpcode::kWord32Shr:
+ right = static_cast<uint32_t>(*j) >> shift;
+ break;
+ }
+ int32_t expected = ((*i & right) == 0) ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32AndInComparison) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i & *j) == 0;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Equal(m.Int32Constant(0), m.Word32And(bt.param0, bt.param1)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i & *j) == 0;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i & *j) == 0;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Equal(m.Word32And(m.Parameter(0), m.Int32Constant(*i)),
+ m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*j & *i) == 0;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32OrP) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32Or(bt.param0, bt.param1));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i | *j;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32Or(bt.param0, m.Word32Not(bt.param1)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i | ~(*j);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32Or(m.Word32Not(bt.param0), bt.param1));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = ~(*i) | *j;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32OrImm) {
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)));
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i | *j;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Or(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i | ~(*j);
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32OrInBranch) {
+ static const int constant = 987654321;
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ bt.AddReturn(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ bt.AddReturn(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i | *j) == 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32NotEqual(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ bt.AddReturn(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ bt.AddReturn(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i | *j) != 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i | *j) == 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(m.Word32NotEqual(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i | *j) != 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<void> m;
+ Operator* shops[] = {m.machine()->Word32Sar(), m.machine()->Word32Shl(),
+ m.machine()->Word32Shr()};
+ for (size_t n = 0; n < ARRAY_SIZE(shops); n++) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(m.Word32Or(m.Parameter(0),
+ m.NewNode(shops[n], m.Parameter(1),
+ m.Parameter(2))),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ int32_t right;
+ switch (shops[n]->opcode()) {
+ default:
+ UNREACHABLE();
+ case IrOpcode::kWord32Sar:
+ right = *j >> shift;
+ break;
+ case IrOpcode::kWord32Shl:
+ right = *j << shift;
+ break;
+ case IrOpcode::kWord32Shr:
+ right = static_cast<uint32_t>(*j) >> shift;
+ break;
+ }
+ int32_t expected = ((*i | right) == 0) ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32OrInComparison) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i | *j) == 0;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(
+ m.Word32Equal(m.Int32Constant(0), m.Word32Or(bt.param0, bt.param1)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i | *j) == 0;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i | *j) == 0;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Equal(m.Word32Or(m.Parameter(0), m.Int32Constant(*i)),
+ m.Int32Constant(0)));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*j | *i) == 0;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32XorP) {
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)));
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i ^ *j;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32Xor(bt.param0, bt.param1));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i ^ *j;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32Xor(bt.param0, m.Word32Not(bt.param1)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i ^ ~(*j);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32Xor(m.Word32Not(bt.param0), bt.param1));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = ~(*i) ^ *j;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Xor(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *i ^ ~(*j);
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32XorInBranch) {
+ static const int constant = 987654321;
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32Equal(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ bt.AddReturn(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ bt.AddReturn(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32NotEqual(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ bt.AddReturn(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ bt.AddReturn(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ FOR_UINT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(
+ m.Word32NotEqual(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<void> m;
+ Operator* shops[] = {m.machine()->Word32Sar(), m.machine()->Word32Shl(),
+ m.machine()->Word32Shr()};
+ for (size_t n = 0; n < ARRAY_SIZE(shops); n++) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ MLabel blocka, blockb;
+ m.Branch(m.Word32Equal(m.Word32Xor(m.Parameter(0),
+ m.NewNode(shops[n], m.Parameter(1),
+ m.Parameter(2))),
+ m.Int32Constant(0)),
+ &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Return(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ m.Return(m.Int32Constant(0 - constant));
+ FOR_UINT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ int32_t right;
+ switch (shops[n]->opcode()) {
+ default:
+ UNREACHABLE();
+ case IrOpcode::kWord32Sar:
+ right = *j >> shift;
+ break;
+ case IrOpcode::kWord32Shl:
+ right = *j << shift;
+ break;
+ case IrOpcode::kWord32Shr:
+ right = static_cast<uint32_t>(*j) >> shift;
+ break;
+ }
+ int32_t expected = ((*i ^ right) == 0) ? constant : 0 - constant;
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32ShlP) {
+ {
+ FOR_UINT32_INPUTS(i) {
+ uint32_t shift = *i & 0x1F;
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)));
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *j << shift;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32Shl(bt.param0, bt.param1));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t shift = *j & 0x1F;
+ uint32_t expected = *i << shift;
+ CHECK_EQ(expected, bt.call(*i, shift));
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32ShrP) {
+ {
+ FOR_UINT32_INPUTS(i) {
+ uint32_t shift = *i & 0x1F;
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)));
+ FOR_UINT32_INPUTS(j) {
+ uint32_t expected = *j >> shift;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32Shr(bt.param0, bt.param1));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ uint32_t shift = *j & 0x1F;
+ uint32_t expected = *i >> shift;
+ CHECK_EQ(expected, bt.call(*i, shift));
+ }
+ }
+ CHECK_EQ(0x00010000, bt.call(0x80000000, 15));
+ }
+}
+
+
+TEST(RunWord32SarP) {
+ {
+ FOR_INT32_INPUTS(i) {
+ int32_t shift = *i & 0x1F;
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)));
+ FOR_INT32_INPUTS(j) {
+ int32_t expected = *j >> shift;
+ CHECK_EQ(expected, m.Call(*j));
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32Sar(bt.param0, bt.param1));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ int32_t shift = *j & 0x1F;
+ int32_t expected = *i >> shift;
+ CHECK_EQ(expected, bt.call(*i, shift));
+ }
+ }
+ CHECK_EQ(0xFFFF0000, bt.call(0x80000000, 15));
+ }
+}
+
+
+TEST(RunWord32NotP) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Word32Not(m.Parameter(0)));
+ FOR_UINT32_INPUTS(i) {
+ int expected = ~(*i);
+ CHECK_EQ(expected, m.Call(*i));
+ }
+}
+
+
+TEST(RunInt32NegP) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ m.Return(m.Int32Neg(m.Parameter(0)));
+ FOR_INT32_INPUTS(i) {
+ int expected = -*i;
+ CHECK_EQ(expected, m.Call(*i));
+ }
+}
+
+
+TEST(RunWord32EqualAndWord32SarP) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Word32Equal(m.Parameter(0),
+ m.Word32Sar(m.Parameter(1), m.Parameter(2))));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ int32_t expected = (*i == (*j >> shift));
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2)));
+ FOR_INT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ uint32_t shift = *j & 0x1F;
+ int32_t expected = ((*i >> shift) == *k);
+ CHECK_EQ(expected, m.Call(*i, shift, *k));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32EqualAndWord32ShlP) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Word32Equal(m.Parameter(0),
+ m.Word32Shl(m.Parameter(1), m.Parameter(2))));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ int32_t expected = (*i == (*j << shift));
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *j & 0x1F;
+ int32_t expected = ((*i << shift) == *k);
+ CHECK_EQ(expected, m.Call(*i, shift, *k));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunWord32EqualAndWord32ShrP) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Word32Equal(m.Parameter(0),
+ m.Word32Shr(m.Parameter(1), m.Parameter(2))));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *k & 0x1F;
+ int32_t expected = (*i == (*j >> shift));
+ CHECK_EQ(expected, m.Call(*i, *j, shift));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32,
+ kMachineWord32);
+ m.Return(m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2)));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ FOR_UINT32_INPUTS(k) {
+ uint32_t shift = *j & 0x1F;
+ int32_t expected = ((*i >> shift) == *k);
+ CHECK_EQ(expected, m.Call(*i, shift, *k));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunDeadNodes) {
+ for (int i = 0; true; i++) {
+ RawMachineAssemblerTester<int32_t> m(i == 5 ? kMachineWord32
+ : kMachineLast);
+ int constant = 0x55 + i;
+ switch (i) {
+ case 0:
+ m.Int32Constant(44);
+ break;
+ case 1:
+ m.StringConstant("unused");
+ break;
+ case 2:
+ m.NumberConstant(11.1);
+ break;
+ case 3:
+ m.PointerConstant(&constant);
+ break;
+ case 4:
+ m.LoadFromPointer(&constant, kMachineWord32);
+ break;
+ case 5:
+ m.Parameter(0);
+ break;
+ default:
+ return;
+ }
+ m.Return(m.Int32Constant(constant));
+ if (i != 5) {
+ CHECK_EQ(constant, m.Call());
+ } else {
+ CHECK_EQ(constant, m.Call(0));
+ }
+ }
+}
+
+
+TEST(RunDeadInt32Binops) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ Operator* ops[] = {
+ m.machine()->Word32And(), m.machine()->Word32Or(),
+ m.machine()->Word32Xor(), m.machine()->Word32Shl(),
+ m.machine()->Word32Shr(), m.machine()->Word32Sar(),
+ m.machine()->Word32Equal(), m.machine()->Int32Add(),
+ m.machine()->Int32Sub(), m.machine()->Int32Mul(),
+ m.machine()->Int32Div(), m.machine()->Int32UDiv(),
+ m.machine()->Int32Mod(), m.machine()->Int32UMod(),
+ m.machine()->Int32LessThan(), m.machine()->Int32LessThanOrEqual(),
+ m.machine()->Uint32LessThan(), m.machine()->Uint32LessThanOrEqual(),
+ NULL};
+
+ for (int i = 0; ops[i] != NULL; i++) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
+ int constant = 0x55555 + i;
+ m.NewNode(ops[i], m.Parameter(0), m.Parameter(1));
+ m.Return(m.Int32Constant(constant));
+
+ CHECK_EQ(constant, m.Call(1, 1));
+ }
+}
+
+
+template <typename Type, typename CType>
+static void RunLoadImmIndex(MachineType rep) {
+ const int kNumElems = 3;
+ CType buffer[kNumElems];
+
+ // initialize the buffer with raw data.
+ byte* raw = reinterpret_cast<byte*>(buffer);
+ for (size_t i = 0; i < sizeof(buffer); i++) {
+ raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA);
+ }
+
+ // Test with various large and small offsets.
+ for (int offset = -1; offset <= 200000; offset *= -5) {
+ for (int i = 0; i < kNumElems; i++) {
+ RawMachineAssemblerTester<Type> m;
+ Node* base = m.PointerConstant(buffer - offset);
+ Node* index = m.Int32Constant((offset + i) * sizeof(buffer[0]));
+ m.Return(m.Load(rep, base, index));
+
+ Type expected = buffer[i];
+ Type actual = static_cast<CType>(m.Call());
+ CHECK_EQ(expected, actual);
+ printf("XXX\n");
+ }
+ }
+}
+
+
+TEST(RunLoadImmIndex) {
+ RunLoadImmIndex<int8_t, uint8_t>(kMachineWord8);
+ RunLoadImmIndex<int16_t, uint16_t>(kMachineWord16);
+ RunLoadImmIndex<int32_t, uint32_t>(kMachineWord32);
+ RunLoadImmIndex<int32_t*, int32_t*>(kMachineTagged);
+
+ // TODO(titzer): test kMachineFloat64 loads
+ // TODO(titzer): test various indexing modes.
+}
+
+
+template <typename CType>
+static void RunLoadStore(MachineType rep) {
+ const int kNumElems = 4;
+ CType buffer[kNumElems];
+
+ for (int32_t x = 0; x < kNumElems; x++) {
+ int32_t y = kNumElems - x - 1;
+ // initialize the buffer with raw data.
+ byte* raw = reinterpret_cast<byte*>(buffer);
+ for (size_t i = 0; i < sizeof(buffer); i++) {
+ raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA);
+ }
+
+ RawMachineAssemblerTester<int32_t> m;
+ int32_t OK = 0x29000 + x;
+ Node* base = m.PointerConstant(buffer);
+ Node* index0 = m.Int32Constant(x * sizeof(buffer[0]));
+ Node* load = m.Load(rep, base, index0);
+ Node* index1 = m.Int32Constant(y * sizeof(buffer[0]));
+ m.Store(rep, base, index1, load);
+ m.Return(m.Int32Constant(OK));
+
+ CHECK_NE(buffer[x], buffer[y]);
+ CHECK_EQ(OK, m.Call());
+ CHECK_EQ(buffer[x], buffer[y]);
+ }
+}
+
+
+TEST(RunLoadStore) {
+ RunLoadStore<int8_t>(kMachineWord8);
+ RunLoadStore<int16_t>(kMachineWord16);
+ RunLoadStore<int32_t>(kMachineWord32);
+ RunLoadStore<void*>(kMachineTagged);
+ RunLoadStore<double>(kMachineFloat64);
+}
+
+
+TEST(RunFloat64Binop) {
+ RawMachineAssemblerTester<int32_t> m;
+ double result;
+
+ Operator* ops[] = {m.machine()->Float64Add(), m.machine()->Float64Sub(),
+ m.machine()->Float64Mul(), m.machine()->Float64Div(),
+ m.machine()->Float64Mod(), NULL};
+
+ double inf = V8_INFINITY;
+ Operator* inputs[] = {
+ m.common()->Float64Constant(0), m.common()->Float64Constant(1),
+ m.common()->Float64Constant(1), m.common()->Float64Constant(0),
+ m.common()->Float64Constant(0), m.common()->Float64Constant(-1),
+ m.common()->Float64Constant(-1), m.common()->Float64Constant(0),
+ m.common()->Float64Constant(0.22), m.common()->Float64Constant(-1.22),
+ m.common()->Float64Constant(-1.22), m.common()->Float64Constant(0.22),
+ m.common()->Float64Constant(inf), m.common()->Float64Constant(0.22),
+ m.common()->Float64Constant(inf), m.common()->Float64Constant(-inf),
+ NULL};
+
+ for (int i = 0; ops[i] != NULL; i++) {
+ for (int j = 0; inputs[j] != NULL; j += 2) {
+ RawMachineAssemblerTester<int32_t> m;
+ Node* a = m.NewNode(inputs[j]);
+ Node* b = m.NewNode(inputs[j + 1]);
+ Node* binop = m.NewNode(ops[i], a, b);
+ Node* base = m.PointerConstant(&result);
+ Node* zero = m.Int32Constant(0);
+ m.Store(kMachineFloat64, base, zero, binop);
+ m.Return(m.Int32Constant(i + j));
+ CHECK_EQ(i + j, m.Call());
+ }
+ }
+}
+
+
+TEST(RunDeadFloat64Binops) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ Operator* ops[] = {m.machine()->Float64Add(), m.machine()->Float64Sub(),
+ m.machine()->Float64Mul(), m.machine()->Float64Div(),
+ m.machine()->Float64Mod(), NULL};
+
+ for (int i = 0; ops[i] != NULL; i++) {
+ RawMachineAssemblerTester<int32_t> m;
+ int constant = 0x53355 + i;
+ m.NewNode(ops[i], m.Float64Constant(0.1), m.Float64Constant(1.11));
+ m.Return(m.Int32Constant(constant));
+ CHECK_EQ(constant, m.Call());
+ }
+}
+
+
+TEST(RunFloat64AddP) {
+ RawMachineAssemblerTester<int32_t> m;
+ Float64BinopTester bt(&m);
+
+ bt.AddReturn(m.Float64Add(bt.param0, bt.param1));
+
+ FOR_FLOAT64_INPUTS(pl) {
+ FOR_FLOAT64_INPUTS(pr) {
+ double expected = *pl + *pr;
+ CHECK_EQ(expected, bt.call(*pl, *pr));
+ }
+ }
+}
+
+
+TEST(RunFloat64SubP) {
+ RawMachineAssemblerTester<int32_t> m;
+ Float64BinopTester bt(&m);
+
+ bt.AddReturn(m.Float64Sub(bt.param0, bt.param1));
+
+ FOR_FLOAT64_INPUTS(pl) {
+ FOR_FLOAT64_INPUTS(pr) {
+ double expected = *pl - *pr;
+ CHECK_EQ(expected, bt.call(*pl, *pr));
+ }
+ }
+}
+
+
+TEST(RunFloat64SubImm1) {
+ double input = 0.0;
+ double output = 0.0;
+
+ FOR_FLOAT64_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m;
+ Node* t0 = m.LoadFromPointer(&input, kMachineFloat64);
+ Node* t1 = m.Float64Sub(m.Float64Constant(*i), t0);
+ m.StoreToPointer(&output, kMachineFloat64, t1);
+ m.Return(m.Int32Constant(0));
+ FOR_FLOAT64_INPUTS(j) {
+ input = *j;
+ double expected = *i - input;
+ CHECK_EQ(0, m.Call());
+ CHECK_EQ(expected, output);
+ }
+ }
+}
+
+
+TEST(RunFloat64SubImm2) {
+ double input = 0.0;
+ double output = 0.0;
+
+ FOR_FLOAT64_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m;
+ Node* t0 = m.LoadFromPointer(&input, kMachineFloat64);
+ Node* t1 = m.Float64Sub(t0, m.Float64Constant(*i));
+ m.StoreToPointer(&output, kMachineFloat64, t1);
+ m.Return(m.Int32Constant(0));
+ FOR_FLOAT64_INPUTS(j) {
+ input = *j;
+ double expected = input - *i;
+ CHECK_EQ(0, m.Call());
+ CHECK_EQ(expected, output);
+ }
+ }
+}
+
+
+TEST(RunFloat64MulP) {
+ RawMachineAssemblerTester<int32_t> m;
+ Float64BinopTester bt(&m);
+
+ bt.AddReturn(m.Float64Mul(bt.param0, bt.param1));
+
+ FOR_FLOAT64_INPUTS(pl) {
+ FOR_FLOAT64_INPUTS(pr) {
+ double expected = *pl * *pr;
+ CHECK_EQ(expected, bt.call(*pl, *pr));
+ }
+ }
+}
+
+
+TEST(RunFloat64MulAndFloat64AddP) {
+ double input_a = 0.0;
+ double input_b = 0.0;
+ double input_c = 0.0;
+ double output = 0.0;
+
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Node* a = m.LoadFromPointer(&input_a, kMachineFloat64);
+ Node* b = m.LoadFromPointer(&input_b, kMachineFloat64);
+ Node* c = m.LoadFromPointer(&input_c, kMachineFloat64);
+ m.StoreToPointer(&output, kMachineFloat64,
+ m.Float64Add(m.Float64Mul(a, b), c));
+ m.Return(m.Int32Constant(0));
+ FOR_FLOAT64_INPUTS(i) {
+ FOR_FLOAT64_INPUTS(j) {
+ FOR_FLOAT64_INPUTS(k) {
+ input_a = *i;
+ input_b = *j;
+ input_c = *k;
+ volatile double temp = input_a * input_b;
+ volatile double expected = temp + input_c;
+ CHECK_EQ(0, m.Call());
+ CHECK_EQ(expected, output);
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Node* a = m.LoadFromPointer(&input_a, kMachineFloat64);
+ Node* b = m.LoadFromPointer(&input_b, kMachineFloat64);
+ Node* c = m.LoadFromPointer(&input_c, kMachineFloat64);
+ m.StoreToPointer(&output, kMachineFloat64,
+ m.Float64Add(a, m.Float64Mul(b, c)));
+ m.Return(m.Int32Constant(0));
+ FOR_FLOAT64_INPUTS(i) {
+ FOR_FLOAT64_INPUTS(j) {
+ FOR_FLOAT64_INPUTS(k) {
+ input_a = *i;
+ input_b = *j;
+ input_c = *k;
+ volatile double temp = input_b * input_c;
+ volatile double expected = input_a + temp;
+ CHECK_EQ(0, m.Call());
+ CHECK_EQ(expected, output);
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunFloat64MulAndFloat64SubP) {
+ double input_a = 0.0;
+ double input_b = 0.0;
+ double input_c = 0.0;
+ double output = 0.0;
+
+ RawMachineAssemblerTester<int32_t> m;
+ Node* a = m.LoadFromPointer(&input_a, kMachineFloat64);
+ Node* b = m.LoadFromPointer(&input_b, kMachineFloat64);
+ Node* c = m.LoadFromPointer(&input_c, kMachineFloat64);
+ m.StoreToPointer(&output, kMachineFloat64,
+ m.Float64Sub(a, m.Float64Mul(b, c)));
+ m.Return(m.Int32Constant(0));
+
+ FOR_FLOAT64_INPUTS(i) {
+ FOR_FLOAT64_INPUTS(j) {
+ FOR_FLOAT64_INPUTS(k) {
+ input_a = *i;
+ input_b = *j;
+ input_c = *k;
+ volatile double temp = input_b * input_c;
+ volatile double expected = input_a - temp;
+ CHECK_EQ(0, m.Call());
+ CHECK_EQ(expected, output);
+ }
+ }
+ }
+}
+
+
+TEST(RunFloat64MulImm) {
+ double input = 0.0;
+ double output = 0.0;
+
+ {
+ FOR_FLOAT64_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m;
+ Node* t0 = m.LoadFromPointer(&input, kMachineFloat64);
+ Node* t1 = m.Float64Mul(m.Float64Constant(*i), t0);
+ m.StoreToPointer(&output, kMachineFloat64, t1);
+ m.Return(m.Int32Constant(0));
+ FOR_FLOAT64_INPUTS(j) {
+ input = *j;
+ double expected = *i * input;
+ CHECK_EQ(0, m.Call());
+ CHECK_EQ(expected, output);
+ }
+ }
+ }
+ {
+ FOR_FLOAT64_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m;
+ Node* t0 = m.LoadFromPointer(&input, kMachineFloat64);
+ Node* t1 = m.Float64Mul(t0, m.Float64Constant(*i));
+ m.StoreToPointer(&output, kMachineFloat64, t1);
+ m.Return(m.Int32Constant(0));
+ FOR_FLOAT64_INPUTS(j) {
+ input = *j;
+ double expected = input * *i;
+ CHECK_EQ(0, m.Call());
+ CHECK_EQ(expected, output);
+ }
+ }
+ }
+}
+
+
+TEST(RunFloat64DivP) {
+ RawMachineAssemblerTester<int32_t> m;
+ Float64BinopTester bt(&m);
+
+ bt.AddReturn(m.Float64Div(bt.param0, bt.param1));
+
+ FOR_FLOAT64_INPUTS(pl) {
+ FOR_FLOAT64_INPUTS(pr) {
+ double expected = *pl / *pr;
+ CHECK_EQ(expected, bt.call(*pl, *pr));
+ }
+ }
+}
+
+
+TEST(RunFloat64ModP) {
+ RawMachineAssemblerTester<int32_t> m;
+ Float64BinopTester bt(&m);
+
+ bt.AddReturn(m.Float64Mod(bt.param0, bt.param1));
+
+ FOR_FLOAT64_INPUTS(i) {
+ FOR_FLOAT64_INPUTS(j) {
+ double expected = modulo(*i, *j);
+ double found = bt.call(*i, *j);
+ CHECK_EQ(expected, found);
+ }
+ }
+}
+
+
+TEST(RunChangeInt32ToFloat64_A) {
+ RawMachineAssemblerTester<int32_t> m;
+ int32_t magic = 0x986234;
+ double result = 0;
+
+ Node* convert = m.ChangeInt32ToFloat64(m.Int32Constant(magic));
+ m.Store(kMachineFloat64, m.PointerConstant(&result), m.Int32Constant(0),
+ convert);
+ m.Return(m.Int32Constant(magic));
+
+ CHECK_EQ(magic, m.Call());
+ CHECK_EQ(static_cast<double>(magic), result);
+}
+
+
+TEST(RunChangeInt32ToFloat64_B) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ double output = 0;
+
+ Node* convert = m.ChangeInt32ToFloat64(m.Parameter(0));
+ m.Store(kMachineFloat64, m.PointerConstant(&output), m.Int32Constant(0),
+ convert);
+ m.Return(m.Parameter(0));
+
+ FOR_INT32_INPUTS(i) {
+ int32_t expect = *i;
+ CHECK_EQ(expect, m.Call(expect));
+ CHECK_EQ(static_cast<double>(expect), output);
+ }
+}
+
+
+TEST(RunChangeUint32ToFloat64_B) {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ double output = 0;
+
+ Node* convert = m.ChangeUint32ToFloat64(m.Parameter(0));
+ m.Store(kMachineFloat64, m.PointerConstant(&output), m.Int32Constant(0),
+ convert);
+ m.Return(m.Parameter(0));
+
+ FOR_UINT32_INPUTS(i) {
+ uint32_t expect = *i;
+ CHECK_EQ(expect, m.Call(expect));
+ CHECK_EQ(static_cast<double>(expect), output);
+ }
+}
+
+
+TEST(RunChangeFloat64ToInt32_A) {
+ RawMachineAssemblerTester<int32_t> m;
+ int32_t magic = 0x786234;
+ double input = 11.1;
+ int32_t result = 0;
+
+ m.Store(kMachineWord32, m.PointerConstant(&result), m.Int32Constant(0),
+ m.ChangeFloat64ToInt32(m.Float64Constant(input)));
+ m.Return(m.Int32Constant(magic));
+
+ CHECK_EQ(magic, m.Call());
+ CHECK_EQ(static_cast<int32_t>(input), result);
+}
+
+
+TEST(RunChangeFloat64ToInt32_B) {
+ RawMachineAssemblerTester<int32_t> m;
+ double input = 0;
+ int32_t output = 0;
+
+ Node* load =
+ m.Load(kMachineFloat64, m.PointerConstant(&input), m.Int32Constant(0));
+ Node* convert = m.ChangeFloat64ToInt32(load);
+ m.Store(kMachineWord32, m.PointerConstant(&output), m.Int32Constant(0),
+ convert);
+ m.Return(convert);
+
+ {
+ FOR_INT32_INPUTS(i) {
+ input = *i;
+ int32_t expect = *i;
+ CHECK_EQ(expect, m.Call());
+ CHECK_EQ(expect, output);
+ }
+ }
+
+ // Check various powers of 2.
+ for (int32_t n = 1; n < 31; ++n) {
+ {
+ input = 1 << n;
+ int32_t expect = static_cast<int32_t>(input);
+ CHECK_EQ(expect, m.Call());
+ CHECK_EQ(expect, output);
+ }
+
+ {
+ input = 3 << n;
+ int32_t expect = static_cast<int32_t>(input);
+ CHECK_EQ(expect, m.Call());
+ CHECK_EQ(expect, output);
+ }
+ }
+ // Note we don't check fractional inputs, because these Convert operators
+ // really should be Change operators.
+}
+
+
+TEST(RunChangeFloat64ToUint32_B) {
+ RawMachineAssemblerTester<int32_t> m;
+ double input = 0;
+ int32_t output = 0;
+
+ Node* load =
+ m.Load(kMachineFloat64, m.PointerConstant(&input), m.Int32Constant(0));
+ Node* convert = m.ChangeFloat64ToUint32(load);
+ m.Store(kMachineWord32, m.PointerConstant(&output), m.Int32Constant(0),
+ convert);
+ m.Return(convert);
+
+ {
+ FOR_UINT32_INPUTS(i) {
+ input = *i;
+ // TODO(titzer): add a CheckEqualsHelper overload for uint32_t.
+ int32_t expect = static_cast<int32_t>(*i);
+ CHECK_EQ(expect, m.Call());
+ CHECK_EQ(expect, output);
+ }
+ }
+
+ // Check various powers of 2.
+ for (int32_t n = 1; n < 31; ++n) {
+ {
+ input = 1u << n;
+ int32_t expect = static_cast<int32_t>(static_cast<uint32_t>(input));
+ CHECK_EQ(expect, m.Call());
+ CHECK_EQ(expect, output);
+ }
+
+ {
+ input = 3u << n;
+ int32_t expect = static_cast<int32_t>(static_cast<uint32_t>(input));
+ CHECK_EQ(expect, m.Call());
+ CHECK_EQ(expect, output);
+ }
+ }
+ // Note we don't check fractional inputs, because these Convert operators
+ // really should be Change operators.
+}
+
+
+TEST(RunChangeFloat64ToInt32_spilled) {
+ RawMachineAssemblerTester<int32_t> m;
+ const int kNumInputs = 32;
+ int32_t magic = 0x786234;
+ double input[kNumInputs];
+ int32_t result[kNumInputs];
+ Node* input_node[kNumInputs];
+
+ for (int i = 0; i < kNumInputs; i++) {
+ input_node[i] = m.Load(kMachineFloat64, m.PointerConstant(&input),
+ m.Int32Constant(i * 8));
+ }
+
+ for (int i = 0; i < kNumInputs; i++) {
+ m.Store(kMachineWord32, m.PointerConstant(&result), m.Int32Constant(i * 4),
+ m.ChangeFloat64ToInt32(input_node[i]));
+ }
+
+ m.Return(m.Int32Constant(magic));
+
+ for (int i = 0; i < kNumInputs; i++) {
+ input[i] = 100.9 + i;
+ }
+
+ CHECK_EQ(magic, m.Call());
+
+ for (int i = 0; i < kNumInputs; i++) {
+ CHECK_EQ(result[i], 100 + i);
+ }
+}
+
+
+TEST(RunDeadChangeFloat64ToInt32) {
+ RawMachineAssemblerTester<int32_t> m;
+ const int magic = 0x88abcda4;
+ m.ChangeFloat64ToInt32(m.Float64Constant(999.78));
+ m.Return(m.Int32Constant(magic));
+ CHECK_EQ(magic, m.Call());
+}
+
+
+TEST(RunDeadChangeInt32ToFloat64) {
+ RawMachineAssemblerTester<int32_t> m;
+ const int magic = 0x8834abcd;
+ m.ChangeInt32ToFloat64(m.Int32Constant(magic - 6888));
+ m.Return(m.Int32Constant(magic));
+ CHECK_EQ(magic, m.Call());
+}
+
+
+TEST(RunLoopPhiInduction2) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ int false_val = 0x10777;
+
+ // x = false_val; while(false) { x++; } return x;
+ MLabel header, body, end;
+ Node* false_node = m.Int32Constant(false_val);
+ m.Goto(&header);
+ m.Bind(&header);
+ Node* phi = m.Phi(false_node, false_node);
+ m.Branch(m.Int32Constant(0), &body, &end);
+ m.Bind(&body);
+ Node* add = m.Int32Add(phi, m.Int32Constant(1));
+ phi->ReplaceInput(1, add);
+ m.Goto(&header);
+ m.Bind(&end);
+ m.Return(phi);
+
+ CHECK_EQ(false_val, m.Call());
+}
+
+
+TEST(RunDoubleDiamond) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ const int magic = 99645;
+ double buffer = 0.1;
+ double constant = 99.99;
+
+ MLabel blocka, blockb, end;
+ Node* k1 = m.Float64Constant(constant);
+ Node* k2 = m.Float64Constant(0 - constant);
+ m.Branch(m.Int32Constant(0), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Goto(&end);
+ m.Bind(&blockb);
+ m.Goto(&end);
+ m.Bind(&end);
+ Node* phi = m.Phi(k2, k1);
+ m.Store(kMachineFloat64, m.PointerConstant(&buffer), m.Int32Constant(0), phi);
+ m.Return(m.Int32Constant(magic));
+
+ CHECK_EQ(magic, m.Call());
+ CHECK_EQ(constant, buffer);
+}
+
+
+TEST(RunRefDiamond) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ const int magic = 99644;
+ Handle<String> rexpected =
+ CcTest::i_isolate()->factory()->InternalizeUtf8String("A");
+ String* buffer;
+
+ MLabel blocka, blockb, end;
+ Node* k1 = m.StringConstant("A");
+ Node* k2 = m.StringConstant("B");
+ m.Branch(m.Int32Constant(0), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Goto(&end);
+ m.Bind(&blockb);
+ m.Goto(&end);
+ m.Bind(&end);
+ Node* phi = m.Phi(k2, k1);
+ m.Store(kMachineTagged, m.PointerConstant(&buffer), m.Int32Constant(0), phi);
+ m.Return(m.Int32Constant(magic));
+
+ CHECK_EQ(magic, m.Call());
+ CHECK(rexpected->SameValue(buffer));
+}
+
+
+TEST(RunDoubleRefDiamond) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ const int magic = 99648;
+ double dbuffer = 0.1;
+ double dconstant = 99.99;
+ Handle<String> rexpected =
+ CcTest::i_isolate()->factory()->InternalizeUtf8String("AX");
+ String* rbuffer;
+
+ MLabel blocka, blockb, end;
+ Node* d1 = m.Float64Constant(dconstant);
+ Node* d2 = m.Float64Constant(0 - dconstant);
+ Node* r1 = m.StringConstant("AX");
+ Node* r2 = m.StringConstant("BX");
+ m.Branch(m.Int32Constant(0), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Goto(&end);
+ m.Bind(&blockb);
+ m.Goto(&end);
+ m.Bind(&end);
+ Node* dphi = m.Phi(d2, d1);
+ Node* rphi = m.Phi(r2, r1);
+ m.Store(kMachineFloat64, m.PointerConstant(&dbuffer), m.Int32Constant(0),
+ dphi);
+ m.Store(kMachineTagged, m.PointerConstant(&rbuffer), m.Int32Constant(0),
+ rphi);
+ m.Return(m.Int32Constant(magic));
+
+ CHECK_EQ(magic, m.Call());
+ CHECK_EQ(dconstant, dbuffer);
+ CHECK(rexpected->SameValue(rbuffer));
+}
+
+
+TEST(RunDoubleRefDoubleDiamond) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ const int magic = 99649;
+ double dbuffer = 0.1;
+ double dconstant = 99.997;
+ Handle<String> rexpected =
+ CcTest::i_isolate()->factory()->InternalizeUtf8String("AD");
+ String* rbuffer;
+
+ MLabel blocka, blockb, mid, blockd, blocke, end;
+ Node* d1 = m.Float64Constant(dconstant);
+ Node* d2 = m.Float64Constant(0 - dconstant);
+ Node* r1 = m.StringConstant("AD");
+ Node* r2 = m.StringConstant("BD");
+ m.Branch(m.Int32Constant(0), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Goto(&mid);
+ m.Bind(&blockb);
+ m.Goto(&mid);
+ m.Bind(&mid);
+ Node* dphi1 = m.Phi(d2, d1);
+ Node* rphi1 = m.Phi(r2, r1);
+ m.Branch(m.Int32Constant(0), &blockd, &blocke);
+
+ m.Bind(&blockd);
+ m.Goto(&end);
+ m.Bind(&blocke);
+ m.Goto(&end);
+ m.Bind(&end);
+ Node* dphi2 = m.Phi(d1, dphi1);
+ Node* rphi2 = m.Phi(r1, rphi1);
+
+ m.Store(kMachineFloat64, m.PointerConstant(&dbuffer), m.Int32Constant(0),
+ dphi2);
+ m.Store(kMachineTagged, m.PointerConstant(&rbuffer), m.Int32Constant(0),
+ rphi2);
+ m.Return(m.Int32Constant(magic));
+
+ CHECK_EQ(magic, m.Call());
+ CHECK_EQ(dconstant, dbuffer);
+ CHECK(rexpected->SameValue(rbuffer));
+}
+
+
+TEST(RunDoubleLoopPhi) {
+ RawMachineAssemblerTester<int32_t> m;
+ MLabel header, body, end;
+
+ int magic = 99773;
+ double buffer = 0.99;
+ double dconstant = 777.1;
+
+ Node* zero = m.Int32Constant(0);
+ Node* dk = m.Float64Constant(dconstant);
+
+ m.Goto(&header);
+ m.Bind(&header);
+ Node* phi = m.Phi(dk, dk);
+ phi->ReplaceInput(1, phi);
+ m.Branch(zero, &body, &end);
+ m.Bind(&body);
+ m.Goto(&header);
+ m.Bind(&end);
+ m.Store(kMachineFloat64, m.PointerConstant(&buffer), m.Int32Constant(0), phi);
+ m.Return(m.Int32Constant(magic));
+
+ CHECK_EQ(magic, m.Call());
+}
+
+
+TEST(RunCountToTenAccRaw) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ Node* zero = m.Int32Constant(0);
+ Node* ten = m.Int32Constant(10);
+ Node* one = m.Int32Constant(1);
+
+ MLabel header, body, body_cont, end;
+
+ m.Goto(&header);
+
+ m.Bind(&header);
+ Node* i = m.Phi(zero, zero);
+ Node* j = m.Phi(zero, zero);
+ m.Goto(&body);
+
+ m.Bind(&body);
+ Node* next_i = m.Int32Add(i, one);
+ Node* next_j = m.Int32Add(j, one);
+ m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont);
+
+ m.Bind(&body_cont);
+ i->ReplaceInput(1, next_i);
+ j->ReplaceInput(1, next_j);
+ m.Goto(&header);
+
+ m.Bind(&end);
+ m.Return(ten);
+
+ CHECK_EQ(10, m.Call());
+}
+
+
+TEST(RunCountToTenAccRaw2) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ Node* zero = m.Int32Constant(0);
+ Node* ten = m.Int32Constant(10);
+ Node* one = m.Int32Constant(1);
+
+ MLabel header, body, body_cont, end;
+
+ m.Goto(&header);
+
+ m.Bind(&header);
+ Node* i = m.Phi(zero, zero);
+ Node* j = m.Phi(zero, zero);
+ Node* k = m.Phi(zero, zero);
+ m.Goto(&body);
+
+ m.Bind(&body);
+ Node* next_i = m.Int32Add(i, one);
+ Node* next_j = m.Int32Add(j, one);
+ Node* next_k = m.Int32Add(j, one);
+ m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont);
+
+ m.Bind(&body_cont);
+ i->ReplaceInput(1, next_i);
+ j->ReplaceInput(1, next_j);
+ k->ReplaceInput(1, next_k);
+ m.Goto(&header);
+
+ m.Bind(&end);
+ m.Return(ten);
+
+ CHECK_EQ(10, m.Call());
+}
+
+
+TEST(RunAddTree) {
+ RawMachineAssemblerTester<int32_t> m;
+ int32_t inputs[] = {11, 12, 13, 14, 15, 16, 17, 18};
+
+ Node* base = m.PointerConstant(inputs);
+ Node* n0 = m.Load(kMachineWord32, base, m.Int32Constant(0 * sizeof(int32_t)));
+ Node* n1 = m.Load(kMachineWord32, base, m.Int32Constant(1 * sizeof(int32_t)));
+ Node* n2 = m.Load(kMachineWord32, base, m.Int32Constant(2 * sizeof(int32_t)));
+ Node* n3 = m.Load(kMachineWord32, base, m.Int32Constant(3 * sizeof(int32_t)));
+ Node* n4 = m.Load(kMachineWord32, base, m.Int32Constant(4 * sizeof(int32_t)));
+ Node* n5 = m.Load(kMachineWord32, base, m.Int32Constant(5 * sizeof(int32_t)));
+ Node* n6 = m.Load(kMachineWord32, base, m.Int32Constant(6 * sizeof(int32_t)));
+ Node* n7 = m.Load(kMachineWord32, base, m.Int32Constant(7 * sizeof(int32_t)));
+
+ Node* i1 = m.Int32Add(n0, n1);
+ Node* i2 = m.Int32Add(n2, n3);
+ Node* i3 = m.Int32Add(n4, n5);
+ Node* i4 = m.Int32Add(n6, n7);
+
+ Node* i5 = m.Int32Add(i1, i2);
+ Node* i6 = m.Int32Add(i3, i4);
+
+ Node* i7 = m.Int32Add(i5, i6);
+
+ m.Return(i7);
+
+ CHECK_EQ(116, m.Call());
+}
+
+
+#if MACHINE_ASSEMBLER_SUPPORTS_CALL_C
+
+static int Seven() { return 7; }
+static int UnaryMinus(int a) { return -a; }
+static int APlusTwoB(int a, int b) { return a + 2 * b; }
+
+
+TEST(RunCallSeven) {
+ for (int i = 0; i < 2; i++) {
+ bool call_direct = i == 0;
+ void* function_address =
+ reinterpret_cast<void*>(reinterpret_cast<intptr_t>(&Seven));
+
+ RawMachineAssemblerTester<int32_t> m;
+ Node** args = NULL;
+ MachineType* arg_types = NULL;
+ Node* function =
+ call_direct ? m.PointerConstant(function_address)
+ : m.LoadFromPointer(&function_address,
+ MachineOperatorBuilder::pointer_rep());
+ m.Return(m.CallC(function, kMachineWord32, arg_types, args, 0));
+
+ CHECK_EQ(7, m.Call());
+ }
+}
+
+
+TEST(RunCallUnaryMinus) {
+ for (int i = 0; i < 2; i++) {
+ bool call_direct = i == 0;
+ void* function_address =
+ reinterpret_cast<void*>(reinterpret_cast<intptr_t>(&UnaryMinus));
+
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ Node* args[] = {m.Parameter(0)};
+ MachineType arg_types[] = {kMachineWord32};
+ Node* function =
+ call_direct ? m.PointerConstant(function_address)
+ : m.LoadFromPointer(&function_address,
+ MachineOperatorBuilder::pointer_rep());
+ m.Return(m.CallC(function, kMachineWord32, arg_types, args, 1));
+
+ FOR_INT32_INPUTS(i) {
+ int a = *i;
+ CHECK_EQ(-a, m.Call(a));
+ }
+ }
+}
+
+
+TEST(RunCallAPlusTwoB) {
+ for (int i = 0; i < 2; i++) {
+ bool call_direct = i == 0;
+ void* function_address =
+ reinterpret_cast<void*>(reinterpret_cast<intptr_t>(&APlusTwoB));
+
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
+ Node* args[] = {m.Parameter(0), m.Parameter(1)};
+ MachineType arg_types[] = {kMachineWord32, kMachineWord32};
+ Node* function =
+ call_direct ? m.PointerConstant(function_address)
+ : m.LoadFromPointer(&function_address,
+ MachineOperatorBuilder::pointer_rep());
+ m.Return(m.CallC(function, kMachineWord32, arg_types, args, 2));
+
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ int a = *i;
+ int b = *j;
+ int result = m.Call(a, b);
+ CHECK_EQ(a + 2 * b, result);
+ }
+ }
+ }
+}
+
+#endif // MACHINE_ASSEMBLER_SUPPORTS_CALL_C
+
+
+static const int kFloat64CompareHelperTestCases = 15;
+static const int kFloat64CompareHelperNodeType = 4;
+
+static int Float64CompareHelper(RawMachineAssemblerTester<int32_t>* m,
+ int test_case, int node_type, double x,
+ double y) {
+ static double buffer[2];
+ buffer[0] = x;
+ buffer[1] = y;
+ CHECK(0 <= test_case && test_case < kFloat64CompareHelperTestCases);
+ CHECK(0 <= node_type && node_type < kFloat64CompareHelperNodeType);
+ CHECK(x < y);
+ bool load_a = node_type / 2 == 1;
+ bool load_b = node_type % 2 == 1;
+ Node* a = load_a ? m->Load(kMachineFloat64, m->PointerConstant(&buffer[0]))
+ : m->Float64Constant(x);
+ Node* b = load_b ? m->Load(kMachineFloat64, m->PointerConstant(&buffer[1]))
+ : m->Float64Constant(y);
+ Node* cmp = NULL;
+ bool expected = false;
+ switch (test_case) {
+ // Equal tests.
+ case 0:
+ cmp = m->Float64Equal(a, b);
+ expected = false;
+ break;
+ case 1:
+ cmp = m->Float64Equal(a, a);
+ expected = true;
+ break;
+ // LessThan tests.
+ case 2:
+ cmp = m->Float64LessThan(a, b);
+ expected = true;
+ break;
+ case 3:
+ cmp = m->Float64LessThan(b, a);
+ expected = false;
+ break;
+ case 4:
+ cmp = m->Float64LessThan(a, a);
+ expected = false;
+ break;
+ // LessThanOrEqual tests.
+ case 5:
+ cmp = m->Float64LessThanOrEqual(a, b);
+ expected = true;
+ break;
+ case 6:
+ cmp = m->Float64LessThanOrEqual(b, a);
+ expected = false;
+ break;
+ case 7:
+ cmp = m->Float64LessThanOrEqual(a, a);
+ expected = true;
+ break;
+ // NotEqual tests.
+ case 8:
+ cmp = m->Float64NotEqual(a, b);
+ expected = true;
+ break;
+ case 9:
+ cmp = m->Float64NotEqual(b, a);
+ expected = true;
+ break;
+ case 10:
+ cmp = m->Float64NotEqual(a, a);
+ expected = false;
+ break;
+ // GreaterThan tests.
+ case 11:
+ cmp = m->Float64GreaterThan(a, a);
+ expected = false;
+ break;
+ case 12:
+ cmp = m->Float64GreaterThan(a, b);
+ expected = false;
+ break;
+ // GreaterThanOrEqual tests.
+ case 13:
+ cmp = m->Float64GreaterThanOrEqual(a, a);
+ expected = true;
+ break;
+ case 14:
+ cmp = m->Float64GreaterThanOrEqual(b, a);
+ expected = true;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ m->Return(cmp);
+ return expected;
+}
+
+
+TEST(RunFloat64Compare) {
+ double inf = V8_INFINITY;
+ // All pairs (a1, a2) are of the form a1 < a2.
+ double inputs[] = {0.0, 1.0, -1.0, 0.22, -1.22, 0.22,
+ -inf, 0.22, 0.22, inf, -inf, inf};
+
+ for (int test = 0; test < kFloat64CompareHelperTestCases; test++) {
+ for (int node_type = 0; node_type < kFloat64CompareHelperNodeType;
+ node_type++) {
+ for (size_t input = 0; input < ARRAY_SIZE(inputs); input += 2) {
+ RawMachineAssemblerTester<int32_t> m;
+ int expected = Float64CompareHelper(&m, test, node_type, inputs[input],
+ inputs[input + 1]);
+ CHECK_EQ(expected, m.Call());
+ }
+ }
+ }
+}
+
+
+TEST(RunFloat64UnorderedCompare) {
+ RawMachineAssemblerTester<int32_t> m;
+
+ Operator* operators[] = {m.machine()->Float64Equal(),
+ m.machine()->Float64LessThan(),
+ m.machine()->Float64LessThanOrEqual()};
+
+ double nan = v8::base::OS::nan_value();
+
+ FOR_FLOAT64_INPUTS(i) {
+ for (size_t o = 0; o < ARRAY_SIZE(operators); ++o) {
+ for (int j = 0; j < 2; j++) {
+ RawMachineAssemblerTester<int32_t> m;
+ Node* a = m.Float64Constant(*i);
+ Node* b = m.Float64Constant(nan);
+ if (j == 1) std::swap(a, b);
+ m.Return(m.NewNode(operators[o], a, b));
+ CHECK_EQ(0, m.Call());
+ }
+ }
+ }
+}
+
+
+TEST(RunFloat64Equal) {
+ double input_a = 0.0;
+ double input_b = 0.0;
+
+ RawMachineAssemblerTester<int32_t> m;
+ Node* a = m.LoadFromPointer(&input_a, kMachineFloat64);
+ Node* b = m.LoadFromPointer(&input_b, kMachineFloat64);
+ m.Return(m.Float64Equal(a, b));
+
+ CompareWrapper cmp(IrOpcode::kFloat64Equal);
+ FOR_FLOAT64_INPUTS(pl) {
+ FOR_FLOAT64_INPUTS(pr) {
+ input_a = *pl;
+ input_b = *pr;
+ int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0;
+ CHECK_EQ(expected, m.Call());
+ }
+ }
+}
+
+
+TEST(RunFloat64LessThan) {
+ double input_a = 0.0;
+ double input_b = 0.0;
+
+ RawMachineAssemblerTester<int32_t> m;
+ Node* a = m.LoadFromPointer(&input_a, kMachineFloat64);
+ Node* b = m.LoadFromPointer(&input_b, kMachineFloat64);
+ m.Return(m.Float64LessThan(a, b));
+
+ CompareWrapper cmp(IrOpcode::kFloat64LessThan);
+ FOR_FLOAT64_INPUTS(pl) {
+ FOR_FLOAT64_INPUTS(pr) {
+ input_a = *pl;
+ input_b = *pr;
+ int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0;
+ CHECK_EQ(expected, m.Call());
+ }
+ }
+}
+
+
+template <typename IntType, MachineType kRepresentation>
+static void LoadStoreTruncation() {
+ IntType input;
+
+ RawMachineAssemblerTester<int32_t> m;
+ Node* a = m.LoadFromPointer(&input, kRepresentation);
+ Node* ap1 = m.Int32Add(a, m.Int32Constant(1));
+ m.StoreToPointer(&input, kRepresentation, ap1);
+ m.Return(ap1);
+
+ const IntType max = std::numeric_limits<IntType>::max();
+ const IntType min = std::numeric_limits<IntType>::min();
+
+ // Test upper bound.
+ input = max;
+ CHECK_EQ(max + 1, m.Call());
+ CHECK_EQ(min, input);
+
+ // Test lower bound.
+ input = min;
+ CHECK_EQ(max + 2, m.Call());
+ CHECK_EQ(min + 1, input);
+
+ // Test all one byte values that are not one byte bounds.
+ for (int i = -127; i < 127; i++) {
+ input = i;
+ int expected = i >= 0 ? i + 1 : max + (i - min) + 2;
+ CHECK_EQ(expected, m.Call());
+ CHECK_EQ(i + 1, input);
+ }
+}
+
+
+TEST(RunLoadStoreTruncation) {
+ LoadStoreTruncation<int8_t, kMachineWord8>();
+ LoadStoreTruncation<int16_t, kMachineWord16>();
+}
+
+
+static void IntPtrCompare(intptr_t left, intptr_t right) {
+ for (int test = 0; test < 7; test++) {
+ RawMachineAssemblerTester<bool> m(MachineOperatorBuilder::pointer_rep(),
+ MachineOperatorBuilder::pointer_rep());
+ Node* p0 = m.Parameter(0);
+ Node* p1 = m.Parameter(1);
+ Node* res = NULL;
+ bool expected = false;
+ switch (test) {
+ case 0:
+ res = m.IntPtrLessThan(p0, p1);
+ expected = true;
+ break;
+ case 1:
+ res = m.IntPtrLessThanOrEqual(p0, p1);
+ expected = true;
+ break;
+ case 2:
+ res = m.IntPtrEqual(p0, p1);
+ expected = false;
+ break;
+ case 3:
+ res = m.IntPtrGreaterThanOrEqual(p0, p1);
+ expected = false;
+ break;
+ case 4:
+ res = m.IntPtrGreaterThan(p0, p1);
+ expected = false;
+ break;
+ case 5:
+ res = m.IntPtrEqual(p0, p0);
+ expected = true;
+ break;
+ case 6:
+ res = m.IntPtrNotEqual(p0, p1);
+ expected = true;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ m.Return(res);
+ CHECK_EQ(expected, m.Call(reinterpret_cast<int32_t*>(left),
+ reinterpret_cast<int32_t*>(right)));
+ }
+}
+
+
+TEST(RunIntPtrCompare) {
+ intptr_t min = std::numeric_limits<intptr_t>::min();
+ intptr_t max = std::numeric_limits<intptr_t>::max();
+ // An ascending chain of intptr_t
+ intptr_t inputs[] = {min, min / 2, -1, 0, 1, max / 2, max};
+ for (size_t i = 0; i < ARRAY_SIZE(inputs) - 1; i++) {
+ IntPtrCompare(inputs[i], inputs[i + 1]);
+ }
+}
+
+
+TEST(RunTestIntPtrArithmetic) {
+ static const int kInputSize = 10;
+ int32_t inputs[kInputSize];
+ int32_t outputs[kInputSize];
+ for (int i = 0; i < kInputSize; i++) {
+ inputs[i] = i;
+ outputs[i] = -1;
+ }
+ RawMachineAssemblerTester<int32_t*> m;
+ Node* input = m.PointerConstant(&inputs[0]);
+ Node* output = m.PointerConstant(&outputs[kInputSize - 1]);
+ Node* elem_size = m.ConvertInt32ToIntPtr(m.Int32Constant(sizeof(inputs[0])));
+ for (int i = 0; i < kInputSize; i++) {
+ m.Store(kMachineWord32, output, m.Load(kMachineWord32, input));
+ input = m.IntPtrAdd(input, elem_size);
+ output = m.IntPtrSub(output, elem_size);
+ }
+ m.Return(input);
+ CHECK_EQ(&inputs[kInputSize], m.Call());
+ for (int i = 0; i < kInputSize; i++) {
+ CHECK_EQ(i, inputs[i]);
+ CHECK_EQ(kInputSize - i - 1, outputs[i]);
+ }
+}
+
+
+static inline uint32_t rotr32(uint32_t i, uint32_t j) {
+ return (i >> j) | (i << (32 - j));
+}
+
+
+TEST(RunTestInt32RotateRightP) {
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32Or(
+ m.Word32Shr(bt.param0, bt.param1),
+ m.Word32Shl(bt.param0, m.Int32Sub(m.Int32Constant(32), bt.param1))));
+ bt.Run(ValueHelper::uint32_vector(), ValueHelper::ror_vector(), rotr32);
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Word32Or(
+ m.Word32Shl(bt.param0, m.Int32Sub(m.Int32Constant(32), bt.param1)),
+ m.Word32Shr(bt.param0, bt.param1)));
+ bt.Run(ValueHelper::uint32_vector(), ValueHelper::ror_vector(), rotr32);
+ }
+}
+
+
+TEST(RunTestInt32RotateRightImm) {
+ FOR_INPUTS(uint32_t, ror, i) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ Node* value = m.Parameter(0);
+ m.Return(m.Word32Or(m.Word32Shr(value, m.Int32Constant(*i)),
+ m.Word32Shl(value, m.Int32Constant(32 - *i))));
+ m.Run(ValueHelper::uint32_vector(),
+ std::bind2nd(std::ptr_fun(&rotr32), *i));
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ Node* value = m.Parameter(0);
+ m.Return(m.Word32Or(m.Word32Shl(value, m.Int32Constant(32 - *i)),
+ m.Word32Shr(value, m.Int32Constant(*i))));
+ m.Run(ValueHelper::uint32_vector(),
+ std::bind2nd(std::ptr_fun(&rotr32), *i));
+ }
+ }
+}
+
+
+TEST(RunSpillLotsOfThings) {
+ static const int kInputSize = 1000;
+ RawMachineAssemblerTester<void> m;
+ Node* accs[kInputSize];
+ int32_t outputs[kInputSize];
+ Node* one = m.Int32Constant(1);
+ Node* acc = one;
+ for (int i = 0; i < kInputSize; i++) {
+ acc = m.Int32Add(acc, one);
+ accs[i] = acc;
+ }
+ for (int i = 0; i < kInputSize; i++) {
+ m.StoreToPointer(&outputs[i], kMachineWord32, accs[i]);
+ }
+ m.Return(one);
+ m.Call();
+ for (int i = 0; i < kInputSize; i++) {
+ CHECK_EQ(outputs[i], i + 2);
+ }
+}
+
+
+TEST(RunSpillConstantsAndParameters) {
+ static const int kInputSize = 1000;
+ static const int32_t kBase = 987;
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
+ int32_t outputs[kInputSize];
+ Node* csts[kInputSize];
+ Node* accs[kInputSize];
+ Node* acc = m.Int32Constant(0);
+ for (int i = 0; i < kInputSize; i++) {
+ csts[i] = m.Int32Constant(static_cast<int32_t>(kBase + i));
+ }
+ for (int i = 0; i < kInputSize; i++) {
+ acc = m.Int32Add(acc, csts[i]);
+ accs[i] = acc;
+ }
+ for (int i = 0; i < kInputSize; i++) {
+ m.StoreToPointer(&outputs[i], kMachineWord32, accs[i]);
+ }
+ m.Return(m.Int32Add(acc, m.Int32Add(m.Parameter(0), m.Parameter(1))));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ int32_t expected = *i + *j;
+ for (int k = 0; k < kInputSize; k++) {
+ expected += kBase + k;
+ }
+ CHECK_EQ(expected, m.Call(*i, *j));
+ expected = 0;
+ for (int k = 0; k < kInputSize; k++) {
+ expected += kBase + k;
+ CHECK_EQ(expected, outputs[k]);
+ }
+ }
+ }
+}
+
+
+TEST(RunNewSpaceConstantsInPhi) {
+ RawMachineAssemblerTester<Object*> m(kMachineWord32);
+
+ Isolate* isolate = CcTest::i_isolate();
+ Handle<HeapNumber> true_val = isolate->factory()->NewHeapNumber(11.2);
+ Handle<HeapNumber> false_val = isolate->factory()->NewHeapNumber(11.3);
+ Node* true_node = m.HeapConstant(true_val);
+ Node* false_node = m.HeapConstant(false_val);
+
+ MLabel blocka, blockb, end;
+ m.Branch(m.Parameter(0), &blocka, &blockb);
+ m.Bind(&blocka);
+ m.Goto(&end);
+ m.Bind(&blockb);
+ m.Goto(&end);
+
+ m.Bind(&end);
+ Node* phi = m.Phi(true_node, false_node);
+ m.Return(phi);
+
+ CHECK_EQ(*false_val, m.Call(0));
+ CHECK_EQ(*true_val, m.Call(1));
+}
+
+
+#if MACHINE_ASSEMBLER_SUPPORTS_CALL_C
+
+TEST(RunSpillLotsOfThingsWithCall) {
+ static const int kInputSize = 1000;
+ RawMachineAssemblerTester<void> m;
+ Node* accs[kInputSize];
+ int32_t outputs[kInputSize];
+ Node* one = m.Int32Constant(1);
+ Node* acc = one;
+ for (int i = 0; i < kInputSize; i++) {
+ acc = m.Int32Add(acc, one);
+ accs[i] = acc;
+ }
+ // If the spill slot computation is wrong, it might load from the c frame
+ {
+ void* func = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(&Seven));
+ Node** args = NULL;
+ MachineType* arg_types = NULL;
+ m.CallC(m.PointerConstant(func), kMachineWord32, arg_types, args, 0);
+ }
+ for (int i = 0; i < kInputSize; i++) {
+ m.StoreToPointer(&outputs[i], kMachineWord32, accs[i]);
+ }
+ m.Return(one);
+ m.Call();
+ for (int i = 0; i < kInputSize; i++) {
+ CHECK_EQ(outputs[i], i + 2);
+ }
+}
+
+#endif // MACHINE_ASSEMBLER_SUPPORTS_CALL_C
+
+
+static bool sadd_overflow(int32_t x, int32_t y, int32_t* val) {
+ int32_t v =
+ static_cast<int32_t>(static_cast<uint32_t>(x) + static_cast<uint32_t>(y));
+ *val = v;
+ return (((v ^ x) & (v ^ y)) >> 31) & 1;
+}
+
+
+static bool ssub_overflow(int32_t x, int32_t y, int32_t* val) {
+ int32_t v =
+ static_cast<int32_t>(static_cast<uint32_t>(x) - static_cast<uint32_t>(y));
+ *val = v;
+ return (((v ^ x) & (v ^ ~y)) >> 31) & 1;
+}
+
+
+TEST(RunInt32AddWithOverflowP) {
+ int32_t actual_val = -1;
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
+ Node* val = m.Projection(0, add);
+ Node* ovf = m.Projection(1, add);
+ m.StoreToPointer(&actual_val, kMachineWord32, val);
+ bt.AddReturn(ovf);
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ int32_t expected_val;
+ int expected_ovf = sadd_overflow(*i, *j, &expected_val);
+ CHECK_EQ(expected_ovf, bt.call(*i, *j));
+ CHECK_EQ(expected_val, actual_val);
+ }
+ }
+}
+
+
+TEST(RunInt32AddWithOverflowImm) {
+ int32_t actual_val = -1, expected_val = 0;
+ FOR_INT32_INPUTS(i) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ Node* add = m.Int32AddWithOverflow(m.Int32Constant(*i), m.Parameter(0));
+ Node* val = m.Projection(0, add);
+ Node* ovf = m.Projection(1, add);
+ m.StoreToPointer(&actual_val, kMachineWord32, val);
+ m.Return(ovf);
+ FOR_INT32_INPUTS(j) {
+ int expected_ovf = sadd_overflow(*i, *j, &expected_val);
+ CHECK_EQ(expected_ovf, m.Call(*j));
+ CHECK_EQ(expected_val, actual_val);
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ Node* add = m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(*i));
+ Node* val = m.Projection(0, add);
+ Node* ovf = m.Projection(1, add);
+ m.StoreToPointer(&actual_val, kMachineWord32, val);
+ m.Return(ovf);
+ FOR_INT32_INPUTS(j) {
+ int expected_ovf = sadd_overflow(*i, *j, &expected_val);
+ CHECK_EQ(expected_ovf, m.Call(*j));
+ CHECK_EQ(expected_val, actual_val);
+ }
+ }
+ FOR_INT32_INPUTS(j) {
+ RawMachineAssemblerTester<int32_t> m;
+ Node* add =
+ m.Int32AddWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
+ Node* val = m.Projection(0, add);
+ Node* ovf = m.Projection(1, add);
+ m.StoreToPointer(&actual_val, kMachineWord32, val);
+ m.Return(ovf);
+ int expected_ovf = sadd_overflow(*i, *j, &expected_val);
+ CHECK_EQ(expected_ovf, m.Call());
+ CHECK_EQ(expected_val, actual_val);
+ }
+ }
+}
+
+
+TEST(RunInt32AddWithOverflowInBranchP) {
+ int constant = 911777;
+ MLabel blocka, blockb;
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
+ Node* ovf = m.Projection(1, add);
+ m.Branch(ovf, &blocka, &blockb);
+ m.Bind(&blocka);
+ bt.AddReturn(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ Node* val = m.Projection(0, add);
+ bt.AddReturn(val);
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected;
+ if (sadd_overflow(*i, *j, &expected)) expected = constant;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+}
+
+
+TEST(RunInt32SubWithOverflowP) {
+ int32_t actual_val = -1;
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ Node* add = m.Int32SubWithOverflow(bt.param0, bt.param1);
+ Node* val = m.Projection(0, add);
+ Node* ovf = m.Projection(1, add);
+ m.StoreToPointer(&actual_val, kMachineWord32, val);
+ bt.AddReturn(ovf);
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ int32_t expected_val;
+ int expected_ovf = ssub_overflow(*i, *j, &expected_val);
+ CHECK_EQ(expected_ovf, bt.call(*i, *j));
+ CHECK_EQ(expected_val, actual_val);
+ }
+ }
+}
+
+
+TEST(RunInt32SubWithOverflowImm) {
+ int32_t actual_val = -1, expected_val = 0;
+ FOR_INT32_INPUTS(i) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ Node* add = m.Int32SubWithOverflow(m.Int32Constant(*i), m.Parameter(0));
+ Node* val = m.Projection(0, add);
+ Node* ovf = m.Projection(1, add);
+ m.StoreToPointer(&actual_val, kMachineWord32, val);
+ m.Return(ovf);
+ FOR_INT32_INPUTS(j) {
+ int expected_ovf = ssub_overflow(*i, *j, &expected_val);
+ CHECK_EQ(expected_ovf, m.Call(*j));
+ CHECK_EQ(expected_val, actual_val);
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachineWord32);
+ Node* add = m.Int32SubWithOverflow(m.Parameter(0), m.Int32Constant(*i));
+ Node* val = m.Projection(0, add);
+ Node* ovf = m.Projection(1, add);
+ m.StoreToPointer(&actual_val, kMachineWord32, val);
+ m.Return(ovf);
+ FOR_INT32_INPUTS(j) {
+ int expected_ovf = ssub_overflow(*j, *i, &expected_val);
+ CHECK_EQ(expected_ovf, m.Call(*j));
+ CHECK_EQ(expected_val, actual_val);
+ }
+ }
+ FOR_INT32_INPUTS(j) {
+ RawMachineAssemblerTester<int32_t> m;
+ Node* add =
+ m.Int32SubWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
+ Node* val = m.Projection(0, add);
+ Node* ovf = m.Projection(1, add);
+ m.StoreToPointer(&actual_val, kMachineWord32, val);
+ m.Return(ovf);
+ int expected_ovf = ssub_overflow(*i, *j, &expected_val);
+ CHECK_EQ(expected_ovf, m.Call());
+ CHECK_EQ(expected_val, actual_val);
+ }
+ }
+}
+
+
+TEST(RunInt32SubWithOverflowInBranchP) {
+ int constant = 911999;
+ MLabel blocka, blockb;
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ Node* sub = m.Int32SubWithOverflow(bt.param0, bt.param1);
+ Node* ovf = m.Projection(1, sub);
+ m.Branch(ovf, &blocka, &blockb);
+ m.Bind(&blocka);
+ bt.AddReturn(m.Int32Constant(constant));
+ m.Bind(&blockb);
+ Node* val = m.Projection(0, sub);
+ bt.AddReturn(val);
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected;
+ if (ssub_overflow(*i, *j, &expected)) expected = constant;
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+}
+
+#endif // V8_TURBOFAN_TARGET
diff --git a/deps/v8/test/cctest/compiler/test-run-variables.cc b/deps/v8/test/cctest/compiler/test-run-variables.cc
new file mode 100644
index 000000000..bf86e0d42
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-run-variables.cc
@@ -0,0 +1,121 @@
+// 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 "src/v8.h"
+
+#include "test/cctest/compiler/function-tester.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+static const char* throws = NULL;
+
+static const char* load_tests[] = {
+ "var x = a; r = x", "123", "0",
+ "var x = (r = x)", "undefined", "undefined",
+ "var x = (a?1:2); r = x", "1", "2",
+ "const x = a; r = x", "123", "0",
+ "const x = (r = x)", "undefined", "undefined",
+ "const x = (a?3:4); r = x", "3", "4",
+ "'use strict'; const x = a; r = x", "123", "0",
+ "'use strict'; const x = (r = x)", throws, throws,
+ "'use strict'; const x = (a?5:6); r = x", "5", "6",
+ "'use strict'; let x = a; r = x", "123", "0",
+ "'use strict'; let x = (r = x)", throws, throws,
+ "'use strict'; let x = (a?7:8); r = x", "7", "8",
+ NULL};
+
+static const char* store_tests[] = {
+ "var x = 1; x = a; r = x", "123", "0",
+ "var x = (a?(x=4,2):3); r = x", "2", "3",
+ "var x = (a?4:5); x = a; r = x", "123", "0",
+ "const x = 1; x = a; r = x", "1", "1",
+ "const x = (a?(x=4,2):3); r = x", "2", "3",
+ "const x = (a?4:5); x = a; r = x", "4", "5",
+ // Assignments to 'const' are SyntaxErrors, handled by the parser,
+ // hence we cannot test them here because they are early errors.
+ "'use strict'; let x = 1; x = a; r = x", "123", "0",
+ "'use strict'; let x = (a?(x=4,2):3); r = x", throws, "3",
+ "'use strict'; let x = (a?4:5); x = a; r = x", "123", "0",
+ NULL};
+
+static const char* bind_tests[] = {
+ "if (a) { const x = a }; r = x;", "123", "undefined",
+ "for (; a > 0; a--) { const x = a }; r = x", "123", "undefined",
+ // Re-initialization of variables other than legacy 'const' is not
+ // possible due to sane variable scoping, hence no tests here.
+ NULL};
+
+
+static void RunVariableTests(const char* source, const char* tests[]) {
+ FLAG_harmony_scoping = true;
+ EmbeddedVector<char, 512> buffer;
+
+ for (int i = 0; tests[i] != NULL; i += 3) {
+ SNPrintF(buffer, source, tests[i]);
+ PrintF("#%d: %s\n", i / 3, buffer.start());
+ FunctionTester T(buffer.start());
+
+ // Check function with non-falsey parameter.
+ if (tests[i + 1] != throws) {
+ Handle<Object> r = v8::Utils::OpenHandle(*CompileRun(tests[i + 1]));
+ T.CheckCall(r, T.Val(123), T.Val("result"));
+ } else {
+ T.CheckThrows(T.Val(123), T.Val("result"));
+ }
+
+ // Check function with falsey parameter.
+ if (tests[i + 2] != throws) {
+ Handle<Object> r = v8::Utils::OpenHandle(*CompileRun(tests[i + 2]));
+ T.CheckCall(r, T.Val(0.0), T.Val("result"));
+ } else {
+ T.CheckThrows(T.Val(0.0), T.Val("result"));
+ }
+ }
+}
+
+
+TEST(StackLoadVariables) {
+ const char* source = "(function(a,r) { %s; return r; })";
+ RunVariableTests(source, load_tests);
+}
+
+
+TEST(ContextLoadVariables) {
+ const char* source = "(function(a,r) { %s; function f() {x} return r; })";
+ RunVariableTests(source, load_tests);
+}
+
+
+TEST(StackStoreVariables) {
+ const char* source = "(function(a,r) { %s; return r; })";
+ RunVariableTests(source, store_tests);
+}
+
+
+TEST(ContextStoreVariables) {
+ const char* source = "(function(a,r) { %s; function f() {x} return r; })";
+ RunVariableTests(source, store_tests);
+}
+
+
+TEST(StackInitializeVariables) {
+ const char* source = "(function(a,r) { %s; return r; })";
+ RunVariableTests(source, bind_tests);
+}
+
+
+TEST(ContextInitializeVariables) {
+ const char* source = "(function(a,r) { %s; function f() {x} return r; })";
+ RunVariableTests(source, bind_tests);
+}
+
+
+TEST(SelfReferenceVariable) {
+ FunctionTester T("(function self() { return self; })");
+
+ T.CheckCall(T.function);
+ CompileRun("var self = 'not a function'");
+ T.CheckCall(T.function);
+}
diff --git a/deps/v8/test/cctest/compiler/test-schedule.cc b/deps/v8/test/cctest/compiler/test-schedule.cc
new file mode 100644
index 000000000..bfa47d872
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-schedule.cc
@@ -0,0 +1,159 @@
+// Copyright 2013 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 "src/v8.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/generic-node-inl.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/node.h"
+#include "src/compiler/operator.h"
+#include "src/compiler/schedule.h"
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+static SimpleOperator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
+ 0, 0, "dummy");
+
+TEST(TestScheduleAllocation) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+
+ CHECK_NE(NULL, schedule.entry());
+ CHECK_EQ(schedule.entry(), *(schedule.all_blocks().begin()));
+}
+
+
+TEST(TestScheduleAddNode) {
+ HandleAndZoneScope scope;
+ Graph graph(scope.main_zone());
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+
+ Schedule schedule(scope.main_zone());
+
+ BasicBlock* entry = schedule.entry();
+ schedule.AddNode(entry, n0);
+ schedule.AddNode(entry, n1);
+
+ CHECK_EQ(entry, schedule.block(n0));
+ CHECK_EQ(entry, schedule.block(n1));
+ CHECK(schedule.SameBasicBlock(n0, n1));
+
+ Node* n2 = graph.NewNode(&dummy_operator);
+ CHECK_EQ(NULL, schedule.block(n2));
+}
+
+
+TEST(TestScheduleAddGoto) {
+ HandleAndZoneScope scope;
+
+ Schedule schedule(scope.main_zone());
+ BasicBlock* entry = schedule.entry();
+ BasicBlock* next = schedule.NewBasicBlock();
+
+ schedule.AddGoto(entry, next);
+
+ CHECK_EQ(0, entry->PredecessorCount());
+ CHECK_EQ(1, entry->SuccessorCount());
+ CHECK_EQ(next, entry->SuccessorAt(0));
+
+ CHECK_EQ(1, next->PredecessorCount());
+ CHECK_EQ(entry, next->PredecessorAt(0));
+ CHECK_EQ(0, next->SuccessorCount());
+}
+
+
+TEST(TestScheduleAddBranch) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+
+ BasicBlock* entry = schedule.entry();
+ BasicBlock* tblock = schedule.NewBasicBlock();
+ BasicBlock* fblock = schedule.NewBasicBlock();
+
+ Graph graph(scope.main_zone());
+ CommonOperatorBuilder common(scope.main_zone());
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* b = graph.NewNode(common.Branch(), n0);
+
+ schedule.AddBranch(entry, b, tblock, fblock);
+
+ CHECK_EQ(0, entry->PredecessorCount());
+ CHECK_EQ(2, entry->SuccessorCount());
+ CHECK_EQ(tblock, entry->SuccessorAt(0));
+ CHECK_EQ(fblock, entry->SuccessorAt(1));
+
+ CHECK_EQ(1, tblock->PredecessorCount());
+ CHECK_EQ(entry, tblock->PredecessorAt(0));
+ CHECK_EQ(0, tblock->SuccessorCount());
+
+ CHECK_EQ(1, fblock->PredecessorCount());
+ CHECK_EQ(entry, fblock->PredecessorAt(0));
+ CHECK_EQ(0, fblock->SuccessorCount());
+}
+
+
+TEST(TestScheduleAddReturn) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+ Graph graph(scope.main_zone());
+ Node* n0 = graph.NewNode(&dummy_operator);
+ BasicBlock* entry = schedule.entry();
+ schedule.AddReturn(entry, n0);
+
+ CHECK_EQ(0, entry->PredecessorCount());
+ CHECK_EQ(1, entry->SuccessorCount());
+ CHECK_EQ(schedule.exit(), entry->SuccessorAt(0));
+}
+
+
+TEST(TestScheduleAddThrow) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+ Graph graph(scope.main_zone());
+ Node* n0 = graph.NewNode(&dummy_operator);
+ BasicBlock* entry = schedule.entry();
+ schedule.AddThrow(entry, n0);
+
+ CHECK_EQ(0, entry->PredecessorCount());
+ CHECK_EQ(1, entry->SuccessorCount());
+ CHECK_EQ(schedule.exit(), entry->SuccessorAt(0));
+}
+
+
+TEST(TestScheduleAddDeopt) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+ Graph graph(scope.main_zone());
+ Node* n0 = graph.NewNode(&dummy_operator);
+ BasicBlock* entry = schedule.entry();
+ schedule.AddDeoptimize(entry, n0);
+
+ CHECK_EQ(0, entry->PredecessorCount());
+ CHECK_EQ(1, entry->SuccessorCount());
+ CHECK_EQ(schedule.exit(), entry->SuccessorAt(0));
+}
+
+
+TEST(BuildMulNodeGraph) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+ Graph graph(scope.main_zone());
+ CommonOperatorBuilder common(scope.main_zone());
+ MachineOperatorBuilder machine(scope.main_zone(), kMachineWord32);
+
+ Node* start = graph.NewNode(common.Start(0));
+ graph.SetStart(start);
+ Node* param0 = graph.NewNode(common.Parameter(0), graph.start());
+ Node* param1 = graph.NewNode(common.Parameter(1), graph.start());
+
+ Node* mul = graph.NewNode(machine.Int32Mul(), param0, param1);
+ Node* ret = graph.NewNode(common.Return(), mul, start);
+
+ USE(ret);
+}
diff --git a/deps/v8/test/cctest/compiler/test-scheduler.cc b/deps/v8/test/cctest/compiler/test-scheduler.cc
new file mode 100644
index 000000000..ec4e77e11
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-scheduler.cc
@@ -0,0 +1,1809 @@
+// 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 "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/generic-node-inl.h"
+#include "src/compiler/generic-node.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/graph-visualizer.h"
+#include "src/compiler/js-operator.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/node.h"
+#include "src/compiler/operator.h"
+#include "src/compiler/schedule.h"
+#include "src/compiler/scheduler.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+struct TestLoop {
+ int count;
+ BasicBlock** nodes;
+ BasicBlock* header() { return nodes[0]; }
+ BasicBlock* last() { return nodes[count - 1]; }
+ ~TestLoop() { delete[] nodes; }
+};
+
+
+static TestLoop* CreateLoop(Schedule* schedule, int count) {
+ TestLoop* loop = new TestLoop();
+ loop->count = count;
+ loop->nodes = new BasicBlock* [count];
+ for (int i = 0; i < count; i++) {
+ loop->nodes[i] = schedule->NewBasicBlock();
+ if (i > 0) schedule->AddSuccessor(loop->nodes[i - 1], loop->nodes[i]);
+ }
+ schedule->AddSuccessor(loop->nodes[count - 1], loop->nodes[0]);
+ return loop;
+}
+
+
+static void CheckRPONumbers(BasicBlockVector* order, int expected,
+ bool loops_allowed) {
+ CHECK_EQ(expected, static_cast<int>(order->size()));
+ for (int i = 0; i < static_cast<int>(order->size()); i++) {
+ CHECK(order->at(i)->rpo_number_ == i);
+ if (!loops_allowed) CHECK_LT(order->at(i)->loop_end_, 0);
+ }
+}
+
+
+static void CheckLoopContains(BasicBlock** blocks, int body_size) {
+ BasicBlock* header = blocks[0];
+ CHECK_GT(header->loop_end_, 0);
+ CHECK_EQ(body_size, (header->loop_end_ - header->rpo_number_));
+ for (int i = 0; i < body_size; i++) {
+ int num = blocks[i]->rpo_number_;
+ CHECK(num >= header->rpo_number_ && num < header->loop_end_);
+ CHECK(header->LoopContains(blocks[i]));
+ CHECK(header->IsLoopHeader() || blocks[i]->loop_header_ == header);
+ }
+}
+
+
+TEST(RPODegenerate1) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 1, false);
+ CHECK_EQ(schedule.entry(), order->at(0));
+}
+
+
+TEST(RPODegenerate2) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+
+ schedule.AddGoto(schedule.entry(), schedule.exit());
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 2, false);
+ CHECK_EQ(schedule.entry(), order->at(0));
+ CHECK_EQ(schedule.exit(), order->at(1));
+}
+
+
+TEST(RPOLine) {
+ HandleAndZoneScope scope;
+
+ for (int i = 0; i < 10; i++) {
+ Schedule schedule(scope.main_zone());
+
+ BasicBlock* last = schedule.entry();
+ for (int j = 0; j < i; j++) {
+ BasicBlock* block = schedule.NewBasicBlock();
+ schedule.AddGoto(last, block);
+ last = block;
+ }
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 1 + i, false);
+
+ Schedule::BasicBlocks blocks(schedule.all_blocks());
+ for (Schedule::BasicBlocks::iterator iter = blocks.begin();
+ iter != blocks.end(); ++iter) {
+ BasicBlock* block = *iter;
+ if (block->rpo_number_ >= 0 && block->SuccessorCount() == 1) {
+ CHECK(block->rpo_number_ + 1 == block->SuccessorAt(0)->rpo_number_);
+ }
+ }
+ }
+}
+
+
+TEST(RPOSelfLoop) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+ schedule.AddSuccessor(schedule.entry(), schedule.entry());
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 1, true);
+ BasicBlock* loop[] = {schedule.entry()};
+ CheckLoopContains(loop, 1);
+}
+
+
+TEST(RPOEntryLoop) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+ schedule.AddSuccessor(schedule.entry(), schedule.exit());
+ schedule.AddSuccessor(schedule.exit(), schedule.entry());
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 2, true);
+ BasicBlock* loop[] = {schedule.entry(), schedule.exit()};
+ CheckLoopContains(loop, 2);
+}
+
+
+TEST(RPOEndLoop) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+ SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2));
+ schedule.AddSuccessor(schedule.entry(), loop1->header());
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 3, true);
+ CheckLoopContains(loop1->nodes, loop1->count);
+}
+
+
+TEST(RPOEndLoopNested) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+ SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2));
+ schedule.AddSuccessor(schedule.entry(), loop1->header());
+ schedule.AddSuccessor(loop1->last(), schedule.entry());
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 3, true);
+ CheckLoopContains(loop1->nodes, loop1->count);
+}
+
+
+TEST(RPODiamond) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+
+ BasicBlock* A = schedule.entry();
+ BasicBlock* B = schedule.NewBasicBlock();
+ BasicBlock* C = schedule.NewBasicBlock();
+ BasicBlock* D = schedule.exit();
+
+ schedule.AddSuccessor(A, B);
+ schedule.AddSuccessor(A, C);
+ schedule.AddSuccessor(B, D);
+ schedule.AddSuccessor(C, D);
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 4, false);
+
+ CHECK_EQ(0, A->rpo_number_);
+ CHECK((B->rpo_number_ == 1 && C->rpo_number_ == 2) ||
+ (B->rpo_number_ == 2 && C->rpo_number_ == 1));
+ CHECK_EQ(3, D->rpo_number_);
+}
+
+
+TEST(RPOLoop1) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+
+ BasicBlock* A = schedule.entry();
+ BasicBlock* B = schedule.NewBasicBlock();
+ BasicBlock* C = schedule.NewBasicBlock();
+ BasicBlock* D = schedule.exit();
+
+ schedule.AddSuccessor(A, B);
+ schedule.AddSuccessor(B, C);
+ schedule.AddSuccessor(C, B);
+ schedule.AddSuccessor(C, D);
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 4, true);
+ BasicBlock* loop[] = {B, C};
+ CheckLoopContains(loop, 2);
+}
+
+
+TEST(RPOLoop2) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+
+ BasicBlock* A = schedule.entry();
+ BasicBlock* B = schedule.NewBasicBlock();
+ BasicBlock* C = schedule.NewBasicBlock();
+ BasicBlock* D = schedule.exit();
+
+ schedule.AddSuccessor(A, B);
+ schedule.AddSuccessor(B, C);
+ schedule.AddSuccessor(C, B);
+ schedule.AddSuccessor(B, D);
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 4, true);
+ BasicBlock* loop[] = {B, C};
+ CheckLoopContains(loop, 2);
+}
+
+
+TEST(RPOLoopN) {
+ HandleAndZoneScope scope;
+
+ for (int i = 0; i < 11; i++) {
+ Schedule schedule(scope.main_zone());
+ BasicBlock* A = schedule.entry();
+ BasicBlock* B = schedule.NewBasicBlock();
+ BasicBlock* C = schedule.NewBasicBlock();
+ BasicBlock* D = schedule.NewBasicBlock();
+ BasicBlock* E = schedule.NewBasicBlock();
+ BasicBlock* F = schedule.NewBasicBlock();
+ BasicBlock* G = schedule.exit();
+
+ schedule.AddSuccessor(A, B);
+ schedule.AddSuccessor(B, C);
+ schedule.AddSuccessor(C, D);
+ schedule.AddSuccessor(D, E);
+ schedule.AddSuccessor(E, F);
+ schedule.AddSuccessor(F, B);
+ schedule.AddSuccessor(B, G);
+
+ // Throw in extra backedges from time to time.
+ if (i == 1) schedule.AddSuccessor(B, B);
+ if (i == 2) schedule.AddSuccessor(C, B);
+ if (i == 3) schedule.AddSuccessor(D, B);
+ if (i == 4) schedule.AddSuccessor(E, B);
+ if (i == 5) schedule.AddSuccessor(F, B);
+
+ // Throw in extra loop exits from time to time.
+ if (i == 6) schedule.AddSuccessor(B, G);
+ if (i == 7) schedule.AddSuccessor(C, G);
+ if (i == 8) schedule.AddSuccessor(D, G);
+ if (i == 9) schedule.AddSuccessor(E, G);
+ if (i == 10) schedule.AddSuccessor(F, G);
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 7, true);
+ BasicBlock* loop[] = {B, C, D, E, F};
+ CheckLoopContains(loop, 5);
+ }
+}
+
+
+TEST(RPOLoopNest1) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+
+ BasicBlock* A = schedule.entry();
+ BasicBlock* B = schedule.NewBasicBlock();
+ BasicBlock* C = schedule.NewBasicBlock();
+ BasicBlock* D = schedule.NewBasicBlock();
+ BasicBlock* E = schedule.NewBasicBlock();
+ BasicBlock* F = schedule.exit();
+
+ schedule.AddSuccessor(A, B);
+ schedule.AddSuccessor(B, C);
+ schedule.AddSuccessor(C, D);
+ schedule.AddSuccessor(D, C);
+ schedule.AddSuccessor(D, E);
+ schedule.AddSuccessor(E, B);
+ schedule.AddSuccessor(E, F);
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 6, true);
+ BasicBlock* loop1[] = {B, C, D, E};
+ CheckLoopContains(loop1, 4);
+
+ BasicBlock* loop2[] = {C, D};
+ CheckLoopContains(loop2, 2);
+}
+
+
+TEST(RPOLoopNest2) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+
+ BasicBlock* A = schedule.entry();
+ BasicBlock* B = schedule.NewBasicBlock();
+ BasicBlock* C = schedule.NewBasicBlock();
+ BasicBlock* D = schedule.NewBasicBlock();
+ BasicBlock* E = schedule.NewBasicBlock();
+ BasicBlock* F = schedule.NewBasicBlock();
+ BasicBlock* G = schedule.NewBasicBlock();
+ BasicBlock* H = schedule.exit();
+
+ schedule.AddSuccessor(A, B);
+ schedule.AddSuccessor(B, C);
+ schedule.AddSuccessor(C, D);
+ schedule.AddSuccessor(D, E);
+ schedule.AddSuccessor(E, F);
+ schedule.AddSuccessor(F, G);
+ schedule.AddSuccessor(G, H);
+
+ schedule.AddSuccessor(E, D);
+ schedule.AddSuccessor(F, C);
+ schedule.AddSuccessor(G, B);
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 8, true);
+ BasicBlock* loop1[] = {B, C, D, E, F, G};
+ CheckLoopContains(loop1, 6);
+
+ BasicBlock* loop2[] = {C, D, E, F};
+ CheckLoopContains(loop2, 4);
+
+ BasicBlock* loop3[] = {D, E};
+ CheckLoopContains(loop3, 2);
+}
+
+
+TEST(RPOLoopFollow1) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+
+ SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1));
+ SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1));
+
+ BasicBlock* A = schedule.entry();
+ BasicBlock* E = schedule.exit();
+
+ schedule.AddSuccessor(A, loop1->header());
+ schedule.AddSuccessor(loop1->header(), loop2->header());
+ schedule.AddSuccessor(loop2->last(), E);
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+
+ CheckLoopContains(loop1->nodes, loop1->count);
+
+ CHECK_EQ(schedule.BasicBlockCount(), static_cast<int>(order->size()));
+ CheckLoopContains(loop1->nodes, loop1->count);
+ CheckLoopContains(loop2->nodes, loop2->count);
+}
+
+
+TEST(RPOLoopFollow2) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+
+ SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1));
+ SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1));
+
+ BasicBlock* A = schedule.entry();
+ BasicBlock* S = schedule.NewBasicBlock();
+ BasicBlock* E = schedule.exit();
+
+ schedule.AddSuccessor(A, loop1->header());
+ schedule.AddSuccessor(loop1->header(), S);
+ schedule.AddSuccessor(S, loop2->header());
+ schedule.AddSuccessor(loop2->last(), E);
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+
+ CheckLoopContains(loop1->nodes, loop1->count);
+
+ CHECK_EQ(schedule.BasicBlockCount(), static_cast<int>(order->size()));
+ CheckLoopContains(loop1->nodes, loop1->count);
+ CheckLoopContains(loop2->nodes, loop2->count);
+}
+
+
+TEST(RPOLoopFollowN) {
+ HandleAndZoneScope scope;
+
+ for (int size = 1; size < 5; size++) {
+ for (int exit = 0; exit < size; exit++) {
+ Schedule schedule(scope.main_zone());
+ SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
+ SmartPointer<TestLoop> loop2(CreateLoop(&schedule, size));
+ BasicBlock* A = schedule.entry();
+ BasicBlock* E = schedule.exit();
+
+ schedule.AddSuccessor(A, loop1->header());
+ schedule.AddSuccessor(loop1->nodes[exit], loop2->header());
+ schedule.AddSuccessor(loop2->nodes[exit], E);
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckLoopContains(loop1->nodes, loop1->count);
+
+ CHECK_EQ(schedule.BasicBlockCount(), static_cast<int>(order->size()));
+ CheckLoopContains(loop1->nodes, loop1->count);
+ CheckLoopContains(loop2->nodes, loop2->count);
+ }
+ }
+}
+
+
+TEST(RPONestedLoopFollow1) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+
+ SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1));
+ SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1));
+
+ BasicBlock* A = schedule.entry();
+ BasicBlock* B = schedule.NewBasicBlock();
+ BasicBlock* C = schedule.NewBasicBlock();
+ BasicBlock* E = schedule.exit();
+
+ schedule.AddSuccessor(A, B);
+ schedule.AddSuccessor(B, loop1->header());
+ schedule.AddSuccessor(loop1->header(), loop2->header());
+ schedule.AddSuccessor(loop2->last(), C);
+ schedule.AddSuccessor(C, E);
+ schedule.AddSuccessor(C, B);
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+
+ CheckLoopContains(loop1->nodes, loop1->count);
+
+ CHECK_EQ(schedule.BasicBlockCount(), static_cast<int>(order->size()));
+ CheckLoopContains(loop1->nodes, loop1->count);
+ CheckLoopContains(loop2->nodes, loop2->count);
+
+ BasicBlock* loop3[] = {B, loop1->nodes[0], loop2->nodes[0], C};
+ CheckLoopContains(loop3, 4);
+}
+
+
+TEST(RPOLoopBackedges1) {
+ HandleAndZoneScope scope;
+
+ int size = 8;
+ for (int i = 0; i < size; i++) {
+ for (int j = 0; j < size; j++) {
+ Schedule schedule(scope.main_zone());
+ BasicBlock* A = schedule.entry();
+ BasicBlock* E = schedule.exit();
+
+ SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
+ schedule.AddSuccessor(A, loop1->header());
+ schedule.AddSuccessor(loop1->last(), E);
+
+ schedule.AddSuccessor(loop1->nodes[i], loop1->header());
+ schedule.AddSuccessor(loop1->nodes[j], E);
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, schedule.BasicBlockCount(), true);
+ CheckLoopContains(loop1->nodes, loop1->count);
+ }
+ }
+}
+
+
+TEST(RPOLoopOutedges1) {
+ HandleAndZoneScope scope;
+
+ int size = 8;
+ for (int i = 0; i < size; i++) {
+ for (int j = 0; j < size; j++) {
+ Schedule schedule(scope.main_zone());
+ BasicBlock* A = schedule.entry();
+ BasicBlock* D = schedule.NewBasicBlock();
+ BasicBlock* E = schedule.exit();
+
+ SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
+ schedule.AddSuccessor(A, loop1->header());
+ schedule.AddSuccessor(loop1->last(), E);
+
+ schedule.AddSuccessor(loop1->nodes[i], loop1->header());
+ schedule.AddSuccessor(loop1->nodes[j], D);
+ schedule.AddSuccessor(D, E);
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, schedule.BasicBlockCount(), true);
+ CheckLoopContains(loop1->nodes, loop1->count);
+ }
+ }
+}
+
+
+TEST(RPOLoopOutedges2) {
+ HandleAndZoneScope scope;
+
+ int size = 8;
+ for (int i = 0; i < size; i++) {
+ Schedule schedule(scope.main_zone());
+ BasicBlock* A = schedule.entry();
+ BasicBlock* E = schedule.exit();
+
+ SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
+ schedule.AddSuccessor(A, loop1->header());
+ schedule.AddSuccessor(loop1->last(), E);
+
+ for (int j = 0; j < size; j++) {
+ BasicBlock* O = schedule.NewBasicBlock();
+ schedule.AddSuccessor(loop1->nodes[j], O);
+ schedule.AddSuccessor(O, E);
+ }
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, schedule.BasicBlockCount(), true);
+ CheckLoopContains(loop1->nodes, loop1->count);
+ }
+}
+
+
+TEST(RPOLoopOutloops1) {
+ HandleAndZoneScope scope;
+
+ int size = 8;
+ for (int i = 0; i < size; i++) {
+ Schedule schedule(scope.main_zone());
+ BasicBlock* A = schedule.entry();
+ BasicBlock* E = schedule.exit();
+ SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
+ schedule.AddSuccessor(A, loop1->header());
+ schedule.AddSuccessor(loop1->last(), E);
+
+ TestLoop** loopN = new TestLoop* [size];
+ for (int j = 0; j < size; j++) {
+ loopN[j] = CreateLoop(&schedule, 2);
+ schedule.AddSuccessor(loop1->nodes[j], loopN[j]->header());
+ schedule.AddSuccessor(loopN[j]->last(), E);
+ }
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, schedule.BasicBlockCount(), true);
+ CheckLoopContains(loop1->nodes, loop1->count);
+
+ for (int j = 0; j < size; j++) {
+ CheckLoopContains(loopN[j]->nodes, loopN[j]->count);
+ delete loopN[j];
+ }
+ delete[] loopN;
+ }
+}
+
+
+TEST(RPOLoopMultibackedge) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+
+ BasicBlock* A = schedule.entry();
+ BasicBlock* B = schedule.NewBasicBlock();
+ BasicBlock* C = schedule.NewBasicBlock();
+ BasicBlock* D = schedule.exit();
+ BasicBlock* E = schedule.NewBasicBlock();
+
+ schedule.AddSuccessor(A, B);
+ schedule.AddSuccessor(B, C);
+ schedule.AddSuccessor(B, D);
+ schedule.AddSuccessor(B, E);
+ schedule.AddSuccessor(C, B);
+ schedule.AddSuccessor(D, B);
+ schedule.AddSuccessor(E, B);
+
+ BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+ CheckRPONumbers(order, 5, true);
+
+ BasicBlock* loop1[] = {B, C, D, E};
+ CheckLoopContains(loop1, 4);
+}
+
+
+TEST(BuildScheduleEmpty) {
+ HandleAndZoneScope scope;
+ Graph graph(scope.main_zone());
+ CommonOperatorBuilder builder(scope.main_zone());
+ graph.SetStart(graph.NewNode(builder.Start(0)));
+ graph.SetEnd(graph.NewNode(builder.End(), graph.start()));
+
+ USE(Scheduler::ComputeSchedule(&graph));
+}
+
+
+TEST(BuildScheduleOneParameter) {
+ HandleAndZoneScope scope;
+ Graph graph(scope.main_zone());
+ CommonOperatorBuilder builder(scope.main_zone());
+ graph.SetStart(graph.NewNode(builder.Start(0)));
+
+ Node* p1 = graph.NewNode(builder.Parameter(0), graph.start());
+ Node* ret = graph.NewNode(builder.Return(), p1, graph.start(), graph.start());
+
+ graph.SetEnd(graph.NewNode(builder.End(), ret));
+
+ USE(Scheduler::ComputeSchedule(&graph));
+}
+
+
+static int GetScheduledNodeCount(Schedule* schedule) {
+ int node_count = 0;
+ for (BasicBlockVectorIter i = schedule->rpo_order()->begin();
+ i != schedule->rpo_order()->end(); ++i) {
+ BasicBlock* block = *i;
+ for (BasicBlock::const_iterator j = block->begin(); j != block->end();
+ ++j) {
+ ++node_count;
+ }
+ BasicBlock::Control control = block->control_;
+ if (control != BasicBlock::kNone) {
+ ++node_count;
+ }
+ }
+ return node_count;
+}
+
+
+static void PrintGraph(Graph* graph) {
+ OFStream os(stdout);
+ os << AsDOT(*graph);
+}
+
+
+static void PrintSchedule(Schedule* schedule) {
+ OFStream os(stdout);
+ os << *schedule << endl;
+}
+
+
+TEST(BuildScheduleIfSplit) {
+ HandleAndZoneScope scope;
+ Graph graph(scope.main_zone());
+ CommonOperatorBuilder builder(scope.main_zone());
+ JSOperatorBuilder js_builder(scope.main_zone());
+ graph.SetStart(graph.NewNode(builder.Start(3)));
+
+ Node* p1 = graph.NewNode(builder.Parameter(0), graph.start());
+ Node* p2 = graph.NewNode(builder.Parameter(1), graph.start());
+ Node* p3 = graph.NewNode(builder.Parameter(2), graph.start());
+ Node* p4 = graph.NewNode(builder.Parameter(3), graph.start());
+ Node* p5 = graph.NewNode(builder.Parameter(4), graph.start());
+ Node* cmp = graph.NewNode(js_builder.LessThanOrEqual(), p1, p2, p3,
+ graph.start(), graph.start());
+ Node* branch = graph.NewNode(builder.Branch(), cmp, graph.start());
+ Node* true_branch = graph.NewNode(builder.IfTrue(), branch);
+ Node* false_branch = graph.NewNode(builder.IfFalse(), branch);
+
+ Node* ret1 = graph.NewNode(builder.Return(), p4, graph.start(), true_branch);
+ Node* ret2 = graph.NewNode(builder.Return(), p5, graph.start(), false_branch);
+ Node* merge = graph.NewNode(builder.Merge(2), ret1, ret2);
+ graph.SetEnd(graph.NewNode(builder.End(), merge));
+
+ PrintGraph(&graph);
+
+ Schedule* schedule = Scheduler::ComputeSchedule(&graph);
+
+ PrintSchedule(schedule);
+
+
+ CHECK_EQ(13, GetScheduledNodeCount(schedule));
+}
+
+
+TEST(BuildScheduleIfSplitWithEffects) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Graph graph(scope.main_zone());
+ CommonOperatorBuilder common_builder(scope.main_zone());
+ JSOperatorBuilder js_builder(scope.main_zone());
+ Operator* op;
+
+ Handle<Object> object =
+ Handle<Object>(isolate->heap()->undefined_value(), isolate);
+ PrintableUnique<Object> unique_constant =
+ PrintableUnique<Object>::CreateUninitialized(scope.main_zone(), object);
+
+ // Manually transcripted code for:
+ // function turbo_fan_test(a, b, c, y) {
+ // if (a < b) {
+ // return a + b - c * c - a + y;
+ // } else {
+ // return c * c - a;
+ // }
+ // }
+ op = common_builder.Start(0);
+ Node* n0 = graph.NewNode(op);
+ USE(n0);
+ Node* nil = graph.NewNode(common_builder.Dead());
+ op = common_builder.End();
+ Node* n23 = graph.NewNode(op, nil);
+ USE(n23);
+ op = common_builder.Merge(2);
+ Node* n22 = graph.NewNode(op, nil, nil);
+ USE(n22);
+ op = common_builder.Return();
+ Node* n16 = graph.NewNode(op, nil, nil, nil);
+ USE(n16);
+ op = js_builder.Add();
+ Node* n15 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n15);
+ op = js_builder.Subtract();
+ Node* n14 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n14);
+ op = js_builder.Subtract();
+ Node* n13 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n13);
+ op = js_builder.Add();
+ Node* n11 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n11);
+ op = common_builder.Parameter(0);
+ Node* n2 = graph.NewNode(op, n0);
+ USE(n2);
+ n11->ReplaceInput(0, n2);
+ op = common_builder.Parameter(0);
+ Node* n3 = graph.NewNode(op, n0);
+ USE(n3);
+ n11->ReplaceInput(1, n3);
+ op = common_builder.HeapConstant(unique_constant);
+ Node* n7 = graph.NewNode(op);
+ USE(n7);
+ n11->ReplaceInput(2, n7);
+ op = js_builder.LessThan();
+ Node* n8 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n8);
+ n8->ReplaceInput(0, n2);
+ n8->ReplaceInput(1, n3);
+ n8->ReplaceInput(2, n7);
+ n8->ReplaceInput(3, n0);
+ n8->ReplaceInput(4, n0);
+ n11->ReplaceInput(3, n8);
+ op = common_builder.IfTrue();
+ Node* n10 = graph.NewNode(op, nil);
+ USE(n10);
+ op = common_builder.Branch();
+ Node* n9 = graph.NewNode(op, nil, nil);
+ USE(n9);
+ n9->ReplaceInput(0, n8);
+ n9->ReplaceInput(1, n0);
+ n10->ReplaceInput(0, n9);
+ n11->ReplaceInput(4, n10);
+ n13->ReplaceInput(0, n11);
+ op = js_builder.Multiply();
+ Node* n12 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n12);
+ op = common_builder.Parameter(0);
+ Node* n4 = graph.NewNode(op, n0);
+ USE(n4);
+ n12->ReplaceInput(0, n4);
+ n12->ReplaceInput(1, n4);
+ n12->ReplaceInput(2, n7);
+ n12->ReplaceInput(3, n11);
+ n12->ReplaceInput(4, n10);
+ n13->ReplaceInput(1, n12);
+ n13->ReplaceInput(2, n7);
+ n13->ReplaceInput(3, n12);
+ n13->ReplaceInput(4, n10);
+ n14->ReplaceInput(0, n13);
+ n14->ReplaceInput(1, n2);
+ n14->ReplaceInput(2, n7);
+ n14->ReplaceInput(3, n13);
+ n14->ReplaceInput(4, n10);
+ n15->ReplaceInput(0, n14);
+ op = common_builder.Parameter(0);
+ Node* n5 = graph.NewNode(op, n0);
+ USE(n5);
+ n15->ReplaceInput(1, n5);
+ n15->ReplaceInput(2, n7);
+ n15->ReplaceInput(3, n14);
+ n15->ReplaceInput(4, n10);
+ n16->ReplaceInput(0, n15);
+ n16->ReplaceInput(1, n15);
+ n16->ReplaceInput(2, n10);
+ n22->ReplaceInput(0, n16);
+ op = common_builder.Return();
+ Node* n21 = graph.NewNode(op, nil, nil, nil);
+ USE(n21);
+ op = js_builder.Subtract();
+ Node* n20 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n20);
+ op = js_builder.Multiply();
+ Node* n19 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n19);
+ n19->ReplaceInput(0, n4);
+ n19->ReplaceInput(1, n4);
+ n19->ReplaceInput(2, n7);
+ n19->ReplaceInput(3, n8);
+ op = common_builder.IfFalse();
+ Node* n18 = graph.NewNode(op, nil);
+ USE(n18);
+ n18->ReplaceInput(0, n9);
+ n19->ReplaceInput(4, n18);
+ n20->ReplaceInput(0, n19);
+ n20->ReplaceInput(1, n2);
+ n20->ReplaceInput(2, n7);
+ n20->ReplaceInput(3, n19);
+ n20->ReplaceInput(4, n18);
+ n21->ReplaceInput(0, n20);
+ n21->ReplaceInput(1, n20);
+ n21->ReplaceInput(2, n18);
+ n22->ReplaceInput(1, n21);
+ n23->ReplaceInput(0, n22);
+
+ graph.SetStart(n0);
+ graph.SetEnd(n23);
+
+ PrintGraph(&graph);
+
+ Schedule* schedule = Scheduler::ComputeSchedule(&graph);
+
+ PrintSchedule(schedule);
+
+ CHECK_EQ(20, GetScheduledNodeCount(schedule));
+}
+
+
+TEST(BuildScheduleSimpleLoop) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Graph graph(scope.main_zone());
+ CommonOperatorBuilder common_builder(scope.main_zone());
+ JSOperatorBuilder js_builder(scope.main_zone());
+ Operator* op;
+
+ Handle<Object> object =
+ Handle<Object>(isolate->heap()->undefined_value(), isolate);
+ PrintableUnique<Object> unique_constant =
+ PrintableUnique<Object>::CreateUninitialized(scope.main_zone(), object);
+
+ // Manually transcripted code for:
+ // function turbo_fan_test(a, b) {
+ // while (a < b) {
+ // a++;
+ // }
+ // return a;
+ // }
+ op = common_builder.Start(0);
+ Node* n0 = graph.NewNode(op);
+ USE(n0);
+ Node* nil = graph.NewNode(common_builder.Dead());
+ op = common_builder.End();
+ Node* n20 = graph.NewNode(op, nil);
+ USE(n20);
+ op = common_builder.Return();
+ Node* n19 = graph.NewNode(op, nil, nil, nil);
+ USE(n19);
+ op = common_builder.Phi(2);
+ Node* n8 = graph.NewNode(op, nil, nil, nil);
+ USE(n8);
+ op = common_builder.Parameter(0);
+ Node* n2 = graph.NewNode(op, n0);
+ USE(n2);
+ n8->ReplaceInput(0, n2);
+ op = js_builder.Add();
+ Node* n18 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n18);
+ op = js_builder.ToNumber();
+ Node* n16 = graph.NewNode(op, nil, nil, nil, nil);
+ USE(n16);
+ n16->ReplaceInput(0, n8);
+ op = common_builder.HeapConstant(unique_constant);
+ Node* n5 = graph.NewNode(op);
+ USE(n5);
+ n16->ReplaceInput(1, n5);
+ op = js_builder.LessThan();
+ Node* n12 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n12);
+ n12->ReplaceInput(0, n8);
+ op = common_builder.Phi(2);
+ Node* n9 = graph.NewNode(op, nil, nil, nil);
+ USE(n9);
+ op = common_builder.Parameter(0);
+ Node* n3 = graph.NewNode(op, n0);
+ USE(n3);
+ n9->ReplaceInput(0, n3);
+ n9->ReplaceInput(1, n9);
+ op = common_builder.Loop(2);
+ Node* n6 = graph.NewNode(op, nil, nil);
+ USE(n6);
+ n6->ReplaceInput(0, n0);
+ op = common_builder.IfTrue();
+ Node* n14 = graph.NewNode(op, nil);
+ USE(n14);
+ op = common_builder.Branch();
+ Node* n13 = graph.NewNode(op, nil, nil);
+ USE(n13);
+ n13->ReplaceInput(0, n12);
+ n13->ReplaceInput(1, n6);
+ n14->ReplaceInput(0, n13);
+ n6->ReplaceInput(1, n14);
+ n9->ReplaceInput(2, n6);
+ n12->ReplaceInput(1, n9);
+ n12->ReplaceInput(2, n5);
+ op = common_builder.Phi(2);
+ Node* n10 = graph.NewNode(op, nil, nil, nil);
+ USE(n10);
+ n10->ReplaceInput(0, n0);
+ n10->ReplaceInput(1, n18);
+ n10->ReplaceInput(2, n6);
+ n12->ReplaceInput(3, n10);
+ n12->ReplaceInput(4, n6);
+ n16->ReplaceInput(2, n12);
+ n16->ReplaceInput(3, n14);
+ n18->ReplaceInput(0, n16);
+ op = common_builder.NumberConstant(0);
+ Node* n17 = graph.NewNode(op);
+ USE(n17);
+ n18->ReplaceInput(1, n17);
+ n18->ReplaceInput(2, n5);
+ n18->ReplaceInput(3, n16);
+ n18->ReplaceInput(4, n14);
+ n8->ReplaceInput(1, n18);
+ n8->ReplaceInput(2, n6);
+ n19->ReplaceInput(0, n8);
+ n19->ReplaceInput(1, n12);
+ op = common_builder.IfFalse();
+ Node* n15 = graph.NewNode(op, nil);
+ USE(n15);
+ n15->ReplaceInput(0, n13);
+ n19->ReplaceInput(2, n15);
+ n20->ReplaceInput(0, n19);
+
+ graph.SetStart(n0);
+ graph.SetEnd(n20);
+
+ PrintGraph(&graph);
+
+ Schedule* schedule = Scheduler::ComputeSchedule(&graph);
+
+ PrintSchedule(schedule);
+
+ CHECK_EQ(19, GetScheduledNodeCount(schedule));
+}
+
+
+TEST(BuildScheduleComplexLoops) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Graph graph(scope.main_zone());
+ CommonOperatorBuilder common_builder(scope.main_zone());
+ JSOperatorBuilder js_builder(scope.main_zone());
+ Operator* op;
+
+ Handle<Object> object =
+ Handle<Object>(isolate->heap()->undefined_value(), isolate);
+ PrintableUnique<Object> unique_constant =
+ PrintableUnique<Object>::CreateUninitialized(scope.main_zone(), object);
+
+ // Manually transcripted code for:
+ // function turbo_fan_test(a, b, c) {
+ // while (a < b) {
+ // a++;
+ // while (c < b) {
+ // c++;
+ // }
+ // }
+ // while (a < b) {
+ // a += 2;
+ // }
+ // return a;
+ // }
+ op = common_builder.Start(0);
+ Node* n0 = graph.NewNode(op);
+ USE(n0);
+ Node* nil = graph.NewNode(common_builder.Dead());
+ op = common_builder.End();
+ Node* n46 = graph.NewNode(op, nil);
+ USE(n46);
+ op = common_builder.Return();
+ Node* n45 = graph.NewNode(op, nil, nil, nil);
+ USE(n45);
+ op = common_builder.Phi(2);
+ Node* n35 = graph.NewNode(op, nil, nil, nil);
+ USE(n35);
+ op = common_builder.Phi(2);
+ Node* n9 = graph.NewNode(op, nil, nil, nil);
+ USE(n9);
+ op = common_builder.Parameter(0);
+ Node* n2 = graph.NewNode(op, n0);
+ USE(n2);
+ n9->ReplaceInput(0, n2);
+ op = common_builder.Phi(2);
+ Node* n23 = graph.NewNode(op, nil, nil, nil);
+ USE(n23);
+ op = js_builder.Add();
+ Node* n20 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n20);
+ op = js_builder.ToNumber();
+ Node* n18 = graph.NewNode(op, nil, nil, nil, nil);
+ USE(n18);
+ n18->ReplaceInput(0, n9);
+ op = common_builder.HeapConstant(unique_constant);
+ Node* n6 = graph.NewNode(op);
+ USE(n6);
+ n18->ReplaceInput(1, n6);
+ op = js_builder.LessThan();
+ Node* n14 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n14);
+ n14->ReplaceInput(0, n9);
+ op = common_builder.Phi(2);
+ Node* n10 = graph.NewNode(op, nil, nil, nil);
+ USE(n10);
+ op = common_builder.Parameter(0);
+ Node* n3 = graph.NewNode(op, n0);
+ USE(n3);
+ n10->ReplaceInput(0, n3);
+ op = common_builder.Phi(2);
+ Node* n24 = graph.NewNode(op, nil, nil, nil);
+ USE(n24);
+ n24->ReplaceInput(0, n10);
+ n24->ReplaceInput(1, n24);
+ op = common_builder.Loop(2);
+ Node* n21 = graph.NewNode(op, nil, nil);
+ USE(n21);
+ op = common_builder.IfTrue();
+ Node* n16 = graph.NewNode(op, nil);
+ USE(n16);
+ op = common_builder.Branch();
+ Node* n15 = graph.NewNode(op, nil, nil);
+ USE(n15);
+ n15->ReplaceInput(0, n14);
+ op = common_builder.Loop(2);
+ Node* n7 = graph.NewNode(op, nil, nil);
+ USE(n7);
+ n7->ReplaceInput(0, n0);
+ op = common_builder.IfFalse();
+ Node* n30 = graph.NewNode(op, nil);
+ USE(n30);
+ op = common_builder.Branch();
+ Node* n28 = graph.NewNode(op, nil, nil);
+ USE(n28);
+ op = js_builder.LessThan();
+ Node* n27 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n27);
+ op = common_builder.Phi(2);
+ Node* n25 = graph.NewNode(op, nil, nil, nil);
+ USE(n25);
+ op = common_builder.Phi(2);
+ Node* n11 = graph.NewNode(op, nil, nil, nil);
+ USE(n11);
+ op = common_builder.Parameter(0);
+ Node* n4 = graph.NewNode(op, n0);
+ USE(n4);
+ n11->ReplaceInput(0, n4);
+ n11->ReplaceInput(1, n25);
+ n11->ReplaceInput(2, n7);
+ n25->ReplaceInput(0, n11);
+ op = js_builder.Add();
+ Node* n32 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n32);
+ op = js_builder.ToNumber();
+ Node* n31 = graph.NewNode(op, nil, nil, nil, nil);
+ USE(n31);
+ n31->ReplaceInput(0, n25);
+ n31->ReplaceInput(1, n6);
+ n31->ReplaceInput(2, n27);
+ op = common_builder.IfTrue();
+ Node* n29 = graph.NewNode(op, nil);
+ USE(n29);
+ n29->ReplaceInput(0, n28);
+ n31->ReplaceInput(3, n29);
+ n32->ReplaceInput(0, n31);
+ op = common_builder.NumberConstant(0);
+ Node* n19 = graph.NewNode(op);
+ USE(n19);
+ n32->ReplaceInput(1, n19);
+ n32->ReplaceInput(2, n6);
+ n32->ReplaceInput(3, n31);
+ n32->ReplaceInput(4, n29);
+ n25->ReplaceInput(1, n32);
+ n25->ReplaceInput(2, n21);
+ n27->ReplaceInput(0, n25);
+ n27->ReplaceInput(1, n24);
+ n27->ReplaceInput(2, n6);
+ op = common_builder.Phi(2);
+ Node* n26 = graph.NewNode(op, nil, nil, nil);
+ USE(n26);
+ n26->ReplaceInput(0, n20);
+ n26->ReplaceInput(1, n32);
+ n26->ReplaceInput(2, n21);
+ n27->ReplaceInput(3, n26);
+ n27->ReplaceInput(4, n21);
+ n28->ReplaceInput(0, n27);
+ n28->ReplaceInput(1, n21);
+ n30->ReplaceInput(0, n28);
+ n7->ReplaceInput(1, n30);
+ n15->ReplaceInput(1, n7);
+ n16->ReplaceInput(0, n15);
+ n21->ReplaceInput(0, n16);
+ n21->ReplaceInput(1, n29);
+ n24->ReplaceInput(2, n21);
+ n10->ReplaceInput(1, n24);
+ n10->ReplaceInput(2, n7);
+ n14->ReplaceInput(1, n10);
+ n14->ReplaceInput(2, n6);
+ op = common_builder.Phi(2);
+ Node* n12 = graph.NewNode(op, nil, nil, nil);
+ USE(n12);
+ n12->ReplaceInput(0, n0);
+ n12->ReplaceInput(1, n27);
+ n12->ReplaceInput(2, n7);
+ n14->ReplaceInput(3, n12);
+ n14->ReplaceInput(4, n7);
+ n18->ReplaceInput(2, n14);
+ n18->ReplaceInput(3, n16);
+ n20->ReplaceInput(0, n18);
+ n20->ReplaceInput(1, n19);
+ n20->ReplaceInput(2, n6);
+ n20->ReplaceInput(3, n18);
+ n20->ReplaceInput(4, n16);
+ n23->ReplaceInput(0, n20);
+ n23->ReplaceInput(1, n23);
+ n23->ReplaceInput(2, n21);
+ n9->ReplaceInput(1, n23);
+ n9->ReplaceInput(2, n7);
+ n35->ReplaceInput(0, n9);
+ op = js_builder.Add();
+ Node* n44 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n44);
+ n44->ReplaceInput(0, n35);
+ op = common_builder.NumberConstant(0);
+ Node* n43 = graph.NewNode(op);
+ USE(n43);
+ n44->ReplaceInput(1, n43);
+ n44->ReplaceInput(2, n6);
+ op = js_builder.LessThan();
+ Node* n39 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n39);
+ n39->ReplaceInput(0, n35);
+ op = common_builder.Phi(2);
+ Node* n36 = graph.NewNode(op, nil, nil, nil);
+ USE(n36);
+ n36->ReplaceInput(0, n10);
+ n36->ReplaceInput(1, n36);
+ op = common_builder.Loop(2);
+ Node* n33 = graph.NewNode(op, nil, nil);
+ USE(n33);
+ op = common_builder.IfFalse();
+ Node* n17 = graph.NewNode(op, nil);
+ USE(n17);
+ n17->ReplaceInput(0, n15);
+ n33->ReplaceInput(0, n17);
+ op = common_builder.IfTrue();
+ Node* n41 = graph.NewNode(op, nil);
+ USE(n41);
+ op = common_builder.Branch();
+ Node* n40 = graph.NewNode(op, nil, nil);
+ USE(n40);
+ n40->ReplaceInput(0, n39);
+ n40->ReplaceInput(1, n33);
+ n41->ReplaceInput(0, n40);
+ n33->ReplaceInput(1, n41);
+ n36->ReplaceInput(2, n33);
+ n39->ReplaceInput(1, n36);
+ n39->ReplaceInput(2, n6);
+ op = common_builder.Phi(2);
+ Node* n38 = graph.NewNode(op, nil, nil, nil);
+ USE(n38);
+ n38->ReplaceInput(0, n14);
+ n38->ReplaceInput(1, n44);
+ n38->ReplaceInput(2, n33);
+ n39->ReplaceInput(3, n38);
+ n39->ReplaceInput(4, n33);
+ n44->ReplaceInput(3, n39);
+ n44->ReplaceInput(4, n41);
+ n35->ReplaceInput(1, n44);
+ n35->ReplaceInput(2, n33);
+ n45->ReplaceInput(0, n35);
+ n45->ReplaceInput(1, n39);
+ op = common_builder.IfFalse();
+ Node* n42 = graph.NewNode(op, nil);
+ USE(n42);
+ n42->ReplaceInput(0, n40);
+ n45->ReplaceInput(2, n42);
+ n46->ReplaceInput(0, n45);
+
+ graph.SetStart(n0);
+ graph.SetEnd(n46);
+
+ PrintGraph(&graph);
+
+ Schedule* schedule = Scheduler::ComputeSchedule(&graph);
+
+ PrintSchedule(schedule);
+
+ CHECK_EQ(46, GetScheduledNodeCount(schedule));
+}
+
+
+TEST(BuildScheduleBreakAndContinue) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Graph graph(scope.main_zone());
+ CommonOperatorBuilder common_builder(scope.main_zone());
+ JSOperatorBuilder js_builder(scope.main_zone());
+ Operator* op;
+
+ Handle<Object> object =
+ Handle<Object>(isolate->heap()->undefined_value(), isolate);
+ PrintableUnique<Object> unique_constant =
+ PrintableUnique<Object>::CreateUninitialized(scope.main_zone(), object);
+
+ // Manually transcripted code for:
+ // function turbo_fan_test(a, b, c) {
+ // var d = 0;
+ // while (a < b) {
+ // a++;
+ // while (c < b) {
+ // c++;
+ // if (d == 0) break;
+ // a++;
+ // }
+ // if (a == 1) continue;
+ // d++;
+ // }
+ // return a + d;
+ // }
+ op = common_builder.Start(0);
+ Node* n0 = graph.NewNode(op);
+ USE(n0);
+ Node* nil = graph.NewNode(common_builder.Dead());
+ op = common_builder.End();
+ Node* n58 = graph.NewNode(op, nil);
+ USE(n58);
+ op = common_builder.Return();
+ Node* n57 = graph.NewNode(op, nil, nil, nil);
+ USE(n57);
+ op = js_builder.Add();
+ Node* n56 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n56);
+ op = common_builder.Phi(2);
+ Node* n10 = graph.NewNode(op, nil, nil, nil);
+ USE(n10);
+ op = common_builder.Parameter(0);
+ Node* n2 = graph.NewNode(op, n0);
+ USE(n2);
+ n10->ReplaceInput(0, n2);
+ op = common_builder.Phi(2);
+ Node* n25 = graph.NewNode(op, nil, nil, nil);
+ USE(n25);
+ op = js_builder.Add();
+ Node* n22 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n22);
+ op = js_builder.ToNumber();
+ Node* n20 = graph.NewNode(op, nil, nil, nil, nil);
+ USE(n20);
+ n20->ReplaceInput(0, n10);
+ op = common_builder.HeapConstant(unique_constant);
+ Node* n6 = graph.NewNode(op);
+ USE(n6);
+ n20->ReplaceInput(1, n6);
+ op = js_builder.LessThan();
+ Node* n16 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n16);
+ n16->ReplaceInput(0, n10);
+ op = common_builder.Phi(2);
+ Node* n11 = graph.NewNode(op, nil, nil, nil);
+ USE(n11);
+ op = common_builder.Parameter(0);
+ Node* n3 = graph.NewNode(op, n0);
+ USE(n3);
+ n11->ReplaceInput(0, n3);
+ op = common_builder.Phi(2);
+ Node* n26 = graph.NewNode(op, nil, nil, nil);
+ USE(n26);
+ n26->ReplaceInput(0, n11);
+ n26->ReplaceInput(1, n26);
+ op = common_builder.Loop(2);
+ Node* n23 = graph.NewNode(op, nil, nil);
+ USE(n23);
+ op = common_builder.IfTrue();
+ Node* n18 = graph.NewNode(op, nil);
+ USE(n18);
+ op = common_builder.Branch();
+ Node* n17 = graph.NewNode(op, nil, nil);
+ USE(n17);
+ n17->ReplaceInput(0, n16);
+ op = common_builder.Loop(2);
+ Node* n8 = graph.NewNode(op, nil, nil);
+ USE(n8);
+ n8->ReplaceInput(0, n0);
+ op = common_builder.Merge(2);
+ Node* n53 = graph.NewNode(op, nil, nil);
+ USE(n53);
+ op = common_builder.IfTrue();
+ Node* n49 = graph.NewNode(op, nil);
+ USE(n49);
+ op = common_builder.Branch();
+ Node* n48 = graph.NewNode(op, nil, nil);
+ USE(n48);
+ op = js_builder.Equal();
+ Node* n47 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n47);
+ n47->ReplaceInput(0, n25);
+ op = common_builder.NumberConstant(0);
+ Node* n46 = graph.NewNode(op);
+ USE(n46);
+ n47->ReplaceInput(1, n46);
+ n47->ReplaceInput(2, n6);
+ op = common_builder.Phi(2);
+ Node* n42 = graph.NewNode(op, nil, nil, nil);
+ USE(n42);
+ op = js_builder.LessThan();
+ Node* n30 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n30);
+ op = common_builder.Phi(2);
+ Node* n27 = graph.NewNode(op, nil, nil, nil);
+ USE(n27);
+ op = common_builder.Phi(2);
+ Node* n12 = graph.NewNode(op, nil, nil, nil);
+ USE(n12);
+ op = common_builder.Parameter(0);
+ Node* n4 = graph.NewNode(op, n0);
+ USE(n4);
+ n12->ReplaceInput(0, n4);
+ op = common_builder.Phi(2);
+ Node* n41 = graph.NewNode(op, nil, nil, nil);
+ USE(n41);
+ n41->ReplaceInput(0, n27);
+ op = js_builder.Add();
+ Node* n35 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n35);
+ op = js_builder.ToNumber();
+ Node* n34 = graph.NewNode(op, nil, nil, nil, nil);
+ USE(n34);
+ n34->ReplaceInput(0, n27);
+ n34->ReplaceInput(1, n6);
+ n34->ReplaceInput(2, n30);
+ op = common_builder.IfTrue();
+ Node* n32 = graph.NewNode(op, nil);
+ USE(n32);
+ op = common_builder.Branch();
+ Node* n31 = graph.NewNode(op, nil, nil);
+ USE(n31);
+ n31->ReplaceInput(0, n30);
+ n31->ReplaceInput(1, n23);
+ n32->ReplaceInput(0, n31);
+ n34->ReplaceInput(3, n32);
+ n35->ReplaceInput(0, n34);
+ op = common_builder.NumberConstant(0);
+ Node* n21 = graph.NewNode(op);
+ USE(n21);
+ n35->ReplaceInput(1, n21);
+ n35->ReplaceInput(2, n6);
+ n35->ReplaceInput(3, n34);
+ n35->ReplaceInput(4, n32);
+ n41->ReplaceInput(1, n35);
+ op = common_builder.Merge(2);
+ Node* n40 = graph.NewNode(op, nil, nil);
+ USE(n40);
+ op = common_builder.IfFalse();
+ Node* n33 = graph.NewNode(op, nil);
+ USE(n33);
+ n33->ReplaceInput(0, n31);
+ n40->ReplaceInput(0, n33);
+ op = common_builder.IfTrue();
+ Node* n39 = graph.NewNode(op, nil);
+ USE(n39);
+ op = common_builder.Branch();
+ Node* n38 = graph.NewNode(op, nil, nil);
+ USE(n38);
+ op = js_builder.Equal();
+ Node* n37 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n37);
+ op = common_builder.Phi(2);
+ Node* n28 = graph.NewNode(op, nil, nil, nil);
+ USE(n28);
+ op = common_builder.Phi(2);
+ Node* n13 = graph.NewNode(op, nil, nil, nil);
+ USE(n13);
+ op = common_builder.NumberConstant(0);
+ Node* n7 = graph.NewNode(op);
+ USE(n7);
+ n13->ReplaceInput(0, n7);
+ op = common_builder.Phi(2);
+ Node* n54 = graph.NewNode(op, nil, nil, nil);
+ USE(n54);
+ n54->ReplaceInput(0, n28);
+ op = js_builder.Add();
+ Node* n52 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n52);
+ op = js_builder.ToNumber();
+ Node* n51 = graph.NewNode(op, nil, nil, nil, nil);
+ USE(n51);
+ n51->ReplaceInput(0, n28);
+ n51->ReplaceInput(1, n6);
+ n51->ReplaceInput(2, n47);
+ op = common_builder.IfFalse();
+ Node* n50 = graph.NewNode(op, nil);
+ USE(n50);
+ n50->ReplaceInput(0, n48);
+ n51->ReplaceInput(3, n50);
+ n52->ReplaceInput(0, n51);
+ n52->ReplaceInput(1, n21);
+ n52->ReplaceInput(2, n6);
+ n52->ReplaceInput(3, n51);
+ n52->ReplaceInput(4, n50);
+ n54->ReplaceInput(1, n52);
+ n54->ReplaceInput(2, n53);
+ n13->ReplaceInput(1, n54);
+ n13->ReplaceInput(2, n8);
+ n28->ReplaceInput(0, n13);
+ n28->ReplaceInput(1, n28);
+ n28->ReplaceInput(2, n23);
+ n37->ReplaceInput(0, n28);
+ op = common_builder.NumberConstant(0);
+ Node* n36 = graph.NewNode(op);
+ USE(n36);
+ n37->ReplaceInput(1, n36);
+ n37->ReplaceInput(2, n6);
+ n37->ReplaceInput(3, n35);
+ n37->ReplaceInput(4, n32);
+ n38->ReplaceInput(0, n37);
+ n38->ReplaceInput(1, n32);
+ n39->ReplaceInput(0, n38);
+ n40->ReplaceInput(1, n39);
+ n41->ReplaceInput(2, n40);
+ n12->ReplaceInput(1, n41);
+ n12->ReplaceInput(2, n8);
+ n27->ReplaceInput(0, n12);
+ n27->ReplaceInput(1, n35);
+ n27->ReplaceInput(2, n23);
+ n30->ReplaceInput(0, n27);
+ n30->ReplaceInput(1, n26);
+ n30->ReplaceInput(2, n6);
+ op = common_builder.Phi(2);
+ Node* n29 = graph.NewNode(op, nil, nil, nil);
+ USE(n29);
+ n29->ReplaceInput(0, n22);
+ op = js_builder.Add();
+ Node* n45 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n45);
+ op = js_builder.ToNumber();
+ Node* n44 = graph.NewNode(op, nil, nil, nil, nil);
+ USE(n44);
+ n44->ReplaceInput(0, n25);
+ n44->ReplaceInput(1, n6);
+ n44->ReplaceInput(2, n37);
+ op = common_builder.IfFalse();
+ Node* n43 = graph.NewNode(op, nil);
+ USE(n43);
+ n43->ReplaceInput(0, n38);
+ n44->ReplaceInput(3, n43);
+ n45->ReplaceInput(0, n44);
+ n45->ReplaceInput(1, n21);
+ n45->ReplaceInput(2, n6);
+ n45->ReplaceInput(3, n44);
+ n45->ReplaceInput(4, n43);
+ n29->ReplaceInput(1, n45);
+ n29->ReplaceInput(2, n23);
+ n30->ReplaceInput(3, n29);
+ n30->ReplaceInput(4, n23);
+ n42->ReplaceInput(0, n30);
+ n42->ReplaceInput(1, n37);
+ n42->ReplaceInput(2, n40);
+ n47->ReplaceInput(3, n42);
+ n47->ReplaceInput(4, n40);
+ n48->ReplaceInput(0, n47);
+ n48->ReplaceInput(1, n40);
+ n49->ReplaceInput(0, n48);
+ n53->ReplaceInput(0, n49);
+ n53->ReplaceInput(1, n50);
+ n8->ReplaceInput(1, n53);
+ n17->ReplaceInput(1, n8);
+ n18->ReplaceInput(0, n17);
+ n23->ReplaceInput(0, n18);
+ n23->ReplaceInput(1, n43);
+ n26->ReplaceInput(2, n23);
+ n11->ReplaceInput(1, n26);
+ n11->ReplaceInput(2, n8);
+ n16->ReplaceInput(1, n11);
+ n16->ReplaceInput(2, n6);
+ op = common_builder.Phi(2);
+ Node* n14 = graph.NewNode(op, nil, nil, nil);
+ USE(n14);
+ n14->ReplaceInput(0, n0);
+ op = common_builder.Phi(2);
+ Node* n55 = graph.NewNode(op, nil, nil, nil);
+ USE(n55);
+ n55->ReplaceInput(0, n47);
+ n55->ReplaceInput(1, n52);
+ n55->ReplaceInput(2, n53);
+ n14->ReplaceInput(1, n55);
+ n14->ReplaceInput(2, n8);
+ n16->ReplaceInput(3, n14);
+ n16->ReplaceInput(4, n8);
+ n20->ReplaceInput(2, n16);
+ n20->ReplaceInput(3, n18);
+ n22->ReplaceInput(0, n20);
+ n22->ReplaceInput(1, n21);
+ n22->ReplaceInput(2, n6);
+ n22->ReplaceInput(3, n20);
+ n22->ReplaceInput(4, n18);
+ n25->ReplaceInput(0, n22);
+ n25->ReplaceInput(1, n45);
+ n25->ReplaceInput(2, n23);
+ n10->ReplaceInput(1, n25);
+ n10->ReplaceInput(2, n8);
+ n56->ReplaceInput(0, n10);
+ n56->ReplaceInput(1, n13);
+ n56->ReplaceInput(2, n6);
+ n56->ReplaceInput(3, n16);
+ op = common_builder.IfFalse();
+ Node* n19 = graph.NewNode(op, nil);
+ USE(n19);
+ n19->ReplaceInput(0, n17);
+ n56->ReplaceInput(4, n19);
+ n57->ReplaceInput(0, n56);
+ n57->ReplaceInput(1, n56);
+ n57->ReplaceInput(2, n19);
+ n58->ReplaceInput(0, n57);
+
+ graph.SetStart(n0);
+ graph.SetEnd(n58);
+
+ PrintGraph(&graph);
+
+ Schedule* schedule = Scheduler::ComputeSchedule(&graph);
+
+ PrintSchedule(schedule);
+
+ CHECK_EQ(62, GetScheduledNodeCount(schedule));
+}
+
+
+TEST(BuildScheduleSimpleLoopWithCodeMotion) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Graph graph(scope.main_zone());
+ CommonOperatorBuilder common_builder(scope.main_zone());
+ JSOperatorBuilder js_builder(scope.main_zone());
+ MachineOperatorBuilder machine_builder(scope.main_zone(), kMachineWord32);
+ Operator* op;
+
+ Handle<Object> object =
+ Handle<Object>(isolate->heap()->undefined_value(), isolate);
+ PrintableUnique<Object> unique_constant =
+ PrintableUnique<Object>::CreateUninitialized(scope.main_zone(), object);
+
+ // Manually transcripted code for:
+ // function turbo_fan_test(a, b, c) {
+ // while (a < b) {
+ // a += b + c;
+ // }
+ // return a;
+ // }
+ op = common_builder.Start(0);
+ Node* n0 = graph.NewNode(op);
+ USE(n0);
+ Node* nil = graph.NewNode(common_builder.Dead());
+ op = common_builder.End();
+ Node* n22 = graph.NewNode(op, nil);
+ USE(n22);
+ op = common_builder.Return();
+ Node* n21 = graph.NewNode(op, nil, nil, nil);
+ USE(n21);
+ op = common_builder.Phi(2);
+ Node* n9 = graph.NewNode(op, nil, nil, nil);
+ USE(n9);
+ op = common_builder.Parameter(0);
+ Node* n2 = graph.NewNode(op, n0);
+ USE(n2);
+ n9->ReplaceInput(0, n2);
+ op = js_builder.Add();
+ Node* n20 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n20);
+ n20->ReplaceInput(0, n9);
+ op = machine_builder.Int32Add();
+ Node* n19 = graph.NewNode(op, nil, nil);
+ USE(n19);
+ op = common_builder.Phi(2);
+ Node* n10 = graph.NewNode(op, nil, nil, nil);
+ USE(n10);
+ op = common_builder.Parameter(0);
+ Node* n3 = graph.NewNode(op, n0);
+ USE(n3);
+ n10->ReplaceInput(0, n3);
+ n10->ReplaceInput(1, n10);
+ op = common_builder.Loop(2);
+ Node* n7 = graph.NewNode(op, nil, nil);
+ USE(n7);
+ n7->ReplaceInput(0, n0);
+ op = common_builder.IfTrue();
+ Node* n17 = graph.NewNode(op, nil);
+ USE(n17);
+ op = common_builder.Branch();
+ Node* n16 = graph.NewNode(op, nil, nil);
+ USE(n16);
+ op = js_builder.ToBoolean();
+ Node* n15 = graph.NewNode(op, nil, nil, nil, nil);
+ USE(n15);
+ op = js_builder.LessThan();
+ Node* n14 = graph.NewNode(op, nil, nil, nil, nil, nil);
+ USE(n14);
+ n14->ReplaceInput(0, n9);
+ n14->ReplaceInput(1, n10);
+ op = common_builder.HeapConstant(unique_constant);
+ Node* n6 = graph.NewNode(op);
+ USE(n6);
+ n14->ReplaceInput(2, n6);
+ op = common_builder.Phi(2);
+ Node* n12 = graph.NewNode(op, nil, nil, nil);
+ USE(n12);
+ n12->ReplaceInput(0, n0);
+ n12->ReplaceInput(1, n20);
+ n12->ReplaceInput(2, n7);
+ n14->ReplaceInput(3, n12);
+ n14->ReplaceInput(4, n7);
+ n15->ReplaceInput(0, n14);
+ n15->ReplaceInput(1, n6);
+ n15->ReplaceInput(2, n14);
+ n15->ReplaceInput(3, n7);
+ n16->ReplaceInput(0, n15);
+ n16->ReplaceInput(1, n7);
+ n17->ReplaceInput(0, n16);
+ n7->ReplaceInput(1, n17);
+ n10->ReplaceInput(2, n7);
+ n19->ReplaceInput(0, n2);
+ op = common_builder.Phi(2);
+ Node* n11 = graph.NewNode(op, nil, nil, nil);
+ USE(n11);
+ op = common_builder.Parameter(0);
+ Node* n4 = graph.NewNode(op, n0);
+ USE(n4);
+ n11->ReplaceInput(0, n4);
+ n11->ReplaceInput(1, n11);
+ n11->ReplaceInput(2, n7);
+ n19->ReplaceInput(1, n3);
+ n20->ReplaceInput(1, n19);
+ n20->ReplaceInput(2, n6);
+ n20->ReplaceInput(3, n19);
+ n20->ReplaceInput(4, n17);
+ n9->ReplaceInput(1, n20);
+ n9->ReplaceInput(2, n7);
+ n21->ReplaceInput(0, n9);
+ n21->ReplaceInput(1, n15);
+ op = common_builder.IfFalse();
+ Node* n18 = graph.NewNode(op, nil);
+ USE(n18);
+ n18->ReplaceInput(0, n16);
+ n21->ReplaceInput(2, n18);
+ n22->ReplaceInput(0, n21);
+
+ graph.SetStart(n0);
+ graph.SetEnd(n22);
+
+ PrintGraph(&graph);
+
+ Schedule* schedule = Scheduler::ComputeSchedule(&graph);
+
+ PrintSchedule(schedule);
+
+ CHECK_EQ(19, GetScheduledNodeCount(schedule));
+
+ // Make sure the integer-only add gets hoisted to a different block that the
+ // JSAdd.
+ CHECK(schedule->block(n19) != schedule->block(n20));
+}
+
+
+#if V8_TURBOFAN_TARGET
+
+// So we can get a real JS function.
+static Handle<JSFunction> Compile(const char* source) {
+ Isolate* isolate = CcTest::i_isolate();
+ Handle<String> source_code = isolate->factory()
+ ->NewStringFromUtf8(CStrVector(source))
+ .ToHandleChecked();
+ Handle<SharedFunctionInfo> shared_function = Compiler::CompileScript(
+ source_code, Handle<String>(), 0, 0, false,
+ Handle<Context>(isolate->native_context()), NULL, NULL,
+ v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE);
+ return isolate->factory()->NewFunctionFromSharedFunctionInfo(
+ shared_function, isolate->native_context());
+}
+
+
+TEST(BuildScheduleTrivialLazyDeoptCall) {
+ FLAG_turbo_deoptimization = true;
+
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Graph graph(scope.main_zone());
+ CommonOperatorBuilder common(scope.main_zone());
+ JSOperatorBuilder js_builder(scope.main_zone());
+
+ InitializedHandleScope handles;
+ Handle<JSFunction> function = Compile("m()");
+ CompilationInfoWithZone info(function);
+ Linkage linkage(&info);
+
+ // Manually transcribed code for:
+ // function turbo_fan_test() {
+ // m();
+ // }
+ // where m can lazy deopt (so it has a deopt block associated with it).
+
+
+ // Start //
+ // ^ //
+ // | (EC) //
+ // | //
+ // /------> Call <--------------\ //
+ // / ^ ^ \ //
+ // / | | \ undef //
+ // / / \ \ ^ //
+ // (E) | (C) / \ (C) \ (E) | //
+ // | Continuation LazyDeoptimization | | //
+ // \___ ^ ^ / | //
+ // \ | | ______/ Framestate //
+ // undef \ | (VC) | (C) / ^ //
+ // \ \ | | / / //
+ // Return Deoptimization ----------/ //
+ // ^ ^ //
+ // \ / //
+ // (C) \ / (C) //
+ // \ / //
+ // Merge //
+ // ^ //
+ // | //
+ // End //
+
+ Handle<Object> undef_object =
+ Handle<Object>(isolate->heap()->undefined_value(), isolate);
+ PrintableUnique<Object> undef_constant =
+ PrintableUnique<Object>::CreateUninitialized(scope.main_zone(),
+ undef_object);
+
+ Node* undef_node = graph.NewNode(common.HeapConstant(undef_constant));
+
+ Node* start_node = graph.NewNode(common.Start(0));
+
+ CallDescriptor* descriptor = linkage.GetJSCallDescriptor(0);
+ Node* call_node = graph.NewNode(common.Call(descriptor),
+ undef_node, // function
+ undef_node, // context
+ start_node, // effect
+ start_node); // control
+
+ Node* cont_node = graph.NewNode(common.Continuation(), call_node);
+ Node* lazy_deopt_node = graph.NewNode(common.LazyDeoptimization(), call_node);
+
+ Node* parameters = graph.NewNode(common.StateValues(1), undef_node);
+ Node* locals = graph.NewNode(common.StateValues(0));
+ Node* stack = graph.NewNode(common.StateValues(0));
+
+ Node* state_node = graph.NewNode(common.FrameState(BailoutId(1234)),
+ parameters, locals, stack);
+
+ Node* return_node = graph.NewNode(common.Return(),
+ undef_node, // return value
+ call_node, // effect
+ cont_node); // control
+ Node* deoptimization_node = graph.NewNode(common.Deoptimize(),
+ state_node, // deopt environment
+ call_node, // effect
+ lazy_deopt_node); // control
+
+ Node* merge_node =
+ graph.NewNode(common.Merge(2), return_node, deoptimization_node);
+
+ Node* end_node = graph.NewNode(common.End(), merge_node);
+
+ graph.SetStart(start_node);
+ graph.SetEnd(end_node);
+
+ PrintGraph(&graph);
+
+ Schedule* schedule = Scheduler::ComputeSchedule(&graph);
+
+ PrintSchedule(schedule);
+
+ // Tests:
+ // Continuation and deopt have basic blocks.
+ BasicBlock* cont_block = schedule->block(cont_node);
+ BasicBlock* deopt_block = schedule->block(lazy_deopt_node);
+ BasicBlock* call_block = schedule->block(call_node);
+ CHECK_NE(NULL, cont_block);
+ CHECK_NE(NULL, deopt_block);
+ CHECK_NE(NULL, call_block);
+ // The basic blocks are different.
+ CHECK_NE(cont_block, deopt_block);
+ CHECK_NE(cont_block, call_block);
+ CHECK_NE(deopt_block, call_block);
+ // The call node finishes its own basic block.
+ CHECK_EQ(BasicBlock::kCall, call_block->control_);
+ CHECK_EQ(call_node, call_block->control_input_);
+ // The lazy deopt block is deferred.
+ CHECK(deopt_block->deferred_);
+ CHECK(!call_block->deferred_);
+ CHECK(!cont_block->deferred_);
+ // The lazy deopt block contains framestate + bailout (and nothing else).
+ CHECK_EQ(deoptimization_node, deopt_block->control_input_);
+ CHECK_EQ(5, static_cast<int>(deopt_block->nodes_.size()));
+ CHECK_EQ(lazy_deopt_node, deopt_block->nodes_[0]);
+ CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[1]->op()->opcode());
+ CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[2]->op()->opcode());
+ CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[3]->op()->opcode());
+ CHECK_EQ(state_node, deopt_block->nodes_[4]);
+}
+
+#endif
diff --git a/deps/v8/test/cctest/compiler/test-simplified-lowering.cc b/deps/v8/test/cctest/compiler/test-simplified-lowering.cc
new file mode 100644
index 000000000..18f4136b9
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-simplified-lowering.cc
@@ -0,0 +1,1372 @@
+// 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 <limits>
+
+#include "src/compiler/control-builders.h"
+#include "src/compiler/generic-node-inl.h"
+#include "src/compiler/graph-visualizer.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/pipeline.h"
+#include "src/compiler/representation-change.h"
+#include "src/compiler/simplified-lowering.h"
+#include "src/compiler/simplified-node-factory.h"
+#include "src/compiler/typer.h"
+#include "src/compiler/verifier.h"
+#include "src/execution.h"
+#include "src/parser.h"
+#include "src/rewriter.h"
+#include "src/scopes.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/codegen-tester.h"
+#include "test/cctest/compiler/graph-builder-tester.h"
+#include "test/cctest/compiler/value-helper.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+template <typename ReturnType>
+class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
+ public:
+ SimplifiedLoweringTester(MachineType p0 = kMachineLast,
+ MachineType p1 = kMachineLast,
+ MachineType p2 = kMachineLast,
+ MachineType p3 = kMachineLast,
+ MachineType p4 = kMachineLast)
+ : GraphBuilderTester<ReturnType>(p0, p1, p2, p3, p4),
+ typer(this->zone()),
+ source_positions(this->graph()),
+ jsgraph(this->graph(), this->common(), &typer),
+ lowering(&jsgraph, &source_positions) {}
+
+ Typer typer;
+ SourcePositionTable source_positions;
+ JSGraph jsgraph;
+ SimplifiedLowering lowering;
+
+ void LowerAllNodes() {
+ this->End();
+ lowering.LowerAllNodes();
+ }
+
+ Factory* factory() { return this->isolate()->factory(); }
+ Heap* heap() { return this->isolate()->heap(); }
+};
+
+
+// TODO(dcarney): find a home for these functions.
+namespace {
+
+FieldAccess ForJSObjectMap() {
+ FieldAccess access = {kTaggedBase, JSObject::kMapOffset, Handle<Name>(),
+ Type::Any(), kMachineTagged};
+ return access;
+}
+
+
+FieldAccess ForJSObjectProperties() {
+ FieldAccess access = {kTaggedBase, JSObject::kPropertiesOffset,
+ Handle<Name>(), Type::Any(), kMachineTagged};
+ return access;
+}
+
+
+FieldAccess ForArrayBufferBackingStore() {
+ FieldAccess access = {
+ kTaggedBase, JSArrayBuffer::kBackingStoreOffset,
+ Handle<Name>(), Type::UntaggedPtr(),
+ MachineOperatorBuilder::pointer_rep(),
+ };
+ return access;
+}
+
+
+ElementAccess ForFixedArrayElement() {
+ ElementAccess access = {kTaggedBase, FixedArray::kHeaderSize, Type::Any(),
+ kMachineTagged};
+ return access;
+}
+
+
+ElementAccess ForBackingStoreElement(MachineType rep) {
+ ElementAccess access = {kUntaggedBase,
+ kNonHeapObjectHeaderSize - kHeapObjectTag,
+ Type::Any(), rep};
+ return access;
+}
+}
+
+
+// Create a simple JSObject with a unique map.
+static Handle<JSObject> TestObject() {
+ static int index = 0;
+ char buffer[50];
+ v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++);
+ return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer)));
+}
+
+
+TEST(RunLoadMap) {
+ SimplifiedLoweringTester<Object*> t(kMachineTagged);
+ FieldAccess access = ForJSObjectMap();
+ Node* load = t.LoadField(access, t.Parameter(0));
+ t.Return(load);
+
+ t.LowerAllNodes();
+ t.GenerateCode();
+
+ if (Pipeline::SupportedTarget()) {
+ Handle<JSObject> src = TestObject();
+ Handle<Map> src_map(src->map());
+ Object* result = t.Call(*src); // TODO(titzer): raw pointers in call
+ CHECK_EQ(*src_map, result);
+ }
+}
+
+
+TEST(RunStoreMap) {
+ SimplifiedLoweringTester<int32_t> t(kMachineTagged, kMachineTagged);
+ FieldAccess access = ForJSObjectMap();
+ t.StoreField(access, t.Parameter(1), t.Parameter(0));
+ t.Return(t.jsgraph.TrueConstant());
+
+ t.LowerAllNodes();
+ t.GenerateCode();
+
+ if (Pipeline::SupportedTarget()) {
+ Handle<JSObject> src = TestObject();
+ Handle<Map> src_map(src->map());
+ Handle<JSObject> dst = TestObject();
+ CHECK(src->map() != dst->map());
+ t.Call(*src_map, *dst); // TODO(titzer): raw pointers in call
+ CHECK(*src_map == dst->map());
+ }
+}
+
+
+TEST(RunLoadProperties) {
+ SimplifiedLoweringTester<Object*> t(kMachineTagged);
+ FieldAccess access = ForJSObjectProperties();
+ Node* load = t.LoadField(access, t.Parameter(0));
+ t.Return(load);
+
+ t.LowerAllNodes();
+ t.GenerateCode();
+
+ if (Pipeline::SupportedTarget()) {
+ Handle<JSObject> src = TestObject();
+ Handle<FixedArray> src_props(src->properties());
+ Object* result = t.Call(*src); // TODO(titzer): raw pointers in call
+ CHECK_EQ(*src_props, result);
+ }
+}
+
+
+TEST(RunLoadStoreMap) {
+ SimplifiedLoweringTester<Object*> t(kMachineTagged, kMachineTagged);
+ FieldAccess access = ForJSObjectMap();
+ Node* load = t.LoadField(access, t.Parameter(0));
+ t.StoreField(access, t.Parameter(1), load);
+ t.Return(load);
+
+ t.LowerAllNodes();
+ t.GenerateCode();
+
+ if (Pipeline::SupportedTarget()) {
+ Handle<JSObject> src = TestObject();
+ Handle<Map> src_map(src->map());
+ Handle<JSObject> dst = TestObject();
+ CHECK(src->map() != dst->map());
+ Object* result = t.Call(*src, *dst); // TODO(titzer): raw pointers in call
+ CHECK(result->IsMap());
+ CHECK_EQ(*src_map, result);
+ CHECK(*src_map == dst->map());
+ }
+}
+
+
+TEST(RunLoadStoreFixedArrayIndex) {
+ SimplifiedLoweringTester<Object*> t(kMachineTagged);
+ ElementAccess access = ForFixedArrayElement();
+ Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0));
+ t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load);
+ t.Return(load);
+
+ t.LowerAllNodes();
+ t.GenerateCode();
+
+ if (Pipeline::SupportedTarget()) {
+ Handle<FixedArray> array = t.factory()->NewFixedArray(2);
+ Handle<JSObject> src = TestObject();
+ Handle<JSObject> dst = TestObject();
+ array->set(0, *src);
+ array->set(1, *dst);
+ Object* result = t.Call(*array);
+ CHECK_EQ(*src, result);
+ CHECK_EQ(*src, array->get(0));
+ CHECK_EQ(*src, array->get(1));
+ }
+}
+
+
+TEST(RunLoadStoreArrayBuffer) {
+ SimplifiedLoweringTester<Object*> t(kMachineTagged);
+ const int index = 12;
+ ElementAccess buffer_access = ForBackingStoreElement(kMachineWord8);
+ Node* backing_store =
+ t.LoadField(ForArrayBufferBackingStore(), t.Parameter(0));
+ Node* load =
+ t.LoadElement(buffer_access, backing_store, t.Int32Constant(index));
+ t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1),
+ load);
+ t.Return(t.jsgraph.TrueConstant());
+
+ t.LowerAllNodes();
+ t.GenerateCode();
+
+ if (Pipeline::SupportedTarget()) {
+ Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer();
+ const int array_length = 2 * index;
+ Runtime::SetupArrayBufferAllocatingData(t.isolate(), array, array_length);
+ uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store());
+ for (int i = 0; i < array_length; i++) {
+ data[i] = i;
+ }
+
+ // TODO(titzer): raw pointers in call
+ Object* result = t.Call(*array);
+ CHECK_EQ(t.isolate()->heap()->true_value(), result);
+ for (int i = 0; i < array_length; i++) {
+ uint8_t expected = i;
+ if (i == (index + 1)) expected = index;
+ CHECK_EQ(data[i], expected);
+ }
+ }
+}
+
+
+TEST(RunLoadFieldFromUntaggedBase) {
+ Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)};
+
+ for (size_t i = 0; i < ARRAY_SIZE(smis); i++) {
+ int offset = static_cast<int>(i * sizeof(Smi*));
+ FieldAccess access = {kUntaggedBase, offset, Handle<Name>(),
+ Type::Integral32(), kMachineTagged};
+
+ SimplifiedLoweringTester<Object*> t;
+ Node* load = t.LoadField(access, t.PointerConstant(smis));
+ t.Return(load);
+ t.LowerAllNodes();
+
+ if (!Pipeline::SupportedTarget()) continue;
+
+ for (int j = -5; j <= 5; j++) {
+ Smi* expected = Smi::FromInt(j);
+ smis[i] = expected;
+ CHECK_EQ(expected, t.Call());
+ }
+ }
+}
+
+
+TEST(RunStoreFieldToUntaggedBase) {
+ Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)};
+
+ for (size_t i = 0; i < ARRAY_SIZE(smis); i++) {
+ int offset = static_cast<int>(i * sizeof(Smi*));
+ FieldAccess access = {kUntaggedBase, offset, Handle<Name>(),
+ Type::Integral32(), kMachineTagged};
+
+ SimplifiedLoweringTester<Object*> t(kMachineTagged);
+ Node* p0 = t.Parameter(0);
+ t.StoreField(access, t.PointerConstant(smis), p0);
+ t.Return(p0);
+ t.LowerAllNodes();
+
+ if (!Pipeline::SupportedTarget()) continue;
+
+ for (int j = -5; j <= 5; j++) {
+ Smi* expected = Smi::FromInt(j);
+ smis[i] = Smi::FromInt(-100);
+ CHECK_EQ(expected, t.Call(expected));
+ CHECK_EQ(expected, smis[i]);
+ }
+ }
+}
+
+
+TEST(RunLoadElementFromUntaggedBase) {
+ Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3),
+ Smi::FromInt(4), Smi::FromInt(5)};
+
+ for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { // for header sizes
+ for (size_t j = 0; (i + j) < ARRAY_SIZE(smis); j++) { // for element index
+ int offset = static_cast<int>(i * sizeof(Smi*));
+ ElementAccess access = {kUntaggedBase, offset, Type::Integral32(),
+ kMachineTagged};
+
+ SimplifiedLoweringTester<Object*> t;
+ Node* load = t.LoadElement(access, t.PointerConstant(smis),
+ t.Int32Constant(static_cast<int>(j)));
+ t.Return(load);
+ t.LowerAllNodes();
+
+ if (!Pipeline::SupportedTarget()) continue;
+
+ for (int k = -5; k <= 5; k++) {
+ Smi* expected = Smi::FromInt(k);
+ smis[i + j] = expected;
+ CHECK_EQ(expected, t.Call());
+ }
+ }
+ }
+}
+
+
+TEST(RunStoreElementFromUntaggedBase) {
+ Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3),
+ Smi::FromInt(4), Smi::FromInt(5)};
+
+ for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { // for header sizes
+ for (size_t j = 0; (i + j) < ARRAY_SIZE(smis); j++) { // for element index
+ int offset = static_cast<int>(i * sizeof(Smi*));
+ ElementAccess access = {kUntaggedBase, offset, Type::Integral32(),
+ kMachineTagged};
+
+ SimplifiedLoweringTester<Object*> t(kMachineTagged);
+ Node* p0 = t.Parameter(0);
+ t.StoreElement(access, t.PointerConstant(smis),
+ t.Int32Constant(static_cast<int>(j)), p0);
+ t.Return(p0);
+ t.LowerAllNodes();
+
+ if (!Pipeline::SupportedTarget()) continue;
+
+ for (int k = -5; k <= 5; k++) {
+ Smi* expected = Smi::FromInt(k);
+ smis[i + j] = Smi::FromInt(-100);
+ CHECK_EQ(expected, t.Call(expected));
+ CHECK_EQ(expected, smis[i + j]);
+ }
+
+ // TODO(titzer): assert the contents of the array.
+ }
+ }
+}
+
+
+// A helper class for accessing fields and elements of various types, on both
+// tagged and untagged base pointers. Contains both tagged and untagged buffers
+// for testing direct memory access from generated code.
+template <typename E>
+class AccessTester : public HandleAndZoneScope {
+ public:
+ bool tagged;
+ MachineType rep;
+ E* original_elements;
+ size_t num_elements;
+ E* untagged_array;
+ Handle<ByteArray> tagged_array; // TODO(titzer): use FixedArray for tagged.
+
+ AccessTester(bool t, MachineType r, E* orig, size_t num)
+ : tagged(t),
+ rep(r),
+ original_elements(orig),
+ num_elements(num),
+ untagged_array(static_cast<E*>(malloc(ByteSize()))),
+ tagged_array(main_isolate()->factory()->NewByteArray(
+ static_cast<int>(ByteSize()))) {
+ Reinitialize();
+ }
+
+ ~AccessTester() { free(untagged_array); }
+
+ size_t ByteSize() { return num_elements * sizeof(E); }
+
+ // Nuke both {untagged_array} and {tagged_array} with {original_elements}.
+ void Reinitialize() {
+ memcpy(untagged_array, original_elements, ByteSize());
+ CHECK_EQ(static_cast<int>(ByteSize()), tagged_array->length());
+ E* raw = reinterpret_cast<E*>(tagged_array->GetDataStartAddress());
+ memcpy(raw, original_elements, ByteSize());
+ }
+
+ // Create and run code that copies the element in either {untagged_array}
+ // or {tagged_array} at index {from_index} to index {to_index}.
+ void RunCopyElement(int from_index, int to_index) {
+ // TODO(titzer): test element and field accesses where the base is not
+ // a constant in the code.
+ BoundsCheck(from_index);
+ BoundsCheck(to_index);
+ ElementAccess access = GetElementAccess();
+
+ SimplifiedLoweringTester<Object*> t;
+ Node* ptr = GetBaseNode(&t);
+ Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index));
+ t.StoreElement(access, ptr, t.Int32Constant(to_index), load);
+ t.Return(t.jsgraph.TrueConstant());
+ t.LowerAllNodes();
+ t.GenerateCode();
+
+ if (Pipeline::SupportedTarget()) {
+ Object* result = t.Call();
+ CHECK_EQ(t.isolate()->heap()->true_value(), result);
+ }
+ }
+
+ // Create and run code that copies the field in either {untagged_array}
+ // or {tagged_array} at index {from_index} to index {to_index}.
+ void RunCopyField(int from_index, int to_index) {
+ BoundsCheck(from_index);
+ BoundsCheck(to_index);
+ FieldAccess from_access = GetFieldAccess(from_index);
+ FieldAccess to_access = GetFieldAccess(to_index);
+
+ SimplifiedLoweringTester<Object*> t;
+ Node* ptr = GetBaseNode(&t);
+ Node* load = t.LoadField(from_access, ptr);
+ t.StoreField(to_access, ptr, load);
+ t.Return(t.jsgraph.TrueConstant());
+ t.LowerAllNodes();
+ t.GenerateCode();
+
+ if (Pipeline::SupportedTarget()) {
+ Object* result = t.Call();
+ CHECK_EQ(t.isolate()->heap()->true_value(), result);
+ }
+ }
+
+ // Create and run code that copies the elements from {this} to {that}.
+ void RunCopyElements(AccessTester<E>* that) {
+ SimplifiedLoweringTester<Object*> t;
+
+ Node* one = t.Int32Constant(1);
+ Node* index = t.Int32Constant(0);
+ Node* limit = t.Int32Constant(static_cast<int>(num_elements));
+ t.environment()->Push(index);
+ Node* src = this->GetBaseNode(&t);
+ Node* dst = that->GetBaseNode(&t);
+ {
+ LoopBuilder loop(&t);
+ loop.BeginLoop();
+ // Loop exit condition
+ index = t.environment()->Top();
+ Node* condition = t.Int32LessThan(index, limit);
+ loop.BreakUnless(condition);
+ // dst[index] = src[index]
+ index = t.environment()->Pop();
+ Node* load = t.LoadElement(this->GetElementAccess(), src, index);
+ t.StoreElement(that->GetElementAccess(), dst, index, load);
+ // index++
+ index = t.Int32Add(index, one);
+ t.environment()->Push(index);
+ // continue
+ loop.EndBody();
+ loop.EndLoop();
+ }
+ index = t.environment()->Pop();
+ t.Return(t.jsgraph.TrueConstant());
+ t.LowerAllNodes();
+ t.GenerateCode();
+
+ if (Pipeline::SupportedTarget()) {
+ Object* result = t.Call();
+ CHECK_EQ(t.isolate()->heap()->true_value(), result);
+ }
+ }
+
+ E GetElement(int index) {
+ BoundsCheck(index);
+ if (tagged) {
+ E* raw = reinterpret_cast<E*>(tagged_array->GetDataStartAddress());
+ return raw[index];
+ } else {
+ return untagged_array[index];
+ }
+ }
+
+ private:
+ ElementAccess GetElementAccess() {
+ ElementAccess access = {tagged ? kTaggedBase : kUntaggedBase,
+ tagged ? FixedArrayBase::kHeaderSize : 0,
+ Type::Any(), rep};
+ return access;
+ }
+
+ FieldAccess GetFieldAccess(int field) {
+ int offset = field * sizeof(E);
+ FieldAccess access = {tagged ? kTaggedBase : kUntaggedBase,
+ offset + (tagged ? FixedArrayBase::kHeaderSize : 0),
+ Handle<Name>(), Type::Any(), rep};
+ return access;
+ }
+
+ template <typename T>
+ Node* GetBaseNode(SimplifiedLoweringTester<T>* t) {
+ return tagged ? t->HeapConstant(tagged_array)
+ : t->PointerConstant(untagged_array);
+ }
+
+ void BoundsCheck(int index) {
+ CHECK_GE(index, 0);
+ CHECK_LT(index, static_cast<int>(num_elements));
+ CHECK_EQ(static_cast<int>(ByteSize()), tagged_array->length());
+ }
+};
+
+
+template <typename E>
+static void RunAccessTest(MachineType rep, E* original_elements, size_t num) {
+ int num_elements = static_cast<int>(num);
+
+ for (int taggedness = 0; taggedness < 2; taggedness++) {
+ AccessTester<E> a(taggedness == 1, rep, original_elements, num);
+ for (int field = 0; field < 2; field++) {
+ for (int i = 0; i < num_elements - 1; i++) {
+ a.Reinitialize();
+ if (field == 0) {
+ a.RunCopyField(i, i + 1); // Test field read/write.
+ } else {
+ a.RunCopyElement(i, i + 1); // Test element read/write.
+ }
+ if (Pipeline::SupportedTarget()) { // verify.
+ for (int j = 0; j < num_elements; j++) {
+ E expect =
+ j == (i + 1) ? original_elements[i] : original_elements[j];
+ CHECK_EQ(expect, a.GetElement(j));
+ }
+ }
+ }
+ }
+ }
+ // Test array copy.
+ for (int tf = 0; tf < 2; tf++) {
+ for (int tt = 0; tt < 2; tt++) {
+ AccessTester<E> a(tf == 1, rep, original_elements, num);
+ AccessTester<E> b(tt == 1, rep, original_elements, num);
+ a.RunCopyElements(&b);
+ if (Pipeline::SupportedTarget()) { // verify.
+ for (int i = 0; i < num_elements; i++) {
+ CHECK_EQ(a.GetElement(i), b.GetElement(i));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunAccessTests_uint8) {
+ uint8_t data[] = {0x07, 0x16, 0x25, 0x34, 0x43, 0x99,
+ 0xab, 0x78, 0x89, 0x19, 0x2b, 0x38};
+ RunAccessTest<uint8_t>(kMachineWord8, data, ARRAY_SIZE(data));
+}
+
+
+TEST(RunAccessTests_uint16) {
+ uint16_t data[] = {0x071a, 0x162b, 0x253c, 0x344d, 0x435e, 0x7777};
+ RunAccessTest<uint16_t>(kMachineWord16, data, ARRAY_SIZE(data));
+}
+
+
+TEST(RunAccessTests_int32) {
+ int32_t data[] = {-211, 211, 628347, 2000000000, -2000000000, -1, -100000034};
+ RunAccessTest<int32_t>(kMachineWord32, data, ARRAY_SIZE(data));
+}
+
+
+#define V8_2PART_INT64(a, b) (((static_cast<int64_t>(a) << 32) + 0x##b##u))
+
+
+TEST(RunAccessTests_int64) {
+ if (kPointerSize != 8) return;
+ int64_t data[] = {V8_2PART_INT64(0x10111213, 14151617),
+ V8_2PART_INT64(0x20212223, 24252627),
+ V8_2PART_INT64(0x30313233, 34353637),
+ V8_2PART_INT64(0xa0a1a2a3, a4a5a6a7),
+ V8_2PART_INT64(0xf0f1f2f3, f4f5f6f7)};
+ RunAccessTest<int64_t>(kMachineWord64, data, ARRAY_SIZE(data));
+}
+
+
+TEST(RunAccessTests_float64) {
+ double data[] = {1.25, -1.25, 2.75, 11.0, 11100.8};
+ RunAccessTest<double>(kMachineFloat64, data, ARRAY_SIZE(data));
+}
+
+
+TEST(RunAccessTests_Smi) {
+ Smi* data[] = {Smi::FromInt(-1), Smi::FromInt(-9),
+ Smi::FromInt(0), Smi::FromInt(666),
+ Smi::FromInt(77777), Smi::FromInt(Smi::kMaxValue)};
+ RunAccessTest<Smi*>(kMachineTagged, data, ARRAY_SIZE(data));
+}
+
+
+// Fills in most of the nodes of the graph in order to make tests shorter.
+class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
+ public:
+ Typer typer;
+ JSGraph jsgraph;
+ Node* p0;
+ Node* p1;
+ Node* start;
+ Node* end;
+ Node* ret;
+
+ explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None())
+ : GraphAndBuilders(main_zone()),
+ typer(main_zone()),
+ jsgraph(graph(), common(), &typer) {
+ start = graph()->NewNode(common()->Start(2));
+ graph()->SetStart(start);
+ ret =
+ graph()->NewNode(common()->Return(), jsgraph.Constant(0), start, start);
+ end = graph()->NewNode(common()->End(), ret);
+ graph()->SetEnd(end);
+ p0 = graph()->NewNode(common()->Parameter(0), start);
+ p1 = graph()->NewNode(common()->Parameter(1), start);
+ NodeProperties::SetBounds(p0, Bounds(p0_type));
+ NodeProperties::SetBounds(p1, Bounds(p1_type));
+ }
+
+ void CheckLoweringBinop(IrOpcode::Value expected, Operator* op) {
+ Node* node = Return(graph()->NewNode(op, p0, p1));
+ Lower();
+ CHECK_EQ(expected, node->opcode());
+ }
+
+ void CheckLoweringTruncatedBinop(IrOpcode::Value expected, Operator* op,
+ Operator* trunc) {
+ Node* node = graph()->NewNode(op, p0, p1);
+ Return(graph()->NewNode(trunc, node));
+ Lower();
+ CHECK_EQ(expected, node->opcode());
+ }
+
+ void Lower() {
+ SimplifiedLowering lowering(&jsgraph, NULL);
+ lowering.LowerAllNodes();
+ }
+
+ // Inserts the node as the return value of the graph.
+ Node* Return(Node* node) {
+ ret->ReplaceInput(0, node);
+ return node;
+ }
+
+ // Inserts the node as the effect input to the return of the graph.
+ void Effect(Node* node) { ret->ReplaceInput(1, node); }
+
+ Node* ExampleWithOutput(RepType type) {
+ // TODO(titzer): use parameters with guaranteed representations.
+ if (type & tInt32) {
+ return graph()->NewNode(machine()->Int32Add(), jsgraph.Int32Constant(1),
+ jsgraph.Int32Constant(1));
+ } else if (type & tUint32) {
+ return graph()->NewNode(machine()->Word32Shr(), jsgraph.Int32Constant(1),
+ jsgraph.Int32Constant(1));
+ } else if (type & rFloat64) {
+ return graph()->NewNode(machine()->Float64Add(),
+ jsgraph.Float64Constant(1),
+ jsgraph.Float64Constant(1));
+ } else if (type & rBit) {
+ return graph()->NewNode(machine()->Word32Equal(),
+ jsgraph.Int32Constant(1),
+ jsgraph.Int32Constant(1));
+ } else if (type & rWord64) {
+ return graph()->NewNode(machine()->Int64Add(), Int64Constant(1),
+ Int64Constant(1));
+ } else {
+ CHECK(type & rTagged);
+ return p0;
+ }
+ }
+
+ Node* Use(Node* node, RepType type) {
+ if (type & tInt32) {
+ return graph()->NewNode(machine()->Int32LessThan(), node,
+ jsgraph.Int32Constant(1));
+ } else if (type & tUint32) {
+ return graph()->NewNode(machine()->Uint32LessThan(), node,
+ jsgraph.Int32Constant(1));
+ } else if (type & rFloat64) {
+ return graph()->NewNode(machine()->Float64Add(), node,
+ jsgraph.Float64Constant(1));
+ } else if (type & rWord64) {
+ return graph()->NewNode(machine()->Int64LessThan(), node,
+ Int64Constant(1));
+ } else {
+ return graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), node,
+ jsgraph.TrueConstant());
+ }
+ }
+
+ Node* Branch(Node* cond) {
+ Node* br = graph()->NewNode(common()->Branch(), cond, start);
+ Node* tb = graph()->NewNode(common()->IfTrue(), br);
+ Node* fb = graph()->NewNode(common()->IfFalse(), br);
+ Node* m = graph()->NewNode(common()->Merge(2), tb, fb);
+ NodeProperties::ReplaceControlInput(ret, m);
+ return br;
+ }
+
+ Node* Int64Constant(int64_t v) {
+ return graph()->NewNode(common()->Int64Constant(v));
+ }
+
+ SimplifiedOperatorBuilder* simplified() { return &main_simplified_; }
+ MachineOperatorBuilder* machine() { return &main_machine_; }
+ CommonOperatorBuilder* common() { return &main_common_; }
+ Graph* graph() { return main_graph_; }
+};
+
+
+TEST(LowerBooleanNot_bit_bit) {
+ // BooleanNot(x: rBit) used as rBit
+ TestingGraph t(Type::Boolean());
+ Node* b = t.ExampleWithOutput(rBit);
+ Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b);
+ Node* use = t.Branch(inv);
+ t.Lower();
+ Node* cmp = use->InputAt(0);
+ CHECK_EQ(t.machine()->WordEqual()->opcode(), cmp->opcode());
+ CHECK(b == cmp->InputAt(0) || b == cmp->InputAt(1));
+ Node* f = t.jsgraph.Int32Constant(0);
+ CHECK(f == cmp->InputAt(0) || f == cmp->InputAt(1));
+}
+
+
+TEST(LowerBooleanNot_bit_tagged) {
+ // BooleanNot(x: rBit) used as rTagged
+ TestingGraph t(Type::Boolean());
+ Node* b = t.ExampleWithOutput(rBit);
+ Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b);
+ Node* use = t.Use(inv, rTagged);
+ t.Return(use);
+ t.Lower();
+ CHECK_EQ(IrOpcode::kChangeBitToBool, use->InputAt(0)->opcode());
+ Node* cmp = use->InputAt(0)->InputAt(0);
+ CHECK_EQ(t.machine()->WordEqual()->opcode(), cmp->opcode());
+ CHECK(b == cmp->InputAt(0) || b == cmp->InputAt(1));
+ Node* f = t.jsgraph.Int32Constant(0);
+ CHECK(f == cmp->InputAt(0) || f == cmp->InputAt(1));
+}
+
+
+TEST(LowerBooleanNot_tagged_bit) {
+ // BooleanNot(x: rTagged) used as rBit
+ TestingGraph t(Type::Boolean());
+ Node* b = t.p0;
+ Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b);
+ Node* use = t.Branch(inv);
+ t.Lower();
+ Node* cmp = use->InputAt(0);
+ CHECK_EQ(t.machine()->WordEqual()->opcode(), cmp->opcode());
+ CHECK(b == cmp->InputAt(0) || b == cmp->InputAt(1));
+ Node* f = t.jsgraph.FalseConstant();
+ CHECK(f == cmp->InputAt(0) || f == cmp->InputAt(1));
+}
+
+
+TEST(LowerBooleanNot_tagged_tagged) {
+ // BooleanNot(x: rTagged) used as rTagged
+ TestingGraph t(Type::Boolean());
+ Node* b = t.p0;
+ Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b);
+ Node* use = t.Use(inv, rTagged);
+ t.Return(use);
+ t.Lower();
+ CHECK_EQ(IrOpcode::kChangeBitToBool, use->InputAt(0)->opcode());
+ Node* cmp = use->InputAt(0)->InputAt(0);
+ CHECK_EQ(t.machine()->WordEqual()->opcode(), cmp->opcode());
+ CHECK(b == cmp->InputAt(0) || b == cmp->InputAt(1));
+ Node* f = t.jsgraph.FalseConstant();
+ CHECK(f == cmp->InputAt(0) || f == cmp->InputAt(1));
+}
+
+
+static Type* test_types[] = {Type::Signed32(), Type::Unsigned32(),
+ Type::Number(), Type::Any()};
+
+
+TEST(LowerNumberCmp_to_int32) {
+ TestingGraph t(Type::Signed32(), Type::Signed32());
+
+ t.CheckLoweringBinop(IrOpcode::kWord32Equal, t.simplified()->NumberEqual());
+ t.CheckLoweringBinop(IrOpcode::kInt32LessThan,
+ t.simplified()->NumberLessThan());
+ t.CheckLoweringBinop(IrOpcode::kInt32LessThanOrEqual,
+ t.simplified()->NumberLessThanOrEqual());
+}
+
+
+TEST(LowerNumberCmp_to_uint32) {
+ TestingGraph t(Type::Unsigned32(), Type::Unsigned32());
+
+ t.CheckLoweringBinop(IrOpcode::kWord32Equal, t.simplified()->NumberEqual());
+ t.CheckLoweringBinop(IrOpcode::kUint32LessThan,
+ t.simplified()->NumberLessThan());
+ t.CheckLoweringBinop(IrOpcode::kUint32LessThanOrEqual,
+ t.simplified()->NumberLessThanOrEqual());
+}
+
+
+TEST(LowerNumberCmp_to_float64) {
+ static Type* types[] = {Type::Number(), Type::Any()};
+
+ for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+ TestingGraph t(types[i], types[i]);
+
+ t.CheckLoweringBinop(IrOpcode::kFloat64Equal,
+ t.simplified()->NumberEqual());
+ t.CheckLoweringBinop(IrOpcode::kFloat64LessThan,
+ t.simplified()->NumberLessThan());
+ t.CheckLoweringBinop(IrOpcode::kFloat64LessThanOrEqual,
+ t.simplified()->NumberLessThanOrEqual());
+ }
+}
+
+
+TEST(LowerNumberAddSub_to_int32) {
+ TestingGraph t(Type::Signed32(), Type::Signed32());
+ t.CheckLoweringTruncatedBinop(IrOpcode::kInt32Add,
+ t.simplified()->NumberAdd(),
+ t.simplified()->NumberToInt32());
+ t.CheckLoweringTruncatedBinop(IrOpcode::kInt32Sub,
+ t.simplified()->NumberSubtract(),
+ t.simplified()->NumberToInt32());
+}
+
+
+TEST(LowerNumberAddSub_to_uint32) {
+ TestingGraph t(Type::Unsigned32(), Type::Unsigned32());
+ t.CheckLoweringTruncatedBinop(IrOpcode::kInt32Add,
+ t.simplified()->NumberAdd(),
+ t.simplified()->NumberToUint32());
+ t.CheckLoweringTruncatedBinop(IrOpcode::kInt32Sub,
+ t.simplified()->NumberSubtract(),
+ t.simplified()->NumberToUint32());
+}
+
+
+TEST(LowerNumberAddSub_to_float64) {
+ for (size_t i = 0; i < ARRAY_SIZE(test_types); i++) {
+ TestingGraph t(test_types[i], test_types[i]);
+
+ t.CheckLoweringBinop(IrOpcode::kFloat64Add, t.simplified()->NumberAdd());
+ t.CheckLoweringBinop(IrOpcode::kFloat64Sub,
+ t.simplified()->NumberSubtract());
+ }
+}
+
+
+TEST(LowerNumberDivMod_to_float64) {
+ for (size_t i = 0; i < ARRAY_SIZE(test_types); i++) {
+ TestingGraph t(test_types[i], test_types[i]);
+
+ t.CheckLoweringBinop(IrOpcode::kFloat64Div, t.simplified()->NumberDivide());
+ t.CheckLoweringBinop(IrOpcode::kFloat64Mod,
+ t.simplified()->NumberModulus());
+ }
+}
+
+
+static void CheckChangeOf(IrOpcode::Value change, Node* of, Node* node) {
+ CHECK_EQ(change, node->opcode());
+ CHECK_EQ(of, node->InputAt(0));
+}
+
+
+TEST(LowerNumberToInt32_to_nop) {
+ // NumberToInt32(x: rTagged | tInt32) used as rTagged
+ TestingGraph t(Type::Signed32());
+ Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0);
+ Node* use = t.Use(trunc, rTagged);
+ t.Return(use);
+ t.Lower();
+ CHECK_EQ(t.p0, use->InputAt(0));
+}
+
+
+TEST(LowerNumberToInt32_to_ChangeTaggedToFloat64) {
+ // NumberToInt32(x: rTagged | tInt32) used as rFloat64
+ TestingGraph t(Type::Signed32());
+ Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0);
+ Node* use = t.Use(trunc, rFloat64);
+ t.Return(use);
+ t.Lower();
+ CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p0, use->InputAt(0));
+}
+
+
+TEST(LowerNumberToInt32_to_ChangeTaggedToInt32) {
+ // NumberToInt32(x: rTagged | tInt32) used as rWord32
+ TestingGraph t(Type::Signed32());
+ Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0);
+ Node* use = t.Use(trunc, tInt32);
+ t.Return(use);
+ t.Lower();
+ CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p0, use->InputAt(0));
+}
+
+
+TEST(LowerNumberToInt32_to_ChangeFloat64ToTagged) {
+ // TODO(titzer): NumberToInt32(x: rFloat64 | tInt32) used as rTagged
+}
+
+
+TEST(LowerNumberToInt32_to_ChangeFloat64ToInt32) {
+ // TODO(titzer): NumberToInt32(x: rFloat64 | tInt32) used as rWord32 | tInt32
+}
+
+
+TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32) {
+ // TODO(titzer): NumberToInt32(x: rFloat64) used as rWord32 | tUint32
+}
+
+
+TEST(LowerNumberToUint32_to_nop) {
+ // NumberToUint32(x: rTagged | tUint32) used as rTagged
+ TestingGraph t(Type::Unsigned32());
+ Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0);
+ Node* use = t.Use(trunc, rTagged);
+ t.Return(use);
+ t.Lower();
+ CHECK_EQ(t.p0, use->InputAt(0));
+}
+
+
+TEST(LowerNumberToUint32_to_ChangeTaggedToFloat64) {
+ // NumberToUint32(x: rTagged | tUint32) used as rWord32
+ TestingGraph t(Type::Unsigned32());
+ Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0);
+ Node* use = t.Use(trunc, rFloat64);
+ t.Return(use);
+ t.Lower();
+ CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p0, use->InputAt(0));
+}
+
+
+TEST(LowerNumberToUint32_to_ChangeTaggedToUint32) {
+ // NumberToUint32(x: rTagged | tUint32) used as rWord32
+ TestingGraph t(Type::Unsigned32());
+ Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0);
+ Node* use = t.Use(trunc, tUint32);
+ t.Return(use);
+ t.Lower();
+ CheckChangeOf(IrOpcode::kChangeTaggedToUint32, t.p0, use->InputAt(0));
+}
+
+
+TEST(LowerNumberToUint32_to_ChangeFloat64ToTagged) {
+ // TODO(titzer): NumberToUint32(x: rFloat64 | tUint32) used as rTagged
+}
+
+
+TEST(LowerNumberToUint32_to_ChangeFloat64ToUint32) {
+ // TODO(titzer): NumberToUint32(x: rFloat64 | tUint32) used as rWord32
+}
+
+
+TEST(LowerNumberToUint32_to_TruncateFloat64ToUint32) {
+ // TODO(titzer): NumberToUint32(x: rFloat64) used as rWord32
+}
+
+
+TEST(LowerReferenceEqual_to_wordeq) {
+ TestingGraph t(Type::Any(), Type::Any());
+ IrOpcode::Value opcode =
+ static_cast<IrOpcode::Value>(t.machine()->WordEqual()->opcode());
+ t.CheckLoweringBinop(opcode, t.simplified()->ReferenceEqual(Type::Any()));
+}
+
+
+TEST(LowerStringOps_to_rtcalls) {
+ if (false) { // TODO(titzer): lower StringOps to runtime calls
+ TestingGraph t(Type::String(), Type::String());
+ t.CheckLoweringBinop(IrOpcode::kCall, t.simplified()->StringEqual());
+ t.CheckLoweringBinop(IrOpcode::kCall, t.simplified()->StringLessThan());
+ t.CheckLoweringBinop(IrOpcode::kCall,
+ t.simplified()->StringLessThanOrEqual());
+ t.CheckLoweringBinop(IrOpcode::kCall, t.simplified()->StringAdd());
+ }
+}
+
+
+void CheckChangeInsertion(IrOpcode::Value expected, RepType from, RepType to) {
+ TestingGraph t(Type::Any());
+ Node* in = t.ExampleWithOutput(from);
+ Node* use = t.Use(in, to);
+ t.Return(use);
+ t.Lower();
+ CHECK_EQ(expected, use->InputAt(0)->opcode());
+ CHECK_EQ(in, use->InputAt(0)->InputAt(0));
+}
+
+
+TEST(InsertBasicChanges) {
+ if (false) {
+ // TODO(titzer): these changes need the output to have the right type.
+ CheckChangeInsertion(IrOpcode::kChangeFloat64ToInt32, rFloat64, tInt32);
+ CheckChangeInsertion(IrOpcode::kChangeFloat64ToUint32, rFloat64, tUint32);
+ CheckChangeInsertion(IrOpcode::kChangeTaggedToInt32, rTagged, tInt32);
+ CheckChangeInsertion(IrOpcode::kChangeTaggedToUint32, rTagged, tUint32);
+ }
+
+ CheckChangeInsertion(IrOpcode::kChangeFloat64ToTagged, rFloat64, rTagged);
+ CheckChangeInsertion(IrOpcode::kChangeTaggedToFloat64, rTagged, rFloat64);
+
+ CheckChangeInsertion(IrOpcode::kChangeInt32ToFloat64, tInt32, rFloat64);
+ CheckChangeInsertion(IrOpcode::kChangeInt32ToTagged, tInt32, rTagged);
+
+ CheckChangeInsertion(IrOpcode::kChangeUint32ToFloat64, tUint32, rFloat64);
+ CheckChangeInsertion(IrOpcode::kChangeUint32ToTagged, tUint32, rTagged);
+}
+
+
+static void CheckChangesAroundBinop(TestingGraph* t, Operator* op,
+ IrOpcode::Value input_change,
+ IrOpcode::Value output_change) {
+ Node* binop = t->graph()->NewNode(op, t->p0, t->p1);
+ t->Return(binop);
+ t->Lower();
+ CHECK_EQ(input_change, binop->InputAt(0)->opcode());
+ CHECK_EQ(input_change, binop->InputAt(1)->opcode());
+ CHECK_EQ(t->p0, binop->InputAt(0)->InputAt(0));
+ CHECK_EQ(t->p1, binop->InputAt(1)->InputAt(0));
+ CHECK_EQ(output_change, t->ret->InputAt(0)->opcode());
+ CHECK_EQ(binop, t->ret->InputAt(0)->InputAt(0));
+}
+
+
+TEST(InsertChangesAroundInt32Binops) {
+ TestingGraph t(Type::Signed32(), Type::Signed32());
+
+ Operator* ops[] = {t.machine()->Int32Add(), t.machine()->Int32Sub(),
+ t.machine()->Int32Mul(), t.machine()->Int32Div(),
+ t.machine()->Int32Mod(), t.machine()->Word32And(),
+ t.machine()->Word32Or(), t.machine()->Word32Xor(),
+ t.machine()->Word32Shl(), t.machine()->Word32Sar()};
+
+ for (size_t i = 0; i < ARRAY_SIZE(ops); i++) {
+ CheckChangesAroundBinop(&t, ops[i], IrOpcode::kChangeTaggedToInt32,
+ IrOpcode::kChangeInt32ToTagged);
+ }
+}
+
+
+TEST(InsertChangesAroundInt32Cmp) {
+ TestingGraph t(Type::Signed32(), Type::Signed32());
+
+ Operator* ops[] = {t.machine()->Int32LessThan(),
+ t.machine()->Int32LessThanOrEqual()};
+
+ for (size_t i = 0; i < ARRAY_SIZE(ops); i++) {
+ CheckChangesAroundBinop(&t, ops[i], IrOpcode::kChangeTaggedToInt32,
+ IrOpcode::kChangeBitToBool);
+ }
+}
+
+
+TEST(InsertChangesAroundUint32Cmp) {
+ TestingGraph t(Type::Unsigned32(), Type::Unsigned32());
+
+ Operator* ops[] = {t.machine()->Uint32LessThan(),
+ t.machine()->Uint32LessThanOrEqual()};
+
+ for (size_t i = 0; i < ARRAY_SIZE(ops); i++) {
+ CheckChangesAroundBinop(&t, ops[i], IrOpcode::kChangeTaggedToUint32,
+ IrOpcode::kChangeBitToBool);
+ }
+}
+
+
+TEST(InsertChangesAroundFloat64Binops) {
+ TestingGraph t(Type::Number(), Type::Number());
+
+ Operator* ops[] = {
+ t.machine()->Float64Add(), t.machine()->Float64Sub(),
+ t.machine()->Float64Mul(), t.machine()->Float64Div(),
+ t.machine()->Float64Mod(),
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(ops); i++) {
+ CheckChangesAroundBinop(&t, ops[i], IrOpcode::kChangeTaggedToFloat64,
+ IrOpcode::kChangeFloat64ToTagged);
+ }
+}
+
+
+TEST(InsertChangesAroundFloat64Cmp) {
+ TestingGraph t(Type::Number(), Type::Number());
+
+ Operator* ops[] = {t.machine()->Float64Equal(),
+ t.machine()->Float64LessThan(),
+ t.machine()->Float64LessThanOrEqual()};
+
+ for (size_t i = 0; i < ARRAY_SIZE(ops); i++) {
+ CheckChangesAroundBinop(&t, ops[i], IrOpcode::kChangeTaggedToFloat64,
+ IrOpcode::kChangeBitToBool);
+ }
+}
+
+
+void CheckFieldAccessArithmetic(FieldAccess access, Node* load_or_store) {
+ Int32Matcher index = Int32Matcher(load_or_store->InputAt(1));
+ CHECK(index.Is(access.offset - access.tag()));
+}
+
+
+Node* CheckElementAccessArithmetic(ElementAccess access, Node* load_or_store) {
+ Int32BinopMatcher index(load_or_store->InputAt(1));
+ CHECK_EQ(IrOpcode::kInt32Add, index.node()->opcode());
+ CHECK(index.right().Is(access.header_size - access.tag()));
+
+ int element_size = 0;
+ switch (access.representation) {
+ case kMachineTagged:
+ element_size = kPointerSize;
+ break;
+ case kMachineWord8:
+ element_size = 1;
+ break;
+ case kMachineWord16:
+ element_size = 2;
+ break;
+ case kMachineWord32:
+ element_size = 4;
+ break;
+ case kMachineWord64:
+ case kMachineFloat64:
+ element_size = 8;
+ break;
+ case kMachineLast:
+ UNREACHABLE();
+ break;
+ }
+
+ if (element_size != 1) {
+ Int32BinopMatcher mul(index.left().node());
+ CHECK_EQ(IrOpcode::kInt32Mul, mul.node()->opcode());
+ CHECK(mul.right().Is(element_size));
+ return mul.left().node();
+ } else {
+ return index.left().node();
+ }
+}
+
+
+static const MachineType machine_reps[] = {kMachineWord8, kMachineWord16,
+ kMachineWord32, kMachineWord64,
+ kMachineFloat64, kMachineTagged};
+
+
+// Representation types corresponding to those above.
+static const RepType rep_types[] = {static_cast<RepType>(rWord32 | tUint32),
+ static_cast<RepType>(rWord32 | tUint32),
+ static_cast<RepType>(rWord32 | tInt32),
+ static_cast<RepType>(rWord64),
+ static_cast<RepType>(rFloat64 | tNumber),
+ static_cast<RepType>(rTagged | tAny)};
+
+
+TEST(LowerLoadField_to_load) {
+ TestingGraph t(Type::Any(), Type::Signed32());
+
+ for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) {
+ FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
+ Handle<Name>::null(), Type::Any(), machine_reps[i]};
+
+ Node* load =
+ t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start);
+ Node* use = t.Use(load, rep_types[i]);
+ t.Return(use);
+ t.Lower();
+ CHECK_EQ(IrOpcode::kLoad, load->opcode());
+ CHECK_EQ(t.p0, load->InputAt(0));
+ CheckFieldAccessArithmetic(access, load);
+
+ MachineType rep = OpParameter<MachineType>(load);
+ CHECK_EQ(machine_reps[i], rep);
+ }
+}
+
+
+TEST(LowerStoreField_to_store) {
+ TestingGraph t(Type::Any(), Type::Signed32());
+
+ for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) {
+ FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
+ Handle<Name>::null(), Type::Any(), machine_reps[i]};
+
+
+ Node* val = t.ExampleWithOutput(rep_types[i]);
+ Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
+ val, t.start, t.start);
+ t.Effect(store);
+ t.Lower();
+ CHECK_EQ(IrOpcode::kStore, store->opcode());
+ CHECK_EQ(val, store->InputAt(2));
+ CheckFieldAccessArithmetic(access, store);
+
+ StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
+ if (rep_types[i] & rTagged) {
+ CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind);
+ }
+ CHECK_EQ(machine_reps[i], rep.rep);
+ }
+}
+
+
+TEST(LowerLoadElement_to_load) {
+ TestingGraph t(Type::Any(), Type::Signed32());
+
+ for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) {
+ ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
+ Type::Any(), machine_reps[i]};
+
+ Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0,
+ t.p1, t.start);
+ Node* use = t.Use(load, rep_types[i]);
+ t.Return(use);
+ t.Lower();
+ CHECK_EQ(IrOpcode::kLoad, load->opcode());
+ CHECK_EQ(t.p0, load->InputAt(0));
+ CheckElementAccessArithmetic(access, load);
+
+ MachineType rep = OpParameter<MachineType>(load);
+ CHECK_EQ(machine_reps[i], rep);
+ }
+}
+
+
+TEST(LowerStoreElement_to_store) {
+ TestingGraph t(Type::Any(), Type::Signed32());
+
+ for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) {
+ ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
+ Type::Any(), machine_reps[i]};
+
+ Node* val = t.ExampleWithOutput(rep_types[i]);
+ Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0,
+ t.p1, val, t.start, t.start);
+ t.Effect(store);
+ t.Lower();
+ CHECK_EQ(IrOpcode::kStore, store->opcode());
+ CHECK_EQ(val, store->InputAt(2));
+ CheckElementAccessArithmetic(access, store);
+
+ StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
+ if (rep_types[i] & rTagged) {
+ CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind);
+ }
+ CHECK_EQ(machine_reps[i], rep.rep);
+ }
+}
+
+
+TEST(InsertChangeForLoadElementIndex) {
+ // LoadElement(obj: Tagged, index: tInt32 | rTagged) =>
+ // Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k))
+ TestingGraph t(Type::Any(), Type::Signed32());
+ ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
+ kMachineTagged};
+
+ Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0,
+ t.p1, t.start);
+ t.Return(load);
+ t.Lower();
+ CHECK_EQ(IrOpcode::kLoad, load->opcode());
+ CHECK_EQ(t.p0, load->InputAt(0));
+
+ Node* index = CheckElementAccessArithmetic(access, load);
+ CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index);
+}
+
+
+TEST(InsertChangeForStoreElementIndex) {
+ // StoreElement(obj: Tagged, index: tInt32 | rTagged, val) =>
+ // Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k), val)
+ TestingGraph t(Type::Any(), Type::Signed32());
+ ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
+ kMachineTagged};
+
+ Node* store =
+ t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1,
+ t.jsgraph.TrueConstant(), t.start, t.start);
+ t.Effect(store);
+ t.Lower();
+ CHECK_EQ(IrOpcode::kStore, store->opcode());
+ CHECK_EQ(t.p0, store->InputAt(0));
+
+ Node* index = CheckElementAccessArithmetic(access, store);
+ CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index);
+}
+
+
+TEST(InsertChangeForLoadElement) {
+ // TODO(titzer): test all load/store representation change insertions.
+ TestingGraph t(Type::Any(), Type::Signed32());
+ ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
+ kMachineFloat64};
+
+ Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0,
+ t.p1, t.start);
+ t.Return(load);
+ t.Lower();
+ CHECK_EQ(IrOpcode::kLoad, load->opcode());
+ CHECK_EQ(t.p0, load->InputAt(0));
+ CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0));
+}
+
+
+TEST(InsertChangeForLoadField) {
+ // TODO(titzer): test all load/store representation change insertions.
+ TestingGraph t(Type::Any(), Type::Signed32());
+ FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
+ Handle<Name>::null(), Type::Any(), kMachineFloat64};
+
+ Node* load =
+ t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start);
+ t.Return(load);
+ t.Lower();
+ CHECK_EQ(IrOpcode::kLoad, load->opcode());
+ CHECK_EQ(t.p0, load->InputAt(0));
+ CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0));
+}
+
+
+TEST(InsertChangeForStoreElement) {
+ // TODO(titzer): test all load/store representation change insertions.
+ TestingGraph t(Type::Any(), Type::Signed32());
+ ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
+ kMachineFloat64};
+
+ Node* store =
+ t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0,
+ t.jsgraph.Int32Constant(0), t.p1, t.start, t.start);
+ t.Effect(store);
+ t.Lower();
+
+ CHECK_EQ(IrOpcode::kStore, store->opcode());
+ CHECK_EQ(t.p0, store->InputAt(0));
+ CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2));
+}
+
+
+TEST(InsertChangeForStoreField) {
+ // TODO(titzer): test all load/store representation change insertions.
+ TestingGraph t(Type::Any(), Type::Signed32());
+ FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
+ Handle<Name>::null(), Type::Any(), kMachineFloat64};
+
+ Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
+ t.p1, t.start, t.start);
+ t.Effect(store);
+ t.Lower();
+
+ CHECK_EQ(IrOpcode::kStore, store->opcode());
+ CHECK_EQ(t.p0, store->InputAt(0));
+ CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2));
+}
diff --git a/deps/v8/test/cctest/compiler/test-structured-ifbuilder-fuzzer.cc b/deps/v8/test/cctest/compiler/test-structured-ifbuilder-fuzzer.cc
new file mode 100644
index 000000000..02232264d
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-structured-ifbuilder-fuzzer.cc
@@ -0,0 +1,667 @@
+// 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>
+
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/base/utils/random-number-generator.h"
+#include "test/cctest/compiler/codegen-tester.h"
+
+#if V8_TURBOFAN_TARGET
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+typedef StructuredMachineAssembler::IfBuilder IfBuilder;
+typedef StructuredMachineAssembler::LoopBuilder Loop;
+
+static const int32_t kUninitializedVariableOffset = -1;
+static const int32_t kUninitializedOutput = -1;
+static const int32_t kVerifiedOutput = -2;
+
+static const int32_t kInitalVar = 1013;
+static const int32_t kConjunctionInc = 1069;
+static const int32_t kDisjunctionInc = 1151;
+static const int32_t kThenInc = 1223;
+static const int32_t kElseInc = 1291;
+static const int32_t kIfInc = 1373;
+
+class IfBuilderModel {
+ public:
+ explicit IfBuilderModel(Zone* zone)
+ : zone_(zone),
+ variable_offset_(0),
+ root_(new (zone_) Node(NULL)),
+ current_node_(root_),
+ current_expression_(NULL) {}
+
+ void If() {
+ if (current_node_->else_node != NULL) {
+ current_node_ = current_node_->else_node;
+ } else if (current_node_->then_node != NULL) {
+ current_node_ = current_node_->then_node;
+ }
+ DCHECK(current_expression_ == NULL);
+ current_expression_ = new (zone_) Expression(zone_, NULL);
+ current_node_->condition = current_expression_;
+ }
+ void IfNode() { LastChild()->variable_offset = variable_offset_++; }
+
+ void OpenParen() { current_expression_ = LastChild(); }
+ void CloseParen() { current_expression_ = current_expression_->parent; }
+
+ void And() { NewChild()->conjunction = true; }
+ void Or() { NewChild()->disjunction = true; }
+
+ void Then() {
+ DCHECK(current_expression_ == NULL || current_expression_->parent == NULL);
+ current_expression_ = NULL;
+ DCHECK(current_node_->then_node == NULL);
+ current_node_->then_node = new (zone_) Node(current_node_);
+ }
+ void Else() {
+ DCHECK(current_expression_ == NULL || current_expression_->parent == NULL);
+ current_expression_ = NULL;
+ DCHECK(current_node_->else_node == NULL);
+ current_node_->else_node = new (zone_) Node(current_node_);
+ }
+ void Return() {
+ if (current_node_->else_node != NULL) {
+ current_node_->else_node->returns = true;
+ } else if (current_node_->then_node != NULL) {
+ current_node_->then_node->returns = true;
+ } else {
+ CHECK(false);
+ }
+ }
+ void End() {}
+
+ void Print(std::vector<char>* v) { PrintRecursive(v, root_); }
+
+ struct VerificationState {
+ int32_t* inputs;
+ int32_t* outputs;
+ int32_t var;
+ };
+
+ int32_t Verify(int length, int32_t* inputs, int32_t* outputs) {
+ CHECK_EQ(variable_offset_, length);
+ // Input/Output verification.
+ for (int i = 0; i < length; ++i) {
+ CHECK(inputs[i] == 0 || inputs[i] == 1);
+ CHECK(outputs[i] == kUninitializedOutput || outputs[i] >= 0);
+ }
+ // Do verification.
+ VerificationState state;
+ state.inputs = inputs;
+ state.outputs = outputs;
+ state.var = kInitalVar;
+ VerifyRecursive(root_, &state);
+ // Verify all outputs marked.
+ for (int i = 0; i < length; ++i) {
+ CHECK(outputs[i] == kUninitializedOutput ||
+ outputs[i] == kVerifiedOutput);
+ }
+ return state.var;
+ }
+
+ private:
+ struct Expression;
+ typedef std::vector<Expression*, zone_allocator<Expression*> > Expressions;
+
+ struct Expression : public ZoneObject {
+ Expression(Zone* zone, Expression* p)
+ : variable_offset(kUninitializedVariableOffset),
+ disjunction(false),
+ conjunction(false),
+ parent(p),
+ children(Expressions::allocator_type(zone)) {}
+ int variable_offset;
+ bool disjunction;
+ bool conjunction;
+ Expression* parent;
+ Expressions children;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Expression);
+ };
+
+ struct Node : public ZoneObject {
+ explicit Node(Node* p)
+ : parent(p),
+ condition(NULL),
+ then_node(NULL),
+ else_node(NULL),
+ returns(false) {}
+ Node* parent;
+ Expression* condition;
+ Node* then_node;
+ Node* else_node;
+ bool returns;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Node);
+ };
+
+ Expression* LastChild() {
+ if (current_expression_->children.empty()) {
+ current_expression_->children.push_back(
+ new (zone_) Expression(zone_, current_expression_));
+ }
+ return current_expression_->children.back();
+ }
+
+ Expression* NewChild() {
+ Expression* child = new (zone_) Expression(zone_, current_expression_);
+ current_expression_->children.push_back(child);
+ return child;
+ }
+
+ static void PrintRecursive(std::vector<char>* v, Expression* expression) {
+ CHECK(expression != NULL);
+ if (expression->conjunction) {
+ DCHECK(!expression->disjunction);
+ v->push_back('&');
+ } else if (expression->disjunction) {
+ v->push_back('|');
+ }
+ if (expression->variable_offset != kUninitializedVariableOffset) {
+ v->push_back('v');
+ }
+ Expressions& children = expression->children;
+ if (children.empty()) return;
+ v->push_back('(');
+ for (Expressions::iterator i = children.begin(); i != children.end(); ++i) {
+ PrintRecursive(v, *i);
+ }
+ v->push_back(')');
+ }
+
+ static void PrintRecursive(std::vector<char>* v, Node* node) {
+ // Termination condition.
+ if (node->condition == NULL) {
+ CHECK(node->then_node == NULL && node->else_node == NULL);
+ if (node->returns) v->push_back('r');
+ return;
+ }
+ CHECK(!node->returns);
+ v->push_back('i');
+ PrintRecursive(v, node->condition);
+ if (node->then_node != NULL) {
+ v->push_back('t');
+ PrintRecursive(v, node->then_node);
+ }
+ if (node->else_node != NULL) {
+ v->push_back('e');
+ PrintRecursive(v, node->else_node);
+ }
+ }
+
+ static bool VerifyRecursive(Expression* expression,
+ VerificationState* state) {
+ bool result = false;
+ bool first_iteration = true;
+ Expressions& children = expression->children;
+ CHECK(!children.empty());
+ for (Expressions::iterator i = children.begin(); i != children.end(); ++i) {
+ Expression* child = *i;
+ // Short circuit evaluation,
+ // but mixes of &&s and ||s have weird semantics.
+ if ((child->conjunction && !result) || (child->disjunction && result)) {
+ continue;
+ }
+ if (child->conjunction) state->var += kConjunctionInc;
+ if (child->disjunction) state->var += kDisjunctionInc;
+ bool child_result;
+ if (child->variable_offset != kUninitializedVariableOffset) {
+ // Verify output
+ CHECK_EQ(state->var, state->outputs[child->variable_offset]);
+ state->outputs[child->variable_offset] = kVerifiedOutput; // Mark seen.
+ child_result = state->inputs[child->variable_offset];
+ CHECK(child->children.empty());
+ state->var += kIfInc;
+ } else {
+ child_result = VerifyRecursive(child, state);
+ }
+ if (child->conjunction) {
+ result &= child_result;
+ } else if (child->disjunction) {
+ result |= child_result;
+ } else {
+ CHECK(first_iteration);
+ result = child_result;
+ }
+ first_iteration = false;
+ }
+ return result;
+ }
+
+ static void VerifyRecursive(Node* node, VerificationState* state) {
+ if (node->condition == NULL) return;
+ bool result = VerifyRecursive(node->condition, state);
+ if (result) {
+ if (node->then_node) {
+ state->var += kThenInc;
+ return VerifyRecursive(node->then_node, state);
+ }
+ } else {
+ if (node->else_node) {
+ state->var += kElseInc;
+ return VerifyRecursive(node->else_node, state);
+ }
+ }
+ }
+
+ Zone* zone_;
+ int variable_offset_;
+ Node* root_;
+ Node* current_node_;
+ Expression* current_expression_;
+ DISALLOW_COPY_AND_ASSIGN(IfBuilderModel);
+};
+
+
+class IfBuilderGenerator : public StructuredMachineAssemblerTester<int32_t> {
+ public:
+ IfBuilderGenerator()
+ : StructuredMachineAssemblerTester<int32_t>(
+ MachineOperatorBuilder::pointer_rep(),
+ MachineOperatorBuilder::pointer_rep()),
+ var_(NewVariable(Int32Constant(kInitalVar))),
+ c_(this),
+ m_(this->zone()),
+ one_(Int32Constant(1)),
+ offset_(0) {}
+
+ static void GenerateExpression(v8::base::RandomNumberGenerator* rng,
+ std::vector<char>* v, int n_vars) {
+ int depth = 1;
+ v->push_back('(');
+ bool need_if = true;
+ bool populated = false;
+ while (n_vars != 0) {
+ if (need_if) {
+ // can nest a paren or do a variable
+ if (rng->NextBool()) {
+ v->push_back('v');
+ n_vars--;
+ need_if = false;
+ populated = true;
+ } else {
+ v->push_back('(');
+ depth++;
+ populated = false;
+ }
+ } else {
+ // can pop, do && or do ||
+ int options = 3;
+ if (depth == 1 || !populated) {
+ options--;
+ }
+ switch (rng->NextInt(options)) {
+ case 0:
+ v->push_back('&');
+ need_if = true;
+ break;
+ case 1:
+ v->push_back('|');
+ need_if = true;
+ break;
+ case 2:
+ v->push_back(')');
+ depth--;
+ break;
+ }
+ }
+ }
+ CHECK(!need_if);
+ while (depth != 0) {
+ v->push_back(')');
+ depth--;
+ }
+ }
+
+ static void GenerateIfThenElse(v8::base::RandomNumberGenerator* rng,
+ std::vector<char>* v, int n_ifs,
+ int max_exp_length) {
+ CHECK_GT(n_ifs, 0);
+ CHECK_GT(max_exp_length, 0);
+ bool have_env = true;
+ bool then_done = false;
+ bool else_done = false;
+ bool first_iteration = true;
+ while (n_ifs != 0) {
+ if (have_env) {
+ int options = 3;
+ if (else_done || first_iteration) { // Don't do else or return
+ options -= 2;
+ first_iteration = false;
+ }
+ switch (rng->NextInt(options)) {
+ case 0:
+ v->push_back('i');
+ n_ifs--;
+ have_env = false;
+ GenerateExpression(rng, v, rng->NextInt(max_exp_length) + 1);
+ break;
+ case 1:
+ v->push_back('r');
+ have_env = false;
+ break;
+ case 2:
+ v->push_back('e');
+ else_done = true;
+ then_done = false;
+ break;
+ default:
+ CHECK(false);
+ }
+ } else { // Can only do then or else
+ int options = 2;
+ if (then_done) options--;
+ switch (rng->NextInt(options)) {
+ case 0:
+ v->push_back('e');
+ else_done = true;
+ then_done = false;
+ break;
+ case 1:
+ v->push_back('t');
+ then_done = true;
+ else_done = false;
+ break;
+ default:
+ CHECK(false);
+ }
+ have_env = true;
+ }
+ }
+ // Last instruction must have been an if, can complete it in several ways.
+ int options = 2;
+ if (then_done && !else_done) options++;
+ switch (rng->NextInt(3)) {
+ case 0:
+ // Do nothing.
+ break;
+ case 1:
+ v->push_back('t');
+ switch (rng->NextInt(3)) {
+ case 0:
+ v->push_back('r');
+ break;
+ case 1:
+ v->push_back('e');
+ break;
+ case 2:
+ v->push_back('e');
+ v->push_back('r');
+ break;
+ default:
+ CHECK(false);
+ }
+ break;
+ case 2:
+ v->push_back('e');
+ if (rng->NextBool()) v->push_back('r');
+ break;
+ default:
+ CHECK(false);
+ }
+ }
+
+ std::string::const_iterator ParseExpression(std::string::const_iterator it,
+ std::string::const_iterator end) {
+ // Prepare for expression.
+ m_.If();
+ c_.If();
+ int depth = 0;
+ for (; it != end; ++it) {
+ switch (*it) {
+ case 'v':
+ m_.IfNode();
+ {
+ Node* offset = Int32Constant(offset_ * 4);
+ Store(kMachineWord32, Parameter(1), offset, var_.Get());
+ var_.Set(Int32Add(var_.Get(), Int32Constant(kIfInc)));
+ c_.If(Load(kMachineWord32, Parameter(0), offset));
+ offset_++;
+ }
+ break;
+ case '&':
+ m_.And();
+ c_.And();
+ var_.Set(Int32Add(var_.Get(), Int32Constant(kConjunctionInc)));
+ break;
+ case '|':
+ m_.Or();
+ c_.Or();
+ var_.Set(Int32Add(var_.Get(), Int32Constant(kDisjunctionInc)));
+ break;
+ case '(':
+ if (depth != 0) {
+ m_.OpenParen();
+ c_.OpenParen();
+ }
+ depth++;
+ break;
+ case ')':
+ depth--;
+ if (depth == 0) return it;
+ m_.CloseParen();
+ c_.CloseParen();
+ break;
+ default:
+ CHECK(false);
+ }
+ }
+ CHECK(false);
+ return it;
+ }
+
+ void ParseIfThenElse(const std::string& str) {
+ int n_vars = 0;
+ for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) {
+ if (*it == 'v') n_vars++;
+ }
+ InitializeConstants(n_vars);
+ for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) {
+ switch (*it) {
+ case 'i': {
+ it++;
+ CHECK(it != str.end());
+ CHECK_EQ('(', *it);
+ it = ParseExpression(it, str.end());
+ CHECK_EQ(')', *it);
+ break;
+ }
+ case 't':
+ m_.Then();
+ c_.Then();
+ var_.Set(Int32Add(var_.Get(), Int32Constant(kThenInc)));
+ break;
+ case 'e':
+ m_.Else();
+ c_.Else();
+ var_.Set(Int32Add(var_.Get(), Int32Constant(kElseInc)));
+ break;
+ case 'r':
+ m_.Return();
+ Return(var_.Get());
+ break;
+ default:
+ CHECK(false);
+ }
+ }
+ m_.End();
+ c_.End();
+ Return(var_.Get());
+ // Compare generated model to parsed version.
+ {
+ std::vector<char> v;
+ m_.Print(&v);
+ std::string m_str(v.begin(), v.end());
+ CHECK(m_str == str);
+ }
+ }
+
+ void ParseExpression(const std::string& str) {
+ CHECK(inputs_.is_empty());
+ std::string wrapped = "i(" + str + ")te";
+ ParseIfThenElse(wrapped);
+ }
+
+ void ParseRandomIfThenElse(v8::base::RandomNumberGenerator* rng, int n_ifs,
+ int n_vars) {
+ std::vector<char> v;
+ GenerateIfThenElse(rng, &v, n_ifs, n_vars);
+ std::string str(v.begin(), v.end());
+ ParseIfThenElse(str);
+ }
+
+ void RunRandom(v8::base::RandomNumberGenerator* rng) {
+ // TODO(dcarney): permute inputs via model.
+ // TODO(dcarney): compute test_cases from n_ifs and n_vars.
+ int test_cases = 100;
+ for (int test = 0; test < test_cases; test++) {
+ Initialize();
+ for (int i = 0; i < offset_; i++) {
+ inputs_[i] = rng->NextBool();
+ }
+ DoCall();
+ }
+ }
+
+ void Run(const std::string& str, int32_t expected) {
+ Initialize();
+ int offset = 0;
+ for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) {
+ switch (*it) {
+ case 't':
+ inputs_[offset++] = 1;
+ break;
+ case 'f':
+ inputs_[offset++] = 0;
+ break;
+ default:
+ CHECK(false);
+ }
+ }
+ CHECK_EQ(offset_, offset);
+ // Call.
+ int32_t result = DoCall();
+ CHECK_EQ(result, expected);
+ }
+
+ private:
+ typedef std::vector<int32_t, zone_allocator<int32_t> > IOVector;
+
+ void InitializeConstants(int n_vars) {
+ CHECK(inputs_.is_empty());
+ inputs_.Reset(new int32_t[n_vars]);
+ outputs_.Reset(new int32_t[n_vars]);
+ }
+
+ void Initialize() {
+ for (int i = 0; i < offset_; i++) {
+ inputs_[i] = 0;
+ outputs_[i] = kUninitializedOutput;
+ }
+ }
+
+ int32_t DoCall() {
+ int32_t result = Call(inputs_.get(), outputs_.get());
+ int32_t expected = m_.Verify(offset_, inputs_.get(), outputs_.get());
+ CHECK_EQ(result, expected);
+ return result;
+ }
+
+ const v8::internal::compiler::Variable var_;
+ IfBuilder c_;
+ IfBuilderModel m_;
+ Node* one_;
+ int32_t offset_;
+ SmartArrayPointer<int32_t> inputs_;
+ SmartArrayPointer<int32_t> outputs_;
+};
+
+
+TEST(RunExpressionString) {
+ IfBuilderGenerator m;
+ m.ParseExpression("((v|v)|v)");
+ m.Run("ttt", kInitalVar + 1 * kIfInc + kThenInc);
+ m.Run("ftt", kInitalVar + 2 * kIfInc + kDisjunctionInc + kThenInc);
+ m.Run("fft", kInitalVar + 3 * kIfInc + 2 * kDisjunctionInc + kThenInc);
+ m.Run("fff", kInitalVar + 3 * kIfInc + 2 * kDisjunctionInc + kElseInc);
+}
+
+
+TEST(RunExpressionStrings) {
+ const char* strings[] = {
+ "v", "(v)", "((v))", "v|v",
+ "(v|v)", "((v|v))", "v&v", "(v&v)",
+ "((v&v))", "v&(v)", "v&(v|v)", "v&(v|v)&v",
+ "v|(v)", "v|(v&v)", "v|(v&v)|v", "v|(((v)|(v&v)|(v)|v)&(v))|v",
+ };
+ v8::base::RandomNumberGenerator rng;
+ for (size_t i = 0; i < ARRAY_SIZE(strings); i++) {
+ IfBuilderGenerator m;
+ m.ParseExpression(strings[i]);
+ m.RunRandom(&rng);
+ }
+}
+
+
+TEST(RunSimpleIfElseTester) {
+ const char* tests[] = {
+ "i(v)", "i(v)t", "i(v)te",
+ "i(v)er", "i(v)ter", "i(v)ti(v)trei(v)ei(v)ei(v)ei(v)ei(v)ei(v)ei(v)e"};
+ v8::base::RandomNumberGenerator rng;
+ for (size_t i = 0; i < ARRAY_SIZE(tests); ++i) {
+ IfBuilderGenerator m;
+ m.ParseIfThenElse(tests[i]);
+ m.RunRandom(&rng);
+ }
+}
+
+
+TEST(RunRandomExpressions) {
+ v8::base::RandomNumberGenerator rng;
+ for (int n_vars = 1; n_vars < 12; n_vars++) {
+ for (int i = 0; i < n_vars * n_vars + 10; i++) {
+ IfBuilderGenerator m;
+ m.ParseRandomIfThenElse(&rng, 1, n_vars);
+ m.RunRandom(&rng);
+ }
+ }
+}
+
+
+TEST(RunRandomIfElse) {
+ v8::base::RandomNumberGenerator rng;
+ for (int n_ifs = 1; n_ifs < 12; n_ifs++) {
+ for (int i = 0; i < n_ifs * n_ifs + 10; i++) {
+ IfBuilderGenerator m;
+ m.ParseRandomIfThenElse(&rng, n_ifs, 1);
+ m.RunRandom(&rng);
+ }
+ }
+}
+
+
+TEST(RunRandomIfElseExpressions) {
+ v8::base::RandomNumberGenerator rng;
+ for (int n_vars = 2; n_vars < 6; n_vars++) {
+ for (int n_ifs = 2; n_ifs < 7; n_ifs++) {
+ for (int i = 0; i < n_ifs * n_vars + 10; i++) {
+ IfBuilderGenerator m;
+ m.ParseRandomIfThenElse(&rng, n_ifs, n_vars);
+ m.RunRandom(&rng);
+ }
+ }
+ }
+}
+
+#endif
diff --git a/deps/v8/test/cctest/compiler/test-structured-machine-assembler.cc b/deps/v8/test/cctest/compiler/test-structured-machine-assembler.cc
new file mode 100644
index 000000000..6d8020baf
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/test-structured-machine-assembler.cc
@@ -0,0 +1,1055 @@
+// 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 "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/base/utils/random-number-generator.h"
+#include "src/compiler/structured-machine-assembler.h"
+#include "test/cctest/compiler/codegen-tester.h"
+#include "test/cctest/compiler/value-helper.h"
+
+#if V8_TURBOFAN_TARGET
+
+using namespace v8::internal::compiler;
+
+typedef StructuredMachineAssembler::IfBuilder IfBuilder;
+typedef StructuredMachineAssembler::LoopBuilder Loop;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class StructuredMachineAssemblerFriend {
+ public:
+ static bool VariableAlive(StructuredMachineAssembler* m,
+ const Variable& var) {
+ CHECK(m->current_environment_ != NULL);
+ int offset = var.offset_;
+ return offset < static_cast<int>(m->CurrentVars()->size()) &&
+ m->CurrentVars()->at(offset) != NULL;
+ }
+};
+}
+}
+} // namespace v8::internal::compiler
+
+
+TEST(RunVariable) {
+ StructuredMachineAssemblerTester<int32_t> m;
+
+ int32_t constant = 0x86c2bb16;
+
+ Variable v1 = m.NewVariable(m.Int32Constant(constant));
+ Variable v2 = m.NewVariable(v1.Get());
+ m.Return(v2.Get());
+
+ CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunSimpleIf) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ int32_t constant = 0xc4a3e3a6;
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Parameter(0)).Then();
+ m.Return(m.Int32Constant(constant));
+ }
+ m.Return(m.Word32Not(m.Int32Constant(constant)));
+
+ CHECK_EQ(~constant, m.Call(0));
+ CHECK_EQ(constant, m.Call(1));
+}
+
+
+TEST(RunSimpleIfVariable) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ int32_t constant = 0xdb6f20c2;
+ Variable var = m.NewVariable(m.Int32Constant(constant));
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Parameter(0)).Then();
+ var.Set(m.Word32Not(var.Get()));
+ }
+ m.Return(var.Get());
+
+ CHECK_EQ(constant, m.Call(0));
+ CHECK_EQ(~constant, m.Call(1));
+}
+
+
+TEST(RunSimpleElse) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ int32_t constant = 0xfc5eadf4;
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Parameter(0)).Else();
+ m.Return(m.Int32Constant(constant));
+ }
+ m.Return(m.Word32Not(m.Int32Constant(constant)));
+
+ CHECK_EQ(constant, m.Call(0));
+ CHECK_EQ(~constant, m.Call(1));
+}
+
+
+TEST(RunSimpleIfElse) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ int32_t constant = 0xaa9c8cd3;
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Parameter(0)).Then();
+ m.Return(m.Int32Constant(constant));
+ cond.Else();
+ m.Return(m.Word32Not(m.Int32Constant(constant)));
+ }
+
+ CHECK_EQ(~constant, m.Call(0));
+ CHECK_EQ(constant, m.Call(1));
+}
+
+
+TEST(RunSimpleIfElseVariable) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ int32_t constant = 0x67b6f39c;
+ Variable var = m.NewVariable(m.Int32Constant(constant));
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Parameter(0)).Then();
+ var.Set(m.Word32Not(m.Word32Not(var.Get())));
+ cond.Else();
+ var.Set(m.Word32Not(var.Get()));
+ }
+ m.Return(var.Get());
+
+ CHECK_EQ(~constant, m.Call(0));
+ CHECK_EQ(constant, m.Call(1));
+}
+
+
+TEST(RunSimpleIfNoThenElse) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ int32_t constant = 0xd5e550ed;
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Parameter(0));
+ }
+ m.Return(m.Int32Constant(constant));
+
+ CHECK_EQ(constant, m.Call(0));
+ CHECK_EQ(constant, m.Call(1));
+}
+
+
+TEST(RunSimpleConjunctionVariable) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ int32_t constant = 0xf8fb9ec6;
+ Variable var = m.NewVariable(m.Int32Constant(constant));
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Int32Constant(1)).And();
+ var.Set(m.Word32Not(var.Get()));
+ cond.If(m.Parameter(0)).Then();
+ var.Set(m.Word32Not(m.Word32Not(var.Get())));
+ cond.Else();
+ var.Set(m.Word32Not(var.Get()));
+ }
+ m.Return(var.Get());
+
+ CHECK_EQ(constant, m.Call(0));
+ CHECK_EQ(~constant, m.Call(1));
+}
+
+
+TEST(RunSimpleDisjunctionVariable) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ int32_t constant = 0x118f6ffc;
+ Variable var = m.NewVariable(m.Int32Constant(constant));
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Int32Constant(0)).Or();
+ var.Set(m.Word32Not(var.Get()));
+ cond.If(m.Parameter(0)).Then();
+ var.Set(m.Word32Not(m.Word32Not(var.Get())));
+ cond.Else();
+ var.Set(m.Word32Not(var.Get()));
+ }
+ m.Return(var.Get());
+
+ CHECK_EQ(constant, m.Call(0));
+ CHECK_EQ(~constant, m.Call(1));
+}
+
+
+TEST(RunIfElse) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ {
+ IfBuilder cond(&m);
+ bool first = true;
+ FOR_INT32_INPUTS(i) {
+ Node* c = m.Int32Constant(*i);
+ if (first) {
+ cond.If(m.Word32Equal(m.Parameter(0), c)).Then();
+ m.Return(c);
+ first = false;
+ } else {
+ cond.Else();
+ cond.If(m.Word32Equal(m.Parameter(0), c)).Then();
+ m.Return(c);
+ }
+ }
+ }
+ m.Return(m.Int32Constant(333));
+
+ FOR_INT32_INPUTS(i) { CHECK_EQ(*i, m.Call(*i)); }
+}
+
+
+enum IfBuilderBranchType { kSkipBranch, kBranchFallsThrough, kBranchReturns };
+
+
+static IfBuilderBranchType all_branch_types[] = {
+ kSkipBranch, kBranchFallsThrough, kBranchReturns};
+
+
+static void RunIfBuilderDisjunction(size_t max, IfBuilderBranchType then_type,
+ IfBuilderBranchType else_type) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ std::vector<int32_t> inputs = ValueHelper::int32_vector();
+ std::vector<int32_t>::const_iterator i = inputs.begin();
+ int32_t hit = 0x8c723c9a;
+ int32_t miss = 0x88a6b9f3;
+ {
+ Node* p0 = m.Parameter(0);
+ IfBuilder cond(&m);
+ for (size_t j = 0; j < max; j++, ++i) {
+ CHECK(i != inputs.end()); // Thank you STL.
+ if (j > 0) cond.Or();
+ cond.If(m.Word32Equal(p0, m.Int32Constant(*i)));
+ }
+ switch (then_type) {
+ case kSkipBranch:
+ break;
+ case kBranchFallsThrough:
+ cond.Then();
+ break;
+ case kBranchReturns:
+ cond.Then();
+ m.Return(m.Int32Constant(hit));
+ break;
+ }
+ switch (else_type) {
+ case kSkipBranch:
+ break;
+ case kBranchFallsThrough:
+ cond.Else();
+ break;
+ case kBranchReturns:
+ cond.Else();
+ m.Return(m.Int32Constant(miss));
+ break;
+ }
+ }
+ if (then_type != kBranchReturns || else_type != kBranchReturns) {
+ m.Return(m.Int32Constant(miss));
+ }
+
+ if (then_type != kBranchReturns) hit = miss;
+
+ i = inputs.begin();
+ for (size_t j = 0; i != inputs.end(); j++, ++i) {
+ int32_t result = m.Call(*i);
+ CHECK_EQ(j < max ? hit : miss, result);
+ }
+}
+
+
+TEST(RunIfBuilderDisjunction) {
+ size_t len = ValueHelper::int32_vector().size() - 1;
+ size_t max = len > 10 ? 10 : len - 1;
+ for (size_t i = 0; i < ARRAY_SIZE(all_branch_types); i++) {
+ for (size_t j = 0; j < ARRAY_SIZE(all_branch_types); j++) {
+ for (size_t size = 1; size < max; size++) {
+ RunIfBuilderDisjunction(size, all_branch_types[i], all_branch_types[j]);
+ }
+ RunIfBuilderDisjunction(len, all_branch_types[i], all_branch_types[j]);
+ }
+ }
+}
+
+
+static void RunIfBuilderConjunction(size_t max, IfBuilderBranchType then_type,
+ IfBuilderBranchType else_type) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ std::vector<int32_t> inputs = ValueHelper::int32_vector();
+ std::vector<int32_t>::const_iterator i = inputs.begin();
+ int32_t hit = 0xa0ceb9ca;
+ int32_t miss = 0x226cafaa;
+ {
+ IfBuilder cond(&m);
+ Node* p0 = m.Parameter(0);
+ for (size_t j = 0; j < max; j++, ++i) {
+ if (j > 0) cond.And();
+ cond.If(m.Word32NotEqual(p0, m.Int32Constant(*i)));
+ }
+ switch (then_type) {
+ case kSkipBranch:
+ break;
+ case kBranchFallsThrough:
+ cond.Then();
+ break;
+ case kBranchReturns:
+ cond.Then();
+ m.Return(m.Int32Constant(hit));
+ break;
+ }
+ switch (else_type) {
+ case kSkipBranch:
+ break;
+ case kBranchFallsThrough:
+ cond.Else();
+ break;
+ case kBranchReturns:
+ cond.Else();
+ m.Return(m.Int32Constant(miss));
+ break;
+ }
+ }
+ if (then_type != kBranchReturns || else_type != kBranchReturns) {
+ m.Return(m.Int32Constant(miss));
+ }
+
+ if (then_type != kBranchReturns) hit = miss;
+
+ i = inputs.begin();
+ for (size_t j = 0; i != inputs.end(); j++, ++i) {
+ int32_t result = m.Call(*i);
+ CHECK_EQ(j >= max ? hit : miss, result);
+ }
+}
+
+
+TEST(RunIfBuilderConjunction) {
+ size_t len = ValueHelper::int32_vector().size() - 1;
+ size_t max = len > 10 ? 10 : len - 1;
+ for (size_t i = 0; i < ARRAY_SIZE(all_branch_types); i++) {
+ for (size_t j = 0; j < ARRAY_SIZE(all_branch_types); j++) {
+ for (size_t size = 1; size < max; size++) {
+ RunIfBuilderConjunction(size, all_branch_types[i], all_branch_types[j]);
+ }
+ RunIfBuilderConjunction(len, all_branch_types[i], all_branch_types[j]);
+ }
+ }
+}
+
+
+static void RunDisjunctionVariables(int disjunctions, bool explicit_then,
+ bool explicit_else) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ int32_t constant = 0x65a09535;
+
+ Node* cmp_val = m.Int32Constant(constant);
+ Node* one = m.Int32Constant(1);
+ Variable var = m.NewVariable(m.Parameter(0));
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Word32Equal(var.Get(), cmp_val));
+ for (int i = 0; i < disjunctions; i++) {
+ cond.Or();
+ var.Set(m.Int32Add(var.Get(), one));
+ cond.If(m.Word32Equal(var.Get(), cmp_val));
+ }
+ if (explicit_then) {
+ cond.Then();
+ }
+ if (explicit_else) {
+ cond.Else();
+ var.Set(m.Int32Add(var.Get(), one));
+ }
+ }
+ m.Return(var.Get());
+
+ int adds = disjunctions + (explicit_else ? 1 : 0);
+ int32_t input = constant - 2 * adds;
+ for (int i = 0; i < adds; i++) {
+ CHECK_EQ(input + adds, m.Call(input));
+ input++;
+ }
+ for (int i = 0; i < adds + 1; i++) {
+ CHECK_EQ(constant, m.Call(input));
+ input++;
+ }
+ for (int i = 0; i < adds; i++) {
+ CHECK_EQ(input + adds, m.Call(input));
+ input++;
+ }
+}
+
+
+TEST(RunDisjunctionVariables) {
+ for (int disjunctions = 0; disjunctions < 10; disjunctions++) {
+ RunDisjunctionVariables(disjunctions, false, false);
+ RunDisjunctionVariables(disjunctions, false, true);
+ RunDisjunctionVariables(disjunctions, true, false);
+ RunDisjunctionVariables(disjunctions, true, true);
+ }
+}
+
+
+static void RunConjunctionVariables(int conjunctions, bool explicit_then,
+ bool explicit_else) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ int32_t constant = 0x2c7f4b45;
+ Node* cmp_val = m.Int32Constant(constant);
+ Node* one = m.Int32Constant(1);
+ Variable var = m.NewVariable(m.Parameter(0));
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Word32NotEqual(var.Get(), cmp_val));
+ for (int i = 0; i < conjunctions; i++) {
+ cond.And();
+ var.Set(m.Int32Add(var.Get(), one));
+ cond.If(m.Word32NotEqual(var.Get(), cmp_val));
+ }
+ if (explicit_then) {
+ cond.Then();
+ var.Set(m.Int32Add(var.Get(), one));
+ }
+ if (explicit_else) {
+ cond.Else();
+ }
+ }
+ m.Return(var.Get());
+
+ int adds = conjunctions + (explicit_then ? 1 : 0);
+ int32_t input = constant - 2 * adds;
+ for (int i = 0; i < adds; i++) {
+ CHECK_EQ(input + adds, m.Call(input));
+ input++;
+ }
+ for (int i = 0; i < adds + 1; i++) {
+ CHECK_EQ(constant, m.Call(input));
+ input++;
+ }
+ for (int i = 0; i < adds; i++) {
+ CHECK_EQ(input + adds, m.Call(input));
+ input++;
+ }
+}
+
+
+TEST(RunConjunctionVariables) {
+ for (int conjunctions = 0; conjunctions < 10; conjunctions++) {
+ RunConjunctionVariables(conjunctions, false, false);
+ RunConjunctionVariables(conjunctions, false, true);
+ RunConjunctionVariables(conjunctions, true, false);
+ RunConjunctionVariables(conjunctions, true, true);
+ }
+}
+
+
+TEST(RunSimpleNestedIf) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
+ const size_t NUM_VALUES = 7;
+ std::vector<int32_t> inputs = ValueHelper::int32_vector();
+ CHECK(inputs.size() >= NUM_VALUES);
+ Node* values[NUM_VALUES];
+ for (size_t j = 0; j < NUM_VALUES; j++) {
+ values[j] = m.Int32Constant(inputs[j]);
+ }
+ {
+ IfBuilder if_0(&m);
+ if_0.If(m.Word32Equal(m.Parameter(0), values[0])).Then();
+ {
+ IfBuilder if_1(&m);
+ if_1.If(m.Word32Equal(m.Parameter(1), values[1])).Then();
+ { m.Return(values[3]); }
+ if_1.Else();
+ { m.Return(values[4]); }
+ }
+ if_0.Else();
+ {
+ IfBuilder if_1(&m);
+ if_1.If(m.Word32Equal(m.Parameter(1), values[2])).Then();
+ { m.Return(values[5]); }
+ if_1.Else();
+ { m.Return(values[6]); }
+ }
+ }
+
+ int32_t result = m.Call(inputs[0], inputs[1]);
+ CHECK_EQ(inputs[3], result);
+
+ result = m.Call(inputs[0], inputs[1] + 1);
+ CHECK_EQ(inputs[4], result);
+
+ result = m.Call(inputs[0] + 1, inputs[2]);
+ CHECK_EQ(inputs[5], result);
+
+ result = m.Call(inputs[0] + 1, inputs[2] + 1);
+ CHECK_EQ(inputs[6], result);
+}
+
+
+TEST(RunUnreachableBlockAfterIf) {
+ StructuredMachineAssemblerTester<int32_t> m;
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Int32Constant(0)).Then();
+ m.Return(m.Int32Constant(1));
+ cond.Else();
+ m.Return(m.Int32Constant(2));
+ }
+ // This is unreachable.
+ m.Return(m.Int32Constant(3));
+ CHECK_EQ(2, m.Call());
+}
+
+
+TEST(RunUnreachableBlockAfterLoop) {
+ StructuredMachineAssemblerTester<int32_t> m;
+ {
+ Loop loop(&m);
+ m.Return(m.Int32Constant(1));
+ }
+ // This is unreachable.
+ m.Return(m.Int32Constant(3));
+ CHECK_EQ(1, m.Call());
+}
+
+
+TEST(RunSimpleLoop) {
+ StructuredMachineAssemblerTester<int32_t> m;
+ int32_t constant = 0x120c1f85;
+ {
+ Loop loop(&m);
+ m.Return(m.Int32Constant(constant));
+ }
+ CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunSimpleLoopBreak) {
+ StructuredMachineAssemblerTester<int32_t> m;
+ int32_t constant = 0x10ddb0a6;
+ {
+ Loop loop(&m);
+ loop.Break();
+ }
+ m.Return(m.Int32Constant(constant));
+ CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunCountToTen) {
+ StructuredMachineAssemblerTester<int32_t> m;
+ Variable i = m.NewVariable(m.Int32Constant(0));
+ Node* ten = m.Int32Constant(10);
+ Node* one = m.Int32Constant(1);
+ {
+ Loop loop(&m);
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Word32Equal(i.Get(), ten)).Then();
+ loop.Break();
+ }
+ i.Set(m.Int32Add(i.Get(), one));
+ }
+ m.Return(i.Get());
+ CHECK_EQ(10, m.Call());
+}
+
+
+TEST(RunCountToTenAcc) {
+ StructuredMachineAssemblerTester<int32_t> m;
+ int32_t constant = 0xf27aed64;
+ Variable i = m.NewVariable(m.Int32Constant(0));
+ Variable var = m.NewVariable(m.Int32Constant(constant));
+ Node* ten = m.Int32Constant(10);
+ Node* one = m.Int32Constant(1);
+ {
+ Loop loop(&m);
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Word32Equal(i.Get(), ten)).Then();
+ loop.Break();
+ }
+ i.Set(m.Int32Add(i.Get(), one));
+ var.Set(m.Int32Add(var.Get(), i.Get()));
+ }
+ m.Return(var.Get());
+
+ CHECK_EQ(constant + 10 + 9 * 5, m.Call());
+}
+
+
+TEST(RunSimpleNestedLoop) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ Node* zero = m.Int32Constant(0);
+ Node* one = m.Int32Constant(1);
+ Node* two = m.Int32Constant(2);
+ Node* three = m.Int32Constant(3);
+ {
+ Loop l1(&m);
+ {
+ Loop l2(&m);
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Word32Equal(m.Parameter(0), one)).Then();
+ l1.Break();
+ }
+ {
+ Loop l3(&m);
+ {
+ IfBuilder cond(&m);
+ cond.If(m.Word32Equal(m.Parameter(0), two)).Then();
+ l2.Break();
+ cond.Else();
+ cond.If(m.Word32Equal(m.Parameter(0), three)).Then();
+ l3.Break();
+ }
+ m.Return(three);
+ }
+ m.Return(two);
+ }
+ m.Return(one);
+ }
+ m.Return(zero);
+
+ CHECK_EQ(0, m.Call(1));
+ CHECK_EQ(1, m.Call(2));
+ CHECK_EQ(2, m.Call(3));
+ CHECK_EQ(3, m.Call(4));
+}
+
+
+TEST(RunFib) {
+ StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
+
+ // Constants.
+ Node* zero = m.Int32Constant(0);
+ Node* one = m.Int32Constant(1);
+ Node* two = m.Int32Constant(2);
+ // Variables.
+ // cnt = input
+ Variable cnt = m.NewVariable(m.Parameter(0));
+ // if (cnt < 2) return i
+ {
+ IfBuilder lt2(&m);
+ lt2.If(m.Int32LessThan(cnt.Get(), two)).Then();
+ m.Return(cnt.Get());
+ }
+ // cnt -= 2
+ cnt.Set(m.Int32Sub(cnt.Get(), two));
+ // res = 1
+ Variable res = m.NewVariable(one);
+ {
+ // prv_0 = 1
+ // prv_1 = 1
+ Variable prv_0 = m.NewVariable(one);
+ Variable prv_1 = m.NewVariable(one);
+ // while (cnt != 0) {
+ Loop main(&m);
+ {
+ IfBuilder nz(&m);
+ nz.If(m.Word32Equal(cnt.Get(), zero)).Then();
+ main.Break();
+ }
+ // res = prv_0 + prv_1
+ // prv_0 = prv_1
+ // prv_1 = res
+ res.Set(m.Int32Add(prv_0.Get(), prv_1.Get()));
+ prv_0.Set(prv_1.Get());
+ prv_1.Set(res.Get());
+ // cnt--
+ cnt.Set(m.Int32Sub(cnt.Get(), one));
+ }
+ m.Return(res.Get());
+
+ int32_t values[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144};
+ for (size_t i = 0; i < ARRAY_SIZE(values); i++) {
+ CHECK_EQ(values[i], m.Call(static_cast<int32_t>(i)));
+ }
+}
+
+
+static int VariableIntroduction() {
+ while (true) {
+ int ret = 0;
+ for (int i = 0; i < 10; i++) {
+ for (int j = i; j < 10; j++) {
+ for (int k = j; k < 10; k++) {
+ ret++;
+ }
+ ret++;
+ }
+ ret++;
+ }
+ return ret;
+ }
+}
+
+
+TEST(RunVariableIntroduction) {
+ StructuredMachineAssemblerTester<int32_t> m;
+ Node* zero = m.Int32Constant(0);
+ Node* one = m.Int32Constant(1);
+ // Use an IfBuilder to get out of start block.
+ {
+ IfBuilder i0(&m);
+ i0.If(zero).Then();
+ m.Return(one);
+ }
+ Node* ten = m.Int32Constant(10);
+ Variable v0 =
+ m.NewVariable(zero); // Introduce variable outside of start block.
+ {
+ Loop l0(&m);
+ Variable ret = m.NewVariable(zero); // Introduce loop variable.
+ {
+ Loop l1(&m);
+ {
+ IfBuilder i1(&m);
+ i1.If(m.Word32Equal(v0.Get(), ten)).Then();
+ l1.Break();
+ }
+ Variable v1 = m.NewVariable(v0.Get()); // Introduce loop variable.
+ {
+ Loop l2(&m);
+ {
+ IfBuilder i2(&m);
+ i2.If(m.Word32Equal(v1.Get(), ten)).Then();
+ l2.Break();
+ }
+ Variable v2 = m.NewVariable(v1.Get()); // Introduce loop variable.
+ {
+ Loop l3(&m);
+ {
+ IfBuilder i3(&m);
+ i3.If(m.Word32Equal(v2.Get(), ten)).Then();
+ l3.Break();
+ }
+ ret.Set(m.Int32Add(ret.Get(), one));
+ v2.Set(m.Int32Add(v2.Get(), one));
+ }
+ ret.Set(m.Int32Add(ret.Get(), one));
+ v1.Set(m.Int32Add(v1.Get(), one));
+ }
+ ret.Set(m.Int32Add(ret.Get(), one));
+ v0.Set(m.Int32Add(v0.Get(), one));
+ }
+ m.Return(ret.Get()); // Return loop variable.
+ }
+ CHECK_EQ(VariableIntroduction(), m.Call());
+}
+
+
+TEST(RunIfBuilderVariableLiveness) {
+ StructuredMachineAssemblerTester<int32_t> m;
+ typedef i::compiler::StructuredMachineAssemblerFriend F;
+ Node* zero = m.Int32Constant(0);
+ Variable v_outer = m.NewVariable(zero);
+ IfBuilder cond(&m);
+ cond.If(zero).Then();
+ Variable v_then = m.NewVariable(zero);
+ CHECK(F::VariableAlive(&m, v_outer));
+ CHECK(F::VariableAlive(&m, v_then));
+ cond.Else();
+ Variable v_else = m.NewVariable(zero);
+ CHECK(F::VariableAlive(&m, v_outer));
+ CHECK(F::VariableAlive(&m, v_else));
+ CHECK(!F::VariableAlive(&m, v_then));
+ cond.End();
+ CHECK(F::VariableAlive(&m, v_outer));
+ CHECK(!F::VariableAlive(&m, v_then));
+ CHECK(!F::VariableAlive(&m, v_else));
+}
+
+
+TEST(RunSimpleExpression1) {
+ StructuredMachineAssemblerTester<int32_t> m;
+
+ int32_t constant = 0x0c2974ef;
+ Node* zero = m.Int32Constant(0);
+ Node* one = m.Int32Constant(1);
+ {
+ // if (((1 && 1) && 1) && 1) return constant; return 0;
+ IfBuilder cond(&m);
+ cond.OpenParen();
+ cond.OpenParen().If(one).And();
+ cond.If(one).CloseParen().And();
+ cond.If(one).CloseParen().And();
+ cond.If(one).Then();
+ m.Return(m.Int32Constant(constant));
+ }
+ m.Return(zero);
+
+ CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunSimpleExpression2) {
+ StructuredMachineAssemblerTester<int32_t> m;
+
+ int32_t constant = 0x2eddc11b;
+ Node* zero = m.Int32Constant(0);
+ Node* one = m.Int32Constant(1);
+ {
+ // if (((0 || 1) && 1) && 1) return constant; return 0;
+ IfBuilder cond(&m);
+ cond.OpenParen();
+ cond.OpenParen().If(zero).Or();
+ cond.If(one).CloseParen().And();
+ cond.If(one).CloseParen().And();
+ cond.If(one).Then();
+ m.Return(m.Int32Constant(constant));
+ }
+ m.Return(zero);
+
+ CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunSimpleExpression3) {
+ StructuredMachineAssemblerTester<int32_t> m;
+
+ int32_t constant = 0x9ed5e9ef;
+ Node* zero = m.Int32Constant(0);
+ Node* one = m.Int32Constant(1);
+ {
+ // if (1 && ((0 || 1) && 1) && 1) return constant; return 0;
+ IfBuilder cond(&m);
+ cond.If(one).And();
+ cond.OpenParen();
+ cond.OpenParen().If(zero).Or();
+ cond.If(one).CloseParen().And();
+ cond.If(one).CloseParen().And();
+ cond.If(one).Then();
+ m.Return(m.Int32Constant(constant));
+ }
+ m.Return(zero);
+
+ CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunSimpleExpressionVariable1) {
+ StructuredMachineAssemblerTester<int32_t> m;
+
+ int32_t constant = 0x4b40a986;
+ Node* one = m.Int32Constant(1);
+ Variable var = m.NewVariable(m.Int32Constant(constant));
+ {
+ // if (var.Get() && ((!var || var) && var) && var) {} return var;
+ // incrementing var in each environment.
+ IfBuilder cond(&m);
+ cond.If(var.Get()).And();
+ var.Set(m.Int32Add(var.Get(), one));
+ cond.OpenParen().OpenParen().If(m.Word32BinaryNot(var.Get())).Or();
+ var.Set(m.Int32Add(var.Get(), one));
+ cond.If(var.Get()).CloseParen().And();
+ var.Set(m.Int32Add(var.Get(), one));
+ cond.If(var.Get()).CloseParen().And();
+ var.Set(m.Int32Add(var.Get(), one));
+ cond.If(var.Get());
+ }
+ m.Return(var.Get());
+
+ CHECK_EQ(constant + 4, m.Call());
+}
+
+
+class QuicksortHelper : public StructuredMachineAssemblerTester<int32_t> {
+ public:
+ QuicksortHelper()
+ : StructuredMachineAssemblerTester<int32_t>(
+ MachineOperatorBuilder::pointer_rep(), kMachineWord32,
+ MachineOperatorBuilder::pointer_rep(), kMachineWord32),
+ input_(NULL),
+ stack_limit_(NULL),
+ one_(Int32Constant(1)),
+ stack_frame_size_(Int32Constant(kFrameVariables * 4)),
+ left_offset_(Int32Constant(0 * 4)),
+ right_offset_(Int32Constant(1 * 4)) {
+ Build();
+ }
+
+ int32_t DoCall(int32_t* input, int32_t input_length) {
+ int32_t stack_space[20];
+ // Do call.
+ int32_t return_val = Call(input, input_length, stack_space,
+ static_cast<int32_t>(ARRAY_SIZE(stack_space)));
+ // Ran out of stack space.
+ if (return_val != 0) return return_val;
+ // Check sorted.
+ int32_t last = input[0];
+ for (int32_t i = 0; i < input_length; i++) {
+ CHECK(last <= input[i]);
+ last = input[i];
+ }
+ return return_val;
+ }
+
+ private:
+ void Inc32(const Variable& var) { var.Set(Int32Add(var.Get(), one_)); }
+ Node* Index(Node* index) { return Word32Shl(index, Int32Constant(2)); }
+ Node* ArrayLoad(Node* index) {
+ return Load(kMachineWord32, input_, Index(index));
+ }
+ void Swap(Node* a_index, Node* b_index) {
+ Node* a = ArrayLoad(a_index);
+ Node* b = ArrayLoad(b_index);
+ Store(kMachineWord32, input_, Index(a_index), b);
+ Store(kMachineWord32, input_, Index(b_index), a);
+ }
+ void AddToCallStack(const Variable& fp, Node* left, Node* right) {
+ {
+ // Stack limit check.
+ IfBuilder cond(this);
+ cond.If(IntPtrLessThanOrEqual(fp.Get(), stack_limit_)).Then();
+ Return(Int32Constant(-1));
+ }
+ Store(kMachineWord32, fp.Get(), left_offset_, left);
+ Store(kMachineWord32, fp.Get(), right_offset_, right);
+ fp.Set(IntPtrAdd(fp.Get(), ConvertInt32ToIntPtr(stack_frame_size_)));
+ }
+ void Build() {
+ Variable left = NewVariable(Int32Constant(0));
+ Variable right =
+ NewVariable(Int32Sub(Parameter(kInputLengthParameter), one_));
+ input_ = Parameter(kInputParameter);
+ Node* top_of_stack = Parameter(kStackParameter);
+ stack_limit_ = IntPtrSub(
+ top_of_stack, ConvertInt32ToIntPtr(Parameter(kStackLengthParameter)));
+ Variable fp = NewVariable(top_of_stack);
+ {
+ Loop outermost(this);
+ // Edge case - 2 element array.
+ {
+ IfBuilder cond(this);
+ cond.If(Word32Equal(left.Get(), Int32Sub(right.Get(), one_))).And();
+ cond.If(Int32LessThanOrEqual(ArrayLoad(right.Get()),
+ ArrayLoad(left.Get()))).Then();
+ Swap(left.Get(), right.Get());
+ }
+ {
+ IfBuilder cond(this);
+ // Algorithm complete condition.
+ cond.If(WordEqual(top_of_stack, fp.Get())).And();
+ cond.If(Int32LessThanOrEqual(Int32Sub(right.Get(), one_), left.Get()))
+ .Then();
+ outermost.Break();
+ // 'Recursion' exit condition. Pop frame and continue.
+ cond.Else();
+ cond.If(Int32LessThanOrEqual(Int32Sub(right.Get(), one_), left.Get()))
+ .Then();
+ fp.Set(IntPtrSub(fp.Get(), ConvertInt32ToIntPtr(stack_frame_size_)));
+ left.Set(Load(kMachineWord32, fp.Get(), left_offset_));
+ right.Set(Load(kMachineWord32, fp.Get(), right_offset_));
+ outermost.Continue();
+ }
+ // Partition.
+ Variable store_index = NewVariable(left.Get());
+ {
+ Node* pivot_index =
+ Int32Div(Int32Add(left.Get(), right.Get()), Int32Constant(2));
+ Node* pivot = ArrayLoad(pivot_index);
+ Swap(pivot_index, right.Get());
+ Variable i = NewVariable(left.Get());
+ {
+ Loop partition(this);
+ {
+ IfBuilder cond(this);
+ // Parition complete.
+ cond.If(Word32Equal(i.Get(), right.Get())).Then();
+ partition.Break();
+ // Need swap.
+ cond.Else();
+ cond.If(Int32LessThanOrEqual(ArrayLoad(i.Get()), pivot)).Then();
+ Swap(i.Get(), store_index.Get());
+ Inc32(store_index);
+ }
+ Inc32(i);
+ } // End partition loop.
+ Swap(store_index.Get(), right.Get());
+ }
+ // 'Recurse' left and right halves of partition.
+ // Tail recurse second one.
+ AddToCallStack(fp, left.Get(), Int32Sub(store_index.Get(), one_));
+ left.Set(Int32Add(store_index.Get(), one_));
+ } // End outermost loop.
+ Return(Int32Constant(0));
+ }
+
+ static const int kFrameVariables = 2; // left, right
+ // Parameter offsets.
+ static const int kInputParameter = 0;
+ static const int kInputLengthParameter = 1;
+ static const int kStackParameter = 2;
+ static const int kStackLengthParameter = 3;
+ // Function inputs.
+ Node* input_;
+ Node* stack_limit_;
+ // Constants.
+ Node* const one_;
+ // Frame constants.
+ Node* const stack_frame_size_;
+ Node* const left_offset_;
+ Node* const right_offset_;
+};
+
+
+TEST(RunSimpleQuicksort) {
+ QuicksortHelper m;
+ int32_t inputs[] = {9, 7, 1, 8, 11};
+ CHECK_EQ(0, m.DoCall(inputs, ARRAY_SIZE(inputs)));
+}
+
+
+TEST(RunRandomQuicksort) {
+ QuicksortHelper m;
+
+ v8::base::RandomNumberGenerator rng;
+ static const int kMaxLength = 40;
+ int32_t inputs[kMaxLength];
+
+ for (int length = 1; length < kMaxLength; length++) {
+ for (int i = 0; i < 70; i++) {
+ // Randomize inputs.
+ for (int j = 0; j < length; j++) {
+ inputs[j] = rng.NextInt(10) - 5;
+ }
+ CHECK_EQ(0, m.DoCall(inputs, length));
+ }
+ }
+}
+
+
+TEST(MultipleScopes) {
+ StructuredMachineAssemblerTester<int32_t> m;
+ for (int i = 0; i < 10; i++) {
+ IfBuilder b(&m);
+ b.If(m.Int32Constant(0)).Then();
+ m.NewVariable(m.Int32Constant(0));
+ }
+ m.Return(m.Int32Constant(0));
+ CHECK_EQ(0, m.Call());
+}
+
+#endif
diff --git a/deps/v8/test/cctest/compiler/value-helper.h b/deps/v8/test/cctest/compiler/value-helper.h
new file mode 100644
index 000000000..5bfd7884d
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/value-helper.h
@@ -0,0 +1,131 @@
+// 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_CCTEST_COMPILER_VALUE_HELPER_H_
+#define V8_CCTEST_COMPILER_VALUE_HELPER_H_
+
+#include "src/v8.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/node.h"
+#include "src/compiler/node-matchers.h"
+#include "src/isolate.h"
+#include "src/objects.h"
+#include "test/cctest/cctest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// A collection of utilities related to numerical and heap values, including
+// example input values of various types, including int32_t, uint32_t, double,
+// etc.
+class ValueHelper {
+ public:
+ Isolate* isolate_;
+
+ ValueHelper() : isolate_(CcTest::InitIsolateOnce()) {}
+
+ template <typename T>
+ void CheckConstant(T expected, Node* node) {
+ CHECK_EQ(expected, ValueOf<T>(node->op()));
+ }
+
+ void CheckFloat64Constant(double expected, Node* node) {
+ CHECK_EQ(IrOpcode::kFloat64Constant, node->opcode());
+ CHECK_EQ(expected, ValueOf<double>(node->op()));
+ }
+
+ void CheckNumberConstant(double expected, Node* node) {
+ CHECK_EQ(IrOpcode::kNumberConstant, node->opcode());
+ CHECK_EQ(expected, ValueOf<double>(node->op()));
+ }
+
+ void CheckInt32Constant(int32_t expected, Node* node) {
+ CHECK_EQ(IrOpcode::kInt32Constant, node->opcode());
+ CHECK_EQ(expected, ValueOf<int32_t>(node->op()));
+ }
+
+ void CheckUint32Constant(int32_t expected, Node* node) {
+ CHECK_EQ(IrOpcode::kInt32Constant, node->opcode());
+ CHECK_EQ(expected, ValueOf<uint32_t>(node->op()));
+ }
+
+ void CheckHeapConstant(Object* expected, Node* node) {
+ CHECK_EQ(IrOpcode::kHeapConstant, node->opcode());
+ CHECK_EQ(expected, *ValueOf<Handle<Object> >(node->op()));
+ }
+
+ void CheckTrue(Node* node) {
+ CheckHeapConstant(isolate_->heap()->true_value(), node);
+ }
+
+ void CheckFalse(Node* node) {
+ CheckHeapConstant(isolate_->heap()->false_value(), node);
+ }
+
+ static std::vector<double> float64_vector() {
+ static const double nan = v8::base::OS::nan_value();
+ static const double values[] = {
+ 0.125, 0.25, 0.375, 0.5,
+ 1.25, -1.75, 2, 5.125,
+ 6.25, 0.0, -0.0, 982983.25,
+ 888, 2147483647.0, -999.75, 3.1e7,
+ -2e66, 3e-88, -2147483648.0, V8_INFINITY,
+ -V8_INFINITY, nan, 2147483647.375, 2147483647.75,
+ 2147483648.0, 2147483648.25, 2147483649.25, -2147483647.0,
+ -2147483647.125, -2147483647.875, -2147483648.25, -2147483649.5};
+ return std::vector<double>(&values[0], &values[ARRAY_SIZE(values)]);
+ }
+
+ static const std::vector<int32_t> int32_vector() {
+ std::vector<uint32_t> values = uint32_vector();
+ return std::vector<int32_t>(values.begin(), values.end());
+ }
+
+ static const std::vector<uint32_t> uint32_vector() {
+ static const uint32_t kValues[] = {
+ 0x00000000, 0x00000001, 0xffffffff, 0x1b09788b, 0x04c5fce8, 0xcc0de5bf,
+ 0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344,
+ 0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c,
+ 0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00,
+ 0x761c4761, 0x80000000, 0x88888888, 0xa0000000, 0xdddddddd, 0xe0000000,
+ 0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff,
+ 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, 0x0000ffff, 0x00007fff,
+ 0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff};
+ return std::vector<uint32_t>(&kValues[0], &kValues[ARRAY_SIZE(kValues)]);
+ }
+
+ static const std::vector<double> nan_vector(size_t limit = 0) {
+ static const double nan = v8::base::OS::nan_value();
+ static const double values[] = {-nan, -V8_INFINITY * -0.0,
+ -V8_INFINITY * 0.0, V8_INFINITY * -0.0,
+ V8_INFINITY * 0.0, nan};
+ return std::vector<double>(&values[0], &values[ARRAY_SIZE(values)]);
+ }
+
+ static const std::vector<uint32_t> ror_vector() {
+ static const uint32_t kValues[31] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
+ return std::vector<uint32_t>(&kValues[0], &kValues[ARRAY_SIZE(kValues)]);
+ }
+};
+
+// Helper macros that can be used in FOR_INT32_INPUTS(i) { ... *i ... }
+// Watch out, these macros aren't hygenic; they pollute your scope. Thanks STL.
+#define FOR_INPUTS(ctype, itype, var) \
+ std::vector<ctype> var##_vec = ValueHelper::itype##_vector(); \
+ for (std::vector<ctype>::iterator var = var##_vec.begin(); \
+ var != var##_vec.end(); ++var)
+
+#define FOR_INT32_INPUTS(var) FOR_INPUTS(int32_t, int32, var)
+#define FOR_UINT32_INPUTS(var) FOR_INPUTS(uint32_t, uint32, var)
+#define FOR_FLOAT64_INPUTS(var) FOR_INPUTS(double, float64, var)
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
+
+#endif // V8_CCTEST_COMPILER_VALUE_HELPER_H_
diff --git a/deps/v8/test/cctest/gay-fixed.cc b/deps/v8/test/cctest/gay-fixed.cc
index 071ea4f8c..81463ac1f 100644
--- a/deps/v8/test/cctest/gay-fixed.cc
+++ b/deps/v8/test/cctest/gay-fixed.cc
@@ -29,9 +29,9 @@
// have been generated using Gay's dtoa to produce the fixed representation:
// dtoa(v, 3, number_digits, &decimal_point, &sign, NULL);
-#include "v8.h"
+#include "src/v8.h"
-#include "gay-fixed.h"
+#include "test/cctest/gay-fixed.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/test/cctest/gay-precision.cc b/deps/v8/test/cctest/gay-precision.cc
index c0e993509..6ab2715fe 100644
--- a/deps/v8/test/cctest/gay-precision.cc
+++ b/deps/v8/test/cctest/gay-precision.cc
@@ -29,9 +29,9 @@
// have been generated using Gay's dtoa to produce the precision representation:
// dtoa(v, 2, number_digits, &decimal_point, &sign, NULL);
-#include "v8.h"
+#include "src/v8.h"
-#include "gay-precision.h"
+#include "test/cctest/gay-precision.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/test/cctest/gay-shortest.cc b/deps/v8/test/cctest/gay-shortest.cc
index d065e9778..896ea4c51 100644
--- a/deps/v8/test/cctest/gay-shortest.cc
+++ b/deps/v8/test/cctest/gay-shortest.cc
@@ -29,9 +29,9 @@
// have been generated using Gay's dtoa to produce the shortest representation:
// decimal_rep = dtoa(v, 0, 0, &decimal_point, &sign, NULL);
-#include "v8.h"
+#include "src/v8.h"
-#include "gay-shortest.h"
+#include "test/cctest/gay-shortest.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/test/cctest/print-extension.cc b/deps/v8/test/cctest/print-extension.cc
index 9f629195b..d1af3596e 100644
--- a/deps/v8/test/cctest/print-extension.cc
+++ b/deps/v8/test/cctest/print-extension.cc
@@ -25,7 +25,7 @@
// (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 "print-extension.h"
+#include "test/cctest/print-extension.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/test/cctest/print-extension.h b/deps/v8/test/cctest/print-extension.h
index 7fe9226f7..b0d2b1ca1 100644
--- a/deps/v8/test/cctest/print-extension.h
+++ b/deps/v8/test/cctest/print-extension.h
@@ -28,7 +28,7 @@
#ifndef V8_TEST_CCTEST_PRINT_EXTENSION_H_
#define V8_TEST_CCTEST_PRINT_EXTENSION_H_
-#include "v8.h"
+#include "src/v8.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/test/cctest/profiler-extension.cc b/deps/v8/test/cctest/profiler-extension.cc
index 1fdd1ba24..263fc4f38 100644
--- a/deps/v8/test/cctest/profiler-extension.cc
+++ b/deps/v8/test/cctest/profiler-extension.cc
@@ -27,8 +27,8 @@
//
// Tests of profiles generator and utilities.
-#include "profiler-extension.h"
-#include "checks.h"
+#include "src/base/logging.h"
+#include "test/cctest/profiler-extension.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/test/cctest/profiler-extension.h b/deps/v8/test/cctest/profiler-extension.h
index c26a29c39..6f816b33f 100644
--- a/deps/v8/test/cctest/profiler-extension.h
+++ b/deps/v8/test/cctest/profiler-extension.h
@@ -30,7 +30,7 @@
#ifndef V8_TEST_CCTEST_PROFILER_EXTENSION_H_
#define V8_TEST_CCTEST_PROFILER_EXTENSION_H_
-#include "../include/v8-profiler.h"
+#include "include/v8-profiler.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/test/cctest/test-accessors.cc b/deps/v8/test/cctest/test-accessors.cc
index daafb244e..5bf61c8fc 100644
--- a/deps/v8/test/cctest/test-accessors.cc
+++ b/deps/v8/test/cctest/test-accessors.cc
@@ -27,12 +27,12 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "api.h"
-#include "cctest.h"
-#include "frames-inl.h"
-#include "string-stream.h"
+#include "src/api.h"
+#include "src/frames-inl.h"
+#include "src/string-stream.h"
+#include "test/cctest/cctest.h"
using ::v8::ObjectTemplate;
using ::v8::Value;
@@ -229,54 +229,6 @@ THREADED_TEST(AccessorIC) {
}
-static void AccessorProhibitsOverwritingGetter(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
- ApiTestFuzzer::Fuzz();
- info.GetReturnValue().Set(true);
-}
-
-
-THREADED_TEST(AccessorProhibitsOverwriting) {
- LocalContext context;
- v8::Isolate* isolate = context->GetIsolate();
- v8::HandleScope scope(isolate);
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetAccessor(v8_str("x"),
- AccessorProhibitsOverwritingGetter,
- 0,
- v8::Handle<Value>(),
- v8::PROHIBITS_OVERWRITING,
- v8::ReadOnly);
- Local<v8::Object> instance = templ->NewInstance();
- context->Global()->Set(v8_str("obj"), instance);
- Local<Value> value = CompileRun(
- "obj.__defineGetter__('x', function() { return false; });"
- "obj.x");
- CHECK(value->BooleanValue());
- value = CompileRun(
- "var setter_called = false;"
- "obj.__defineSetter__('x', function() { setter_called = true; });"
- "obj.x = 42;"
- "setter_called");
- CHECK(!value->BooleanValue());
- value = CompileRun(
- "obj2 = {};"
- "obj2.__proto__ = obj;"
- "obj2.__defineGetter__('x', function() { return false; });"
- "obj2.x");
- CHECK(value->BooleanValue());
- value = CompileRun(
- "var setter_called = false;"
- "obj2 = {};"
- "obj2.__proto__ = obj;"
- "obj2.__defineSetter__('x', function() { setter_called = true; });"
- "obj2.x = 42;"
- "setter_called");
- CHECK(!value->BooleanValue());
-}
-
-
template <int C>
static void HandleAllocatingGetter(
Local<String> name,
diff --git a/deps/v8/test/cctest/test-alloc.cc b/deps/v8/test/cctest/test-alloc.cc
index 7a213ae4b..314c3c147 100644
--- a/deps/v8/test/cctest/test-alloc.cc
+++ b/deps/v8/test/cctest/test-alloc.cc
@@ -25,11 +25,11 @@
// (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 "accessors.h"
-#include "api.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
-#include "cctest.h"
+#include "src/accessors.h"
+#include "src/api.h"
using namespace v8::internal;
@@ -50,7 +50,6 @@ static AllocationResult AllocateAfterFailures() {
// for specific kinds.
heap->AllocateFixedArray(100).ToObjectChecked();
heap->AllocateHeapNumber(0.42).ToObjectChecked();
- heap->AllocateArgumentsObject(Smi::FromInt(87), 10).ToObjectChecked();
Object* object = heap->AllocateJSObject(
*CcTest::i_isolate()->object_function()).ToObjectChecked();
heap->CopyJSObject(JSObject::cast(object)).ToObjectChecked();
@@ -67,7 +66,7 @@ static AllocationResult AllocateAfterFailures() {
static const int kLargeObjectSpaceFillerLength = 300000;
static const int kLargeObjectSpaceFillerSize = FixedArray::SizeFor(
kLargeObjectSpaceFillerLength);
- ASSERT(kLargeObjectSpaceFillerSize > heap->old_pointer_space()->AreaSize());
+ DCHECK(kLargeObjectSpaceFillerSize > heap->old_pointer_space()->AreaSize());
while (heap->OldGenerationSpaceAvailable() > kLargeObjectSpaceFillerSize) {
heap->AllocateFixedArray(
kLargeObjectSpaceFillerLength, TENURED).ToObjectChecked();
@@ -137,8 +136,8 @@ TEST(StressJS) {
v8::HandleScope scope(CcTest::isolate());
v8::Handle<v8::Context> env = v8::Context::New(CcTest::isolate());
env->Enter();
- Handle<JSFunction> function = factory->NewFunctionWithPrototype(
- factory->function_string(), factory->null_value());
+ Handle<JSFunction> function = factory->NewFunction(
+ factory->function_string());
// Force the creation of an initial map and set the code to
// something empty.
factory->NewJSObject(function);
@@ -147,7 +146,7 @@ TEST(StressJS) {
// Patch the map to have an accessor for "get".
Handle<Map> map(function->initial_map());
Handle<DescriptorArray> instance_descriptors(map->instance_descriptors());
- ASSERT(instance_descriptors->IsEmpty());
+ DCHECK(instance_descriptors->IsEmpty());
PropertyAttributes attrs = static_cast<PropertyAttributes>(0);
Handle<AccessorInfo> foreign = TestAccessorInfo(isolate, attrs);
@@ -196,13 +195,13 @@ class Block {
TEST(CodeRange) {
- const int code_range_size = 32*MB;
+ const size_t code_range_size = 32*MB;
CcTest::InitializeVM();
CodeRange code_range(reinterpret_cast<Isolate*>(CcTest::isolate()));
code_range.SetUp(code_range_size);
- int current_allocated = 0;
- int total_allocated = 0;
- List<Block> blocks(1000);
+ size_t current_allocated = 0;
+ size_t total_allocated = 0;
+ List< ::Block> blocks(1000);
while (total_allocated < 5 * code_range_size) {
if (current_allocated < code_range_size / 10) {
@@ -219,7 +218,7 @@ TEST(CodeRange) {
requested,
&allocated);
CHECK(base != NULL);
- blocks.Add(Block(base, static_cast<int>(allocated)));
+ blocks.Add(::Block(base, static_cast<int>(allocated)));
current_allocated += static_cast<int>(allocated);
total_allocated += static_cast<int>(allocated);
} else {
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index 14df05a8e..9ddc9db71 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -27,30 +27,30 @@
#include <climits>
#include <csignal>
-#include <string>
#include <map>
+#include <string>
-#include "v8.h"
+#include "src/v8.h"
#if V8_OS_POSIX
#include <unistd.h> // NOLINT
#endif
-#include "api.h"
-#include "arguments.h"
-#include "cctest.h"
-#include "compilation-cache.h"
-#include "cpu-profiler.h"
-#include "execution.h"
-#include "isolate.h"
-#include "objects.h"
-#include "parser.h"
-#include "platform.h"
-#include "snapshot.h"
-#include "unicode-inl.h"
-#include "utils.h"
-#include "vm-state.h"
-#include "../include/v8-util.h"
+#include "include/v8-util.h"
+#include "src/api.h"
+#include "src/arguments.h"
+#include "src/base/platform/platform.h"
+#include "src/compilation-cache.h"
+#include "src/cpu-profiler.h"
+#include "src/execution.h"
+#include "src/isolate.h"
+#include "src/objects.h"
+#include "src/parser.h"
+#include "src/snapshot.h"
+#include "src/unicode-inl.h"
+#include "src/utils.h"
+#include "src/vm-state.h"
+#include "test/cctest/cctest.h"
static const bool kLogThreading = false;
@@ -99,50 +99,6 @@ void RunWithProfiler(void (*test)()) {
}
-static void ExpectString(const char* code, const char* expected) {
- Local<Value> result = CompileRun(code);
- CHECK(result->IsString());
- String::Utf8Value utf8(result);
- CHECK_EQ(expected, *utf8);
-}
-
-
-static void ExpectInt32(const char* code, int expected) {
- Local<Value> result = CompileRun(code);
- CHECK(result->IsInt32());
- CHECK_EQ(expected, result->Int32Value());
-}
-
-
-static void ExpectBoolean(const char* code, bool expected) {
- Local<Value> result = CompileRun(code);
- CHECK(result->IsBoolean());
- CHECK_EQ(expected, result->BooleanValue());
-}
-
-
-static void ExpectTrue(const char* code) {
- ExpectBoolean(code, true);
-}
-
-
-static void ExpectFalse(const char* code) {
- ExpectBoolean(code, false);
-}
-
-
-static void ExpectObject(const char* code, Local<Value> expected) {
- Local<Value> result = CompileRun(code);
- CHECK(result->Equals(expected));
-}
-
-
-static void ExpectUndefined(const char* code) {
- Local<Value> result = CompileRun(code);
- CHECK(result->IsUndefined());
-}
-
-
static int signature_callback_count;
static Local<Value> signature_expected_receiver;
static void IncrementingSignatureCallback(
@@ -230,11 +186,11 @@ THREADED_TEST(IsolateOfContext) {
static void TestSignature(const char* loop_js, Local<Value> receiver) {
i::ScopedVector<char> source(200);
- i::OS::SNPrintF(source,
- "for (var i = 0; i < 10; i++) {"
- " %s"
- "}",
- loop_js);
+ i::SNPrintF(source,
+ "for (var i = 0; i < 10; i++) {"
+ " %s"
+ "}",
+ loop_js);
signature_callback_count = 0;
signature_expected_receiver = receiver;
bool expected_to_throw = receiver.IsEmpty();
@@ -307,7 +263,7 @@ THREADED_TEST(ReceiverSignature) {
unsigned bad_signature_start_offset = 2;
for (unsigned i = 0; i < ARRAY_SIZE(test_objects); i++) {
i::ScopedVector<char> source(200);
- i::OS::SNPrintF(
+ i::SNPrintF(
source, "var test_object = %s; test_object", test_objects[i]);
Local<Value> test_object = CompileRun(source.start());
TestSignature("test_object.prop();", test_object);
@@ -451,17 +407,10 @@ THREADED_TEST(Script) {
}
-static uint16_t* AsciiToTwoByteString(const char* source) {
- int array_length = i::StrLength(source) + 1;
- uint16_t* converted = i::NewArray<uint16_t>(array_length);
- for (int i = 0; i < array_length; i++) converted[i] = source[i];
- return converted;
-}
-
-
class TestResource: public String::ExternalStringResource {
public:
- TestResource(uint16_t* data, int* counter = NULL, bool owning_data = true)
+ explicit TestResource(uint16_t* data, int* counter = NULL,
+ bool owning_data = true)
: data_(data), length_(0), counter_(counter), owning_data_(owning_data) {
while (data[length_]) ++length_;
}
@@ -489,11 +438,12 @@ class TestResource: public String::ExternalStringResource {
class TestAsciiResource: public String::ExternalAsciiStringResource {
public:
- TestAsciiResource(const char* data, int* counter = NULL, size_t offset = 0)
+ explicit TestAsciiResource(const char* data, int* counter = NULL,
+ size_t offset = 0)
: orig_data_(data),
data_(data + offset),
length_(strlen(data) - offset),
- counter_(counter) { }
+ counter_(counter) {}
~TestAsciiResource() {
i::DeleteArray(orig_data_);
@@ -2004,6 +1954,27 @@ THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) {
}
+THREADED_TEST(ExecutableAccessorIsPreservedOnAttributeChange) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ LocalContext env;
+ v8::Local<v8::Value> res = CompileRun("var a = []; a;");
+ i::Handle<i::JSObject> a(v8::Utils::OpenHandle(v8::Object::Cast(*res)));
+ CHECK(a->map()->instance_descriptors()->IsFixedArray());
+ CHECK_GT(i::FixedArray::cast(a->map()->instance_descriptors())->length(), 0);
+ CompileRun("Object.defineProperty(a, 'length', { writable: false });");
+ CHECK_EQ(i::FixedArray::cast(a->map()->instance_descriptors())->length(), 0);
+ // But we should still have an ExecutableAccessorInfo.
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i::LookupResult lookup(i_isolate);
+ i::Handle<i::String> name(v8::Utils::OpenHandle(*v8_str("length")));
+ a->LookupOwnRealNamedProperty(name, &lookup);
+ CHECK(lookup.IsPropertyCallbacks());
+ i::Handle<i::Object> callback(lookup.GetCallbackObject(), i_isolate);
+ CHECK(callback->IsExecutableAccessorInfo());
+}
+
+
THREADED_TEST(EmptyInterceptorBreakTransitions) {
v8::HandleScope scope(CcTest::isolate());
Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
@@ -2768,8 +2739,6 @@ THREADED_TEST(GlobalProxyIdentityHash) {
THREADED_TEST(SymbolProperties) {
- i::FLAG_harmony_symbols = true;
-
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
@@ -2918,8 +2887,6 @@ THREADED_TEST(PrivateProperties) {
THREADED_TEST(GlobalSymbols) {
- i::FLAG_harmony_symbols = true;
-
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
@@ -3003,7 +2970,7 @@ THREADED_TEST(ArrayBuffer_ApiInternalToExternal) {
CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength()));
uint8_t* data = static_cast<uint8_t*>(ab_contents.Data());
- ASSERT(data != NULL);
+ DCHECK(data != NULL);
env->Global()->Set(v8_str("ab"), ab);
v8::Handle<v8::Value> result = CompileRun("ab.byteLength");
@@ -3112,7 +3079,7 @@ static void CheckIsNeutered(v8::Handle<v8::TypedArray> ta) {
static void CheckIsTypedArrayVarNeutered(const char* name) {
i::ScopedVector<char> source(1024);
- i::OS::SNPrintF(source,
+ i::SNPrintF(source,
"%s.byteLength == 0 && %s.byteOffset == 0 && %s.length == 0",
name, name, name);
CHECK(CompileRun(source.start())->IsTrue());
@@ -4184,7 +4151,7 @@ bool message_received;
static void check_message_0(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
CHECK_EQ(5.76, data->NumberValue());
- CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
+ CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue());
CHECK(!message->IsSharedCrossOrigin());
message_received = true;
}
@@ -4258,7 +4225,7 @@ TEST(MessageHandler2) {
static void check_message_3(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
CHECK(message->IsSharedCrossOrigin());
- CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
+ CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue());
message_received = true;
}
@@ -4287,7 +4254,7 @@ TEST(MessageHandler3) {
static void check_message_4(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
CHECK(!message->IsSharedCrossOrigin());
- CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
+ CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue());
message_received = true;
}
@@ -4316,7 +4283,7 @@ TEST(MessageHandler4) {
static void check_message_5a(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
CHECK(message->IsSharedCrossOrigin());
- CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
+ CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue());
message_received = true;
}
@@ -4324,7 +4291,7 @@ static void check_message_5a(v8::Handle<v8::Message> message,
static void check_message_5b(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
CHECK(!message->IsSharedCrossOrigin());
- CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
+ CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue());
message_received = true;
}
@@ -4404,7 +4371,7 @@ THREADED_TEST(PropertyAttributes) {
CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(prop));
// read-only
prop = v8_str("read_only");
- context->Global()->Set(prop, v8_num(7), v8::ReadOnly);
+ context->Global()->ForceSet(prop, v8_num(7), v8::ReadOnly);
CHECK_EQ(7, context->Global()->Get(prop)->Int32Value());
CHECK_EQ(v8::ReadOnly, context->Global()->GetPropertyAttributes(prop));
CompileRun("read_only = 9");
@@ -4413,14 +4380,14 @@ THREADED_TEST(PropertyAttributes) {
CHECK_EQ(7, context->Global()->Get(prop)->Int32Value());
// dont-delete
prop = v8_str("dont_delete");
- context->Global()->Set(prop, v8_num(13), v8::DontDelete);
+ context->Global()->ForceSet(prop, v8_num(13), v8::DontDelete);
CHECK_EQ(13, context->Global()->Get(prop)->Int32Value());
CompileRun("delete dont_delete");
CHECK_EQ(13, context->Global()->Get(prop)->Int32Value());
CHECK_EQ(v8::DontDelete, context->Global()->GetPropertyAttributes(prop));
// dont-enum
prop = v8_str("dont_enum");
- context->Global()->Set(prop, v8_num(28), v8::DontEnum);
+ context->Global()->ForceSet(prop, v8_num(28), v8::DontEnum);
CHECK_EQ(v8::DontEnum, context->Global()->GetPropertyAttributes(prop));
// absent
prop = v8_str("absent");
@@ -5343,15 +5310,28 @@ THREADED_TEST(TryCatchAndFinally) {
}
-static void TryCatchNestedHelper(int depth) {
+static void TryCatchNested1Helper(int depth) {
+ if (depth > 0) {
+ v8::TryCatch try_catch;
+ try_catch.SetVerbose(true);
+ TryCatchNested1Helper(depth - 1);
+ CHECK(try_catch.HasCaught());
+ try_catch.ReThrow();
+ } else {
+ CcTest::isolate()->ThrowException(v8_str("E1"));
+ }
+}
+
+
+static void TryCatchNested2Helper(int depth) {
if (depth > 0) {
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
- TryCatchNestedHelper(depth - 1);
+ TryCatchNested2Helper(depth - 1);
CHECK(try_catch.HasCaught());
try_catch.ReThrow();
} else {
- CcTest::isolate()->ThrowException(v8_str("back"));
+ CompileRun("throw 'E2';");
}
}
@@ -5360,17 +5340,29 @@ TEST(TryCatchNested) {
v8::V8::Initialize();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
- TryCatchNestedHelper(5);
- CHECK(try_catch.HasCaught());
- CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "back"));
+
+ {
+ // Test nested try-catch with a native throw in the end.
+ v8::TryCatch try_catch;
+ TryCatchNested1Helper(5);
+ CHECK(try_catch.HasCaught());
+ CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "E1"));
+ }
+
+ {
+ // Test nested try-catch with a JavaScript throw in the end.
+ v8::TryCatch try_catch;
+ TryCatchNested2Helper(5);
+ CHECK(try_catch.HasCaught());
+ CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "E2"));
+ }
}
void TryCatchMixedNestingCheck(v8::TryCatch* try_catch) {
CHECK(try_catch->HasCaught());
Handle<Message> message = try_catch->Message();
- Handle<Value> resource = message->GetScriptResourceName();
+ Handle<Value> resource = message->GetScriptOrigin().ResourceName();
CHECK_EQ(0, strcmp(*v8::String::Utf8Value(resource), "inner"));
CHECK_EQ(0, strcmp(*v8::String::Utf8Value(message->Get()),
"Uncaught Error: a"));
@@ -5409,6 +5401,53 @@ TEST(TryCatchMixedNesting) {
}
+void TryCatchNativeHelper(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ ApiTestFuzzer::Fuzz();
+ v8::TryCatch try_catch;
+ args.GetIsolate()->ThrowException(v8_str("boom"));
+ CHECK(try_catch.HasCaught());
+}
+
+
+TEST(TryCatchNative) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::V8::Initialize();
+ v8::TryCatch try_catch;
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->Set(v8_str("TryCatchNativeHelper"),
+ v8::FunctionTemplate::New(isolate, TryCatchNativeHelper));
+ LocalContext context(0, templ);
+ CompileRun("TryCatchNativeHelper();");
+ CHECK(!try_catch.HasCaught());
+}
+
+
+void TryCatchNativeResetHelper(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ ApiTestFuzzer::Fuzz();
+ v8::TryCatch try_catch;
+ args.GetIsolate()->ThrowException(v8_str("boom"));
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+ CHECK(!try_catch.HasCaught());
+}
+
+
+TEST(TryCatchNativeReset) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::V8::Initialize();
+ v8::TryCatch try_catch;
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->Set(v8_str("TryCatchNativeResetHelper"),
+ v8::FunctionTemplate::New(isolate, TryCatchNativeResetHelper));
+ LocalContext context(0, templ);
+ CompileRun("TryCatchNativeResetHelper();");
+ CHECK(!try_catch.HasCaught());
+}
+
+
THREADED_TEST(Equality) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
@@ -5430,7 +5469,7 @@ THREADED_TEST(Equality) {
CHECK(v8_num(1)->StrictEquals(v8_num(1)));
CHECK(!v8_num(1)->StrictEquals(v8_num(2)));
CHECK(v8_num(0.0)->StrictEquals(v8_num(-0.0)));
- Local<Value> not_a_number = v8_num(i::OS::nan_value());
+ Local<Value> not_a_number = v8_num(v8::base::OS::nan_value());
CHECK(!not_a_number->StrictEquals(not_a_number));
CHECK(v8::False(isolate)->StrictEquals(v8::False(isolate)));
CHECK(!v8::False(isolate)->StrictEquals(v8::Undefined(isolate)));
@@ -6162,15 +6201,17 @@ THREADED_TEST(IndexedInterceptorWithAccessorCheck) {
context->Global()->Set(v8_str("obj"), obj);
const char* code =
- "try {"
- " for (var i = 0; i < 100; i++) {"
+ "var result = 'PASSED';"
+ "for (var i = 0; i < 100; i++) {"
+ " try {"
" var v = obj[0];"
- " if (v != undefined) throw 'Wrong value ' + v + ' at iteration ' + i;"
+ " result = 'Wrong value ' + v + ' at iteration ' + i;"
+ " break;"
+ " } catch (e) {"
+ " /* pass */"
" }"
- " 'PASSED'"
- "} catch(e) {"
- " e"
- "}";
+ "}"
+ "result";
ExpectString(code, "PASSED");
}
@@ -6187,21 +6228,29 @@ THREADED_TEST(IndexedInterceptorWithAccessorCheckSwitchedOn) {
context->Global()->Set(v8_str("obj"), obj);
const char* code =
- "try {"
- " for (var i = 0; i < 100; i++) {"
- " var expected = i;"
+ "var result = 'PASSED';"
+ "for (var i = 0; i < 100; i++) {"
+ " var expected = i;"
+ " if (i == 5) {"
+ " %EnableAccessChecks(obj);"
+ " }"
+ " try {"
+ " var v = obj[i];"
" if (i == 5) {"
- " %EnableAccessChecks(obj);"
- " expected = undefined;"
+ " result = 'Should not have reached this!';"
+ " break;"
+ " } else if (v != expected) {"
+ " result = 'Wrong value ' + v + ' at iteration ' + i;"
+ " break;"
+ " }"
+ " } catch (e) {"
+ " if (i != 5) {"
+ " result = e;"
" }"
- " var v = obj[i];"
- " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
- " if (i == 5) %DisableAccessChecks(obj);"
" }"
- " 'PASSED'"
- "} catch(e) {"
- " e"
- "}";
+ " if (i == 5) %DisableAccessChecks(obj);"
+ "}"
+ "result";
ExpectString(code, "PASSED");
}
@@ -6670,9 +6719,6 @@ TEST(UndetectableOptimized) {
}
-template <typename T> static void USE(T) { }
-
-
// The point of this test is type checking. We run it only so compilers
// don't complain about an unused function.
TEST(PersistentHandles) {
@@ -6728,6 +6774,33 @@ TEST(SimpleExtensions) {
}
+static const char* kStackTraceFromExtensionSource =
+ "function foo() {"
+ " throw new Error();"
+ "}"
+ "function bar() {"
+ " foo();"
+ "}";
+
+
+TEST(StackTraceInExtension) {
+ v8::HandleScope handle_scope(CcTest::isolate());
+ v8::RegisterExtension(new Extension("stacktracetest",
+ kStackTraceFromExtensionSource));
+ const char* extension_names[] = { "stacktracetest" };
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Handle<Context> context =
+ Context::New(CcTest::isolate(), &extensions);
+ Context::Scope lock(context);
+ CompileRun("function user() { bar(); }"
+ "var error;"
+ "try{ user(); } catch (e) { error = e; }");
+ CHECK_EQ(-1, CompileRun("error.stack.indexOf('foo')")->Int32Value());
+ CHECK_EQ(-1, CompileRun("error.stack.indexOf('bar')")->Int32Value());
+ CHECK_NE(-1, CompileRun("error.stack.indexOf('user')")->Int32Value());
+}
+
+
TEST(NullExtensions) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("nulltest", NULL));
@@ -6764,7 +6837,7 @@ TEST(ExtensionWithSourceLength) {
source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) {
v8::HandleScope handle_scope(CcTest::isolate());
i::ScopedVector<char> extension_name(32);
- i::OS::SNPrintF(extension_name, "ext #%d", source_len);
+ i::SNPrintF(extension_name, "ext #%d", source_len);
v8::RegisterExtension(new Extension(extension_name.start(),
kEmbeddedExtensionSource, 0, 0,
source_len));
@@ -7144,8 +7217,9 @@ TEST(ErrorReporting) {
static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
- CHECK(message->GetScriptResourceName()->IsUndefined());
- CHECK_EQ(v8::Undefined(CcTest::isolate()), message->GetScriptResourceName());
+ CHECK(message->GetScriptOrigin().ResourceName()->IsUndefined());
+ CHECK_EQ(v8::Undefined(CcTest::isolate()),
+ message->GetScriptOrigin().ResourceName());
message->GetLineNumber();
message->GetSourceLine();
}
@@ -7924,7 +7998,7 @@ THREADED_TEST(StringWrite) {
static void Utf16Helper(
- LocalContext& context,
+ LocalContext& context, // NOLINT
const char* name,
const char* lengths_name,
int len) {
@@ -7951,7 +8025,7 @@ static uint16_t StringGet(Handle<String> str, int index) {
static void WriteUtf8Helper(
- LocalContext& context,
+ LocalContext& context, // NOLINT
const char* name,
const char* lengths_name,
int len) {
@@ -8330,9 +8404,9 @@ TEST(ApiUncaughtException) {
static const char* script_resource_name = "ExceptionInNativeScript.js";
static void ExceptionInNativeScriptTestListener(v8::Handle<v8::Message> message,
v8::Handle<Value>) {
- v8::Handle<v8::Value> name_val = message->GetScriptResourceName();
+ v8::Handle<v8::Value> name_val = message->GetScriptOrigin().ResourceName();
CHECK(!name_val.IsEmpty() && name_val->IsString());
- v8::String::Utf8Value name(message->GetScriptResourceName());
+ v8::String::Utf8Value name(message->GetScriptOrigin().ResourceName());
CHECK_EQ(script_resource_name, *name);
CHECK_EQ(3, message->GetLineNumber());
v8::String::Utf8Value source_line(message->GetSourceLine());
@@ -8396,6 +8470,41 @@ TEST(TryCatchFinallyUsingTryCatchHandler) {
}
+void CEvaluate(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ v8::HandleScope scope(args.GetIsolate());
+ CompileRun(args[0]->ToString());
+}
+
+
+TEST(TryCatchFinallyStoresMessageUsingTryCatchHandler) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->Set(v8_str("CEvaluate"),
+ v8::FunctionTemplate::New(isolate, CEvaluate));
+ LocalContext context(0, templ);
+ v8::TryCatch try_catch;
+ CompileRun("try {"
+ " CEvaluate('throw 1;');"
+ "} finally {"
+ "}");
+ CHECK(try_catch.HasCaught());
+ CHECK(!try_catch.Message().IsEmpty());
+ String::Utf8Value exception_value(try_catch.Exception());
+ CHECK_EQ(*exception_value, "1");
+ try_catch.Reset();
+ CompileRun("try {"
+ " CEvaluate('throw 1;');"
+ "} finally {"
+ " throw 2;"
+ "}");
+ CHECK(try_catch.HasCaught());
+ CHECK(!try_catch.Message().IsEmpty());
+ String::Utf8Value finally_exception_value(try_catch.Exception());
+ CHECK_EQ(*finally_exception_value, "2");
+}
+
+
// For use within the TestSecurityHandler() test.
static bool g_security_callback_result = false;
static bool NamedSecurityTestCallback(Local<v8::Object> global,
@@ -8552,10 +8661,8 @@ THREADED_TEST(SecurityChecksForPrototypeChain) {
v8::Local<Script> access_other0 = v8_compile("other.Object");
v8::Local<Script> access_other1 = v8_compile("other[42]");
for (int i = 0; i < 5; i++) {
- CHECK(!access_other0->Run()->Equals(other_object));
- CHECK(access_other0->Run()->IsUndefined());
- CHECK(!access_other1->Run()->Equals(v8_num(87)));
- CHECK(access_other1->Run()->IsUndefined());
+ CHECK(access_other0->Run().IsEmpty());
+ CHECK(access_other1->Run().IsEmpty());
}
// Create an object that has 'other' in its prototype chain and make
@@ -8567,10 +8674,8 @@ THREADED_TEST(SecurityChecksForPrototypeChain) {
v8::Local<Script> access_f0 = v8_compile("f.Object");
v8::Local<Script> access_f1 = v8_compile("f[42]");
for (int j = 0; j < 5; j++) {
- CHECK(!access_f0->Run()->Equals(other_object));
- CHECK(access_f0->Run()->IsUndefined());
- CHECK(!access_f1->Run()->Equals(v8_num(87)));
- CHECK(access_f1->Run()->IsUndefined());
+ CHECK(access_f0->Run().IsEmpty());
+ CHECK(access_f1->Run().IsEmpty());
}
// Now it gets hairy: Set the prototype for the other global object
@@ -8589,10 +8694,8 @@ THREADED_TEST(SecurityChecksForPrototypeChain) {
Local<Script> access_f2 = v8_compile("f.foo");
Local<Script> access_f3 = v8_compile("f[99]");
for (int k = 0; k < 5; k++) {
- CHECK(!access_f2->Run()->Equals(v8_num(100)));
- CHECK(access_f2->Run()->IsUndefined());
- CHECK(!access_f3->Run()->Equals(v8_num(101)));
- CHECK(access_f3->Run()->IsUndefined());
+ CHECK(access_f2->Run().IsEmpty());
+ CHECK(access_f3->Run().IsEmpty());
}
}
@@ -8673,7 +8776,7 @@ THREADED_TEST(CrossDomainDelete) {
Context::Scope scope_env2(env2);
Local<Value> result =
CompileRun("delete env1.prop");
- CHECK(result->IsFalse());
+ CHECK(result.IsEmpty());
}
// Check that env1.prop still exists.
@@ -8711,7 +8814,7 @@ THREADED_TEST(CrossDomainIsPropertyEnumerable) {
{
Context::Scope scope_env2(env2);
Local<Value> result = CompileRun(test);
- CHECK(result->IsFalse());
+ CHECK(result.IsEmpty());
}
}
@@ -8738,11 +8841,18 @@ THREADED_TEST(CrossDomainForIn) {
env2->SetSecurityToken(bar);
{
Context::Scope scope_env2(env2);
- Local<Value> result =
- CompileRun("(function(){var obj = {'__proto__':env1};"
- "for (var p in obj)"
- " if (p == 'prop') return false;"
- "return true;})()");
+ Local<Value> result = CompileRun(
+ "(function() {"
+ " var obj = { '__proto__': env1 };"
+ " try {"
+ " for (var p in obj) {"
+ " if (p == 'prop') return false;"
+ " }"
+ " return false;"
+ " } catch (e) {"
+ " return true;"
+ " }"
+ "})()");
CHECK(result->IsTrue());
}
}
@@ -8804,7 +8914,7 @@ TEST(ContextDetachGlobal) {
// Check that env3 is not accessible from env1
{
Local<Value> r = global3->Get(v8_str("prop2"));
- CHECK(r->IsUndefined());
+ CHECK(r.IsEmpty());
}
}
@@ -8843,7 +8953,7 @@ TEST(DetachGlobal) {
// Check that the global has been detached. No other.p property can
// be found.
result = CompileRun("other.p");
- CHECK(result->IsUndefined());
+ CHECK(result.IsEmpty());
// Reuse global2 for env3.
v8::Handle<Context> env3 = Context::New(env1->GetIsolate(),
@@ -8873,7 +8983,7 @@ TEST(DetachGlobal) {
// the global object for env3 which has a different security token,
// so access should be blocked.
result = CompileRun("other.p");
- CHECK(result->IsUndefined());
+ CHECK(result.IsEmpty());
}
@@ -8926,9 +9036,9 @@ TEST(DetachedAccesses) {
result = CompileRun("bound_x()");
CHECK_EQ(v8_str("env2_x"), result);
result = CompileRun("get_x()");
- CHECK(result->IsUndefined());
+ CHECK(result.IsEmpty());
result = CompileRun("get_x_w()");
- CHECK(result->IsUndefined());
+ CHECK(result.IsEmpty());
result = CompileRun("this_x()");
CHECK_EQ(v8_str("env2_x"), result);
@@ -9018,19 +9128,13 @@ static bool IndexedAccessBlocker(Local<v8::Object> global,
}
-static int g_echo_value_1 = -1;
-static int g_echo_value_2 = -1;
+static int g_echo_value = -1;
static void EchoGetter(
Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- info.GetReturnValue().Set(v8_num(g_echo_value_1));
-}
-
-
-static void EchoGetter(const v8::FunctionCallbackInfo<v8::Value>& info) {
- info.GetReturnValue().Set(v8_num(g_echo_value_2));
+ info.GetReturnValue().Set(v8_num(g_echo_value));
}
@@ -9038,14 +9142,7 @@ static void EchoSetter(Local<String> name,
Local<Value> value,
const v8::PropertyCallbackInfo<void>&) {
if (value->IsNumber())
- g_echo_value_1 = value->Int32Value();
-}
-
-
-static void EchoSetter(const v8::FunctionCallbackInfo<v8::Value>& info) {
- v8::Handle<v8::Value> value = info[0];
- if (value->IsNumber())
- g_echo_value_2 = value->Int32Value();
+ g_echo_value = value->Int32Value();
}
@@ -9086,13 +9183,6 @@ TEST(AccessControl) {
v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE));
- global_template->SetAccessorProperty(
- v8_str("accessible_js_prop"),
- v8::FunctionTemplate::New(isolate, EchoGetter),
- v8::FunctionTemplate::New(isolate, EchoSetter),
- v8::None,
- v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE));
-
// Add an accessor that is not accessible by cross-domain JS code.
global_template->SetAccessor(v8_str("blocked_prop"),
UnreachableGetter, UnreachableSetter,
@@ -9144,54 +9234,35 @@ TEST(AccessControl) {
// Access blocked property.
CompileRun("other.blocked_prop = 1");
- ExpectUndefined("other.blocked_prop");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'blocked_prop')");
- ExpectFalse("propertyIsEnumerable.call(other, 'blocked_prop')");
-
- // Enable ACCESS_HAS
- allowed_access_type[v8::ACCESS_HAS] = true;
- ExpectUndefined("other.blocked_prop");
- // ... and now we can get the descriptor...
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'blocked_prop').value");
- // ... and enumerate the property.
- ExpectTrue("propertyIsEnumerable.call(other, 'blocked_prop')");
- allowed_access_type[v8::ACCESS_HAS] = false;
+ CHECK(CompileRun("other.blocked_prop").IsEmpty());
+ CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, 'blocked_prop')")
+ .IsEmpty());
+ CHECK(
+ CompileRun("propertyIsEnumerable.call(other, 'blocked_prop')").IsEmpty());
// Access blocked element.
- CompileRun("other[239] = 1");
+ CHECK(CompileRun("other[239] = 1").IsEmpty());
- ExpectUndefined("other[239]");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '239')");
- ExpectFalse("propertyIsEnumerable.call(other, '239')");
+ CHECK(CompileRun("other[239]").IsEmpty());
+ CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, '239')").IsEmpty());
+ CHECK(CompileRun("propertyIsEnumerable.call(other, '239')").IsEmpty());
// Enable ACCESS_HAS
allowed_access_type[v8::ACCESS_HAS] = true;
- ExpectUndefined("other[239]");
+ CHECK(CompileRun("other[239]").IsEmpty());
// ... and now we can get the descriptor...
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '239').value");
+ CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, '239').value")
+ .IsEmpty());
// ... and enumerate the property.
ExpectTrue("propertyIsEnumerable.call(other, '239')");
allowed_access_type[v8::ACCESS_HAS] = false;
// Access a property with JS accessor.
- CompileRun("other.js_accessor_p = 2");
+ CHECK(CompileRun("other.js_accessor_p = 2").IsEmpty());
- ExpectUndefined("other.js_accessor_p");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p')");
-
- // Enable ACCESS_HAS.
- allowed_access_type[v8::ACCESS_HAS] = true;
- ExpectUndefined("other.js_accessor_p");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
- allowed_access_type[v8::ACCESS_HAS] = false;
+ CHECK(CompileRun("other.js_accessor_p").IsEmpty());
+ CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, 'js_accessor_p')")
+ .IsEmpty());
// Enable both ACCESS_HAS and ACCESS_GET.
allowed_access_type[v8::ACCESS_HAS] = true;
@@ -9200,59 +9271,19 @@ TEST(AccessControl) {
ExpectString("other.js_accessor_p", "getter");
ExpectObject(
"Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter);
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
-
- allowed_access_type[v8::ACCESS_GET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS and ACCESS_SET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_SET] = true;
-
- ExpectUndefined("other.js_accessor_p");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get");
ExpectObject(
"Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter);
ExpectUndefined(
"Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
- allowed_access_type[v8::ACCESS_SET] = false;
allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS, ACCESS_GET and ACCESS_SET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_GET] = true;
- allowed_access_type[v8::ACCESS_SET] = true;
-
- ExpectString("other.js_accessor_p", "getter");
- ExpectObject(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter);
- ExpectObject(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter);
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
-
- allowed_access_type[v8::ACCESS_SET] = false;
allowed_access_type[v8::ACCESS_GET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
// Access an element with JS accessor.
- CompileRun("other[42] = 2");
+ CHECK(CompileRun("other[42] = 2").IsEmpty());
- ExpectUndefined("other[42]");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42')");
-
- // Enable ACCESS_HAS.
- allowed_access_type[v8::ACCESS_HAS] = true;
- ExpectUndefined("other[42]");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').get");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').set");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
- allowed_access_type[v8::ACCESS_HAS] = false;
+ CHECK(CompileRun("other[42]").IsEmpty());
+ CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, '42')").IsEmpty());
// Enable both ACCESS_HAS and ACCESS_GET.
allowed_access_type[v8::ACCESS_HAS] = true;
@@ -9260,37 +9291,11 @@ TEST(AccessControl) {
ExpectString("other[42]", "el_getter");
ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter);
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').set");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
-
- allowed_access_type[v8::ACCESS_GET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS and ACCESS_SET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_SET] = true;
-
- ExpectUndefined("other[42]");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').get");
ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter);
ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
- allowed_access_type[v8::ACCESS_SET] = false;
allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS, ACCESS_GET and ACCESS_SET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_GET] = true;
- allowed_access_type[v8::ACCESS_SET] = true;
-
- ExpectString("other[42]", "el_getter");
- ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter);
- ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter);
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
-
- allowed_access_type[v8::ACCESS_SET] = false;
allowed_access_type[v8::ACCESS_GET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
v8::Handle<Value> value;
@@ -9298,50 +9303,38 @@ TEST(AccessControl) {
value = CompileRun("other.accessible_prop = 3");
CHECK(value->IsNumber());
CHECK_EQ(3, value->Int32Value());
- CHECK_EQ(3, g_echo_value_1);
-
- // Access accessible js property
- value = CompileRun("other.accessible_js_prop = 3");
- CHECK(value->IsNumber());
- CHECK_EQ(3, value->Int32Value());
- CHECK_EQ(3, g_echo_value_2);
+ CHECK_EQ(3, g_echo_value);
value = CompileRun("other.accessible_prop");
CHECK(value->IsNumber());
CHECK_EQ(3, value->Int32Value());
- value = CompileRun("other.accessible_js_prop");
- CHECK(value->IsNumber());
- CHECK_EQ(3, value->Int32Value());
-
value = CompileRun(
"Object.getOwnPropertyDescriptor(other, 'accessible_prop').value");
CHECK(value->IsNumber());
CHECK_EQ(3, value->Int32Value());
- value = CompileRun(
- "Object.getOwnPropertyDescriptor(other, 'accessible_js_prop').get()");
- CHECK(value->IsNumber());
- CHECK_EQ(3, value->Int32Value());
-
value = CompileRun("propertyIsEnumerable.call(other, 'accessible_prop')");
CHECK(value->IsTrue());
- value = CompileRun("propertyIsEnumerable.call(other, 'accessible_js_prop')");
- CHECK(value->IsTrue());
-
// Enumeration doesn't enumerate accessors from inaccessible objects in
// the prototype chain even if the accessors are in themselves accessible.
- value =
- CompileRun("(function(){var obj = {'__proto__':other};"
- "for (var p in obj)"
- " if (p == 'accessible_prop' ||"
- " p == 'accessible_js_prop' ||"
- " p == 'blocked_js_prop' ||"
- " p == 'blocked_js_prop') {"
- " return false;"
- " }"
- "return true;})()");
+ value = CompileRun(
+ "(function() {"
+ " var obj = { '__proto__': other };"
+ " try {"
+ " for (var p in obj) {"
+ " if (p == 'accessible_prop' ||"
+ " p == 'blocked_js_prop' ||"
+ " p == 'blocked_js_prop') {"
+ " return false;"
+ " }"
+ " }"
+ " return false;"
+ " } catch (e) {"
+ " return true;"
+ " }"
+ "})()");
CHECK(value->IsTrue());
context1->Exit();
@@ -9384,16 +9377,15 @@ TEST(AccessControlES5) {
global1->Set(v8_str("other"), global0);
// Regression test for issue 1154.
- ExpectTrue("Object.keys(other).indexOf('blocked_prop') == -1");
-
- ExpectUndefined("other.blocked_prop");
+ CHECK(CompileRun("Object.keys(other)").IsEmpty());
+ CHECK(CompileRun("other.blocked_prop").IsEmpty());
// Regression test for issue 1027.
CompileRun("Object.defineProperty(\n"
" other, 'blocked_prop', {configurable: false})");
- ExpectUndefined("other.blocked_prop");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'blocked_prop')");
+ CHECK(CompileRun("other.blocked_prop").IsEmpty());
+ CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, 'blocked_prop')")
+ .IsEmpty());
// Regression test for issue 1171.
ExpectTrue("Object.isExtensible(other)");
@@ -9411,7 +9403,7 @@ TEST(AccessControlES5) {
// Make sure that we can set the accessible accessors value using normal
// assignment.
CompileRun("other.accessible_prop = 42");
- CHECK_EQ(42, g_echo_value_1);
+ CHECK_EQ(42, g_echo_value);
v8::Handle<Value> value;
CompileRun("Object.defineProperty(other, 'accessible_prop', {value: -1})");
@@ -9469,10 +9461,10 @@ THREADED_TEST(AccessControlGetOwnPropertyNames) {
// proxy object. Accessing the object that requires access checks
// is blocked by the access checks on the object itself.
value = CompileRun("Object.getOwnPropertyNames(other).length == 0");
- CHECK(value->IsTrue());
+ CHECK(value.IsEmpty());
value = CompileRun("Object.getOwnPropertyNames(object).length == 0");
- CHECK(value->IsTrue());
+ CHECK(value.IsEmpty());
context1->Exit();
context0->Exit();
@@ -9580,7 +9572,7 @@ THREADED_TEST(CrossDomainAccessors) {
CHECK_EQ(10, value->Int32Value());
value = v8_compile("other.unreachable")->Run();
- CHECK(value->IsUndefined());
+ CHECK(value.IsEmpty());
context1->Exit();
context0->Exit();
@@ -10219,7 +10211,7 @@ THREADED_TEST(HiddenPrototypeIdentityHash) {
int hash = o->GetIdentityHash();
USE(hash);
o->Set(v8_str("foo"), v8_num(42));
- ASSERT_EQ(hash, o->GetIdentityHash());
+ DCHECK_EQ(hash, o->GetIdentityHash());
}
@@ -10282,7 +10274,7 @@ THREADED_TEST(SetPrototype) {
// Getting property names of an object with a prototype chain that
-// triggers dictionary elements in GetLocalPropertyNames() shouldn't
+// triggers dictionary elements in GetOwnPropertyNames() shouldn't
// crash the runtime.
THREADED_TEST(Regress91517) {
i::FLAG_allow_natives_syntax = true;
@@ -10307,7 +10299,7 @@ THREADED_TEST(Regress91517) {
// Force dictionary-based properties.
i::ScopedVector<char> name_buf(1024);
for (int i = 1; i <= 1000; i++) {
- i::OS::SNPrintF(name_buf, "sdf%d", i);
+ i::SNPrintF(name_buf, "sdf%d", i);
t2->InstanceTemplate()->Set(v8_str(name_buf.start()), v8_num(2));
}
@@ -10321,11 +10313,11 @@ THREADED_TEST(Regress91517) {
CHECK(o3->SetPrototype(o2));
CHECK(o2->SetPrototype(o1));
- // Call the runtime version of GetLocalPropertyNames() on the natively
+ // Call the runtime version of GetOwnPropertyNames() on the natively
// created object through JavaScript.
context->Global()->Set(v8_str("obj"), o4);
// PROPERTY_ATTRIBUTES_NONE = 0
- CompileRun("var names = %GetLocalPropertyNames(obj, 0);");
+ CompileRun("var names = %GetOwnPropertyNames(obj, 0);");
ExpectInt32("names.length", 1006);
ExpectTrue("names.indexOf(\"baz\") >= 0");
@@ -10376,12 +10368,12 @@ THREADED_TEST(Regress269562) {
o1->SetHiddenValue(
v8_str("h1"), v8::Integer::New(context->GetIsolate(), 2013));
- // Call the runtime version of GetLocalPropertyNames() on
+ // Call the runtime version of GetOwnPropertyNames() on
// the natively created object through JavaScript.
context->Global()->Set(v8_str("obj"), o2);
context->Global()->Set(v8_str("sym"), sym);
// PROPERTY_ATTRIBUTES_NONE = 0
- CompileRun("var names = %GetLocalPropertyNames(obj, 0);");
+ CompileRun("var names = %GetOwnPropertyNames(obj, 0);");
ExpectInt32("names.length", 7);
ExpectTrue("names.indexOf(\"foo\") >= 0");
@@ -10442,7 +10434,7 @@ THREADED_TEST(SetPrototypeThrows) {
v8::TryCatch try_catch;
CHECK(!o1->SetPrototype(o0));
CHECK(!try_catch.HasCaught());
- ASSERT(!CcTest::i_isolate()->has_pending_exception());
+ DCHECK(!CcTest::i_isolate()->has_pending_exception());
CHECK_EQ(42, CompileRun("function f() { return 42; }; f()")->Int32Value());
}
@@ -13027,7 +13019,7 @@ static void WebKitLike(Handle<Message> message, Handle<Value> data) {
Handle<String> errorMessageString = message->Get();
CHECK(!errorMessageString.IsEmpty());
message->GetStackTrace();
- message->GetScriptResourceName();
+ message->GetScriptOrigin().ResourceName();
}
@@ -13220,7 +13212,7 @@ THREADED_TEST(ObjectGetConstructorName) {
bool ApiTestFuzzer::fuzzing_ = false;
-i::Semaphore ApiTestFuzzer::all_tests_done_(0);
+v8::base::Semaphore ApiTestFuzzer::all_tests_done_(0);
int ApiTestFuzzer::active_tests_;
int ApiTestFuzzer::tests_being_run_;
int ApiTestFuzzer::current_;
@@ -13514,7 +13506,6 @@ THREADED_TEST(LockUnlockLock) {
static int GetGlobalObjectsCount() {
- CcTest::heap()->EnsureHeapIsIterable();
int count = 0;
i::HeapIterator it(CcTest::heap());
for (i::HeapObject* object = it.next(); object != NULL; object = it.next())
@@ -13549,21 +13540,21 @@ TEST(DontLeakGlobalObjects) {
{ v8::HandleScope scope(CcTest::isolate());
LocalContext context;
}
- v8::V8::ContextDisposedNotification();
+ CcTest::isolate()->ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
{ v8::HandleScope scope(CcTest::isolate());
LocalContext context;
v8_compile("Date")->Run();
}
- v8::V8::ContextDisposedNotification();
+ CcTest::isolate()->ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
{ v8::HandleScope scope(CcTest::isolate());
LocalContext context;
v8_compile("/aaa/")->Run();
}
- v8::V8::ContextDisposedNotification();
+ CcTest::isolate()->ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
{ v8::HandleScope scope(CcTest::isolate());
@@ -13572,7 +13563,7 @@ TEST(DontLeakGlobalObjects) {
LocalContext context(&extensions);
v8_compile("gc();")->Run();
}
- v8::V8::ContextDisposedNotification();
+ CcTest::isolate()->ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
}
}
@@ -14026,12 +14017,12 @@ void SetFunctionEntryHookTest::RunLoopInNewEnv(v8::Isolate* isolate) {
CompileRun(script);
bar_func_ = i::Handle<i::JSFunction>::cast(
v8::Utils::OpenHandle(*env->Global()->Get(v8_str("bar"))));
- ASSERT(!bar_func_.is_null());
+ DCHECK(!bar_func_.is_null());
foo_func_ =
i::Handle<i::JSFunction>::cast(
v8::Utils::OpenHandle(*env->Global()->Get(v8_str("foo"))));
- ASSERT(!foo_func_.is_null());
+ DCHECK(!foo_func_.is_null());
v8::Handle<v8::Value> value = CompileRun("bar();");
CHECK(value->IsNumber());
@@ -14424,7 +14415,7 @@ static void CheckTryCatchSourceInfo(v8::Handle<v8::Script> script,
CHECK_EQ(3, message->GetEndColumn());
v8::String::Utf8Value line(message->GetSourceLine());
CHECK_EQ(" throw 'nirk';", *line);
- v8::String::Utf8Value name(message->GetScriptResourceName());
+ v8::String::Utf8Value name(message->GetScriptOrigin().ResourceName());
CHECK_EQ(resource_name, *name);
}
@@ -14693,13 +14684,13 @@ THREADED_TEST(AccessChecksReenabledCorrectly) {
context->Global()->Set(v8_str("obj_1"), instance_1);
Local<Value> value_1 = CompileRun("obj_1.a");
- CHECK(value_1->IsUndefined());
+ CHECK(value_1.IsEmpty());
Local<v8::Object> instance_2 = templ->NewInstance();
context->Global()->Set(v8_str("obj_2"), instance_2);
Local<Value> value_2 = CompileRun("obj_2.a");
- CHECK(value_2->IsUndefined());
+ CHECK(value_2.IsEmpty());
}
@@ -14780,11 +14771,9 @@ THREADED_TEST(TurnOnAccessCheck) {
context->DetachGlobal();
hidden_global->TurnOnAccessCheck();
- // Failing access check to property get results in undefined.
- CHECK(f1->Call(global, 0, NULL)->IsUndefined());
- CHECK(f2->Call(global, 0, NULL)->IsUndefined());
-
- // Failing access check to function call results in exception.
+ // Failing access check results in exception.
+ CHECK(f1->Call(global, 0, NULL).IsEmpty());
+ CHECK(f2->Call(global, 0, NULL).IsEmpty());
CHECK(g1->Call(global, 0, NULL).IsEmpty());
CHECK(g2->Call(global, 0, NULL).IsEmpty());
@@ -14868,11 +14857,9 @@ THREADED_TEST(TurnOnAccessCheckAndRecompile) {
context->DetachGlobal();
hidden_global->TurnOnAccessCheck();
- // Failing access check to property get results in undefined.
- CHECK(f1->Call(global, 0, NULL)->IsUndefined());
- CHECK(f2->Call(global, 0, NULL)->IsUndefined());
-
- // Failing access check to function call results in exception.
+ // Failing access check results in exception.
+ CHECK(f1->Call(global, 0, NULL).IsEmpty());
+ CHECK(f2->Call(global, 0, NULL).IsEmpty());
CHECK(g1->Call(global, 0, NULL).IsEmpty());
CHECK(g2->Call(global, 0, NULL).IsEmpty());
@@ -14886,13 +14873,13 @@ THREADED_TEST(TurnOnAccessCheckAndRecompile) {
f2 = Local<Function>::Cast(hidden_global->Get(v8_str("f2")));
g1 = Local<Function>::Cast(hidden_global->Get(v8_str("g1")));
g2 = Local<Function>::Cast(hidden_global->Get(v8_str("g2")));
- CHECK(hidden_global->Get(v8_str("h"))->IsUndefined());
+ CHECK(hidden_global->Get(v8_str("h")).IsEmpty());
- // Failing access check to property get results in undefined.
- CHECK(f1->Call(global, 0, NULL)->IsUndefined());
- CHECK(f2->Call(global, 0, NULL)->IsUndefined());
-
- // Failing access check to function call results in exception.
+ // Failing access check results in exception.
+ v8::Local<v8::Value> result = f1->Call(global, 0, NULL);
+ CHECK(result.IsEmpty());
+ CHECK(f1->Call(global, 0, NULL).IsEmpty());
+ CHECK(f2->Call(global, 0, NULL).IsEmpty());
CHECK(g1->Call(global, 0, NULL).IsEmpty());
CHECK(g2->Call(global, 0, NULL).IsEmpty());
}
@@ -14909,137 +14896,24 @@ TEST(PreCompileSerialization) {
const char* script = "function foo(a) { return a+1; }";
v8::ScriptCompiler::Source source(v8_str(script));
v8::ScriptCompiler::Compile(isolate, &source,
- v8::ScriptCompiler::kProduceDataToCache);
+ v8::ScriptCompiler::kProduceParserCache);
// Serialize.
const v8::ScriptCompiler::CachedData* cd = source.GetCachedData();
- char* serialized_data = i::NewArray<char>(cd->length);
- i::OS::MemCopy(serialized_data, cd->data, cd->length);
+ i::byte* serialized_data = i::NewArray<i::byte>(cd->length);
+ i::MemCopy(serialized_data, cd->data, cd->length);
// Deserialize.
- i::ScriptData* deserialized = i::ScriptData::New(serialized_data, cd->length);
+ i::ScriptData* deserialized = new i::ScriptData(serialized_data, cd->length);
// Verify that the original is the same as the deserialized.
- CHECK_EQ(cd->length, deserialized->Length());
- CHECK_EQ(0, memcmp(cd->data, deserialized->Data(), cd->length));
+ CHECK_EQ(cd->length, deserialized->length());
+ CHECK_EQ(0, memcmp(cd->data, deserialized->data(), cd->length));
delete deserialized;
i::DeleteArray(serialized_data);
}
-// Attempts to deserialize bad data.
-TEST(PreCompileDeserializationError) {
- v8::V8::Initialize();
- const char* data = "DONT CARE";
- int invalid_size = 3;
- i::ScriptData* sd = i::ScriptData::New(data, invalid_size);
- CHECK_EQ(NULL, sd);
-}
-
-
-TEST(CompileWithInvalidCachedData) {
- v8::V8::Initialize();
- v8::Isolate* isolate = CcTest::isolate();
- LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- i::FLAG_min_preparse_length = 0;
-
- const char* script = "function foo(){ return 5;}\n"
- "function bar(){ return 6 + 7;} foo();";
- v8::ScriptCompiler::Source source(v8_str(script));
- v8::ScriptCompiler::Compile(isolate, &source,
- v8::ScriptCompiler::kProduceDataToCache);
- // source owns its cached data. Create a ScriptData based on it. The user
- // never needs to create ScriptDatas any more; we only need it here because we
- // want to modify the data before passing it back.
- const v8::ScriptCompiler::CachedData* cd = source.GetCachedData();
- // ScriptData does not take ownership of the buffers passed to it.
- i::ScriptData* sd =
- i::ScriptData::New(reinterpret_cast<const char*>(cd->data), cd->length);
- CHECK(!sd->HasError());
- // ScriptData private implementation details
- const int kHeaderSize = i::PreparseDataConstants::kHeaderSize;
- const int kFunctionEntrySize = i::FunctionEntry::kSize;
- const int kFunctionEntryStartOffset = 0;
- const int kFunctionEntryEndOffset = 1;
- unsigned* sd_data =
- reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data()));
-
- // Overwrite function bar's end position with 0.
- sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryEndOffset] = 0;
- v8::TryCatch try_catch;
-
- // Make the script slightly different so that we don't hit the compilation
- // cache. Don't change the lenghts of tokens.
- const char* script2 = "function foo(){ return 6;}\n"
- "function bar(){ return 6 + 7;} foo();";
- v8::ScriptCompiler::Source source2(
- v8_str(script2),
- // CachedData doesn't take ownership of the buffers, Source takes
- // ownership of CachedData.
- new v8::ScriptCompiler::CachedData(
- reinterpret_cast<const uint8_t*>(sd->Data()), sd->Length()));
- Local<v8::UnboundScript> compiled_script =
- v8::ScriptCompiler::CompileUnbound(isolate, &source2);
-
- CHECK(try_catch.HasCaught());
- {
- String::Utf8Value exception_value(try_catch.Message()->Get());
- CHECK_EQ("Uncaught SyntaxError: Invalid cached data for function bar",
- *exception_value);
- }
-
- try_catch.Reset();
- delete sd;
-
- // Overwrite function bar's start position with 200. The function entry will
- // not be found when searching for it by position, and the compilation fails.
-
- // ScriptData does not take ownership of the buffers passed to it.
- sd = i::ScriptData::New(reinterpret_cast<const char*>(cd->data), cd->length);
- sd_data = reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data()));
- sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryStartOffset] =
- 200;
- const char* script3 = "function foo(){ return 7;}\n"
- "function bar(){ return 6 + 7;} foo();";
- v8::ScriptCompiler::Source source3(
- v8_str(script3),
- new v8::ScriptCompiler::CachedData(
- reinterpret_cast<const uint8_t*>(sd->Data()), sd->Length()));
- compiled_script =
- v8::ScriptCompiler::CompileUnbound(isolate, &source3);
- CHECK(try_catch.HasCaught());
- {
- String::Utf8Value exception_value(try_catch.Message()->Get());
- CHECK_EQ("Uncaught SyntaxError: Invalid cached data for function bar",
- *exception_value);
- }
- CHECK(compiled_script.IsEmpty());
- try_catch.Reset();
- delete sd;
-
- // Try passing in cached data which is obviously invalid (wrong length).
- sd = i::ScriptData::New(reinterpret_cast<const char*>(cd->data), cd->length);
- const char* script4 =
- "function foo(){ return 8;}\n"
- "function bar(){ return 6 + 7;} foo();";
- v8::ScriptCompiler::Source source4(
- v8_str(script4),
- new v8::ScriptCompiler::CachedData(
- reinterpret_cast<const uint8_t*>(sd->Data()), sd->Length() - 1));
- compiled_script =
- v8::ScriptCompiler::CompileUnbound(isolate, &source4);
- CHECK(try_catch.HasCaught());
- {
- String::Utf8Value exception_value(try_catch.Message()->Get());
- CHECK_EQ("Uncaught SyntaxError: Invalid cached data",
- *exception_value);
- }
- CHECK(compiled_script.IsEmpty());
- delete sd;
-}
-
-
// This tests that we do not allow dictionary load/call inline caches
// to use functions that have not yet been compiled. The potential
// problem of loading a function that has not yet been compiled can
@@ -15283,19 +15157,19 @@ struct RegExpInterruptionData {
} regexp_interruption_data;
-class RegExpInterruptionThread : public i::Thread {
+class RegExpInterruptionThread : public v8::base::Thread {
public:
explicit RegExpInterruptionThread(v8::Isolate* isolate)
- : Thread("TimeoutThread"), isolate_(isolate) {}
+ : Thread(Options("TimeoutThread")), isolate_(isolate) {}
virtual void Run() {
for (regexp_interruption_data.loop_count = 0;
regexp_interruption_data.loop_count < 7;
regexp_interruption_data.loop_count++) {
- i::OS::Sleep(50); // Wait a bit before requesting GC.
+ v8::base::OS::Sleep(50); // Wait a bit before requesting GC.
reinterpret_cast<i::Isolate*>(isolate_)->stack_guard()->RequestGC();
}
- i::OS::Sleep(50); // Wait a bit before terminating.
+ v8::base::OS::Sleep(50); // Wait a bit before terminating.
v8::V8::TerminateExecution(isolate_);
}
@@ -15358,8 +15232,10 @@ TEST(ReadOnlyPropertyInGlobalProto) {
v8::Handle<v8::Object> global = context->Global();
v8::Handle<v8::Object> global_proto =
v8::Handle<v8::Object>::Cast(global->Get(v8_str("__proto__")));
- global_proto->Set(v8_str("x"), v8::Integer::New(isolate, 0), v8::ReadOnly);
- global_proto->Set(v8_str("y"), v8::Integer::New(isolate, 0), v8::ReadOnly);
+ global_proto->ForceSet(v8_str("x"), v8::Integer::New(isolate, 0),
+ v8::ReadOnly);
+ global_proto->ForceSet(v8_str("y"), v8::Integer::New(isolate, 0),
+ v8::ReadOnly);
// Check without 'eval' or 'with'.
v8::Handle<v8::Value> res =
CompileRun("function f() { x = 42; return x; }; f()");
@@ -15417,7 +15293,7 @@ TEST(ForceSet) {
// Ordinary properties
v8::Handle<v8::String> simple_property =
v8::String::NewFromUtf8(isolate, "p");
- global->Set(simple_property, v8::Int32::New(isolate, 4), v8::ReadOnly);
+ global->ForceSet(simple_property, v8::Int32::New(isolate, 4), v8::ReadOnly);
CHECK_EQ(4, global->Get(simple_property)->Int32Value());
// This should fail because the property is read-only
global->Set(simple_property, v8::Int32::New(isolate, 5));
@@ -15505,7 +15381,7 @@ THREADED_TEST(ForceDelete) {
// Ordinary properties
v8::Handle<v8::String> simple_property =
v8::String::NewFromUtf8(isolate, "p");
- global->Set(simple_property, v8::Int32::New(isolate, 4), v8::DontDelete);
+ global->ForceSet(simple_property, v8::Int32::New(isolate, 4), v8::DontDelete);
CHECK_EQ(4, global->Get(simple_property)->Int32Value());
// This should fail because the property is dont-delete.
CHECK(!global->Delete(simple_property));
@@ -15542,7 +15418,8 @@ THREADED_TEST(ForceDeleteWithInterceptor) {
v8::Handle<v8::String> some_property =
v8::String::NewFromUtf8(isolate, "a");
- global->Set(some_property, v8::Integer::New(isolate, 42), v8::DontDelete);
+ global->ForceSet(some_property, v8::Integer::New(isolate, 42),
+ v8::DontDelete);
// Deleting a property should get intercepted and nothing should
// happen.
@@ -15831,20 +15708,20 @@ THREADED_TEST(PixelArray) {
i::Handle<i::Object> no_failure;
no_failure = i::JSObject::SetElement(
jsobj, 1, value, NONE, i::SLOPPY).ToHandleChecked();
- ASSERT(!no_failure.is_null());
- i::USE(no_failure);
+ DCHECK(!no_failure.is_null());
+ USE(no_failure);
CheckElementValue(isolate, 2, jsobj, 1);
*value.location() = i::Smi::FromInt(256);
no_failure = i::JSObject::SetElement(
jsobj, 1, value, NONE, i::SLOPPY).ToHandleChecked();
- ASSERT(!no_failure.is_null());
- i::USE(no_failure);
+ DCHECK(!no_failure.is_null());
+ USE(no_failure);
CheckElementValue(isolate, 255, jsobj, 1);
*value.location() = i::Smi::FromInt(-1);
no_failure = i::JSObject::SetElement(
jsobj, 1, value, NONE, i::SLOPPY).ToHandleChecked();
- ASSERT(!no_failure.is_null());
- i::USE(no_failure);
+ DCHECK(!no_failure.is_null());
+ USE(no_failure);
CheckElementValue(isolate, 0, jsobj, 1);
result = CompileRun("for (var i = 0; i < 8; i++) {"
@@ -16316,15 +16193,15 @@ static void ObjectWithExternalArrayTestHelper(
" }"
"}"
"res;";
- i::OS::SNPrintF(test_buf,
- boundary_program,
- low);
+ i::SNPrintF(test_buf,
+ boundary_program,
+ low);
result = CompileRun(test_buf.start());
CHECK_EQ(low, result->IntegerValue());
- i::OS::SNPrintF(test_buf,
- boundary_program,
- high);
+ i::SNPrintF(test_buf,
+ boundary_program,
+ high);
result = CompileRun(test_buf.start());
CHECK_EQ(high, result->IntegerValue());
@@ -16344,28 +16221,28 @@ static void ObjectWithExternalArrayTestHelper(
CHECK_EQ(28, result->Int32Value());
// Make sure out-of-range loads do not throw.
- i::OS::SNPrintF(test_buf,
- "var caught_exception = false;"
- "try {"
- " ext_array[%d];"
- "} catch (e) {"
- " caught_exception = true;"
- "}"
- "caught_exception;",
- element_count);
+ i::SNPrintF(test_buf,
+ "var caught_exception = false;"
+ "try {"
+ " ext_array[%d];"
+ "} catch (e) {"
+ " caught_exception = true;"
+ "}"
+ "caught_exception;",
+ element_count);
result = CompileRun(test_buf.start());
CHECK_EQ(false, result->BooleanValue());
// Make sure out-of-range stores do not throw.
- i::OS::SNPrintF(test_buf,
- "var caught_exception = false;"
- "try {"
- " ext_array[%d] = 1;"
- "} catch (e) {"
- " caught_exception = true;"
- "}"
- "caught_exception;",
- element_count);
+ i::SNPrintF(test_buf,
+ "var caught_exception = false;"
+ "try {"
+ " ext_array[%d] = 1;"
+ "} catch (e) {"
+ " caught_exception = true;"
+ "}"
+ "caught_exception;",
+ element_count);
result = CompileRun(test_buf.start());
CHECK_EQ(false, result->BooleanValue());
@@ -16377,7 +16254,7 @@ static void ObjectWithExternalArrayTestHelper(
CHECK_EQ(0, result->Int32Value());
if (array_type == v8::kExternalFloat64Array ||
array_type == v8::kExternalFloat32Array) {
- CHECK_EQ(static_cast<int>(i::OS::nan_value()),
+ CHECK_EQ(static_cast<int>(v8::base::OS::nan_value()),
static_cast<int>(
i::Object::GetElement(
isolate, jsobj, 7).ToHandleChecked()->Number()));
@@ -16447,20 +16324,20 @@ static void ObjectWithExternalArrayTestHelper(
array_type == v8::kExternalUint32Array);
bool is_pixel_data = array_type == v8::kExternalUint8ClampedArray;
- i::OS::SNPrintF(test_buf,
- "%s"
- "var all_passed = true;"
- "for (var i = 0; i < source_data.length; i++) {"
- " for (var j = 0; j < 8; j++) {"
- " ext_array[j] = source_data[i];"
- " }"
- " all_passed = all_passed &&"
- " (ext_array[5] == expected_results[i]);"
- "}"
- "all_passed;",
- (is_unsigned ?
- unsigned_data :
- (is_pixel_data ? pixel_data : signed_data)));
+ i::SNPrintF(test_buf,
+ "%s"
+ "var all_passed = true;"
+ "for (var i = 0; i < source_data.length; i++) {"
+ " for (var j = 0; j < 8; j++) {"
+ " ext_array[j] = source_data[i];"
+ " }"
+ " all_passed = all_passed &&"
+ " (ext_array[5] == expected_results[i]);"
+ "}"
+ "all_passed;",
+ (is_unsigned ?
+ unsigned_data :
+ (is_pixel_data ? pixel_data : signed_data)));
result = CompileRun(test_buf.start());
CHECK_EQ(true, result->BooleanValue());
}
@@ -17215,7 +17092,7 @@ void AnalyzeStackInNativeCode(const v8::FunctionCallbackInfo<v8::Value>& args) {
const int kOverviewTest = 1;
const int kDetailedTest = 2;
- ASSERT(args.Length() == 1);
+ DCHECK(args.Length() == 1);
int testGroup = args[0]->Int32Value();
if (testGroup == kOverviewTest) {
@@ -17541,9 +17418,9 @@ TEST(SourceURLInStackTrace) {
"eval('(' + outer +')()%s');";
i::ScopedVector<char> code(1024);
- i::OS::SNPrintF(code, source, "//# sourceURL=eval_url");
+ i::SNPrintF(code, source, "//# sourceURL=eval_url");
CHECK(CompileRun(code.start())->IsUndefined());
- i::OS::SNPrintF(code, source, "//@ sourceURL=eval_url");
+ i::SNPrintF(code, source, "//@ sourceURL=eval_url");
CHECK(CompileRun(code.start())->IsUndefined());
}
@@ -17580,7 +17457,7 @@ TEST(ScriptIdInStackTrace) {
script->Run();
for (int i = 0; i < 2; i++) {
CHECK(scriptIdInStack[i] != v8::Message::kNoScriptIdInfo);
- CHECK_EQ(scriptIdInStack[i], script->GetId());
+ CHECK_EQ(scriptIdInStack[i], script->GetUnboundScript()->GetId());
}
}
@@ -17624,9 +17501,9 @@ TEST(InlineScriptWithSourceURLInStackTrace) {
"outer()\n%s";
i::ScopedVector<char> code(1024);
- i::OS::SNPrintF(code, source, "//# sourceURL=source_url");
+ i::SNPrintF(code, source, "//# sourceURL=source_url");
CHECK(CompileRunWithOrigin(code.start(), "url", 0, 1)->IsUndefined());
- i::OS::SNPrintF(code, source, "//@ sourceURL=source_url");
+ i::SNPrintF(code, source, "//@ sourceURL=source_url");
CHECK(CompileRunWithOrigin(code.start(), "url", 0, 1)->IsUndefined());
}
@@ -17670,9 +17547,9 @@ TEST(DynamicWithSourceURLInStackTrace) {
"outer()\n%s";
i::ScopedVector<char> code(1024);
- i::OS::SNPrintF(code, source, "//# sourceURL=source_url");
+ i::SNPrintF(code, source, "//# sourceURL=source_url");
CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined());
- i::OS::SNPrintF(code, source, "//@ sourceURL=source_url");
+ i::SNPrintF(code, source, "//@ sourceURL=source_url");
CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined());
}
@@ -17691,7 +17568,7 @@ TEST(DynamicWithSourceURLInStackTraceString) {
"outer()\n%s";
i::ScopedVector<char> code(1024);
- i::OS::SNPrintF(code, source, "//# sourceURL=source_url");
+ i::SNPrintF(code, source, "//# sourceURL=source_url");
v8::TryCatch try_catch;
CompileRunWithOrigin(code.start(), "", 0, 0);
CHECK(try_catch.HasCaught());
@@ -17700,6 +17577,54 @@ TEST(DynamicWithSourceURLInStackTraceString) {
}
+TEST(EvalWithSourceURLInMessageScriptResourceNameOrSourceURL) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+
+ const char *source =
+ "function outer() {\n"
+ " var scriptContents = \"function foo() { FAIL.FAIL; }\\\n"
+ " //# sourceURL=source_url\";\n"
+ " eval(scriptContents);\n"
+ " foo(); }\n"
+ "outer();\n"
+ "//# sourceURL=outer_url";
+
+ v8::TryCatch try_catch;
+ CompileRun(source);
+ CHECK(try_catch.HasCaught());
+
+ Local<v8::Message> message = try_catch.Message();
+ Handle<Value> sourceURL =
+ message->GetScriptOrigin().ResourceName();
+ CHECK_EQ(*v8::String::Utf8Value(sourceURL), "source_url");
+}
+
+
+TEST(RecursionWithSourceURLInMessageScriptResourceNameOrSourceURL) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+
+ const char *source =
+ "function outer() {\n"
+ " var scriptContents = \"function boo(){ boo(); }\\\n"
+ " //# sourceURL=source_url\";\n"
+ " eval(scriptContents);\n"
+ " boo(); }\n"
+ "outer();\n"
+ "//# sourceURL=outer_url";
+
+ v8::TryCatch try_catch;
+ CompileRun(source);
+ CHECK(try_catch.HasCaught());
+
+ Local<v8::Message> message = try_catch.Message();
+ Handle<Value> sourceURL =
+ message->GetScriptOrigin().ResourceName();
+ CHECK_EQ(*v8::String::Utf8Value(sourceURL), "source_url");
+}
+
+
static void CreateGarbageInOldSpace() {
i::Factory* factory = CcTest::i_isolate()->factory();
v8::HandleScope scope(CcTest::isolate());
@@ -17713,6 +17638,7 @@ static void CreateGarbageInOldSpace() {
// Test that idle notification can be handled and eventually returns true.
TEST(IdleNotification) {
const intptr_t MB = 1024 * 1024;
+ const int IdlePauseInMs = 1000;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
intptr_t initial_size = CcTest::heap()->SizeOfObjects();
@@ -17721,7 +17647,7 @@ TEST(IdleNotification) {
CHECK_GT(size_with_garbage, initial_size + MB);
bool finished = false;
for (int i = 0; i < 200 && !finished; i++) {
- finished = v8::V8::IdleNotification();
+ finished = env->GetIsolate()->IdleNotification(IdlePauseInMs);
}
intptr_t final_size = CcTest::heap()->SizeOfObjects();
CHECK(finished);
@@ -17741,7 +17667,7 @@ TEST(IdleNotificationWithSmallHint) {
CHECK_GT(size_with_garbage, initial_size + MB);
bool finished = false;
for (int i = 0; i < 200 && !finished; i++) {
- finished = v8::V8::IdleNotification(IdlePauseInMs);
+ finished = env->GetIsolate()->IdleNotification(IdlePauseInMs);
}
intptr_t final_size = CcTest::heap()->SizeOfObjects();
CHECK(finished);
@@ -17761,7 +17687,7 @@ TEST(IdleNotificationWithLargeHint) {
CHECK_GT(size_with_garbage, initial_size + MB);
bool finished = false;
for (int i = 0; i < 200 && !finished; i++) {
- finished = v8::V8::IdleNotification(IdlePauseInMs);
+ finished = env->GetIsolate()->IdleNotification(IdlePauseInMs);
}
intptr_t final_size = CcTest::heap()->SizeOfObjects();
CHECK(finished);
@@ -17778,7 +17704,7 @@ TEST(Regress2107) {
v8::HandleScope scope(env->GetIsolate());
intptr_t initial_size = CcTest::heap()->SizeOfObjects();
// Send idle notification to start a round of incremental GCs.
- v8::V8::IdleNotification(kShortIdlePauseInMs);
+ env->GetIsolate()->IdleNotification(kShortIdlePauseInMs);
// Emulate 7 page reloads.
for (int i = 0; i < 7; i++) {
{
@@ -17788,8 +17714,8 @@ TEST(Regress2107) {
CreateGarbageInOldSpace();
ctx->Exit();
}
- v8::V8::ContextDisposedNotification();
- v8::V8::IdleNotification(kLongIdlePauseInMs);
+ env->GetIsolate()->ContextDisposedNotification();
+ env->GetIsolate()->IdleNotification(kLongIdlePauseInMs);
}
// Create garbage and check that idle notification still collects it.
CreateGarbageInOldSpace();
@@ -17797,7 +17723,7 @@ TEST(Regress2107) {
CHECK_GT(size_with_garbage, initial_size + MB);
bool finished = false;
for (int i = 0; i < 200 && !finished; i++) {
- finished = v8::V8::IdleNotification(kShortIdlePauseInMs);
+ finished = env->GetIsolate()->IdleNotification(kShortIdlePauseInMs);
}
intptr_t final_size = CcTest::heap()->SizeOfObjects();
CHECK_LT(final_size, initial_size + 1);
@@ -18093,14 +18019,14 @@ TEST(ExternalInternalizedStringCollectedAtGC) {
static double DoubleFromBits(uint64_t value) {
double target;
- i::OS::MemCopy(&target, &value, sizeof(target));
+ i::MemCopy(&target, &value, sizeof(target));
return target;
}
static uint64_t DoubleToBits(double value) {
uint64_t target;
- i::OS::MemCopy(&target, &value, sizeof(target));
+ i::MemCopy(&target, &value, sizeof(target));
return target;
}
@@ -18108,7 +18034,7 @@ static uint64_t DoubleToBits(double value) {
static double DoubleToDateTime(double input) {
double date_limit = 864e13;
if (std::isnan(input) || input < -date_limit || input > date_limit) {
- return i::OS::nan_value();
+ return v8::base::OS::nan_value();
}
return (input < 0) ? -(std::floor(-input)) : std::floor(input);
}
@@ -18175,7 +18101,8 @@ THREADED_TEST(QuietSignalingNaNs) {
} else {
uint64_t stored_bits = DoubleToBits(stored_number);
// Check if quiet nan (bits 51..62 all set).
-#if defined(V8_TARGET_ARCH_MIPS) && !defined(USE_SIMULATOR)
+#if (defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64)) && \
+ !defined(_MIPS_ARCH_MIPS64R6) && !defined(USE_SIMULATOR)
// Most significant fraction bit for quiet nan is set to 0
// on MIPS architecture. Allowed by IEEE-754.
CHECK_EQ(0xffe, static_cast<int>((stored_bits >> 51) & 0xfff));
@@ -18195,7 +18122,8 @@ THREADED_TEST(QuietSignalingNaNs) {
} else {
uint64_t stored_bits = DoubleToBits(stored_date);
// Check if quiet nan (bits 51..62 all set).
-#if defined(V8_TARGET_ARCH_MIPS) && !defined(USE_SIMULATOR)
+#if (defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64)) && \
+ !defined(_MIPS_ARCH_MIPS64R6) && !defined(USE_SIMULATOR)
// Most significant fraction bit for quiet nan is set to 0
// on MIPS architecture. Allowed by IEEE-754.
CHECK_EQ(0xffe, static_cast<int>((stored_bits >> 51) & 0xfff));
@@ -18271,7 +18199,7 @@ TEST(Regress528) {
CompileRun(source_simple);
context->Exit();
}
- v8::V8::ContextDisposedNotification();
+ isolate->ContextDisposedNotification();
for (gc_count = 1; gc_count < 10; gc_count++) {
other_context->Enter();
CompileRun(source_simple);
@@ -18293,7 +18221,7 @@ TEST(Regress528) {
CompileRun(source_eval);
context->Exit();
}
- v8::V8::ContextDisposedNotification();
+ isolate->ContextDisposedNotification();
for (gc_count = 1; gc_count < 10; gc_count++) {
other_context->Enter();
CompileRun(source_eval);
@@ -18320,7 +18248,7 @@ TEST(Regress528) {
CHECK_EQ(1, message->GetLineNumber());
context->Exit();
}
- v8::V8::ContextDisposedNotification();
+ isolate->ContextDisposedNotification();
for (gc_count = 1; gc_count < 10; gc_count++) {
other_context->Enter();
CompileRun(source_exception);
@@ -18331,7 +18259,7 @@ TEST(Regress528) {
CHECK_GE(2, gc_count);
CHECK_EQ(1, GetGlobalObjectsCount());
- v8::V8::ContextDisposedNotification();
+ isolate->ContextDisposedNotification();
}
@@ -18511,8 +18439,8 @@ THREADED_TEST(FunctionGetScriptId) {
env->Global()->Get(v8::String::NewFromUtf8(isolate, "foo")));
v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::NewFromUtf8(isolate, "bar")));
- CHECK_EQ(script->GetId(), foo->ScriptId());
- CHECK_EQ(script->GetId(), bar->ScriptId());
+ CHECK_EQ(script->GetUnboundScript()->GetId(), foo->ScriptId());
+ CHECK_EQ(script->GetUnboundScript()->GetId(), bar->ScriptId());
}
@@ -18586,8 +18514,7 @@ TEST(SetterOnConstructorPrototype) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetAccessor(v8_str("x"),
- GetterWhichReturns42,
+ templ->SetAccessor(v8_str("x"), GetterWhichReturns42,
SetterWhichSetsYOnThisTo23);
LocalContext context;
context->Global()->Set(v8_str("P"), templ->NewInstance());
@@ -18700,8 +18627,7 @@ TEST(Regress618) {
// Use an API object with accessors as prototype.
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetAccessor(v8_str("x"),
- GetterWhichReturns42,
+ templ->SetAccessor(v8_str("x"), GetterWhichReturns42,
SetterWhichSetsYOnThisTo23);
context->Global()->Set(v8_str("P"), templ->NewInstance());
@@ -19252,7 +19178,7 @@ TEST(GCInFailedAccessCheckCallback) {
ExpectUndefined("Object.prototype.__lookupGetter__.call("
" other, \'x\')");
- // HasLocalElement.
+ // HasOwnElement.
ExpectFalse("Object.prototype.hasOwnProperty.call(other, \'0\')");
CHECK_EQ(false, global0->HasRealIndexedProperty(0));
@@ -19269,7 +19195,6 @@ TEST(IsolateNewDispose) {
v8::Isolate* current_isolate = CcTest::isolate();
v8::Isolate* isolate = v8::Isolate::New();
CHECK(isolate != NULL);
- CHECK(!reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate());
CHECK(current_isolate != isolate);
CHECK(current_isolate == CcTest::isolate());
@@ -19430,23 +19355,23 @@ static int CalcFibonacci(v8::Isolate* isolate, int limit) {
v8::HandleScope scope(isolate);
LocalContext context(isolate);
i::ScopedVector<char> code(1024);
- i::OS::SNPrintF(code, "function fib(n) {"
- " if (n <= 2) return 1;"
- " return fib(n-1) + fib(n-2);"
- "}"
- "fib(%d)", limit);
+ i::SNPrintF(code, "function fib(n) {"
+ " if (n <= 2) return 1;"
+ " return fib(n-1) + fib(n-2);"
+ "}"
+ "fib(%d)", limit);
Local<Value> value = CompileRun(code.start());
CHECK(value->IsNumber());
return static_cast<int>(value->NumberValue());
}
-class IsolateThread : public v8::internal::Thread {
+class IsolateThread : public v8::base::Thread {
public:
IsolateThread(v8::Isolate* isolate, int fib_limit)
- : Thread("IsolateThread"),
+ : Thread(Options("IsolateThread")),
isolate_(isolate),
fib_limit_(fib_limit),
- result_(0) { }
+ result_(0) {}
void Run() {
result_ = CalcFibonacci(isolate_, fib_limit_);
@@ -19514,7 +19439,7 @@ TEST(IsolateDifferentContexts) {
isolate->Dispose();
}
-class InitDefaultIsolateThread : public v8::internal::Thread {
+class InitDefaultIsolateThread : public v8::base::Thread {
public:
enum TestCase {
SetResourceConstraints,
@@ -19525,19 +19450,18 @@ class InitDefaultIsolateThread : public v8::internal::Thread {
};
explicit InitDefaultIsolateThread(TestCase testCase)
- : Thread("InitDefaultIsolateThread"),
+ : Thread(Options("InitDefaultIsolateThread")),
testCase_(testCase),
- result_(false) { }
+ result_(false) {}
void Run() {
v8::Isolate* isolate = v8::Isolate::New();
isolate->Enter();
switch (testCase_) {
case SetResourceConstraints: {
- static const int K = 1024;
v8::ResourceConstraints constraints;
- constraints.set_max_new_space_size(2 * K * K);
- constraints.set_max_old_space_size(4 * K * K);
+ constraints.set_max_semi_space_size(1);
+ constraints.set_max_old_space_size(4);
v8::SetResourceConstraints(CcTest::isolate(), &constraints);
break;
}
@@ -19547,15 +19471,15 @@ class InitDefaultIsolateThread : public v8::internal::Thread {
break;
case SetCounterFunction:
- v8::V8::SetCounterFunction(NULL);
+ CcTest::isolate()->SetCounterFunction(NULL);
break;
case SetCreateHistogramFunction:
- v8::V8::SetCreateHistogramFunction(NULL);
+ CcTest::isolate()->SetCreateHistogramFunction(NULL);
break;
case SetAddHistogramSampleFunction:
- v8::V8::SetAddHistogramSampleFunction(NULL);
+ CcTest::isolate()->SetAddHistogramSampleFunction(NULL);
break;
}
isolate->Exit();
@@ -19749,7 +19673,7 @@ TEST(DontDeleteCellLoadICAPI) {
// cell created using the API.
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- context->Global()->Set(v8_str("cell"), v8_str("value"), v8::DontDelete);
+ context->Global()->ForceSet(v8_str("cell"), v8_str("value"), v8::DontDelete);
ExpectBoolean("delete cell", false);
CompileRun(function_code);
ExpectString("readCell()", "value");
@@ -19832,6 +19756,7 @@ TEST(PersistentHandleInNewSpaceVisitor) {
CHECK_EQ(42, object1.WrapperClassId());
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
v8::Persistent<v8::Object> object2(isolate, v8::Object::New(isolate));
CHECK_EQ(0, object2.WrapperClassId());
@@ -20345,15 +20270,15 @@ THREADED_TEST(ReadOnlyIndexedProperties) {
LocalContext context;
Local<v8::Object> obj = templ->NewInstance();
context->Global()->Set(v8_str("obj"), obj);
- obj->Set(v8_str("1"), v8_str("DONT_CHANGE"), v8::ReadOnly);
+ obj->ForceSet(v8_str("1"), v8_str("DONT_CHANGE"), v8::ReadOnly);
obj->Set(v8_str("1"), v8_str("foobar"));
CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_str("1")));
- obj->Set(v8_num(2), v8_str("DONT_CHANGE"), v8::ReadOnly);
+ obj->ForceSet(v8_num(2), v8_str("DONT_CHANGE"), v8::ReadOnly);
obj->Set(v8_num(2), v8_str("foobar"));
CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_num(2)));
// Test non-smi case.
- obj->Set(v8_str("2000000000"), v8_str("DONT_CHANGE"), v8::ReadOnly);
+ obj->ForceSet(v8_str("2000000000"), v8_str("DONT_CHANGE"), v8::ReadOnly);
obj->Set(v8_str("2000000000"), v8_str("foobar"));
CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_str("2000000000")));
}
@@ -20477,20 +20402,20 @@ THREADED_TEST(Regress93759) {
CHECK(result1->Equals(simple_object->GetPrototype()));
Local<Value> result2 = CompileRun("Object.getPrototypeOf(protected)");
- CHECK(result2->Equals(Undefined(isolate)));
+ CHECK(result2.IsEmpty());
Local<Value> result3 = CompileRun("Object.getPrototypeOf(global)");
CHECK(result3->Equals(global_object->GetPrototype()));
Local<Value> result4 = CompileRun("Object.getPrototypeOf(proxy)");
- CHECK(result4->Equals(Undefined(isolate)));
+ CHECK(result4.IsEmpty());
Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)");
CHECK(result5->Equals(
object_with_hidden->GetPrototype()->ToObject()->GetPrototype()));
Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)");
- CHECK(result6->Equals(Undefined(isolate)));
+ CHECK(result6.IsEmpty());
}
@@ -20624,13 +20549,13 @@ uint8_t callback_fired = 0;
void CallCompletedCallback1() {
- i::OS::Print("Firing callback 1.\n");
+ v8::base::OS::Print("Firing callback 1.\n");
callback_fired ^= 1; // Toggle first bit.
}
void CallCompletedCallback2() {
- i::OS::Print("Firing callback 2.\n");
+ v8::base::OS::Print("Firing callback 2.\n");
callback_fired ^= 2; // Toggle second bit.
}
@@ -20639,15 +20564,15 @@ void RecursiveCall(const v8::FunctionCallbackInfo<v8::Value>& args) {
int32_t level = args[0]->Int32Value();
if (level < 3) {
level++;
- i::OS::Print("Entering recursion level %d.\n", level);
+ v8::base::OS::Print("Entering recursion level %d.\n", level);
char script[64];
i::Vector<char> script_vector(script, sizeof(script));
- i::OS::SNPrintF(script_vector, "recursion(%d)", level);
+ i::SNPrintF(script_vector, "recursion(%d)", level);
CompileRun(script_vector.start());
- i::OS::Print("Leaving recursion level %d.\n", level);
+ v8::base::OS::Print("Leaving recursion level %d.\n", level);
CHECK_EQ(0, callback_fired);
} else {
- i::OS::Print("Recursion ends.\n");
+ v8::base::OS::Print("Recursion ends.\n");
CHECK_EQ(0, callback_fired);
}
}
@@ -20664,19 +20589,19 @@ TEST(CallCompletedCallback) {
env->GetIsolate()->AddCallCompletedCallback(CallCompletedCallback1);
env->GetIsolate()->AddCallCompletedCallback(CallCompletedCallback1);
env->GetIsolate()->AddCallCompletedCallback(CallCompletedCallback2);
- i::OS::Print("--- Script (1) ---\n");
+ v8::base::OS::Print("--- Script (1) ---\n");
Local<Script> script = v8::Script::Compile(
v8::String::NewFromUtf8(env->GetIsolate(), "recursion(0)"));
script->Run();
CHECK_EQ(3, callback_fired);
- i::OS::Print("\n--- Script (2) ---\n");
+ v8::base::OS::Print("\n--- Script (2) ---\n");
callback_fired = 0;
env->GetIsolate()->RemoveCallCompletedCallback(CallCompletedCallback1);
script->Run();
CHECK_EQ(2, callback_fired);
- i::OS::Print("\n--- Function ---\n");
+ v8::base::OS::Print("\n--- Function ---\n");
callback_fired = 0;
Local<Function> recursive_function =
Local<Function>::Cast(env->Global()->Get(v8_str("recursion")));
@@ -20726,6 +20651,14 @@ static void MicrotaskTwo(const v8::FunctionCallbackInfo<Value>& info) {
}
+void* g_passed_to_three = NULL;
+
+
+static void MicrotaskThree(void* data) {
+ g_passed_to_three = data;
+}
+
+
TEST(EnqueueMicrotask) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -20759,6 +20692,62 @@ TEST(EnqueueMicrotask) {
CompileRun("1+1;");
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value());
+
+ g_passed_to_three = NULL;
+ env->GetIsolate()->EnqueueMicrotask(MicrotaskThree);
+ CompileRun("1+1;");
+ CHECK_EQ(NULL, g_passed_to_three);
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value());
+
+ int dummy;
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskOne));
+ env->GetIsolate()->EnqueueMicrotask(MicrotaskThree, &dummy);
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskTwo));
+ CompileRun("1+1;");
+ CHECK_EQ(&dummy, g_passed_to_three);
+ CHECK_EQ(3, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value());
+ g_passed_to_three = NULL;
+}
+
+
+static void MicrotaskExceptionOne(
+ const v8::FunctionCallbackInfo<Value>& info) {
+ v8::HandleScope scope(info.GetIsolate());
+ CompileRun("exception1Calls++;");
+ info.GetIsolate()->ThrowException(
+ v8::Exception::Error(v8_str("first")));
+}
+
+
+static void MicrotaskExceptionTwo(
+ const v8::FunctionCallbackInfo<Value>& info) {
+ v8::HandleScope scope(info.GetIsolate());
+ CompileRun("exception2Calls++;");
+ info.GetIsolate()->ThrowException(
+ v8::Exception::Error(v8_str("second")));
+}
+
+
+TEST(RunMicrotasksIgnoresThrownExceptions) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ CompileRun(
+ "var exception1Calls = 0;"
+ "var exception2Calls = 0;");
+ isolate->EnqueueMicrotask(
+ Function::New(isolate, MicrotaskExceptionOne));
+ isolate->EnqueueMicrotask(
+ Function::New(isolate, MicrotaskExceptionTwo));
+ TryCatch try_catch;
+ CompileRun("1+1;");
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(1, CompileRun("exception1Calls")->Int32Value());
+ CHECK_EQ(1, CompileRun("exception2Calls")->Int32Value());
}
@@ -20823,6 +20812,57 @@ TEST(SetAutorunMicrotasks) {
}
+TEST(RunMicrotasksWithoutEnteringContext) {
+ v8::Isolate* isolate = CcTest::isolate();
+ HandleScope handle_scope(isolate);
+ isolate->SetAutorunMicrotasks(false);
+ Handle<Context> context = Context::New(isolate);
+ {
+ Context::Scope context_scope(context);
+ CompileRun("var ext1Calls = 0;");
+ isolate->EnqueueMicrotask(Function::New(isolate, MicrotaskOne));
+ }
+ isolate->RunMicrotasks();
+ {
+ Context::Scope context_scope(context);
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value());
+ }
+ isolate->SetAutorunMicrotasks(true);
+}
+
+
+static void DebugEventInObserver(const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ if (event != v8::Break) return;
+ Handle<Object> exec_state = event_details.GetExecutionState();
+ Handle<Value> break_id = exec_state->Get(v8_str("break_id"));
+ CompileRun("function f(id) { new FrameDetails(id, 0); }");
+ Handle<Function> fun = Handle<Function>::Cast(
+ CcTest::global()->Get(v8_str("f"))->ToObject());
+ fun->Call(CcTest::global(), 1, &break_id);
+}
+
+
+TEST(Regress385349) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ HandleScope handle_scope(isolate);
+ isolate->SetAutorunMicrotasks(false);
+ Handle<Context> context = Context::New(isolate);
+ v8::Debug::SetDebugEventListener(DebugEventInObserver);
+ {
+ Context::Scope context_scope(context);
+ CompileRun("var obj = {};"
+ "Object.observe(obj, function(changes) { debugger; });"
+ "obj.a = 0;");
+ }
+ isolate->RunMicrotasks();
+ isolate->SetAutorunMicrotasks(true);
+ v8::Debug::SetDebugEventListener(NULL);
+}
+
+
+#ifdef DEBUG
static int probes_counter = 0;
static int misses_counter = 0;
static int updates_counter = 0;
@@ -20852,11 +20892,10 @@ static const char* kMegamorphicTestProgram =
" fooify(a);"
" fooify(b);"
"}";
+#endif
static void StubCacheHelper(bool primary) {
- V8::SetCounterFunction(LookupCounter);
- USE(kMegamorphicTestProgram);
#ifdef DEBUG
i::FLAG_native_code_counters = true;
if (primary) {
@@ -20866,6 +20905,7 @@ static void StubCacheHelper(bool primary) {
}
i::FLAG_crankshaft = false;
LocalContext env;
+ env->GetIsolate()->SetCounterFunction(LookupCounter);
v8::HandleScope scope(env->GetIsolate());
int initial_probes = probes_counter;
int initial_misses = misses_counter;
@@ -20895,6 +20935,7 @@ TEST(PrimaryStubCache) {
}
+#ifdef DEBUG
static int cow_arrays_created_runtime = 0;
@@ -20904,13 +20945,14 @@ static int* LookupCounterCOWArrays(const char* name) {
}
return NULL;
}
+#endif
TEST(CheckCOWArraysCreatedRuntimeCounter) {
- V8::SetCounterFunction(LookupCounterCOWArrays);
#ifdef DEBUG
i::FLAG_native_code_counters = true;
LocalContext env;
+ env->GetIsolate()->SetCounterFunction(LookupCounterCOWArrays);
v8::HandleScope scope(env->GetIsolate());
int initial_cow_arrays = cow_arrays_created_runtime;
CompileRun("var o = [1, 2, 3];");
@@ -21001,8 +21043,7 @@ static void InstanceCheckedSetter(Local<String> name,
}
-static void CheckInstanceCheckedResult(int getters,
- int setters,
+static void CheckInstanceCheckedResult(int getters, int setters,
bool expects_callbacks,
TryCatch* try_catch) {
if (expects_callbacks) {
@@ -21125,10 +21166,8 @@ THREADED_TEST(InstanceCheckOnPrototypeAccessor) {
Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate());
Local<ObjectTemplate> proto = templ->PrototypeTemplate();
- proto->SetAccessor(v8_str("foo"),
- InstanceCheckedGetter, InstanceCheckedSetter,
- Handle<Value>(),
- v8::DEFAULT,
+ proto->SetAccessor(v8_str("foo"), InstanceCheckedGetter,
+ InstanceCheckedSetter, Handle<Value>(), v8::DEFAULT,
v8::None,
v8::AccessorSignature::New(context->GetIsolate(), templ));
context->Global()->Set(v8_str("f"), templ->GetFunction());
@@ -21394,7 +21433,6 @@ THREADED_TEST(Regress157124) {
THREADED_TEST(Regress2535) {
- i::FLAG_harmony_collections = true;
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
Local<Value> set_value = CompileRun("new Set();");
@@ -21469,16 +21507,16 @@ class ThreadInterruptTest {
private:
static const int kExpectedValue = 1;
- class InterruptThread : public i::Thread {
+ class InterruptThread : public v8::base::Thread {
public:
explicit InterruptThread(ThreadInterruptTest* test)
- : Thread("InterruptThread"), test_(test) {}
+ : Thread(Options("InterruptThread")), test_(test) {}
virtual void Run() {
struct sigaction action;
// Ensure that we'll enter waiting condition
- i::OS::Sleep(100);
+ v8::base::OS::Sleep(100);
// Setup signal handler
memset(&action, 0, sizeof(action));
@@ -21489,7 +21527,7 @@ class ThreadInterruptTest {
kill(getpid(), SIGCHLD);
// Ensure that if wait has returned because of error
- i::OS::Sleep(100);
+ v8::base::OS::Sleep(100);
// Set value and signal semaphore
test_->sem_value_ = 1;
@@ -21503,7 +21541,7 @@ class ThreadInterruptTest {
ThreadInterruptTest* test_;
};
- i::Semaphore sem_;
+ v8::base::Semaphore sem_;
volatile int sem_value_;
};
@@ -21570,11 +21608,9 @@ TEST(JSONStringifyAccessCheck) {
LocalContext context1(NULL, global_template);
context1->Global()->Set(v8_str("other"), global0);
- ExpectString("JSON.stringify(other)", "{}");
- ExpectString("JSON.stringify({ 'a' : other, 'b' : ['c'] })",
- "{\"a\":{},\"b\":[\"c\"]}");
- ExpectString("JSON.stringify([other, 'b', 'c'])",
- "[{},\"b\",\"c\"]");
+ CHECK(CompileRun("JSON.stringify(other)").IsEmpty());
+ CHECK(CompileRun("JSON.stringify({ 'a' : other, 'b' : ['c'] })").IsEmpty());
+ CHECK(CompileRun("JSON.stringify([other, 'b', 'c'])").IsEmpty());
v8::Handle<v8::Array> array = v8::Array::New(isolate, 2);
array->Set(0, v8_str("a"));
@@ -21582,9 +21618,9 @@ TEST(JSONStringifyAccessCheck) {
context1->Global()->Set(v8_str("array"), array);
ExpectString("JSON.stringify(array)", "[\"a\",\"b\"]");
array->TurnOnAccessCheck();
- ExpectString("JSON.stringify(array)", "[]");
- ExpectString("JSON.stringify([array])", "[[]]");
- ExpectString("JSON.stringify({'a' : array})", "{\"a\":[]}");
+ CHECK(CompileRun("JSON.stringify(array)").IsEmpty());
+ CHECK(CompileRun("JSON.stringify([array])").IsEmpty());
+ CHECK(CompileRun("JSON.stringify({'a' : array})").IsEmpty());
}
}
@@ -21624,7 +21660,7 @@ void CheckCorrectThrow(const char* script) {
access_check_fail_thrown = false;
catch_callback_called = false;
i::ScopedVector<char> source(1024);
- i::OS::SNPrintF(source, "try { %s; } catch (e) { catcher(e); }", script);
+ i::SNPrintF(source, "try { %s; } catch (e) { catcher(e); }", script);
CompileRun(source.start());
CHECK(access_check_fail_thrown);
CHECK(catch_callback_called);
@@ -21682,18 +21718,18 @@ TEST(AccessCheckThrows) {
CheckCorrectThrow("JSON.stringify(other)");
CheckCorrectThrow("has_own_property(other, 'x')");
CheckCorrectThrow("%GetProperty(other, 'x')");
- CheckCorrectThrow("%SetProperty(other, 'x', 'foo', 1, 0)");
- CheckCorrectThrow("%IgnoreAttributesAndSetProperty(other, 'x', 'foo')");
+ CheckCorrectThrow("%SetProperty(other, 'x', 'foo', 0)");
+ CheckCorrectThrow("%AddNamedProperty(other, 'x', 'foo', 1)");
CheckCorrectThrow("%DeleteProperty(other, 'x', 0)");
CheckCorrectThrow("%DeleteProperty(other, '1', 0)");
- CheckCorrectThrow("%HasLocalProperty(other, 'x')");
+ CheckCorrectThrow("%HasOwnProperty(other, 'x')");
CheckCorrectThrow("%HasProperty(other, 'x')");
CheckCorrectThrow("%HasElement(other, 1)");
CheckCorrectThrow("%IsPropertyEnumerable(other, 'x')");
CheckCorrectThrow("%GetPropertyNames(other)");
// PROPERTY_ATTRIBUTES_NONE = 0
- CheckCorrectThrow("%GetLocalPropertyNames(other, 0)");
- CheckCorrectThrow("%DefineOrRedefineAccessorProperty("
+ CheckCorrectThrow("%GetOwnPropertyNames(other, 0)");
+ CheckCorrectThrow("%DefineAccessorPropertyUnchecked("
"other, 'x', null, null, 1)");
// Reset the failed access check callback so it does not influence
@@ -21819,11 +21855,12 @@ class RequestInterruptTestBase {
virtual ~RequestInterruptTestBase() { }
+ virtual void StartInterruptThread() = 0;
+
virtual void TestBody() = 0;
void RunTest() {
- InterruptThread i_thread(this);
- i_thread.Start();
+ StartInterruptThread();
v8::HandleScope handle_scope(isolate_);
@@ -21852,7 +21889,6 @@ class RequestInterruptTestBase {
return should_continue_;
}
- protected:
static void ShouldContinueCallback(
const v8::FunctionCallbackInfo<Value>& info) {
RequestInterruptTestBase* test =
@@ -21861,10 +21897,28 @@ class RequestInterruptTestBase {
info.GetReturnValue().Set(test->ShouldContinue());
}
- class InterruptThread : public i::Thread {
+ LocalContext env_;
+ v8::Isolate* isolate_;
+ v8::base::Semaphore sem_;
+ int warmup_;
+ bool should_continue_;
+};
+
+
+class RequestInterruptTestBaseWithSimpleInterrupt
+ : public RequestInterruptTestBase {
+ public:
+ RequestInterruptTestBaseWithSimpleInterrupt() : i_thread(this) { }
+
+ virtual void StartInterruptThread() {
+ i_thread.Start();
+ }
+
+ private:
+ class InterruptThread : public v8::base::Thread {
public:
explicit InterruptThread(RequestInterruptTestBase* test)
- : Thread("RequestInterruptTest"), test_(test) {}
+ : Thread(Options("RequestInterruptTest")), test_(test) {}
virtual void Run() {
test_->sem_.Wait();
@@ -21880,15 +21934,12 @@ class RequestInterruptTestBase {
RequestInterruptTestBase* test_;
};
- LocalContext env_;
- v8::Isolate* isolate_;
- i::Semaphore sem_;
- int warmup_;
- bool should_continue_;
+ InterruptThread i_thread;
};
-class RequestInterruptTestWithFunctionCall : public RequestInterruptTestBase {
+class RequestInterruptTestWithFunctionCall
+ : public RequestInterruptTestBaseWithSimpleInterrupt {
public:
virtual void TestBody() {
Local<Function> func = Function::New(
@@ -21900,7 +21951,8 @@ class RequestInterruptTestWithFunctionCall : public RequestInterruptTestBase {
};
-class RequestInterruptTestWithMethodCall : public RequestInterruptTestBase {
+class RequestInterruptTestWithMethodCall
+ : public RequestInterruptTestBaseWithSimpleInterrupt {
public:
virtual void TestBody() {
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_);
@@ -21914,7 +21966,8 @@ class RequestInterruptTestWithMethodCall : public RequestInterruptTestBase {
};
-class RequestInterruptTestWithAccessor : public RequestInterruptTestBase {
+class RequestInterruptTestWithAccessor
+ : public RequestInterruptTestBaseWithSimpleInterrupt {
public:
virtual void TestBody() {
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_);
@@ -21928,7 +21981,8 @@ class RequestInterruptTestWithAccessor : public RequestInterruptTestBase {
};
-class RequestInterruptTestWithNativeAccessor : public RequestInterruptTestBase {
+class RequestInterruptTestWithNativeAccessor
+ : public RequestInterruptTestBaseWithSimpleInterrupt {
public:
virtual void TestBody() {
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_);
@@ -21955,7 +22009,7 @@ class RequestInterruptTestWithNativeAccessor : public RequestInterruptTestBase {
class RequestInterruptTestWithMethodCallAndInterceptor
- : public RequestInterruptTestBase {
+ : public RequestInterruptTestBaseWithSimpleInterrupt {
public:
virtual void TestBody() {
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_);
@@ -21978,7 +22032,8 @@ class RequestInterruptTestWithMethodCallAndInterceptor
};
-class RequestInterruptTestWithMathAbs : public RequestInterruptTestBase {
+class RequestInterruptTestWithMathAbs
+ : public RequestInterruptTestBaseWithSimpleInterrupt {
public:
virtual void TestBody() {
env_->Global()->Set(v8_str("WakeUpInterruptor"), Function::New(
@@ -22062,6 +22117,61 @@ TEST(RequestInterruptTestWithMathAbs) {
}
+class ClearInterruptFromAnotherThread
+ : public RequestInterruptTestBase {
+ public:
+ ClearInterruptFromAnotherThread() : i_thread(this), sem2_(0) { }
+
+ virtual void StartInterruptThread() {
+ i_thread.Start();
+ }
+
+ virtual void TestBody() {
+ Local<Function> func = Function::New(
+ isolate_, ShouldContinueCallback, v8::External::New(isolate_, this));
+ env_->Global()->Set(v8_str("ShouldContinue"), func);
+
+ CompileRun("while (ShouldContinue()) { }");
+ }
+
+ private:
+ class InterruptThread : public v8::base::Thread {
+ public:
+ explicit InterruptThread(ClearInterruptFromAnotherThread* test)
+ : Thread(Options("RequestInterruptTest")), test_(test) {}
+
+ virtual void Run() {
+ test_->sem_.Wait();
+ test_->isolate_->RequestInterrupt(&OnInterrupt, test_);
+ test_->sem_.Wait();
+ test_->isolate_->ClearInterrupt();
+ test_->sem2_.Signal();
+ }
+
+ static void OnInterrupt(v8::Isolate* isolate, void* data) {
+ ClearInterruptFromAnotherThread* test =
+ reinterpret_cast<ClearInterruptFromAnotherThread*>(data);
+ test->sem_.Signal();
+ bool success = test->sem2_.WaitFor(v8::base::TimeDelta::FromSeconds(2));
+ // Crash instead of timeout to make this failure more prominent.
+ CHECK(success);
+ test->should_continue_ = false;
+ }
+
+ private:
+ ClearInterruptFromAnotherThread* test_;
+ };
+
+ InterruptThread i_thread;
+ v8::base::Semaphore sem2_;
+};
+
+
+TEST(ClearInterruptFromAnotherThread) {
+ ClearInterruptFromAnotherThread().RunTest();
+}
+
+
static Local<Value> function_new_expected_env;
static void FunctionNewCallback(const v8::FunctionCallbackInfo<Value>& info) {
CHECK_EQ(function_new_expected_env, info.Data());
@@ -22167,152 +22277,152 @@ class ApiCallOptimizationChecker {
info.GetReturnValue().Set(v8_str("returned"));
}
- public:
- enum SignatureType {
- kNoSignature,
- kSignatureOnReceiver,
- kSignatureOnPrototype
- };
-
- void RunAll() {
- SignatureType signature_types[] =
- {kNoSignature, kSignatureOnReceiver, kSignatureOnPrototype};
- for (unsigned i = 0; i < ARRAY_SIZE(signature_types); i++) {
- SignatureType signature_type = signature_types[i];
- for (int j = 0; j < 2; j++) {
- bool global = j == 0;
- int key = signature_type +
- ARRAY_SIZE(signature_types) * (global ? 1 : 0);
- Run(signature_type, global, key);
- }
+ public:
+ enum SignatureType {
+ kNoSignature,
+ kSignatureOnReceiver,
+ kSignatureOnPrototype
+ };
+
+ void RunAll() {
+ SignatureType signature_types[] =
+ {kNoSignature, kSignatureOnReceiver, kSignatureOnPrototype};
+ for (unsigned i = 0; i < ARRAY_SIZE(signature_types); i++) {
+ SignatureType signature_type = signature_types[i];
+ for (int j = 0; j < 2; j++) {
+ bool global = j == 0;
+ int key = signature_type +
+ ARRAY_SIZE(signature_types) * (global ? 1 : 0);
+ Run(signature_type, global, key);
}
}
+ }
- void Run(SignatureType signature_type, bool global, int key) {
- v8::Isolate* isolate = CcTest::isolate();
- v8::HandleScope scope(isolate);
- // Build a template for signature checks.
- Local<v8::ObjectTemplate> signature_template;
- Local<v8::Signature> signature;
- {
- Local<v8::FunctionTemplate> parent_template =
- FunctionTemplate::New(isolate);
- parent_template->SetHiddenPrototype(true);
- Local<v8::FunctionTemplate> function_template
- = FunctionTemplate::New(isolate);
- function_template->Inherit(parent_template);
- switch (signature_type) {
- case kNoSignature:
- break;
- case kSignatureOnReceiver:
- signature = v8::Signature::New(isolate, function_template);
- break;
- case kSignatureOnPrototype:
- signature = v8::Signature::New(isolate, parent_template);
- break;
- }
- signature_template = function_template->InstanceTemplate();
- }
- // Global object must pass checks.
- Local<v8::Context> context =
- v8::Context::New(isolate, NULL, signature_template);
- v8::Context::Scope context_scope(context);
- // Install regular object that can pass signature checks.
- Local<Object> function_receiver = signature_template->NewInstance();
- context->Global()->Set(v8_str("function_receiver"), function_receiver);
- // Get the holder objects.
- Local<Object> inner_global =
- Local<Object>::Cast(context->Global()->GetPrototype());
- // Install functions on hidden prototype object if there is one.
- data = Object::New(isolate);
- Local<FunctionTemplate> function_template = FunctionTemplate::New(
- isolate, OptimizationCallback, data, signature);
- Local<Function> function = function_template->GetFunction();
- Local<Object> global_holder = inner_global;
- Local<Object> function_holder = function_receiver;
- if (signature_type == kSignatureOnPrototype) {
- function_holder = Local<Object>::Cast(function_holder->GetPrototype());
- global_holder = Local<Object>::Cast(global_holder->GetPrototype());
+ void Run(SignatureType signature_type, bool global, int key) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ // Build a template for signature checks.
+ Local<v8::ObjectTemplate> signature_template;
+ Local<v8::Signature> signature;
+ {
+ Local<v8::FunctionTemplate> parent_template =
+ FunctionTemplate::New(isolate);
+ parent_template->SetHiddenPrototype(true);
+ Local<v8::FunctionTemplate> function_template
+ = FunctionTemplate::New(isolate);
+ function_template->Inherit(parent_template);
+ switch (signature_type) {
+ case kNoSignature:
+ break;
+ case kSignatureOnReceiver:
+ signature = v8::Signature::New(isolate, function_template);
+ break;
+ case kSignatureOnPrototype:
+ signature = v8::Signature::New(isolate, parent_template);
+ break;
}
- global_holder->Set(v8_str("g_f"), function);
- global_holder->SetAccessorProperty(v8_str("g_acc"), function, function);
- function_holder->Set(v8_str("f"), function);
- function_holder->SetAccessorProperty(v8_str("acc"), function, function);
- // Initialize expected values.
- callee = function;
- count = 0;
- if (global) {
- receiver = context->Global();
- holder = inner_global;
- } else {
- holder = function_receiver;
- // If not using a signature, add something else to the prototype chain
- // to test the case that holder != receiver
- if (signature_type == kNoSignature) {
- receiver = Local<Object>::Cast(CompileRun(
- "var receiver_subclass = {};\n"
- "receiver_subclass.__proto__ = function_receiver;\n"
- "receiver_subclass"));
- } else {
- receiver = Local<Object>::Cast(CompileRun(
- "var receiver_subclass = function_receiver;\n"
+ signature_template = function_template->InstanceTemplate();
+ }
+ // Global object must pass checks.
+ Local<v8::Context> context =
+ v8::Context::New(isolate, NULL, signature_template);
+ v8::Context::Scope context_scope(context);
+ // Install regular object that can pass signature checks.
+ Local<Object> function_receiver = signature_template->NewInstance();
+ context->Global()->Set(v8_str("function_receiver"), function_receiver);
+ // Get the holder objects.
+ Local<Object> inner_global =
+ Local<Object>::Cast(context->Global()->GetPrototype());
+ // Install functions on hidden prototype object if there is one.
+ data = Object::New(isolate);
+ Local<FunctionTemplate> function_template = FunctionTemplate::New(
+ isolate, OptimizationCallback, data, signature);
+ Local<Function> function = function_template->GetFunction();
+ Local<Object> global_holder = inner_global;
+ Local<Object> function_holder = function_receiver;
+ if (signature_type == kSignatureOnPrototype) {
+ function_holder = Local<Object>::Cast(function_holder->GetPrototype());
+ global_holder = Local<Object>::Cast(global_holder->GetPrototype());
+ }
+ global_holder->Set(v8_str("g_f"), function);
+ global_holder->SetAccessorProperty(v8_str("g_acc"), function, function);
+ function_holder->Set(v8_str("f"), function);
+ function_holder->SetAccessorProperty(v8_str("acc"), function, function);
+ // Initialize expected values.
+ callee = function;
+ count = 0;
+ if (global) {
+ receiver = context->Global();
+ holder = inner_global;
+ } else {
+ holder = function_receiver;
+ // If not using a signature, add something else to the prototype chain
+ // to test the case that holder != receiver
+ if (signature_type == kNoSignature) {
+ receiver = Local<Object>::Cast(CompileRun(
+ "var receiver_subclass = {};\n"
+ "receiver_subclass.__proto__ = function_receiver;\n"
"receiver_subclass"));
- }
- }
- // With no signature, the holder is not set.
- if (signature_type == kNoSignature) holder = receiver;
- // build wrap_function
- i::ScopedVector<char> wrap_function(200);
- if (global) {
- i::OS::SNPrintF(
- wrap_function,
- "function wrap_f_%d() { var f = g_f; return f(); }\n"
- "function wrap_get_%d() { return this.g_acc; }\n"
- "function wrap_set_%d() { return this.g_acc = 1; }\n",
- key, key, key);
} else {
- i::OS::SNPrintF(
- wrap_function,
- "function wrap_f_%d() { return receiver_subclass.f(); }\n"
- "function wrap_get_%d() { return receiver_subclass.acc; }\n"
- "function wrap_set_%d() { return receiver_subclass.acc = 1; }\n",
- key, key, key);
+ receiver = Local<Object>::Cast(CompileRun(
+ "var receiver_subclass = function_receiver;\n"
+ "receiver_subclass"));
}
- // build source string
- i::ScopedVector<char> source(1000);
- i::OS::SNPrintF(
- source,
- "%s\n" // wrap functions
- "function wrap_f() { return wrap_f_%d(); }\n"
- "function wrap_get() { return wrap_get_%d(); }\n"
- "function wrap_set() { return wrap_set_%d(); }\n"
- "check = function(returned) {\n"
- " if (returned !== 'returned') { throw returned; }\n"
- "}\n"
- "\n"
- "check(wrap_f());\n"
- "check(wrap_f());\n"
- "%%OptimizeFunctionOnNextCall(wrap_f_%d);\n"
- "check(wrap_f());\n"
- "\n"
- "check(wrap_get());\n"
- "check(wrap_get());\n"
- "%%OptimizeFunctionOnNextCall(wrap_get_%d);\n"
- "check(wrap_get());\n"
- "\n"
- "check = function(returned) {\n"
- " if (returned !== 1) { throw returned; }\n"
- "}\n"
- "check(wrap_set());\n"
- "check(wrap_set());\n"
- "%%OptimizeFunctionOnNextCall(wrap_set_%d);\n"
- "check(wrap_set());\n",
- wrap_function.start(), key, key, key, key, key, key);
- v8::TryCatch try_catch;
- CompileRun(source.start());
- ASSERT(!try_catch.HasCaught());
- CHECK_EQ(9, count);
}
+ // With no signature, the holder is not set.
+ if (signature_type == kNoSignature) holder = receiver;
+ // build wrap_function
+ i::ScopedVector<char> wrap_function(200);
+ if (global) {
+ i::SNPrintF(
+ wrap_function,
+ "function wrap_f_%d() { var f = g_f; return f(); }\n"
+ "function wrap_get_%d() { return this.g_acc; }\n"
+ "function wrap_set_%d() { return this.g_acc = 1; }\n",
+ key, key, key);
+ } else {
+ i::SNPrintF(
+ wrap_function,
+ "function wrap_f_%d() { return receiver_subclass.f(); }\n"
+ "function wrap_get_%d() { return receiver_subclass.acc; }\n"
+ "function wrap_set_%d() { return receiver_subclass.acc = 1; }\n",
+ key, key, key);
+ }
+ // build source string
+ i::ScopedVector<char> source(1000);
+ i::SNPrintF(
+ source,
+ "%s\n" // wrap functions
+ "function wrap_f() { return wrap_f_%d(); }\n"
+ "function wrap_get() { return wrap_get_%d(); }\n"
+ "function wrap_set() { return wrap_set_%d(); }\n"
+ "check = function(returned) {\n"
+ " if (returned !== 'returned') { throw returned; }\n"
+ "}\n"
+ "\n"
+ "check(wrap_f());\n"
+ "check(wrap_f());\n"
+ "%%OptimizeFunctionOnNextCall(wrap_f_%d);\n"
+ "check(wrap_f());\n"
+ "\n"
+ "check(wrap_get());\n"
+ "check(wrap_get());\n"
+ "%%OptimizeFunctionOnNextCall(wrap_get_%d);\n"
+ "check(wrap_get());\n"
+ "\n"
+ "check = function(returned) {\n"
+ " if (returned !== 1) { throw returned; }\n"
+ "}\n"
+ "check(wrap_set());\n"
+ "check(wrap_set());\n"
+ "%%OptimizeFunctionOnNextCall(wrap_set_%d);\n"
+ "check(wrap_set());\n",
+ wrap_function.start(), key, key, key, key, key, key);
+ v8::TryCatch try_catch;
+ CompileRun(source.start());
+ DCHECK(!try_catch.HasCaught());
+ CHECK_EQ(9, count);
+ }
};
@@ -22341,14 +22451,13 @@ void StoringEventLoggerCallback(const char* message, int status) {
TEST(EventLogging) {
v8::Isolate* isolate = CcTest::isolate();
isolate->SetEventLogger(StoringEventLoggerCallback);
- v8::internal::HistogramTimer* histogramTimer =
- new v8::internal::HistogramTimer(
- "V8.Test", 0, 10000, 50,
- reinterpret_cast<v8::internal::Isolate*>(isolate));
- histogramTimer->Start();
+ v8::internal::HistogramTimer histogramTimer(
+ "V8.Test", 0, 10000, 50,
+ reinterpret_cast<v8::internal::Isolate*>(isolate));
+ histogramTimer.Start();
CHECK_EQ("V8.Test", last_event_message);
CHECK_EQ(0, last_event_status);
- histogramTimer->Stop();
+ histogramTimer.Stop();
CHECK_EQ("V8.Test", last_event_message);
CHECK_EQ(1, last_event_status);
}
@@ -22448,6 +22557,72 @@ TEST(Promises) {
}
+TEST(PromiseThen) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Handle<Object> global = context->Global();
+
+ // Creation.
+ Handle<v8::Promise::Resolver> pr = v8::Promise::Resolver::New(isolate);
+ Handle<v8::Promise::Resolver> qr = v8::Promise::Resolver::New(isolate);
+ Handle<v8::Promise> p = pr->GetPromise();
+ Handle<v8::Promise> q = qr->GetPromise();
+
+ CHECK(p->IsPromise());
+ CHECK(q->IsPromise());
+
+ pr->Resolve(v8::Integer::New(isolate, 1));
+ qr->Resolve(p);
+
+ // Chaining non-pending promises.
+ CompileRun(
+ "var x1 = 0;\n"
+ "var x2 = 0;\n"
+ "function f1(x) { x1 = x; return x+1 };\n"
+ "function f2(x) { x2 = x; return x+1 };\n");
+ Handle<Function> f1 = Handle<Function>::Cast(global->Get(v8_str("f1")));
+ Handle<Function> f2 = Handle<Function>::Cast(global->Get(v8_str("f2")));
+
+ // Chain
+ q->Chain(f1);
+ CHECK(global->Get(v8_str("x1"))->IsNumber());
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK(!global->Get(v8_str("x1"))->IsNumber());
+ CHECK_EQ(p, global->Get(v8_str("x1")));
+
+ // Then
+ CompileRun("x1 = x2 = 0;");
+ q->Then(f1);
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK_EQ(1, global->Get(v8_str("x1"))->Int32Value());
+
+ // Then
+ CompileRun("x1 = x2 = 0;");
+ pr = v8::Promise::Resolver::New(isolate);
+ qr = v8::Promise::Resolver::New(isolate);
+
+ qr->Resolve(pr);
+ qr->GetPromise()->Then(f1)->Then(f2);
+
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+
+ pr->Resolve(v8::Integer::New(isolate, 3));
+
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK_EQ(3, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(4, global->Get(v8_str("x2"))->Int32Value());
+}
+
+
TEST(DisallowJavascriptExecutionScope) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
@@ -22540,3 +22715,158 @@ TEST(CaptureStackTraceForStackOverflow) {
CompileRun("(function f(x) { f(x+1); })(0)");
CHECK(try_catch.HasCaught());
}
+
+
+TEST(ScriptNameAndLineNumber) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ const char* url = "http://www.foo.com/foo.js";
+ v8::ScriptOrigin origin(v8_str(url), v8::Integer::New(isolate, 13));
+ v8::ScriptCompiler::Source script_source(v8_str("var foo;"), origin);
+ Local<Script> script = v8::ScriptCompiler::Compile(
+ isolate, &script_source);
+ Local<Value> script_name = script->GetUnboundScript()->GetScriptName();
+ CHECK(!script_name.IsEmpty());
+ CHECK(script_name->IsString());
+ String::Utf8Value utf8_name(script_name);
+ CHECK_EQ(url, *utf8_name);
+ int line_number = script->GetUnboundScript()->GetLineNumber(0);
+ CHECK_EQ(13, line_number);
+}
+
+
+Local<v8::Context> call_eval_context;
+Local<v8::Function> call_eval_bound_function;
+static void CallEval(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ v8::Context::Scope scope(call_eval_context);
+ args.GetReturnValue().Set(
+ call_eval_bound_function->Call(call_eval_context->Global(), 0, NULL));
+}
+
+
+TEST(CrossActivationEval) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ {
+ call_eval_context = v8::Context::New(isolate);
+ v8::Context::Scope scope(call_eval_context);
+ call_eval_bound_function =
+ Local<Function>::Cast(CompileRun("eval.bind(this, '1')"));
+ }
+ env->Global()->Set(v8_str("CallEval"),
+ v8::FunctionTemplate::New(isolate, CallEval)->GetFunction());
+ Local<Value> result = CompileRun("CallEval();");
+ CHECK_EQ(result, v8::Integer::New(isolate, 1));
+}
+
+
+void SourceURLHelper(const char* source, const char* expected_source_url,
+ const char* expected_source_mapping_url) {
+ Local<Script> script = v8_compile(source);
+ if (expected_source_url != NULL) {
+ v8::String::Utf8Value url(script->GetUnboundScript()->GetSourceURL());
+ CHECK_EQ(expected_source_url, *url);
+ } else {
+ CHECK(script->GetUnboundScript()->GetSourceURL()->IsUndefined());
+ }
+ if (expected_source_mapping_url != NULL) {
+ v8::String::Utf8Value url(
+ script->GetUnboundScript()->GetSourceMappingURL());
+ CHECK_EQ(expected_source_mapping_url, *url);
+ } else {
+ CHECK(script->GetUnboundScript()->GetSourceMappingURL()->IsUndefined());
+ }
+}
+
+
+TEST(ScriptSourceURLAndSourceMappingURL) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar1.js\n", "bar1.js", NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceMappingURL=bar2.js\n", NULL, "bar2.js");
+
+ // Both sourceURL and sourceMappingURL.
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar3.js\n"
+ "//# sourceMappingURL=bar4.js\n", "bar3.js", "bar4.js");
+
+ // Two source URLs; the first one is ignored.
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=ignoreme.js\n"
+ "//# sourceURL=bar5.js\n", "bar5.js", NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceMappingURL=ignoreme.js\n"
+ "//# sourceMappingURL=bar6.js\n", NULL, "bar6.js");
+
+ // SourceURL or sourceMappingURL in the middle of the script.
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar7.js\n"
+ "function baz() {}\n", "bar7.js", NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceMappingURL=bar8.js\n"
+ "function baz() {}\n", NULL, "bar8.js");
+
+ // Too much whitespace.
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar9.js\n"
+ "//# sourceMappingURL=bar10.js\n", NULL, NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL =bar11.js\n"
+ "//# sourceMappingURL =bar12.js\n", NULL, NULL);
+
+ // Disallowed characters in value.
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar13 .js \n"
+ "//# sourceMappingURL=bar14 .js \n",
+ NULL, NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar15\t.js \n"
+ "//# sourceMappingURL=bar16\t.js \n",
+ NULL, NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar17'.js \n"
+ "//# sourceMappingURL=bar18'.js \n",
+ NULL, NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar19\".js \n"
+ "//# sourceMappingURL=bar20\".js \n",
+ NULL, NULL);
+
+ // Not too much whitespace.
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL= bar21.js \n"
+ "//# sourceMappingURL= bar22.js \n", "bar21.js", "bar22.js");
+}
+
+
+TEST(GetOwnPropertyDescriptor) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ CompileRun(
+ "var x = { value : 13};"
+ "Object.defineProperty(x, 'p0', {value : 12});"
+ "Object.defineProperty(x, 'p1', {"
+ " set : function(value) { this.value = value; },"
+ " get : function() { return this.value; },"
+ "});");
+ Local<Object> x = Local<Object>::Cast(env->Global()->Get(v8_str("x")));
+ Local<Value> desc = x->GetOwnPropertyDescriptor(v8_str("no_prop"));
+ CHECK(desc->IsUndefined());
+ desc = x->GetOwnPropertyDescriptor(v8_str("p0"));
+ CHECK_EQ(v8_num(12), Local<Object>::Cast(desc)->Get(v8_str("value")));
+ desc = x->GetOwnPropertyDescriptor(v8_str("p1"));
+ Local<Function> set =
+ Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("set")));
+ Local<Function> get =
+ Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("get")));
+ CHECK_EQ(v8_num(13), get->Call(x, 0, NULL));
+ Handle<Value> args[] = { v8_num(14) };
+ set->Call(x, 1, args);
+ CHECK_EQ(v8_num(14), get->Call(x, 0, NULL));
+}
diff --git a/deps/v8/test/cctest/test-assembler-arm.cc b/deps/v8/test/cctest/test-assembler-arm.cc
index 470cd6163..4c339a32b 100644
--- a/deps/v8/test/cctest/test-assembler-arm.cc
+++ b/deps/v8/test/cctest/test-assembler-arm.cc
@@ -25,13 +25,14 @@
// (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 "src/v8.h"
+#include "test/cctest/cctest.h"
-#include "disassembler.h"
-#include "factory.h"
-#include "arm/simulator-arm.h"
-#include "arm/assembler-arm-inl.h"
-#include "cctest.h"
+#include "src/arm/assembler-arm-inl.h"
+#include "src/arm/simulator-arm.h"
+#include "src/disassembler.h"
+#include "src/factory.h"
+#include "src/ostreams.h"
using namespace v8::internal;
@@ -60,7 +61,8 @@ TEST(0) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F2 f = FUNCTION_CAST<F2>(code->entry());
int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 3, 4, 0, 0, 0));
@@ -95,7 +97,8 @@ TEST(1) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 100, 0, 0, 0, 0));
@@ -139,7 +142,8 @@ TEST(2) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 10, 0, 0, 0, 0));
@@ -185,7 +189,8 @@ TEST(3) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
t.i = 100000;
@@ -308,7 +313,8 @@ TEST(4) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
t.a = 1.5;
@@ -368,7 +374,8 @@ TEST(5) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
int res = reinterpret_cast<int>(
@@ -401,7 +408,8 @@ TEST(6) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
int res = reinterpret_cast<int>(
@@ -474,7 +482,8 @@ static void TestRoundingMode(VCVTTypes types,
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
int res = reinterpret_cast<int>(
@@ -657,7 +666,8 @@ TEST(8) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F4 fn = FUNCTION_CAST<F4>(code->entry());
d.a = 1.1;
@@ -766,7 +776,8 @@ TEST(9) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F4 fn = FUNCTION_CAST<F4>(code->entry());
d.a = 1.1;
@@ -871,7 +882,8 @@ TEST(10) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F4 fn = FUNCTION_CAST<F4>(code->entry());
d.a = 1.1;
@@ -965,7 +977,8 @@ TEST(11) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
Object* dummy = CALL_GENERATED_CODE(f, &i, 0, 0, 0, 0);
@@ -1092,7 +1105,8 @@ TEST(13) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
t.a = 1.5;
@@ -1164,7 +1178,8 @@ TEST(14) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
t.left = BitCast<double>(kHoleNanInt64);
@@ -1180,7 +1195,7 @@ TEST(14) {
#ifdef DEBUG
const uint64_t kArmNanInt64 =
(static_cast<uint64_t>(kArmNanUpper32) << 32) | kArmNanLower32;
- ASSERT(kArmNanInt64 != kHoleNanInt64);
+ DCHECK(kArmNanInt64 != kHoleNanInt64);
#endif
// With VFP2 the sign of the canonicalized Nan is undefined. So
// we remove the sign bit for the upper tests.
@@ -1267,7 +1282,8 @@ TEST(15) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
t.src0 = 0x01020304;
@@ -1369,7 +1385,8 @@ TEST(16) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
t.src0 = 0x01020304;
@@ -1451,7 +1468,8 @@ TEST(18) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef DEBUG
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
Object* dummy;
diff --git a/deps/v8/test/cctest/test-assembler-arm64.cc b/deps/v8/test/cctest/test-assembler-arm64.cc
index 25f3adb50..3d05487f3 100644
--- a/deps/v8/test/cctest/test-assembler-arm64.cc
+++ b/deps/v8/test/cctest/test-assembler-arm64.cc
@@ -31,15 +31,15 @@
#include <cmath>
#include <limits>
-#include "v8.h"
+#include "src/v8.h"
-#include "macro-assembler.h"
-#include "arm64/simulator-arm64.h"
-#include "arm64/decoder-arm64-inl.h"
-#include "arm64/disasm-arm64.h"
-#include "arm64/utils-arm64.h"
-#include "cctest.h"
-#include "test-utils-arm64.h"
+#include "src/arm64/decoder-arm64-inl.h"
+#include "src/arm64/disasm-arm64.h"
+#include "src/arm64/simulator-arm64.h"
+#include "src/arm64/utils-arm64.h"
+#include "src/macro-assembler.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-utils-arm64.h"
using namespace v8::internal;
@@ -58,7 +58,7 @@ using namespace v8::internal;
//
// RUN();
//
-// ASSERT_EQUAL_64(1, x0);
+// CHECK_EQUAL_64(1, x0);
//
// TEARDOWN();
// }
@@ -74,22 +74,22 @@ using namespace v8::internal;
//
// We provide some helper assert to handle common cases:
//
-// ASSERT_EQUAL_32(int32_t, int_32t)
-// ASSERT_EQUAL_FP32(float, float)
-// ASSERT_EQUAL_32(int32_t, W register)
-// ASSERT_EQUAL_FP32(float, S register)
-// ASSERT_EQUAL_64(int64_t, int_64t)
-// ASSERT_EQUAL_FP64(double, double)
-// ASSERT_EQUAL_64(int64_t, X register)
-// ASSERT_EQUAL_64(X register, X register)
-// ASSERT_EQUAL_FP64(double, D register)
+// CHECK_EQUAL_32(int32_t, int_32t)
+// CHECK_EQUAL_FP32(float, float)
+// CHECK_EQUAL_32(int32_t, W register)
+// CHECK_EQUAL_FP32(float, S register)
+// CHECK_EQUAL_64(int64_t, int_64t)
+// CHECK_EQUAL_FP64(double, double)
+// CHECK_EQUAL_64(int64_t, X register)
+// CHECK_EQUAL_64(X register, X register)
+// CHECK_EQUAL_FP64(double, D register)
//
-// e.g. ASSERT_EQUAL_64(0.5, d30);
+// e.g. CHECK_EQUAL_64(0.5, d30);
//
// If more advance computation is required before the assert then access the
// RegisterDump named core directly:
//
-// ASSERT_EQUAL_64(0x1234, core.xreg(0) & 0xffff);
+// CHECK_EQUAL_64(0x1234, core.xreg(0) & 0xffff);
#if 0 // TODO(all): enable.
@@ -116,7 +116,7 @@ static void InitializeVM() {
#define SETUP_SIZE(buf_size) \
Isolate* isolate = Isolate::Current(); \
HandleScope scope(isolate); \
- ASSERT(isolate != NULL); \
+ DCHECK(isolate != NULL); \
byte* buf = new byte[buf_size]; \
MacroAssembler masm(isolate, buf, buf_size); \
Decoder<DispatchingDecoderVisitor>* decoder = \
@@ -170,11 +170,10 @@ static void InitializeVM() {
#define SETUP_SIZE(buf_size) \
Isolate* isolate = Isolate::Current(); \
HandleScope scope(isolate); \
- ASSERT(isolate != NULL); \
+ DCHECK(isolate != NULL); \
byte* buf = new byte[buf_size]; \
MacroAssembler masm(isolate, buf, buf_size); \
- RegisterDump core; \
- CpuFeatures::Probe(false);
+ RegisterDump core;
#define RESET() \
__ Reset(); \
@@ -191,12 +190,12 @@ static void InitializeVM() {
RESET(); \
START_AFTER_RESET();
-#define RUN() \
- CPU::FlushICache(buf, masm.SizeOfGeneratedCode()); \
- { \
- void (*test_function)(void); \
- memcpy(&test_function, &buf, sizeof(buf)); \
- test_function(); \
+#define RUN() \
+ CpuFeatures::FlushICache(buf, masm.SizeOfGeneratedCode()); \
+ { \
+ void (*test_function)(void); \
+ memcpy(&test_function, &buf, sizeof(buf)); \
+ test_function(); \
}
#define END() \
@@ -210,29 +209,29 @@ static void InitializeVM() {
#endif // ifdef USE_SIMULATOR.
-#define ASSERT_EQUAL_NZCV(expected) \
+#define CHECK_EQUAL_NZCV(expected) \
CHECK(EqualNzcv(expected, core.flags_nzcv()))
-#define ASSERT_EQUAL_REGISTERS(expected) \
+#define CHECK_EQUAL_REGISTERS(expected) \
CHECK(EqualRegisters(&expected, &core))
-#define ASSERT_EQUAL_32(expected, result) \
+#define CHECK_EQUAL_32(expected, result) \
CHECK(Equal32(static_cast<uint32_t>(expected), &core, result))
-#define ASSERT_EQUAL_FP32(expected, result) \
+#define CHECK_EQUAL_FP32(expected, result) \
CHECK(EqualFP32(expected, &core, result))
-#define ASSERT_EQUAL_64(expected, result) \
+#define CHECK_EQUAL_64(expected, result) \
CHECK(Equal64(expected, &core, result))
-#define ASSERT_EQUAL_FP64(expected, result) \
+#define CHECK_EQUAL_FP64(expected, result) \
CHECK(EqualFP64(expected, &core, result))
#ifdef DEBUG
-#define ASSERT_LITERAL_POOL_SIZE(expected) \
+#define DCHECK_LITERAL_POOL_SIZE(expected) \
CHECK((expected) == (__ LiteralPoolSize()))
#else
-#define ASSERT_LITERAL_POOL_SIZE(expected) \
+#define DCHECK_LITERAL_POOL_SIZE(expected) \
((void) 0)
#endif
@@ -277,12 +276,12 @@ TEST(stack_ops) {
RUN();
- ASSERT_EQUAL_64(0x1000, x0);
- ASSERT_EQUAL_64(0x1050, x1);
- ASSERT_EQUAL_64(0x104f, x2);
- ASSERT_EQUAL_64(0x1fff, x3);
- ASSERT_EQUAL_64(0xfffffff8, x4);
- ASSERT_EQUAL_64(0xfffffff8, x5);
+ CHECK_EQUAL_64(0x1000, x0);
+ CHECK_EQUAL_64(0x1050, x1);
+ CHECK_EQUAL_64(0x104f, x2);
+ CHECK_EQUAL_64(0x1fff, x3);
+ CHECK_EQUAL_64(0xfffffff8, x4);
+ CHECK_EQUAL_64(0xfffffff8, x5);
TEARDOWN();
}
@@ -313,22 +312,22 @@ TEST(mvn) {
RUN();
- ASSERT_EQUAL_64(0xfffff000, x0);
- ASSERT_EQUAL_64(0xfffffffffffff000UL, x1);
- ASSERT_EQUAL_64(0x00001fff, x2);
- ASSERT_EQUAL_64(0x0000000000003fffUL, x3);
- ASSERT_EQUAL_64(0xe00001ff, x4);
- ASSERT_EQUAL_64(0xf0000000000000ffUL, x5);
- ASSERT_EQUAL_64(0x00000001, x6);
- ASSERT_EQUAL_64(0x0, x7);
- ASSERT_EQUAL_64(0x7ff80000, x8);
- ASSERT_EQUAL_64(0x3ffc000000000000UL, x9);
- ASSERT_EQUAL_64(0xffffff00, x10);
- ASSERT_EQUAL_64(0x0000000000000001UL, x11);
- ASSERT_EQUAL_64(0xffff8003, x12);
- ASSERT_EQUAL_64(0xffffffffffff0007UL, x13);
- ASSERT_EQUAL_64(0xfffffffffffe000fUL, x14);
- ASSERT_EQUAL_64(0xfffffffffffe000fUL, x15);
+ CHECK_EQUAL_64(0xfffff000, x0);
+ CHECK_EQUAL_64(0xfffffffffffff000UL, x1);
+ CHECK_EQUAL_64(0x00001fff, x2);
+ CHECK_EQUAL_64(0x0000000000003fffUL, x3);
+ CHECK_EQUAL_64(0xe00001ff, x4);
+ CHECK_EQUAL_64(0xf0000000000000ffUL, x5);
+ CHECK_EQUAL_64(0x00000001, x6);
+ CHECK_EQUAL_64(0x0, x7);
+ CHECK_EQUAL_64(0x7ff80000, x8);
+ CHECK_EQUAL_64(0x3ffc000000000000UL, x9);
+ CHECK_EQUAL_64(0xffffff00, x10);
+ CHECK_EQUAL_64(0x0000000000000001UL, x11);
+ CHECK_EQUAL_64(0xffff8003, x12);
+ CHECK_EQUAL_64(0xffffffffffff0007UL, x13);
+ CHECK_EQUAL_64(0xfffffffffffe000fUL, x14);
+ CHECK_EQUAL_64(0xfffffffffffe000fUL, x15);
TEARDOWN();
}
@@ -385,31 +384,31 @@ TEST(mov) {
RUN();
- ASSERT_EQUAL_64(0x0123456789abcdefL, x0);
- ASSERT_EQUAL_64(0x00000000abcd0000L, x1);
- ASSERT_EQUAL_64(0xffffabcdffffffffL, x2);
- ASSERT_EQUAL_64(0x5432ffffffffffffL, x3);
- ASSERT_EQUAL_64(x4, x5);
- ASSERT_EQUAL_32(-1, w6);
- ASSERT_EQUAL_64(0x0123456789abcdefL, x7);
- ASSERT_EQUAL_32(0x89abcdefL, w8);
- ASSERT_EQUAL_64(0x0123456789abcdefL, x9);
- ASSERT_EQUAL_32(0x89abcdefL, w10);
- ASSERT_EQUAL_64(0x00000fff, x11);
- ASSERT_EQUAL_64(0x0000000000000fffUL, x12);
- ASSERT_EQUAL_64(0x00001ffe, x13);
- ASSERT_EQUAL_64(0x0000000000003ffcUL, x14);
- ASSERT_EQUAL_64(0x000001ff, x15);
- ASSERT_EQUAL_64(0x00000000000000ffUL, x18);
- ASSERT_EQUAL_64(0x00000001, x19);
- ASSERT_EQUAL_64(0x0, x20);
- ASSERT_EQUAL_64(0x7ff80000, x21);
- ASSERT_EQUAL_64(0x3ffc000000000000UL, x22);
- ASSERT_EQUAL_64(0x000000fe, x23);
- ASSERT_EQUAL_64(0xfffffffffffffffcUL, x24);
- ASSERT_EQUAL_64(0x00007ff8, x25);
- ASSERT_EQUAL_64(0x000000000000fff0UL, x26);
- ASSERT_EQUAL_64(0x000000000001ffe0UL, x27);
+ CHECK_EQUAL_64(0x0123456789abcdefL, x0);
+ CHECK_EQUAL_64(0x00000000abcd0000L, x1);
+ CHECK_EQUAL_64(0xffffabcdffffffffL, x2);
+ CHECK_EQUAL_64(0x5432ffffffffffffL, x3);
+ CHECK_EQUAL_64(x4, x5);
+ CHECK_EQUAL_32(-1, w6);
+ CHECK_EQUAL_64(0x0123456789abcdefL, x7);
+ CHECK_EQUAL_32(0x89abcdefL, w8);
+ CHECK_EQUAL_64(0x0123456789abcdefL, x9);
+ CHECK_EQUAL_32(0x89abcdefL, w10);
+ CHECK_EQUAL_64(0x00000fff, x11);
+ CHECK_EQUAL_64(0x0000000000000fffUL, x12);
+ CHECK_EQUAL_64(0x00001ffe, x13);
+ CHECK_EQUAL_64(0x0000000000003ffcUL, x14);
+ CHECK_EQUAL_64(0x000001ff, x15);
+ CHECK_EQUAL_64(0x00000000000000ffUL, x18);
+ CHECK_EQUAL_64(0x00000001, x19);
+ CHECK_EQUAL_64(0x0, x20);
+ CHECK_EQUAL_64(0x7ff80000, x21);
+ CHECK_EQUAL_64(0x3ffc000000000000UL, x22);
+ CHECK_EQUAL_64(0x000000fe, x23);
+ CHECK_EQUAL_64(0xfffffffffffffffcUL, x24);
+ CHECK_EQUAL_64(0x00007ff8, x25);
+ CHECK_EQUAL_64(0x000000000000fff0UL, x26);
+ CHECK_EQUAL_64(0x000000000001ffe0UL, x27);
TEARDOWN();
}
@@ -427,17 +426,23 @@ TEST(mov_imm_w) {
__ Mov(w4, 0x00001234L);
__ Mov(w5, 0x12340000L);
__ Mov(w6, 0x12345678L);
+ __ Mov(w7, (int32_t)0x80000000);
+ __ Mov(w8, (int32_t)0xffff0000);
+ __ Mov(w9, kWMinInt);
END();
RUN();
- ASSERT_EQUAL_64(0xffffffffL, x0);
- ASSERT_EQUAL_64(0xffff1234L, x1);
- ASSERT_EQUAL_64(0x1234ffffL, x2);
- ASSERT_EQUAL_64(0x00000000L, x3);
- ASSERT_EQUAL_64(0x00001234L, x4);
- ASSERT_EQUAL_64(0x12340000L, x5);
- ASSERT_EQUAL_64(0x12345678L, x6);
+ CHECK_EQUAL_64(0xffffffffL, x0);
+ CHECK_EQUAL_64(0xffff1234L, x1);
+ CHECK_EQUAL_64(0x1234ffffL, x2);
+ CHECK_EQUAL_64(0x00000000L, x3);
+ CHECK_EQUAL_64(0x00001234L, x4);
+ CHECK_EQUAL_64(0x12340000L, x5);
+ CHECK_EQUAL_64(0x12345678L, x6);
+ CHECK_EQUAL_64(0x80000000L, x7);
+ CHECK_EQUAL_64(0xffff0000L, x8);
+ CHECK_EQUAL_32(kWMinInt, w9);
TEARDOWN();
}
@@ -479,32 +484,32 @@ TEST(mov_imm_x) {
RUN();
- ASSERT_EQUAL_64(0xffffffffffff1234L, x1);
- ASSERT_EQUAL_64(0xffffffff12345678L, x2);
- ASSERT_EQUAL_64(0xffff1234ffff5678L, x3);
- ASSERT_EQUAL_64(0x1234ffffffff5678L, x4);
- ASSERT_EQUAL_64(0x1234ffff5678ffffL, x5);
- ASSERT_EQUAL_64(0x12345678ffffffffL, x6);
- ASSERT_EQUAL_64(0x1234ffffffffffffL, x7);
- ASSERT_EQUAL_64(0x123456789abcffffL, x8);
- ASSERT_EQUAL_64(0x12345678ffff9abcL, x9);
- ASSERT_EQUAL_64(0x1234ffff56789abcL, x10);
- ASSERT_EQUAL_64(0xffff123456789abcL, x11);
- ASSERT_EQUAL_64(0x0000000000000000L, x12);
- ASSERT_EQUAL_64(0x0000000000001234L, x13);
- ASSERT_EQUAL_64(0x0000000012345678L, x14);
- ASSERT_EQUAL_64(0x0000123400005678L, x15);
- ASSERT_EQUAL_64(0x1234000000005678L, x18);
- ASSERT_EQUAL_64(0x1234000056780000L, x19);
- ASSERT_EQUAL_64(0x1234567800000000L, x20);
- ASSERT_EQUAL_64(0x1234000000000000L, x21);
- ASSERT_EQUAL_64(0x123456789abc0000L, x22);
- ASSERT_EQUAL_64(0x1234567800009abcL, x23);
- ASSERT_EQUAL_64(0x1234000056789abcL, x24);
- ASSERT_EQUAL_64(0x0000123456789abcL, x25);
- ASSERT_EQUAL_64(0x123456789abcdef0L, x26);
- ASSERT_EQUAL_64(0xffff000000000001L, x27);
- ASSERT_EQUAL_64(0x8000ffff00000000L, x28);
+ CHECK_EQUAL_64(0xffffffffffff1234L, x1);
+ CHECK_EQUAL_64(0xffffffff12345678L, x2);
+ CHECK_EQUAL_64(0xffff1234ffff5678L, x3);
+ CHECK_EQUAL_64(0x1234ffffffff5678L, x4);
+ CHECK_EQUAL_64(0x1234ffff5678ffffL, x5);
+ CHECK_EQUAL_64(0x12345678ffffffffL, x6);
+ CHECK_EQUAL_64(0x1234ffffffffffffL, x7);
+ CHECK_EQUAL_64(0x123456789abcffffL, x8);
+ CHECK_EQUAL_64(0x12345678ffff9abcL, x9);
+ CHECK_EQUAL_64(0x1234ffff56789abcL, x10);
+ CHECK_EQUAL_64(0xffff123456789abcL, x11);
+ CHECK_EQUAL_64(0x0000000000000000L, x12);
+ CHECK_EQUAL_64(0x0000000000001234L, x13);
+ CHECK_EQUAL_64(0x0000000012345678L, x14);
+ CHECK_EQUAL_64(0x0000123400005678L, x15);
+ CHECK_EQUAL_64(0x1234000000005678L, x18);
+ CHECK_EQUAL_64(0x1234000056780000L, x19);
+ CHECK_EQUAL_64(0x1234567800000000L, x20);
+ CHECK_EQUAL_64(0x1234000000000000L, x21);
+ CHECK_EQUAL_64(0x123456789abc0000L, x22);
+ CHECK_EQUAL_64(0x1234567800009abcL, x23);
+ CHECK_EQUAL_64(0x1234000056789abcL, x24);
+ CHECK_EQUAL_64(0x0000123456789abcL, x25);
+ CHECK_EQUAL_64(0x123456789abcdef0L, x26);
+ CHECK_EQUAL_64(0xffff000000000001L, x27);
+ CHECK_EQUAL_64(0x8000ffff00000000L, x28);
TEARDOWN();
}
@@ -532,16 +537,16 @@ TEST(orr) {
RUN();
- ASSERT_EQUAL_64(0xf000f0ff, x2);
- ASSERT_EQUAL_64(0xf000f0f0, x3);
- ASSERT_EQUAL_64(0xf00000ff0000f0f0L, x4);
- ASSERT_EQUAL_64(0x0f00f0ff, x5);
- ASSERT_EQUAL_64(0xff00f0ff, x6);
- ASSERT_EQUAL_64(0x0f00f0ff, x7);
- ASSERT_EQUAL_64(0x0ffff0f0, x8);
- ASSERT_EQUAL_64(0x0ff00000000ff0f0L, x9);
- ASSERT_EQUAL_64(0xf0ff, x10);
- ASSERT_EQUAL_64(0xf0000000f000f0f0L, x11);
+ CHECK_EQUAL_64(0xf000f0ff, x2);
+ CHECK_EQUAL_64(0xf000f0f0, x3);
+ CHECK_EQUAL_64(0xf00000ff0000f0f0L, x4);
+ CHECK_EQUAL_64(0x0f00f0ff, x5);
+ CHECK_EQUAL_64(0xff00f0ff, x6);
+ CHECK_EQUAL_64(0x0f00f0ff, x7);
+ CHECK_EQUAL_64(0x0ffff0f0, x8);
+ CHECK_EQUAL_64(0x0ff00000000ff0f0L, x9);
+ CHECK_EQUAL_64(0xf0ff, x10);
+ CHECK_EQUAL_64(0xf0000000f000f0f0L, x11);
TEARDOWN();
}
@@ -566,14 +571,14 @@ TEST(orr_extend) {
RUN();
- ASSERT_EQUAL_64(0x00000081, x6);
- ASSERT_EQUAL_64(0x00010101, x7);
- ASSERT_EQUAL_64(0x00020201, x8);
- ASSERT_EQUAL_64(0x0000000400040401UL, x9);
- ASSERT_EQUAL_64(0x00000000ffffff81UL, x10);
- ASSERT_EQUAL_64(0xffffffffffff0101UL, x11);
- ASSERT_EQUAL_64(0xfffffffe00020201UL, x12);
- ASSERT_EQUAL_64(0x0000000400040401UL, x13);
+ CHECK_EQUAL_64(0x00000081, x6);
+ CHECK_EQUAL_64(0x00010101, x7);
+ CHECK_EQUAL_64(0x00020201, x8);
+ CHECK_EQUAL_64(0x0000000400040401UL, x9);
+ CHECK_EQUAL_64(0x00000000ffffff81UL, x10);
+ CHECK_EQUAL_64(0xffffffffffff0101UL, x11);
+ CHECK_EQUAL_64(0xfffffffe00020201UL, x12);
+ CHECK_EQUAL_64(0x0000000400040401UL, x13);
TEARDOWN();
}
@@ -589,14 +594,19 @@ TEST(bitwise_wide_imm) {
__ Orr(x10, x0, Operand(0x1234567890abcdefUL));
__ Orr(w11, w1, Operand(0x90abcdef));
+
+ __ Orr(w12, w0, kWMinInt);
+ __ Eor(w13, w0, kWMinInt);
END();
RUN();
- ASSERT_EQUAL_64(0, x0);
- ASSERT_EQUAL_64(0xf0f0f0f0f0f0f0f0UL, x1);
- ASSERT_EQUAL_64(0x1234567890abcdefUL, x10);
- ASSERT_EQUAL_64(0xf0fbfdffUL, x11);
+ CHECK_EQUAL_64(0, x0);
+ CHECK_EQUAL_64(0xf0f0f0f0f0f0f0f0UL, x1);
+ CHECK_EQUAL_64(0x1234567890abcdefUL, x10);
+ CHECK_EQUAL_64(0xf0fbfdffUL, x11);
+ CHECK_EQUAL_32(kWMinInt, w12);
+ CHECK_EQUAL_32(kWMinInt, w13);
TEARDOWN();
}
@@ -624,16 +634,16 @@ TEST(orn) {
RUN();
- ASSERT_EQUAL_64(0xffffffff0ffffff0L, x2);
- ASSERT_EQUAL_64(0xfffff0ff, x3);
- ASSERT_EQUAL_64(0xfffffff0fffff0ffL, x4);
- ASSERT_EQUAL_64(0xffffffff87fffff0L, x5);
- ASSERT_EQUAL_64(0x07fffff0, x6);
- ASSERT_EQUAL_64(0xffffffff87fffff0L, x7);
- ASSERT_EQUAL_64(0xff00ffff, x8);
- ASSERT_EQUAL_64(0xff00ffffffffffffL, x9);
- ASSERT_EQUAL_64(0xfffff0f0, x10);
- ASSERT_EQUAL_64(0xffff0000fffff0f0L, x11);
+ CHECK_EQUAL_64(0xffffffff0ffffff0L, x2);
+ CHECK_EQUAL_64(0xfffff0ff, x3);
+ CHECK_EQUAL_64(0xfffffff0fffff0ffL, x4);
+ CHECK_EQUAL_64(0xffffffff87fffff0L, x5);
+ CHECK_EQUAL_64(0x07fffff0, x6);
+ CHECK_EQUAL_64(0xffffffff87fffff0L, x7);
+ CHECK_EQUAL_64(0xff00ffff, x8);
+ CHECK_EQUAL_64(0xff00ffffffffffffL, x9);
+ CHECK_EQUAL_64(0xfffff0f0, x10);
+ CHECK_EQUAL_64(0xffff0000fffff0f0L, x11);
TEARDOWN();
}
@@ -658,14 +668,14 @@ TEST(orn_extend) {
RUN();
- ASSERT_EQUAL_64(0xffffff7f, x6);
- ASSERT_EQUAL_64(0xfffffffffffefefdUL, x7);
- ASSERT_EQUAL_64(0xfffdfdfb, x8);
- ASSERT_EQUAL_64(0xfffffffbfffbfbf7UL, x9);
- ASSERT_EQUAL_64(0x0000007f, x10);
- ASSERT_EQUAL_64(0x0000fefd, x11);
- ASSERT_EQUAL_64(0x00000001fffdfdfbUL, x12);
- ASSERT_EQUAL_64(0xfffffffbfffbfbf7UL, x13);
+ CHECK_EQUAL_64(0xffffff7f, x6);
+ CHECK_EQUAL_64(0xfffffffffffefefdUL, x7);
+ CHECK_EQUAL_64(0xfffdfdfb, x8);
+ CHECK_EQUAL_64(0xfffffffbfffbfbf7UL, x9);
+ CHECK_EQUAL_64(0x0000007f, x10);
+ CHECK_EQUAL_64(0x0000fefd, x11);
+ CHECK_EQUAL_64(0x00000001fffdfdfbUL, x12);
+ CHECK_EQUAL_64(0xfffffffbfffbfbf7UL, x13);
TEARDOWN();
}
@@ -693,16 +703,16 @@ TEST(and_) {
RUN();
- ASSERT_EQUAL_64(0x000000f0, x2);
- ASSERT_EQUAL_64(0x00000ff0, x3);
- ASSERT_EQUAL_64(0x00000ff0, x4);
- ASSERT_EQUAL_64(0x00000070, x5);
- ASSERT_EQUAL_64(0x0000ff00, x6);
- ASSERT_EQUAL_64(0x00000f00, x7);
- ASSERT_EQUAL_64(0x00000ff0, x8);
- ASSERT_EQUAL_64(0x00000000, x9);
- ASSERT_EQUAL_64(0x0000ff00, x10);
- ASSERT_EQUAL_64(0x000000f0, x11);
+ CHECK_EQUAL_64(0x000000f0, x2);
+ CHECK_EQUAL_64(0x00000ff0, x3);
+ CHECK_EQUAL_64(0x00000ff0, x4);
+ CHECK_EQUAL_64(0x00000070, x5);
+ CHECK_EQUAL_64(0x0000ff00, x6);
+ CHECK_EQUAL_64(0x00000f00, x7);
+ CHECK_EQUAL_64(0x00000ff0, x8);
+ CHECK_EQUAL_64(0x00000000, x9);
+ CHECK_EQUAL_64(0x0000ff00, x10);
+ CHECK_EQUAL_64(0x000000f0, x11);
TEARDOWN();
}
@@ -727,14 +737,14 @@ TEST(and_extend) {
RUN();
- ASSERT_EQUAL_64(0x00000081, x6);
- ASSERT_EQUAL_64(0x00010102, x7);
- ASSERT_EQUAL_64(0x00020204, x8);
- ASSERT_EQUAL_64(0x0000000400040408UL, x9);
- ASSERT_EQUAL_64(0xffffff81, x10);
- ASSERT_EQUAL_64(0xffffffffffff0102UL, x11);
- ASSERT_EQUAL_64(0xfffffffe00020204UL, x12);
- ASSERT_EQUAL_64(0x0000000400040408UL, x13);
+ CHECK_EQUAL_64(0x00000081, x6);
+ CHECK_EQUAL_64(0x00010102, x7);
+ CHECK_EQUAL_64(0x00020204, x8);
+ CHECK_EQUAL_64(0x0000000400040408UL, x9);
+ CHECK_EQUAL_64(0xffffff81, x10);
+ CHECK_EQUAL_64(0xffffffffffff0102UL, x11);
+ CHECK_EQUAL_64(0xfffffffe00020204UL, x12);
+ CHECK_EQUAL_64(0x0000000400040408UL, x13);
TEARDOWN();
}
@@ -751,8 +761,8 @@ TEST(ands) {
RUN();
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0xf00000ff, x0);
+ CHECK_EQUAL_NZCV(NFlag);
+ CHECK_EQUAL_64(0xf00000ff, x0);
START();
__ Mov(x0, 0xfff0);
@@ -762,8 +772,8 @@ TEST(ands) {
RUN();
- ASSERT_EQUAL_NZCV(ZFlag);
- ASSERT_EQUAL_64(0x00000000, x0);
+ CHECK_EQUAL_NZCV(ZFlag);
+ CHECK_EQUAL_64(0x00000000, x0);
START();
__ Mov(x0, 0x8000000000000000L);
@@ -773,8 +783,8 @@ TEST(ands) {
RUN();
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0x8000000000000000L, x0);
+ CHECK_EQUAL_NZCV(NFlag);
+ CHECK_EQUAL_64(0x8000000000000000L, x0);
START();
__ Mov(x0, 0xfff0);
@@ -783,8 +793,8 @@ TEST(ands) {
RUN();
- ASSERT_EQUAL_NZCV(ZFlag);
- ASSERT_EQUAL_64(0x00000000, x0);
+ CHECK_EQUAL_NZCV(ZFlag);
+ CHECK_EQUAL_64(0x00000000, x0);
START();
__ Mov(x0, 0xff000000);
@@ -793,8 +803,8 @@ TEST(ands) {
RUN();
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0x80000000, x0);
+ CHECK_EQUAL_NZCV(NFlag);
+ CHECK_EQUAL_64(0x80000000, x0);
TEARDOWN();
}
@@ -832,18 +842,18 @@ TEST(bic) {
RUN();
- ASSERT_EQUAL_64(0x0000ff00, x2);
- ASSERT_EQUAL_64(0x0000f000, x3);
- ASSERT_EQUAL_64(0x0000f000, x4);
- ASSERT_EQUAL_64(0x0000ff80, x5);
- ASSERT_EQUAL_64(0x000000f0, x6);
- ASSERT_EQUAL_64(0x0000f0f0, x7);
- ASSERT_EQUAL_64(0x0000f000, x8);
- ASSERT_EQUAL_64(0x0000ff00, x9);
- ASSERT_EQUAL_64(0x0000ffe0, x10);
- ASSERT_EQUAL_64(0x0000fef0, x11);
+ CHECK_EQUAL_64(0x0000ff00, x2);
+ CHECK_EQUAL_64(0x0000f000, x3);
+ CHECK_EQUAL_64(0x0000f000, x4);
+ CHECK_EQUAL_64(0x0000ff80, x5);
+ CHECK_EQUAL_64(0x000000f0, x6);
+ CHECK_EQUAL_64(0x0000f0f0, x7);
+ CHECK_EQUAL_64(0x0000f000, x8);
+ CHECK_EQUAL_64(0x0000ff00, x9);
+ CHECK_EQUAL_64(0x0000ffe0, x10);
+ CHECK_EQUAL_64(0x0000fef0, x11);
- ASSERT_EQUAL_64(0x543210, x21);
+ CHECK_EQUAL_64(0x543210, x21);
TEARDOWN();
}
@@ -868,14 +878,14 @@ TEST(bic_extend) {
RUN();
- ASSERT_EQUAL_64(0xffffff7e, x6);
- ASSERT_EQUAL_64(0xfffffffffffefefdUL, x7);
- ASSERT_EQUAL_64(0xfffdfdfb, x8);
- ASSERT_EQUAL_64(0xfffffffbfffbfbf7UL, x9);
- ASSERT_EQUAL_64(0x0000007e, x10);
- ASSERT_EQUAL_64(0x0000fefd, x11);
- ASSERT_EQUAL_64(0x00000001fffdfdfbUL, x12);
- ASSERT_EQUAL_64(0xfffffffbfffbfbf7UL, x13);
+ CHECK_EQUAL_64(0xffffff7e, x6);
+ CHECK_EQUAL_64(0xfffffffffffefefdUL, x7);
+ CHECK_EQUAL_64(0xfffdfdfb, x8);
+ CHECK_EQUAL_64(0xfffffffbfffbfbf7UL, x9);
+ CHECK_EQUAL_64(0x0000007e, x10);
+ CHECK_EQUAL_64(0x0000fefd, x11);
+ CHECK_EQUAL_64(0x00000001fffdfdfbUL, x12);
+ CHECK_EQUAL_64(0xfffffffbfffbfbf7UL, x13);
TEARDOWN();
}
@@ -892,8 +902,8 @@ TEST(bics) {
RUN();
- ASSERT_EQUAL_NZCV(ZFlag);
- ASSERT_EQUAL_64(0x00000000, x0);
+ CHECK_EQUAL_NZCV(ZFlag);
+ CHECK_EQUAL_64(0x00000000, x0);
START();
__ Mov(x0, 0xffffffff);
@@ -902,8 +912,8 @@ TEST(bics) {
RUN();
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0x80000000, x0);
+ CHECK_EQUAL_NZCV(NFlag);
+ CHECK_EQUAL_64(0x80000000, x0);
START();
__ Mov(x0, 0x8000000000000000L);
@@ -913,8 +923,8 @@ TEST(bics) {
RUN();
- ASSERT_EQUAL_NZCV(ZFlag);
- ASSERT_EQUAL_64(0x00000000, x0);
+ CHECK_EQUAL_NZCV(ZFlag);
+ CHECK_EQUAL_64(0x00000000, x0);
START();
__ Mov(x0, 0xffffffffffffffffL);
@@ -923,8 +933,8 @@ TEST(bics) {
RUN();
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0x8000000000000000L, x0);
+ CHECK_EQUAL_NZCV(NFlag);
+ CHECK_EQUAL_64(0x8000000000000000L, x0);
START();
__ Mov(w0, 0xffff0000);
@@ -933,8 +943,8 @@ TEST(bics) {
RUN();
- ASSERT_EQUAL_NZCV(ZFlag);
- ASSERT_EQUAL_64(0x00000000, x0);
+ CHECK_EQUAL_NZCV(ZFlag);
+ CHECK_EQUAL_64(0x00000000, x0);
TEARDOWN();
}
@@ -962,16 +972,16 @@ TEST(eor) {
RUN();
- ASSERT_EQUAL_64(0xf000ff0f, x2);
- ASSERT_EQUAL_64(0x0000f000, x3);
- ASSERT_EQUAL_64(0x0000000f0000f000L, x4);
- ASSERT_EQUAL_64(0x7800ff8f, x5);
- ASSERT_EQUAL_64(0xffff00f0, x6);
- ASSERT_EQUAL_64(0x0000f0f0, x7);
- ASSERT_EQUAL_64(0x0000f00f, x8);
- ASSERT_EQUAL_64(0x00000ff00000ffffL, x9);
- ASSERT_EQUAL_64(0xff0000f0, x10);
- ASSERT_EQUAL_64(0xff00ff00ff0000f0L, x11);
+ CHECK_EQUAL_64(0xf000ff0f, x2);
+ CHECK_EQUAL_64(0x0000f000, x3);
+ CHECK_EQUAL_64(0x0000000f0000f000L, x4);
+ CHECK_EQUAL_64(0x7800ff8f, x5);
+ CHECK_EQUAL_64(0xffff00f0, x6);
+ CHECK_EQUAL_64(0x0000f0f0, x7);
+ CHECK_EQUAL_64(0x0000f00f, x8);
+ CHECK_EQUAL_64(0x00000ff00000ffffL, x9);
+ CHECK_EQUAL_64(0xff0000f0, x10);
+ CHECK_EQUAL_64(0xff00ff00ff0000f0L, x11);
TEARDOWN();
}
@@ -996,14 +1006,14 @@ TEST(eor_extend) {
RUN();
- ASSERT_EQUAL_64(0x11111190, x6);
- ASSERT_EQUAL_64(0x1111111111101013UL, x7);
- ASSERT_EQUAL_64(0x11131315, x8);
- ASSERT_EQUAL_64(0x1111111511151519UL, x9);
- ASSERT_EQUAL_64(0xeeeeee90, x10);
- ASSERT_EQUAL_64(0xeeeeeeeeeeee1013UL, x11);
- ASSERT_EQUAL_64(0xeeeeeeef11131315UL, x12);
- ASSERT_EQUAL_64(0x1111111511151519UL, x13);
+ CHECK_EQUAL_64(0x11111190, x6);
+ CHECK_EQUAL_64(0x1111111111101013UL, x7);
+ CHECK_EQUAL_64(0x11131315, x8);
+ CHECK_EQUAL_64(0x1111111511151519UL, x9);
+ CHECK_EQUAL_64(0xeeeeee90, x10);
+ CHECK_EQUAL_64(0xeeeeeeeeeeee1013UL, x11);
+ CHECK_EQUAL_64(0xeeeeeeef11131315UL, x12);
+ CHECK_EQUAL_64(0x1111111511151519UL, x13);
TEARDOWN();
}
@@ -1031,16 +1041,16 @@ TEST(eon) {
RUN();
- ASSERT_EQUAL_64(0xffffffff0fff00f0L, x2);
- ASSERT_EQUAL_64(0xffff0fff, x3);
- ASSERT_EQUAL_64(0xfffffff0ffff0fffL, x4);
- ASSERT_EQUAL_64(0xffffffff87ff0070L, x5);
- ASSERT_EQUAL_64(0x0000ff0f, x6);
- ASSERT_EQUAL_64(0xffffffffffff0f0fL, x7);
- ASSERT_EQUAL_64(0xffff0ff0, x8);
- ASSERT_EQUAL_64(0xfffff00fffff0000L, x9);
- ASSERT_EQUAL_64(0xfc3f03cf, x10);
- ASSERT_EQUAL_64(0xffffefffffff100fL, x11);
+ CHECK_EQUAL_64(0xffffffff0fff00f0L, x2);
+ CHECK_EQUAL_64(0xffff0fff, x3);
+ CHECK_EQUAL_64(0xfffffff0ffff0fffL, x4);
+ CHECK_EQUAL_64(0xffffffff87ff0070L, x5);
+ CHECK_EQUAL_64(0x0000ff0f, x6);
+ CHECK_EQUAL_64(0xffffffffffff0f0fL, x7);
+ CHECK_EQUAL_64(0xffff0ff0, x8);
+ CHECK_EQUAL_64(0xfffff00fffff0000L, x9);
+ CHECK_EQUAL_64(0xfc3f03cf, x10);
+ CHECK_EQUAL_64(0xffffefffffff100fL, x11);
TEARDOWN();
}
@@ -1065,14 +1075,14 @@ TEST(eon_extend) {
RUN();
- ASSERT_EQUAL_64(0xeeeeee6f, x6);
- ASSERT_EQUAL_64(0xeeeeeeeeeeefefecUL, x7);
- ASSERT_EQUAL_64(0xeeececea, x8);
- ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6UL, x9);
- ASSERT_EQUAL_64(0x1111116f, x10);
- ASSERT_EQUAL_64(0x111111111111efecUL, x11);
- ASSERT_EQUAL_64(0x11111110eeececeaUL, x12);
- ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6UL, x13);
+ CHECK_EQUAL_64(0xeeeeee6f, x6);
+ CHECK_EQUAL_64(0xeeeeeeeeeeefefecUL, x7);
+ CHECK_EQUAL_64(0xeeececea, x8);
+ CHECK_EQUAL_64(0xeeeeeeeaeeeaeae6UL, x9);
+ CHECK_EQUAL_64(0x1111116f, x10);
+ CHECK_EQUAL_64(0x111111111111efecUL, x11);
+ CHECK_EQUAL_64(0x11111110eeececeaUL, x12);
+ CHECK_EQUAL_64(0xeeeeeeeaeeeaeae6UL, x13);
TEARDOWN();
}
@@ -1111,25 +1121,25 @@ TEST(mul) {
RUN();
- ASSERT_EQUAL_64(0, x0);
- ASSERT_EQUAL_64(0, x1);
- ASSERT_EQUAL_64(0xffffffff, x2);
- ASSERT_EQUAL_64(1, x3);
- ASSERT_EQUAL_64(0, x4);
- ASSERT_EQUAL_64(0xffffffff, x5);
- ASSERT_EQUAL_64(0xffffffff00000001UL, x6);
- ASSERT_EQUAL_64(1, x7);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x8);
- ASSERT_EQUAL_64(1, x9);
- ASSERT_EQUAL_64(1, x10);
- ASSERT_EQUAL_64(0, x11);
- ASSERT_EQUAL_64(0, x12);
- ASSERT_EQUAL_64(1, x13);
- ASSERT_EQUAL_64(0xffffffff, x14);
- ASSERT_EQUAL_64(0, x20);
- ASSERT_EQUAL_64(0xffffffff00000001UL, x21);
- ASSERT_EQUAL_64(0xffffffff, x22);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x23);
+ CHECK_EQUAL_64(0, x0);
+ CHECK_EQUAL_64(0, x1);
+ CHECK_EQUAL_64(0xffffffff, x2);
+ CHECK_EQUAL_64(1, x3);
+ CHECK_EQUAL_64(0, x4);
+ CHECK_EQUAL_64(0xffffffff, x5);
+ CHECK_EQUAL_64(0xffffffff00000001UL, x6);
+ CHECK_EQUAL_64(1, x7);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x8);
+ CHECK_EQUAL_64(1, x9);
+ CHECK_EQUAL_64(1, x10);
+ CHECK_EQUAL_64(0, x11);
+ CHECK_EQUAL_64(0, x12);
+ CHECK_EQUAL_64(1, x13);
+ CHECK_EQUAL_64(0xffffffff, x14);
+ CHECK_EQUAL_64(0, x20);
+ CHECK_EQUAL_64(0xffffffff00000001UL, x21);
+ CHECK_EQUAL_64(0xffffffff, x22);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x23);
TEARDOWN();
}
@@ -1143,7 +1153,7 @@ static void SmullHelper(int64_t expected, int64_t a, int64_t b) {
__ Smull(x2, w0, w1);
END();
RUN();
- ASSERT_EQUAL_64(expected, x2);
+ CHECK_EQUAL_64(expected, x2);
TEARDOWN();
}
@@ -1199,31 +1209,31 @@ TEST(madd) {
RUN();
- ASSERT_EQUAL_64(0, x0);
- ASSERT_EQUAL_64(1, x1);
- ASSERT_EQUAL_64(0xffffffff, x2);
- ASSERT_EQUAL_64(0xffffffff, x3);
- ASSERT_EQUAL_64(1, x4);
- ASSERT_EQUAL_64(0, x5);
- ASSERT_EQUAL_64(0, x6);
- ASSERT_EQUAL_64(0xffffffff, x7);
- ASSERT_EQUAL_64(0xfffffffe, x8);
- ASSERT_EQUAL_64(2, x9);
- ASSERT_EQUAL_64(0, x10);
- ASSERT_EQUAL_64(0, x11);
+ CHECK_EQUAL_64(0, x0);
+ CHECK_EQUAL_64(1, x1);
+ CHECK_EQUAL_64(0xffffffff, x2);
+ CHECK_EQUAL_64(0xffffffff, x3);
+ CHECK_EQUAL_64(1, x4);
+ CHECK_EQUAL_64(0, x5);
+ CHECK_EQUAL_64(0, x6);
+ CHECK_EQUAL_64(0xffffffff, x7);
+ CHECK_EQUAL_64(0xfffffffe, x8);
+ CHECK_EQUAL_64(2, x9);
+ CHECK_EQUAL_64(0, x10);
+ CHECK_EQUAL_64(0, x11);
- ASSERT_EQUAL_64(0, x12);
- ASSERT_EQUAL_64(1, x13);
- ASSERT_EQUAL_64(0xffffffff, x14);
- ASSERT_EQUAL_64(0xffffffffffffffff, x15);
- ASSERT_EQUAL_64(1, x20);
- ASSERT_EQUAL_64(0x100000000UL, x21);
- ASSERT_EQUAL_64(0, x22);
- ASSERT_EQUAL_64(0xffffffff, x23);
- ASSERT_EQUAL_64(0x1fffffffe, x24);
- ASSERT_EQUAL_64(0xfffffffe00000002UL, x25);
- ASSERT_EQUAL_64(0, x26);
- ASSERT_EQUAL_64(0, x27);
+ CHECK_EQUAL_64(0, x12);
+ CHECK_EQUAL_64(1, x13);
+ CHECK_EQUAL_64(0xffffffff, x14);
+ CHECK_EQUAL_64(0xffffffffffffffff, x15);
+ CHECK_EQUAL_64(1, x20);
+ CHECK_EQUAL_64(0x100000000UL, x21);
+ CHECK_EQUAL_64(0, x22);
+ CHECK_EQUAL_64(0xffffffff, x23);
+ CHECK_EQUAL_64(0x1fffffffe, x24);
+ CHECK_EQUAL_64(0xfffffffe00000002UL, x25);
+ CHECK_EQUAL_64(0, x26);
+ CHECK_EQUAL_64(0, x27);
TEARDOWN();
}
@@ -1269,31 +1279,31 @@ TEST(msub) {
RUN();
- ASSERT_EQUAL_64(0, x0);
- ASSERT_EQUAL_64(1, x1);
- ASSERT_EQUAL_64(0xffffffff, x2);
- ASSERT_EQUAL_64(0xffffffff, x3);
- ASSERT_EQUAL_64(1, x4);
- ASSERT_EQUAL_64(0xfffffffe, x5);
- ASSERT_EQUAL_64(0xfffffffe, x6);
- ASSERT_EQUAL_64(1, x7);
- ASSERT_EQUAL_64(0, x8);
- ASSERT_EQUAL_64(0, x9);
- ASSERT_EQUAL_64(0xfffffffe, x10);
- ASSERT_EQUAL_64(0xfffffffe, x11);
+ CHECK_EQUAL_64(0, x0);
+ CHECK_EQUAL_64(1, x1);
+ CHECK_EQUAL_64(0xffffffff, x2);
+ CHECK_EQUAL_64(0xffffffff, x3);
+ CHECK_EQUAL_64(1, x4);
+ CHECK_EQUAL_64(0xfffffffe, x5);
+ CHECK_EQUAL_64(0xfffffffe, x6);
+ CHECK_EQUAL_64(1, x7);
+ CHECK_EQUAL_64(0, x8);
+ CHECK_EQUAL_64(0, x9);
+ CHECK_EQUAL_64(0xfffffffe, x10);
+ CHECK_EQUAL_64(0xfffffffe, x11);
- ASSERT_EQUAL_64(0, x12);
- ASSERT_EQUAL_64(1, x13);
- ASSERT_EQUAL_64(0xffffffff, x14);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x15);
- ASSERT_EQUAL_64(1, x20);
- ASSERT_EQUAL_64(0xfffffffeUL, x21);
- ASSERT_EQUAL_64(0xfffffffffffffffeUL, x22);
- ASSERT_EQUAL_64(0xffffffff00000001UL, x23);
- ASSERT_EQUAL_64(0, x24);
- ASSERT_EQUAL_64(0x200000000UL, x25);
- ASSERT_EQUAL_64(0x1fffffffeUL, x26);
- ASSERT_EQUAL_64(0xfffffffffffffffeUL, x27);
+ CHECK_EQUAL_64(0, x12);
+ CHECK_EQUAL_64(1, x13);
+ CHECK_EQUAL_64(0xffffffff, x14);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x15);
+ CHECK_EQUAL_64(1, x20);
+ CHECK_EQUAL_64(0xfffffffeUL, x21);
+ CHECK_EQUAL_64(0xfffffffffffffffeUL, x22);
+ CHECK_EQUAL_64(0xffffffff00000001UL, x23);
+ CHECK_EQUAL_64(0, x24);
+ CHECK_EQUAL_64(0x200000000UL, x25);
+ CHECK_EQUAL_64(0x1fffffffeUL, x26);
+ CHECK_EQUAL_64(0xfffffffffffffffeUL, x27);
TEARDOWN();
}
@@ -1331,18 +1341,18 @@ TEST(smulh) {
RUN();
- ASSERT_EQUAL_64(0, x0);
- ASSERT_EQUAL_64(0, x1);
- ASSERT_EQUAL_64(0, x2);
- ASSERT_EQUAL_64(0x01234567, x3);
- ASSERT_EQUAL_64(0x02468acf, x4);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x5);
- ASSERT_EQUAL_64(0x4000000000000000UL, x6);
- ASSERT_EQUAL_64(0, x7);
- ASSERT_EQUAL_64(0, x8);
- ASSERT_EQUAL_64(0x1c71c71c71c71c71UL, x9);
- ASSERT_EQUAL_64(0xe38e38e38e38e38eUL, x10);
- ASSERT_EQUAL_64(0x1c71c71c71c71c72UL, x11);
+ CHECK_EQUAL_64(0, x0);
+ CHECK_EQUAL_64(0, x1);
+ CHECK_EQUAL_64(0, x2);
+ CHECK_EQUAL_64(0x01234567, x3);
+ CHECK_EQUAL_64(0x02468acf, x4);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x5);
+ CHECK_EQUAL_64(0x4000000000000000UL, x6);
+ CHECK_EQUAL_64(0, x7);
+ CHECK_EQUAL_64(0, x8);
+ CHECK_EQUAL_64(0x1c71c71c71c71c71UL, x9);
+ CHECK_EQUAL_64(0xe38e38e38e38e38eUL, x10);
+ CHECK_EQUAL_64(0x1c71c71c71c71c72UL, x11);
TEARDOWN();
}
@@ -1371,14 +1381,14 @@ TEST(smaddl_umaddl) {
RUN();
- ASSERT_EQUAL_64(3, x9);
- ASSERT_EQUAL_64(5, x10);
- ASSERT_EQUAL_64(5, x11);
- ASSERT_EQUAL_64(0x200000001UL, x12);
- ASSERT_EQUAL_64(0x100000003UL, x13);
- ASSERT_EQUAL_64(0xfffffffe00000005UL, x14);
- ASSERT_EQUAL_64(0xfffffffe00000005UL, x15);
- ASSERT_EQUAL_64(0x1, x22);
+ CHECK_EQUAL_64(3, x9);
+ CHECK_EQUAL_64(5, x10);
+ CHECK_EQUAL_64(5, x11);
+ CHECK_EQUAL_64(0x200000001UL, x12);
+ CHECK_EQUAL_64(0x100000003UL, x13);
+ CHECK_EQUAL_64(0xfffffffe00000005UL, x14);
+ CHECK_EQUAL_64(0xfffffffe00000005UL, x15);
+ CHECK_EQUAL_64(0x1, x22);
TEARDOWN();
}
@@ -1407,14 +1417,14 @@ TEST(smsubl_umsubl) {
RUN();
- ASSERT_EQUAL_64(5, x9);
- ASSERT_EQUAL_64(3, x10);
- ASSERT_EQUAL_64(3, x11);
- ASSERT_EQUAL_64(0x1ffffffffUL, x12);
- ASSERT_EQUAL_64(0xffffffff00000005UL, x13);
- ASSERT_EQUAL_64(0x200000003UL, x14);
- ASSERT_EQUAL_64(0x200000003UL, x15);
- ASSERT_EQUAL_64(0x3ffffffffUL, x22);
+ CHECK_EQUAL_64(5, x9);
+ CHECK_EQUAL_64(3, x10);
+ CHECK_EQUAL_64(3, x11);
+ CHECK_EQUAL_64(0x1ffffffffUL, x12);
+ CHECK_EQUAL_64(0xffffffff00000005UL, x13);
+ CHECK_EQUAL_64(0x200000003UL, x14);
+ CHECK_EQUAL_64(0x200000003UL, x15);
+ CHECK_EQUAL_64(0x3ffffffffUL, x22);
TEARDOWN();
}
@@ -1470,34 +1480,34 @@ TEST(div) {
RUN();
- ASSERT_EQUAL_64(1, x0);
- ASSERT_EQUAL_64(0xffffffff, x1);
- ASSERT_EQUAL_64(1, x2);
- ASSERT_EQUAL_64(0xffffffff, x3);
- ASSERT_EQUAL_64(1, x4);
- ASSERT_EQUAL_64(1, x5);
- ASSERT_EQUAL_64(0, x6);
- ASSERT_EQUAL_64(1, x7);
- ASSERT_EQUAL_64(0, x8);
- ASSERT_EQUAL_64(0xffffffff00000001UL, x9);
- ASSERT_EQUAL_64(0x40000000, x10);
- ASSERT_EQUAL_64(0xC0000000, x11);
- ASSERT_EQUAL_64(0x40000000, x12);
- ASSERT_EQUAL_64(0x40000000, x13);
- ASSERT_EQUAL_64(0x4000000000000000UL, x14);
- ASSERT_EQUAL_64(0xC000000000000000UL, x15);
- ASSERT_EQUAL_64(0, x22);
- ASSERT_EQUAL_64(0x80000000, x23);
- ASSERT_EQUAL_64(0, x24);
- ASSERT_EQUAL_64(0x8000000000000000UL, x25);
- ASSERT_EQUAL_64(0, x26);
- ASSERT_EQUAL_64(0, x27);
- ASSERT_EQUAL_64(0x7fffffffffffffffUL, x28);
- ASSERT_EQUAL_64(0, x29);
- ASSERT_EQUAL_64(0, x18);
- ASSERT_EQUAL_64(0, x19);
- ASSERT_EQUAL_64(0, x20);
- ASSERT_EQUAL_64(0, x21);
+ CHECK_EQUAL_64(1, x0);
+ CHECK_EQUAL_64(0xffffffff, x1);
+ CHECK_EQUAL_64(1, x2);
+ CHECK_EQUAL_64(0xffffffff, x3);
+ CHECK_EQUAL_64(1, x4);
+ CHECK_EQUAL_64(1, x5);
+ CHECK_EQUAL_64(0, x6);
+ CHECK_EQUAL_64(1, x7);
+ CHECK_EQUAL_64(0, x8);
+ CHECK_EQUAL_64(0xffffffff00000001UL, x9);
+ CHECK_EQUAL_64(0x40000000, x10);
+ CHECK_EQUAL_64(0xC0000000, x11);
+ CHECK_EQUAL_64(0x40000000, x12);
+ CHECK_EQUAL_64(0x40000000, x13);
+ CHECK_EQUAL_64(0x4000000000000000UL, x14);
+ CHECK_EQUAL_64(0xC000000000000000UL, x15);
+ CHECK_EQUAL_64(0, x22);
+ CHECK_EQUAL_64(0x80000000, x23);
+ CHECK_EQUAL_64(0, x24);
+ CHECK_EQUAL_64(0x8000000000000000UL, x25);
+ CHECK_EQUAL_64(0, x26);
+ CHECK_EQUAL_64(0, x27);
+ CHECK_EQUAL_64(0x7fffffffffffffffUL, x28);
+ CHECK_EQUAL_64(0, x29);
+ CHECK_EQUAL_64(0, x18);
+ CHECK_EQUAL_64(0, x19);
+ CHECK_EQUAL_64(0, x20);
+ CHECK_EQUAL_64(0, x21);
TEARDOWN();
}
@@ -1520,13 +1530,13 @@ TEST(rbit_rev) {
RUN();
- ASSERT_EQUAL_64(0x084c2a6e, x0);
- ASSERT_EQUAL_64(0x084c2a6e195d3b7fUL, x1);
- ASSERT_EQUAL_64(0x54761032, x2);
- ASSERT_EQUAL_64(0xdcfe98ba54761032UL, x3);
- ASSERT_EQUAL_64(0x10325476, x4);
- ASSERT_EQUAL_64(0x98badcfe10325476UL, x5);
- ASSERT_EQUAL_64(0x1032547698badcfeUL, x6);
+ CHECK_EQUAL_64(0x084c2a6e, x0);
+ CHECK_EQUAL_64(0x084c2a6e195d3b7fUL, x1);
+ CHECK_EQUAL_64(0x54761032, x2);
+ CHECK_EQUAL_64(0xdcfe98ba54761032UL, x3);
+ CHECK_EQUAL_64(0x10325476, x4);
+ CHECK_EQUAL_64(0x98badcfe10325476UL, x5);
+ CHECK_EQUAL_64(0x1032547698badcfeUL, x6);
TEARDOWN();
}
@@ -1556,18 +1566,18 @@ TEST(clz_cls) {
RUN();
- ASSERT_EQUAL_64(8, x0);
- ASSERT_EQUAL_64(12, x1);
- ASSERT_EQUAL_64(0, x2);
- ASSERT_EQUAL_64(0, x3);
- ASSERT_EQUAL_64(32, x4);
- ASSERT_EQUAL_64(64, x5);
- ASSERT_EQUAL_64(7, x6);
- ASSERT_EQUAL_64(11, x7);
- ASSERT_EQUAL_64(12, x8);
- ASSERT_EQUAL_64(8, x9);
- ASSERT_EQUAL_64(31, x10);
- ASSERT_EQUAL_64(63, x11);
+ CHECK_EQUAL_64(8, x0);
+ CHECK_EQUAL_64(12, x1);
+ CHECK_EQUAL_64(0, x2);
+ CHECK_EQUAL_64(0, x3);
+ CHECK_EQUAL_64(32, x4);
+ CHECK_EQUAL_64(64, x5);
+ CHECK_EQUAL_64(7, x6);
+ CHECK_EQUAL_64(11, x7);
+ CHECK_EQUAL_64(12, x8);
+ CHECK_EQUAL_64(8, x9);
+ CHECK_EQUAL_64(31, x10);
+ CHECK_EQUAL_64(63, x11);
TEARDOWN();
}
@@ -1605,8 +1615,8 @@ TEST(label) {
RUN();
- ASSERT_EQUAL_64(0x1, x0);
- ASSERT_EQUAL_64(0x1, x1);
+ CHECK_EQUAL_64(0x1, x0);
+ CHECK_EQUAL_64(0x1, x1);
TEARDOWN();
}
@@ -1639,7 +1649,7 @@ TEST(branch_at_start) {
RUN();
- ASSERT_EQUAL_64(0x1, x0);
+ CHECK_EQUAL_64(0x1, x0);
TEARDOWN();
}
@@ -1683,8 +1693,8 @@ TEST(adr) {
RUN();
- ASSERT_EQUAL_64(0x0, x0);
- ASSERT_EQUAL_64(0x0, x1);
+ CHECK_EQUAL_64(0x0, x0);
+ CHECK_EQUAL_64(0x0, x1);
TEARDOWN();
}
@@ -1749,7 +1759,7 @@ TEST(adr_far) {
RUN();
- ASSERT_EQUAL_64(0xf, x0);
+ CHECK_EQUAL_64(0xf, x0);
TEARDOWN();
}
@@ -1839,7 +1849,7 @@ TEST(branch_cond) {
RUN();
- ASSERT_EQUAL_64(0x1, x0);
+ CHECK_EQUAL_64(0x1, x0);
TEARDOWN();
}
@@ -1886,9 +1896,9 @@ TEST(branch_to_reg) {
RUN();
- ASSERT_EQUAL_64(core.xreg(3) + kInstructionSize, x0);
- ASSERT_EQUAL_64(42, x1);
- ASSERT_EQUAL_64(84, x2);
+ CHECK_EQUAL_64(core.xreg(3) + kInstructionSize, x0);
+ CHECK_EQUAL_64(42, x1);
+ CHECK_EQUAL_64(84, x2);
TEARDOWN();
}
@@ -1956,12 +1966,12 @@ TEST(compare_branch) {
RUN();
- ASSERT_EQUAL_64(1, x0);
- ASSERT_EQUAL_64(0, x1);
- ASSERT_EQUAL_64(1, x2);
- ASSERT_EQUAL_64(0, x3);
- ASSERT_EQUAL_64(1, x4);
- ASSERT_EQUAL_64(0, x5);
+ CHECK_EQUAL_64(1, x0);
+ CHECK_EQUAL_64(0, x1);
+ CHECK_EQUAL_64(1, x2);
+ CHECK_EQUAL_64(0, x3);
+ CHECK_EQUAL_64(1, x4);
+ CHECK_EQUAL_64(0, x5);
TEARDOWN();
}
@@ -2009,10 +2019,10 @@ TEST(test_branch) {
RUN();
- ASSERT_EQUAL_64(1, x0);
- ASSERT_EQUAL_64(0, x1);
- ASSERT_EQUAL_64(1, x2);
- ASSERT_EQUAL_64(0, x3);
+ CHECK_EQUAL_64(1, x0);
+ CHECK_EQUAL_64(0, x1);
+ CHECK_EQUAL_64(1, x2);
+ CHECK_EQUAL_64(0, x3);
TEARDOWN();
}
@@ -2085,8 +2095,8 @@ TEST(far_branch_backward) {
RUN();
- ASSERT_EQUAL_64(0x7, x0);
- ASSERT_EQUAL_64(0x1, x1);
+ CHECK_EQUAL_64(0x7, x0);
+ CHECK_EQUAL_64(0x1, x1);
TEARDOWN();
}
@@ -2155,8 +2165,8 @@ TEST(far_branch_simple_veneer) {
RUN();
- ASSERT_EQUAL_64(0x7, x0);
- ASSERT_EQUAL_64(0x1, x1);
+ CHECK_EQUAL_64(0x7, x0);
+ CHECK_EQUAL_64(0x1, x1);
TEARDOWN();
}
@@ -2250,8 +2260,8 @@ TEST(far_branch_veneer_link_chain) {
RUN();
- ASSERT_EQUAL_64(0x7, x0);
- ASSERT_EQUAL_64(0x1, x1);
+ CHECK_EQUAL_64(0x7, x0);
+ CHECK_EQUAL_64(0x1, x1);
TEARDOWN();
}
@@ -2340,8 +2350,8 @@ TEST(far_branch_veneer_broken_link_chain) {
RUN();
- ASSERT_EQUAL_64(0x3, x0);
- ASSERT_EQUAL_64(0x1, x1);
+ CHECK_EQUAL_64(0x3, x0);
+ CHECK_EQUAL_64(0x1, x1);
TEARDOWN();
}
@@ -2398,7 +2408,7 @@ TEST(branch_type) {
RUN();
- ASSERT_EQUAL_64(0x0, x0);
+ CHECK_EQUAL_64(0x0, x0);
TEARDOWN();
}
@@ -2430,18 +2440,18 @@ TEST(ldr_str_offset) {
RUN();
- ASSERT_EQUAL_64(0x76543210, x0);
- ASSERT_EQUAL_64(0x76543210, dst[0]);
- ASSERT_EQUAL_64(0xfedcba98, x1);
- ASSERT_EQUAL_64(0xfedcba9800000000UL, dst[1]);
- ASSERT_EQUAL_64(0x0123456789abcdefUL, x2);
- ASSERT_EQUAL_64(0x0123456789abcdefUL, dst[2]);
- ASSERT_EQUAL_64(0x32, x3);
- ASSERT_EQUAL_64(0x3200, dst[3]);
- ASSERT_EQUAL_64(0x7654, x4);
- ASSERT_EQUAL_64(0x765400, dst[4]);
- ASSERT_EQUAL_64(src_base, x17);
- ASSERT_EQUAL_64(dst_base, x18);
+ CHECK_EQUAL_64(0x76543210, x0);
+ CHECK_EQUAL_64(0x76543210, dst[0]);
+ CHECK_EQUAL_64(0xfedcba98, x1);
+ CHECK_EQUAL_64(0xfedcba9800000000UL, dst[1]);
+ CHECK_EQUAL_64(0x0123456789abcdefUL, x2);
+ CHECK_EQUAL_64(0x0123456789abcdefUL, dst[2]);
+ CHECK_EQUAL_64(0x32, x3);
+ CHECK_EQUAL_64(0x3200, dst[3]);
+ CHECK_EQUAL_64(0x7654, x4);
+ CHECK_EQUAL_64(0x765400, dst[4]);
+ CHECK_EQUAL_64(src_base, x17);
+ CHECK_EQUAL_64(dst_base, x18);
TEARDOWN();
}
@@ -2479,18 +2489,18 @@ TEST(ldr_str_wide) {
RUN();
- ASSERT_EQUAL_32(8191, w0);
- ASSERT_EQUAL_32(8191, dst[8191]);
- ASSERT_EQUAL_64(src_base, x22);
- ASSERT_EQUAL_64(dst_base, x23);
- ASSERT_EQUAL_32(0, w1);
- ASSERT_EQUAL_32(0, dst[0]);
- ASSERT_EQUAL_64(src_base + 4096 * sizeof(src[0]), x24);
- ASSERT_EQUAL_64(dst_base + 4096 * sizeof(dst[0]), x25);
- ASSERT_EQUAL_32(6144, w2);
- ASSERT_EQUAL_32(6144, dst[6144]);
- ASSERT_EQUAL_64(src_base + 6144 * sizeof(src[0]), x26);
- ASSERT_EQUAL_64(dst_base + 6144 * sizeof(dst[0]), x27);
+ CHECK_EQUAL_32(8191, w0);
+ CHECK_EQUAL_32(8191, dst[8191]);
+ CHECK_EQUAL_64(src_base, x22);
+ CHECK_EQUAL_64(dst_base, x23);
+ CHECK_EQUAL_32(0, w1);
+ CHECK_EQUAL_32(0, dst[0]);
+ CHECK_EQUAL_64(src_base + 4096 * sizeof(src[0]), x24);
+ CHECK_EQUAL_64(dst_base + 4096 * sizeof(dst[0]), x25);
+ CHECK_EQUAL_32(6144, w2);
+ CHECK_EQUAL_32(6144, dst[6144]);
+ CHECK_EQUAL_64(src_base + 6144 * sizeof(src[0]), x26);
+ CHECK_EQUAL_64(dst_base + 6144 * sizeof(dst[0]), x27);
TEARDOWN();
}
@@ -2530,26 +2540,26 @@ TEST(ldr_str_preindex) {
RUN();
- ASSERT_EQUAL_64(0xfedcba98, x0);
- ASSERT_EQUAL_64(0xfedcba9800000000UL, dst[1]);
- ASSERT_EQUAL_64(0x0123456789abcdefUL, x1);
- ASSERT_EQUAL_64(0x0123456789abcdefUL, dst[2]);
- ASSERT_EQUAL_64(0x01234567, x2);
- ASSERT_EQUAL_64(0x0123456700000000UL, dst[4]);
- ASSERT_EQUAL_64(0x32, x3);
- ASSERT_EQUAL_64(0x3200, dst[3]);
- ASSERT_EQUAL_64(0x9876, x4);
- ASSERT_EQUAL_64(0x987600, dst[5]);
- ASSERT_EQUAL_64(src_base + 4, x17);
- ASSERT_EQUAL_64(dst_base + 12, x18);
- ASSERT_EQUAL_64(src_base + 8, x19);
- ASSERT_EQUAL_64(dst_base + 16, x20);
- ASSERT_EQUAL_64(src_base + 12, x21);
- ASSERT_EQUAL_64(dst_base + 36, x22);
- ASSERT_EQUAL_64(src_base + 1, x23);
- ASSERT_EQUAL_64(dst_base + 25, x24);
- ASSERT_EQUAL_64(src_base + 3, x25);
- ASSERT_EQUAL_64(dst_base + 41, x26);
+ CHECK_EQUAL_64(0xfedcba98, x0);
+ CHECK_EQUAL_64(0xfedcba9800000000UL, dst[1]);
+ CHECK_EQUAL_64(0x0123456789abcdefUL, x1);
+ CHECK_EQUAL_64(0x0123456789abcdefUL, dst[2]);
+ CHECK_EQUAL_64(0x01234567, x2);
+ CHECK_EQUAL_64(0x0123456700000000UL, dst[4]);
+ CHECK_EQUAL_64(0x32, x3);
+ CHECK_EQUAL_64(0x3200, dst[3]);
+ CHECK_EQUAL_64(0x9876, x4);
+ CHECK_EQUAL_64(0x987600, dst[5]);
+ CHECK_EQUAL_64(src_base + 4, x17);
+ CHECK_EQUAL_64(dst_base + 12, x18);
+ CHECK_EQUAL_64(src_base + 8, x19);
+ CHECK_EQUAL_64(dst_base + 16, x20);
+ CHECK_EQUAL_64(src_base + 12, x21);
+ CHECK_EQUAL_64(dst_base + 36, x22);
+ CHECK_EQUAL_64(src_base + 1, x23);
+ CHECK_EQUAL_64(dst_base + 25, x24);
+ CHECK_EQUAL_64(src_base + 3, x25);
+ CHECK_EQUAL_64(dst_base + 41, x26);
TEARDOWN();
}
@@ -2589,26 +2599,26 @@ TEST(ldr_str_postindex) {
RUN();
- ASSERT_EQUAL_64(0xfedcba98, x0);
- ASSERT_EQUAL_64(0xfedcba9800000000UL, dst[1]);
- ASSERT_EQUAL_64(0x0123456789abcdefUL, x1);
- ASSERT_EQUAL_64(0x0123456789abcdefUL, dst[2]);
- ASSERT_EQUAL_64(0x0123456789abcdefUL, x2);
- ASSERT_EQUAL_64(0x0123456789abcdefUL, dst[4]);
- ASSERT_EQUAL_64(0x32, x3);
- ASSERT_EQUAL_64(0x3200, dst[3]);
- ASSERT_EQUAL_64(0x9876, x4);
- ASSERT_EQUAL_64(0x987600, dst[5]);
- ASSERT_EQUAL_64(src_base + 8, x17);
- ASSERT_EQUAL_64(dst_base + 24, x18);
- ASSERT_EQUAL_64(src_base + 16, x19);
- ASSERT_EQUAL_64(dst_base + 32, x20);
- ASSERT_EQUAL_64(src_base, x21);
- ASSERT_EQUAL_64(dst_base, x22);
- ASSERT_EQUAL_64(src_base + 2, x23);
- ASSERT_EQUAL_64(dst_base + 30, x24);
- ASSERT_EQUAL_64(src_base, x25);
- ASSERT_EQUAL_64(dst_base, x26);
+ CHECK_EQUAL_64(0xfedcba98, x0);
+ CHECK_EQUAL_64(0xfedcba9800000000UL, dst[1]);
+ CHECK_EQUAL_64(0x0123456789abcdefUL, x1);
+ CHECK_EQUAL_64(0x0123456789abcdefUL, dst[2]);
+ CHECK_EQUAL_64(0x0123456789abcdefUL, x2);
+ CHECK_EQUAL_64(0x0123456789abcdefUL, dst[4]);
+ CHECK_EQUAL_64(0x32, x3);
+ CHECK_EQUAL_64(0x3200, dst[3]);
+ CHECK_EQUAL_64(0x9876, x4);
+ CHECK_EQUAL_64(0x987600, dst[5]);
+ CHECK_EQUAL_64(src_base + 8, x17);
+ CHECK_EQUAL_64(dst_base + 24, x18);
+ CHECK_EQUAL_64(src_base + 16, x19);
+ CHECK_EQUAL_64(dst_base + 32, x20);
+ CHECK_EQUAL_64(src_base, x21);
+ CHECK_EQUAL_64(dst_base, x22);
+ CHECK_EQUAL_64(src_base + 2, x23);
+ CHECK_EQUAL_64(dst_base + 30, x24);
+ CHECK_EQUAL_64(src_base, x25);
+ CHECK_EQUAL_64(dst_base, x26);
TEARDOWN();
}
@@ -2637,16 +2647,16 @@ TEST(load_signed) {
RUN();
- ASSERT_EQUAL_64(0xffffff80, x0);
- ASSERT_EQUAL_64(0x0000007f, x1);
- ASSERT_EQUAL_64(0xffff8080, x2);
- ASSERT_EQUAL_64(0x00007f7f, x3);
- ASSERT_EQUAL_64(0xffffffffffffff80UL, x4);
- ASSERT_EQUAL_64(0x000000000000007fUL, x5);
- ASSERT_EQUAL_64(0xffffffffffff8080UL, x6);
- ASSERT_EQUAL_64(0x0000000000007f7fUL, x7);
- ASSERT_EQUAL_64(0xffffffff80008080UL, x8);
- ASSERT_EQUAL_64(0x000000007fff7f7fUL, x9);
+ CHECK_EQUAL_64(0xffffff80, x0);
+ CHECK_EQUAL_64(0x0000007f, x1);
+ CHECK_EQUAL_64(0xffff8080, x2);
+ CHECK_EQUAL_64(0x00007f7f, x3);
+ CHECK_EQUAL_64(0xffffffffffffff80UL, x4);
+ CHECK_EQUAL_64(0x000000000000007fUL, x5);
+ CHECK_EQUAL_64(0xffffffffffff8080UL, x6);
+ CHECK_EQUAL_64(0x0000000000007f7fUL, x7);
+ CHECK_EQUAL_64(0xffffffff80008080UL, x8);
+ CHECK_EQUAL_64(0x000000007fff7f7fUL, x9);
TEARDOWN();
}
@@ -2686,15 +2696,15 @@ TEST(load_store_regoffset) {
RUN();
- ASSERT_EQUAL_64(1, x0);
- ASSERT_EQUAL_64(0x0000000300000002UL, x1);
- ASSERT_EQUAL_64(3, x2);
- ASSERT_EQUAL_64(3, x3);
- ASSERT_EQUAL_64(2, x4);
- ASSERT_EQUAL_32(1, dst[0]);
- ASSERT_EQUAL_32(2, dst[1]);
- ASSERT_EQUAL_32(3, dst[2]);
- ASSERT_EQUAL_32(3, dst[3]);
+ CHECK_EQUAL_64(1, x0);
+ CHECK_EQUAL_64(0x0000000300000002UL, x1);
+ CHECK_EQUAL_64(3, x2);
+ CHECK_EQUAL_64(3, x3);
+ CHECK_EQUAL_64(2, x4);
+ CHECK_EQUAL_32(1, dst[0]);
+ CHECK_EQUAL_32(2, dst[1]);
+ CHECK_EQUAL_32(3, dst[2]);
+ CHECK_EQUAL_32(3, dst[3]);
TEARDOWN();
}
@@ -2726,18 +2736,18 @@ TEST(load_store_float) {
RUN();
- ASSERT_EQUAL_FP32(2.0, s0);
- ASSERT_EQUAL_FP32(2.0, dst[0]);
- ASSERT_EQUAL_FP32(1.0, s1);
- ASSERT_EQUAL_FP32(1.0, dst[2]);
- ASSERT_EQUAL_FP32(3.0, s2);
- ASSERT_EQUAL_FP32(3.0, dst[1]);
- ASSERT_EQUAL_64(src_base, x17);
- ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
- ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
- ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
- ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
- ASSERT_EQUAL_64(dst_base, x22);
+ CHECK_EQUAL_FP32(2.0, s0);
+ CHECK_EQUAL_FP32(2.0, dst[0]);
+ CHECK_EQUAL_FP32(1.0, s1);
+ CHECK_EQUAL_FP32(1.0, dst[2]);
+ CHECK_EQUAL_FP32(3.0, s2);
+ CHECK_EQUAL_FP32(3.0, dst[1]);
+ CHECK_EQUAL_64(src_base, x17);
+ CHECK_EQUAL_64(dst_base + sizeof(dst[0]), x18);
+ CHECK_EQUAL_64(src_base + sizeof(src[0]), x19);
+ CHECK_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
+ CHECK_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
+ CHECK_EQUAL_64(dst_base, x22);
TEARDOWN();
}
@@ -2769,18 +2779,18 @@ TEST(load_store_double) {
RUN();
- ASSERT_EQUAL_FP64(2.0, d0);
- ASSERT_EQUAL_FP64(2.0, dst[0]);
- ASSERT_EQUAL_FP64(1.0, d1);
- ASSERT_EQUAL_FP64(1.0, dst[2]);
- ASSERT_EQUAL_FP64(3.0, d2);
- ASSERT_EQUAL_FP64(3.0, dst[1]);
- ASSERT_EQUAL_64(src_base, x17);
- ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
- ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
- ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
- ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
- ASSERT_EQUAL_64(dst_base, x22);
+ CHECK_EQUAL_FP64(2.0, d0);
+ CHECK_EQUAL_FP64(2.0, dst[0]);
+ CHECK_EQUAL_FP64(1.0, d1);
+ CHECK_EQUAL_FP64(1.0, dst[2]);
+ CHECK_EQUAL_FP64(3.0, d2);
+ CHECK_EQUAL_FP64(3.0, dst[1]);
+ CHECK_EQUAL_64(src_base, x17);
+ CHECK_EQUAL_64(dst_base + sizeof(dst[0]), x18);
+ CHECK_EQUAL_64(src_base + sizeof(src[0]), x19);
+ CHECK_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
+ CHECK_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
+ CHECK_EQUAL_64(dst_base, x22);
TEARDOWN();
}
@@ -2804,13 +2814,13 @@ TEST(ldp_stp_float) {
RUN();
- ASSERT_EQUAL_FP32(1.0, s31);
- ASSERT_EQUAL_FP32(2.0, s0);
- ASSERT_EQUAL_FP32(0.0, dst[0]);
- ASSERT_EQUAL_FP32(2.0, dst[1]);
- ASSERT_EQUAL_FP32(1.0, dst[2]);
- ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
- ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
+ CHECK_EQUAL_FP32(1.0, s31);
+ CHECK_EQUAL_FP32(2.0, s0);
+ CHECK_EQUAL_FP32(0.0, dst[0]);
+ CHECK_EQUAL_FP32(2.0, dst[1]);
+ CHECK_EQUAL_FP32(1.0, dst[2]);
+ CHECK_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
+ CHECK_EQUAL_64(dst_base + sizeof(dst[1]), x17);
TEARDOWN();
}
@@ -2834,13 +2844,13 @@ TEST(ldp_stp_double) {
RUN();
- ASSERT_EQUAL_FP64(1.0, d31);
- ASSERT_EQUAL_FP64(2.0, d0);
- ASSERT_EQUAL_FP64(0.0, dst[0]);
- ASSERT_EQUAL_FP64(2.0, dst[1]);
- ASSERT_EQUAL_FP64(1.0, dst[2]);
- ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
- ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
+ CHECK_EQUAL_FP64(1.0, d31);
+ CHECK_EQUAL_FP64(2.0, d0);
+ CHECK_EQUAL_FP64(0.0, dst[0]);
+ CHECK_EQUAL_FP64(2.0, dst[1]);
+ CHECK_EQUAL_FP64(1.0, dst[2]);
+ CHECK_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
+ CHECK_EQUAL_64(dst_base + sizeof(dst[1]), x17);
TEARDOWN();
}
@@ -2875,27 +2885,85 @@ TEST(ldp_stp_offset) {
RUN();
- ASSERT_EQUAL_64(0x44556677, x0);
- ASSERT_EQUAL_64(0x00112233, x1);
- ASSERT_EQUAL_64(0x0011223344556677UL, dst[0]);
- ASSERT_EQUAL_64(0x00112233, x2);
- ASSERT_EQUAL_64(0xccddeeff, x3);
- ASSERT_EQUAL_64(0xccddeeff00112233UL, dst[1]);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x4);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[2]);
- ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x5);
- ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[3]);
- ASSERT_EQUAL_64(0x8899aabb, x6);
- ASSERT_EQUAL_64(0xbbaa9988, x7);
- ASSERT_EQUAL_64(0xbbaa99888899aabbUL, dst[4]);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x8);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[5]);
- ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x9);
- ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[6]);
- ASSERT_EQUAL_64(src_base, x16);
- ASSERT_EQUAL_64(dst_base, x17);
- ASSERT_EQUAL_64(src_base + 24, x18);
- ASSERT_EQUAL_64(dst_base + 56, x19);
+ CHECK_EQUAL_64(0x44556677, x0);
+ CHECK_EQUAL_64(0x00112233, x1);
+ CHECK_EQUAL_64(0x0011223344556677UL, dst[0]);
+ CHECK_EQUAL_64(0x00112233, x2);
+ CHECK_EQUAL_64(0xccddeeff, x3);
+ CHECK_EQUAL_64(0xccddeeff00112233UL, dst[1]);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x4);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[2]);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x5);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[3]);
+ CHECK_EQUAL_64(0x8899aabb, x6);
+ CHECK_EQUAL_64(0xbbaa9988, x7);
+ CHECK_EQUAL_64(0xbbaa99888899aabbUL, dst[4]);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x8);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[5]);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x9);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[6]);
+ CHECK_EQUAL_64(src_base, x16);
+ CHECK_EQUAL_64(dst_base, x17);
+ CHECK_EQUAL_64(src_base + 24, x18);
+ CHECK_EQUAL_64(dst_base + 56, x19);
+
+ TEARDOWN();
+}
+
+
+TEST(ldp_stp_offset_wide) {
+ INIT_V8();
+ SETUP();
+
+ uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
+ 0xffeeddccbbaa9988};
+ uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
+ uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
+ uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
+ // Move base too far from the array to force multiple instructions
+ // to be emitted.
+ const int64_t base_offset = 1024;
+
+ START();
+ __ Mov(x20, src_base - base_offset);
+ __ Mov(x21, dst_base - base_offset);
+ __ Mov(x18, src_base + base_offset + 24);
+ __ Mov(x19, dst_base + base_offset + 56);
+ __ Ldp(w0, w1, MemOperand(x20, base_offset));
+ __ Ldp(w2, w3, MemOperand(x20, base_offset + 4));
+ __ Ldp(x4, x5, MemOperand(x20, base_offset + 8));
+ __ Ldp(w6, w7, MemOperand(x18, -12 - base_offset));
+ __ Ldp(x8, x9, MemOperand(x18, -16 - base_offset));
+ __ Stp(w0, w1, MemOperand(x21, base_offset));
+ __ Stp(w2, w3, MemOperand(x21, base_offset + 8));
+ __ Stp(x4, x5, MemOperand(x21, base_offset + 16));
+ __ Stp(w6, w7, MemOperand(x19, -24 - base_offset));
+ __ Stp(x8, x9, MemOperand(x19, -16 - base_offset));
+ END();
+
+ RUN();
+
+ CHECK_EQUAL_64(0x44556677, x0);
+ CHECK_EQUAL_64(0x00112233, x1);
+ CHECK_EQUAL_64(0x0011223344556677UL, dst[0]);
+ CHECK_EQUAL_64(0x00112233, x2);
+ CHECK_EQUAL_64(0xccddeeff, x3);
+ CHECK_EQUAL_64(0xccddeeff00112233UL, dst[1]);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x4);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[2]);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x5);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[3]);
+ CHECK_EQUAL_64(0x8899aabb, x6);
+ CHECK_EQUAL_64(0xbbaa9988, x7);
+ CHECK_EQUAL_64(0xbbaa99888899aabbUL, dst[4]);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x8);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[5]);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x9);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[6]);
+ CHECK_EQUAL_64(src_base - base_offset, x20);
+ CHECK_EQUAL_64(dst_base - base_offset, x21);
+ CHECK_EQUAL_64(src_base + base_offset + 24, x18);
+ CHECK_EQUAL_64(dst_base + base_offset + 56, x19);
TEARDOWN();
}
@@ -2930,27 +2998,27 @@ TEST(ldnp_stnp_offset) {
RUN();
- ASSERT_EQUAL_64(0x44556677, x0);
- ASSERT_EQUAL_64(0x00112233, x1);
- ASSERT_EQUAL_64(0x0011223344556677UL, dst[0]);
- ASSERT_EQUAL_64(0x00112233, x2);
- ASSERT_EQUAL_64(0xccddeeff, x3);
- ASSERT_EQUAL_64(0xccddeeff00112233UL, dst[1]);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x4);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[2]);
- ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x5);
- ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[3]);
- ASSERT_EQUAL_64(0x8899aabb, x6);
- ASSERT_EQUAL_64(0xbbaa9988, x7);
- ASSERT_EQUAL_64(0xbbaa99888899aabbUL, dst[4]);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x8);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[5]);
- ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x9);
- ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[6]);
- ASSERT_EQUAL_64(src_base, x16);
- ASSERT_EQUAL_64(dst_base, x17);
- ASSERT_EQUAL_64(src_base + 24, x18);
- ASSERT_EQUAL_64(dst_base + 56, x19);
+ CHECK_EQUAL_64(0x44556677, x0);
+ CHECK_EQUAL_64(0x00112233, x1);
+ CHECK_EQUAL_64(0x0011223344556677UL, dst[0]);
+ CHECK_EQUAL_64(0x00112233, x2);
+ CHECK_EQUAL_64(0xccddeeff, x3);
+ CHECK_EQUAL_64(0xccddeeff00112233UL, dst[1]);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x4);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[2]);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x5);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[3]);
+ CHECK_EQUAL_64(0x8899aabb, x6);
+ CHECK_EQUAL_64(0xbbaa9988, x7);
+ CHECK_EQUAL_64(0xbbaa99888899aabbUL, dst[4]);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x8);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[5]);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x9);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[6]);
+ CHECK_EQUAL_64(src_base, x16);
+ CHECK_EQUAL_64(dst_base, x17);
+ CHECK_EQUAL_64(src_base + 24, x18);
+ CHECK_EQUAL_64(dst_base + 56, x19);
TEARDOWN();
}
@@ -2986,26 +3054,89 @@ TEST(ldp_stp_preindex) {
RUN();
- ASSERT_EQUAL_64(0x00112233, x0);
- ASSERT_EQUAL_64(0xccddeeff, x1);
- ASSERT_EQUAL_64(0x44556677, x2);
- ASSERT_EQUAL_64(0x00112233, x3);
- ASSERT_EQUAL_64(0xccddeeff00112233UL, dst[0]);
- ASSERT_EQUAL_64(0x0000000000112233UL, dst[1]);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x4);
- ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x5);
- ASSERT_EQUAL_64(0x0011223344556677UL, x6);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x7);
- ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[3]);
- ASSERT_EQUAL_64(0x0011223344556677UL, dst[4]);
- ASSERT_EQUAL_64(src_base, x16);
- ASSERT_EQUAL_64(dst_base, x17);
- ASSERT_EQUAL_64(dst_base + 16, x18);
- ASSERT_EQUAL_64(src_base + 4, x19);
- ASSERT_EQUAL_64(dst_base + 4, x20);
- ASSERT_EQUAL_64(src_base + 8, x21);
- ASSERT_EQUAL_64(dst_base + 24, x22);
+ CHECK_EQUAL_64(0x00112233, x0);
+ CHECK_EQUAL_64(0xccddeeff, x1);
+ CHECK_EQUAL_64(0x44556677, x2);
+ CHECK_EQUAL_64(0x00112233, x3);
+ CHECK_EQUAL_64(0xccddeeff00112233UL, dst[0]);
+ CHECK_EQUAL_64(0x0000000000112233UL, dst[1]);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x4);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x5);
+ CHECK_EQUAL_64(0x0011223344556677UL, x6);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x7);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[3]);
+ CHECK_EQUAL_64(0x0011223344556677UL, dst[4]);
+ CHECK_EQUAL_64(src_base, x16);
+ CHECK_EQUAL_64(dst_base, x17);
+ CHECK_EQUAL_64(dst_base + 16, x18);
+ CHECK_EQUAL_64(src_base + 4, x19);
+ CHECK_EQUAL_64(dst_base + 4, x20);
+ CHECK_EQUAL_64(src_base + 8, x21);
+ CHECK_EQUAL_64(dst_base + 24, x22);
+
+ TEARDOWN();
+}
+
+
+TEST(ldp_stp_preindex_wide) {
+ INIT_V8();
+ SETUP();
+
+ uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
+ 0xffeeddccbbaa9988};
+ uint64_t dst[5] = {0, 0, 0, 0, 0};
+ uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
+ uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
+ // Move base too far from the array to force multiple instructions
+ // to be emitted.
+ const int64_t base_offset = 1024;
+
+ START();
+ __ Mov(x24, src_base - base_offset);
+ __ Mov(x25, dst_base + base_offset);
+ __ Mov(x18, dst_base + base_offset + 16);
+ __ Ldp(w0, w1, MemOperand(x24, base_offset + 4, PreIndex));
+ __ Mov(x19, x24);
+ __ Mov(x24, src_base - base_offset + 4);
+ __ Ldp(w2, w3, MemOperand(x24, base_offset - 4, PreIndex));
+ __ Stp(w2, w3, MemOperand(x25, 4 - base_offset, PreIndex));
+ __ Mov(x20, x25);
+ __ Mov(x25, dst_base + base_offset + 4);
+ __ Mov(x24, src_base - base_offset);
+ __ Stp(w0, w1, MemOperand(x25, -4 - base_offset, PreIndex));
+ __ Ldp(x4, x5, MemOperand(x24, base_offset + 8, PreIndex));
+ __ Mov(x21, x24);
+ __ Mov(x24, src_base - base_offset + 8);
+ __ Ldp(x6, x7, MemOperand(x24, base_offset - 8, PreIndex));
+ __ Stp(x7, x6, MemOperand(x18, 8 - base_offset, PreIndex));
+ __ Mov(x22, x18);
+ __ Mov(x18, dst_base + base_offset + 16 + 8);
+ __ Stp(x5, x4, MemOperand(x18, -8 - base_offset, PreIndex));
+ END();
+
+ RUN();
+
+ CHECK_EQUAL_64(0x00112233, x0);
+ CHECK_EQUAL_64(0xccddeeff, x1);
+ CHECK_EQUAL_64(0x44556677, x2);
+ CHECK_EQUAL_64(0x00112233, x3);
+ CHECK_EQUAL_64(0xccddeeff00112233UL, dst[0]);
+ CHECK_EQUAL_64(0x0000000000112233UL, dst[1]);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x4);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x5);
+ CHECK_EQUAL_64(0x0011223344556677UL, x6);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x7);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[3]);
+ CHECK_EQUAL_64(0x0011223344556677UL, dst[4]);
+ CHECK_EQUAL_64(src_base, x24);
+ CHECK_EQUAL_64(dst_base, x25);
+ CHECK_EQUAL_64(dst_base + 16, x18);
+ CHECK_EQUAL_64(src_base + 4, x19);
+ CHECK_EQUAL_64(dst_base + 4, x20);
+ CHECK_EQUAL_64(src_base + 8, x21);
+ CHECK_EQUAL_64(dst_base + 24, x22);
TEARDOWN();
}
@@ -3041,26 +3172,89 @@ TEST(ldp_stp_postindex) {
RUN();
- ASSERT_EQUAL_64(0x44556677, x0);
- ASSERT_EQUAL_64(0x00112233, x1);
- ASSERT_EQUAL_64(0x00112233, x2);
- ASSERT_EQUAL_64(0xccddeeff, x3);
- ASSERT_EQUAL_64(0x4455667700112233UL, dst[0]);
- ASSERT_EQUAL_64(0x0000000000112233UL, dst[1]);
- ASSERT_EQUAL_64(0x0011223344556677UL, x4);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x5);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x6);
- ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x7);
- ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]);
- ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[3]);
- ASSERT_EQUAL_64(0x0011223344556677UL, dst[4]);
- ASSERT_EQUAL_64(src_base, x16);
- ASSERT_EQUAL_64(dst_base, x17);
- ASSERT_EQUAL_64(dst_base + 16, x18);
- ASSERT_EQUAL_64(src_base + 4, x19);
- ASSERT_EQUAL_64(dst_base + 4, x20);
- ASSERT_EQUAL_64(src_base + 8, x21);
- ASSERT_EQUAL_64(dst_base + 24, x22);
+ CHECK_EQUAL_64(0x44556677, x0);
+ CHECK_EQUAL_64(0x00112233, x1);
+ CHECK_EQUAL_64(0x00112233, x2);
+ CHECK_EQUAL_64(0xccddeeff, x3);
+ CHECK_EQUAL_64(0x4455667700112233UL, dst[0]);
+ CHECK_EQUAL_64(0x0000000000112233UL, dst[1]);
+ CHECK_EQUAL_64(0x0011223344556677UL, x4);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x5);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x6);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x7);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[3]);
+ CHECK_EQUAL_64(0x0011223344556677UL, dst[4]);
+ CHECK_EQUAL_64(src_base, x16);
+ CHECK_EQUAL_64(dst_base, x17);
+ CHECK_EQUAL_64(dst_base + 16, x18);
+ CHECK_EQUAL_64(src_base + 4, x19);
+ CHECK_EQUAL_64(dst_base + 4, x20);
+ CHECK_EQUAL_64(src_base + 8, x21);
+ CHECK_EQUAL_64(dst_base + 24, x22);
+
+ TEARDOWN();
+}
+
+
+TEST(ldp_stp_postindex_wide) {
+ INIT_V8();
+ SETUP();
+
+ uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff, 0xffeeddccbbaa9988,
+ 0x7766554433221100};
+ uint64_t dst[5] = {0, 0, 0, 0, 0};
+ uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
+ uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
+ // Move base too far from the array to force multiple instructions
+ // to be emitted.
+ const int64_t base_offset = 1024;
+
+ START();
+ __ Mov(x24, src_base);
+ __ Mov(x25, dst_base);
+ __ Mov(x18, dst_base + 16);
+ __ Ldp(w0, w1, MemOperand(x24, base_offset + 4, PostIndex));
+ __ Mov(x19, x24);
+ __ Sub(x24, x24, base_offset);
+ __ Ldp(w2, w3, MemOperand(x24, base_offset - 4, PostIndex));
+ __ Stp(w2, w3, MemOperand(x25, 4 - base_offset, PostIndex));
+ __ Mov(x20, x25);
+ __ Sub(x24, x24, base_offset);
+ __ Add(x25, x25, base_offset);
+ __ Stp(w0, w1, MemOperand(x25, -4 - base_offset, PostIndex));
+ __ Ldp(x4, x5, MemOperand(x24, base_offset + 8, PostIndex));
+ __ Mov(x21, x24);
+ __ Sub(x24, x24, base_offset);
+ __ Ldp(x6, x7, MemOperand(x24, base_offset - 8, PostIndex));
+ __ Stp(x7, x6, MemOperand(x18, 8 - base_offset, PostIndex));
+ __ Mov(x22, x18);
+ __ Add(x18, x18, base_offset);
+ __ Stp(x5, x4, MemOperand(x18, -8 - base_offset, PostIndex));
+ END();
+
+ RUN();
+
+ CHECK_EQUAL_64(0x44556677, x0);
+ CHECK_EQUAL_64(0x00112233, x1);
+ CHECK_EQUAL_64(0x00112233, x2);
+ CHECK_EQUAL_64(0xccddeeff, x3);
+ CHECK_EQUAL_64(0x4455667700112233UL, dst[0]);
+ CHECK_EQUAL_64(0x0000000000112233UL, dst[1]);
+ CHECK_EQUAL_64(0x0011223344556677UL, x4);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x5);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, x6);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x7);
+ CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]);
+ CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[3]);
+ CHECK_EQUAL_64(0x0011223344556677UL, dst[4]);
+ CHECK_EQUAL_64(src_base + base_offset, x24);
+ CHECK_EQUAL_64(dst_base - base_offset, x25);
+ CHECK_EQUAL_64(dst_base - base_offset + 16, x18);
+ CHECK_EQUAL_64(src_base + base_offset + 4, x19);
+ CHECK_EQUAL_64(dst_base - base_offset + 4, x20);
+ CHECK_EQUAL_64(src_base + base_offset + 8, x21);
+ CHECK_EQUAL_64(dst_base - base_offset + 24, x22);
TEARDOWN();
}
@@ -3080,8 +3274,8 @@ TEST(ldp_sign_extend) {
RUN();
- ASSERT_EQUAL_64(0xffffffff80000000UL, x0);
- ASSERT_EQUAL_64(0x000000007fffffffUL, x1);
+ CHECK_EQUAL_64(0xffffffff80000000UL, x0);
+ CHECK_EQUAL_64(0x000000007fffffffUL, x1);
TEARDOWN();
}
@@ -3114,19 +3308,19 @@ TEST(ldur_stur) {
RUN();
- ASSERT_EQUAL_64(0x6789abcd, x0);
- ASSERT_EQUAL_64(0x6789abcd0000L, dst[0]);
- ASSERT_EQUAL_64(0xabcdef0123456789L, x1);
- ASSERT_EQUAL_64(0xcdef012345678900L, dst[1]);
- ASSERT_EQUAL_64(0x000000ab, dst[2]);
- ASSERT_EQUAL_64(0xabcdef01, x2);
- ASSERT_EQUAL_64(0x00abcdef01000000L, dst[3]);
- ASSERT_EQUAL_64(0x00000001, x3);
- ASSERT_EQUAL_64(0x0100000000000000L, dst[4]);
- ASSERT_EQUAL_64(src_base, x17);
- ASSERT_EQUAL_64(dst_base, x18);
- ASSERT_EQUAL_64(src_base + 16, x19);
- ASSERT_EQUAL_64(dst_base + 32, x20);
+ CHECK_EQUAL_64(0x6789abcd, x0);
+ CHECK_EQUAL_64(0x6789abcd0000L, dst[0]);
+ CHECK_EQUAL_64(0xabcdef0123456789L, x1);
+ CHECK_EQUAL_64(0xcdef012345678900L, dst[1]);
+ CHECK_EQUAL_64(0x000000ab, dst[2]);
+ CHECK_EQUAL_64(0xabcdef01, x2);
+ CHECK_EQUAL_64(0x00abcdef01000000L, dst[3]);
+ CHECK_EQUAL_64(0x00000001, x3);
+ CHECK_EQUAL_64(0x0100000000000000L, dst[4]);
+ CHECK_EQUAL_64(src_base, x17);
+ CHECK_EQUAL_64(dst_base, x18);
+ CHECK_EQUAL_64(src_base + 16, x19);
+ CHECK_EQUAL_64(dst_base + 32, x20);
TEARDOWN();
}
@@ -3147,10 +3341,10 @@ TEST(ldr_literal) {
RUN();
- ASSERT_EQUAL_64(0x1234567890abcdefUL, x2);
- ASSERT_EQUAL_64(0xfedcba09, x3);
- ASSERT_EQUAL_FP64(1.234, d13);
- ASSERT_EQUAL_FP32(2.5, s25);
+ CHECK_EQUAL_64(0x1234567890abcdefUL, x2);
+ CHECK_EQUAL_64(0xfedcba09, x3);
+ CHECK_EQUAL_FP64(1.234, d13);
+ CHECK_EQUAL_FP32(2.5, s25);
TEARDOWN();
}
@@ -3159,7 +3353,7 @@ TEST(ldr_literal) {
static void LdrLiteralRangeHelper(ptrdiff_t range_,
LiteralPoolEmitOption option,
bool expect_dump) {
- ASSERT(range_ > 0);
+ DCHECK(range_ > 0);
SETUP_SIZE(range_ + 1024);
Label label_1, label_2;
@@ -3178,19 +3372,19 @@ static void LdrLiteralRangeHelper(ptrdiff_t range_,
START();
// Force a pool dump so the pool starts off empty.
__ EmitLiteralPool(JumpRequired);
- ASSERT_LITERAL_POOL_SIZE(0);
+ DCHECK_LITERAL_POOL_SIZE(0);
__ Ldr(x0, 0x1234567890abcdefUL);
__ Ldr(w1, 0xfedcba09);
__ Ldr(d0, 1.234);
__ Ldr(s1, 2.5);
- ASSERT_LITERAL_POOL_SIZE(4);
+ DCHECK_LITERAL_POOL_SIZE(4);
code_size += 4 * sizeof(Instr);
// Check that the requested range (allowing space for a branch over the pool)
// can be handled by this test.
- ASSERT((code_size + pool_guard_size) <= range);
+ DCHECK((code_size + pool_guard_size) <= range);
// Emit NOPs up to 'range', leaving space for the pool guard.
while ((code_size + pool_guard_size) < range) {
@@ -3204,41 +3398,41 @@ static void LdrLiteralRangeHelper(ptrdiff_t range_,
code_size += sizeof(Instr);
}
- ASSERT(code_size == range);
- ASSERT_LITERAL_POOL_SIZE(4);
+ DCHECK(code_size == range);
+ DCHECK_LITERAL_POOL_SIZE(4);
// Possibly generate a literal pool.
__ CheckLiteralPool(option);
__ Bind(&label_1);
if (expect_dump) {
- ASSERT_LITERAL_POOL_SIZE(0);
+ DCHECK_LITERAL_POOL_SIZE(0);
} else {
- ASSERT_LITERAL_POOL_SIZE(4);
+ DCHECK_LITERAL_POOL_SIZE(4);
}
// Force a pool flush to check that a second pool functions correctly.
__ EmitLiteralPool(JumpRequired);
- ASSERT_LITERAL_POOL_SIZE(0);
+ DCHECK_LITERAL_POOL_SIZE(0);
// These loads should be after the pool (and will require a new one).
__ Ldr(x4, 0x34567890abcdef12UL);
__ Ldr(w5, 0xdcba09fe);
__ Ldr(d4, 123.4);
__ Ldr(s5, 250.0);
- ASSERT_LITERAL_POOL_SIZE(4);
+ DCHECK_LITERAL_POOL_SIZE(4);
END();
RUN();
// Check that the literals loaded correctly.
- ASSERT_EQUAL_64(0x1234567890abcdefUL, x0);
- ASSERT_EQUAL_64(0xfedcba09, x1);
- ASSERT_EQUAL_FP64(1.234, d0);
- ASSERT_EQUAL_FP32(2.5, s1);
- ASSERT_EQUAL_64(0x34567890abcdef12UL, x4);
- ASSERT_EQUAL_64(0xdcba09fe, x5);
- ASSERT_EQUAL_FP64(123.4, d4);
- ASSERT_EQUAL_FP32(250.0, s5);
+ CHECK_EQUAL_64(0x1234567890abcdefUL, x0);
+ CHECK_EQUAL_64(0xfedcba09, x1);
+ CHECK_EQUAL_FP64(1.234, d0);
+ CHECK_EQUAL_FP32(2.5, s1);
+ CHECK_EQUAL_64(0x34567890abcdef12UL, x4);
+ CHECK_EQUAL_64(0xdcba09fe, x5);
+ CHECK_EQUAL_FP64(123.4, d4);
+ CHECK_EQUAL_FP32(250.0, s5);
TEARDOWN();
}
@@ -3325,25 +3519,25 @@ TEST(add_sub_imm) {
RUN();
- ASSERT_EQUAL_64(0x123, x10);
- ASSERT_EQUAL_64(0x123111, x11);
- ASSERT_EQUAL_64(0xabc000, x12);
- ASSERT_EQUAL_64(0x0, x13);
+ CHECK_EQUAL_64(0x123, x10);
+ CHECK_EQUAL_64(0x123111, x11);
+ CHECK_EQUAL_64(0xabc000, x12);
+ CHECK_EQUAL_64(0x0, x13);
- ASSERT_EQUAL_32(0x123, w14);
- ASSERT_EQUAL_32(0x123111, w15);
- ASSERT_EQUAL_32(0xabc000, w16);
- ASSERT_EQUAL_32(0x0, w17);
+ CHECK_EQUAL_32(0x123, w14);
+ CHECK_EQUAL_32(0x123111, w15);
+ CHECK_EQUAL_32(0xabc000, w16);
+ CHECK_EQUAL_32(0x0, w17);
- ASSERT_EQUAL_64(0xffffffffffffffffL, x20);
- ASSERT_EQUAL_64(0x1000, x21);
- ASSERT_EQUAL_64(0x111, x22);
- ASSERT_EQUAL_64(0x7fffffffffffffffL, x23);
+ CHECK_EQUAL_64(0xffffffffffffffffL, x20);
+ CHECK_EQUAL_64(0x1000, x21);
+ CHECK_EQUAL_64(0x111, x22);
+ CHECK_EQUAL_64(0x7fffffffffffffffL, x23);
- ASSERT_EQUAL_32(0xffffffff, w24);
- ASSERT_EQUAL_32(0x1000, w25);
- ASSERT_EQUAL_32(0x111, w26);
- ASSERT_EQUAL_32(0xffffffff, w27);
+ CHECK_EQUAL_32(0xffffffff, w24);
+ CHECK_EQUAL_32(0x1000, w25);
+ CHECK_EQUAL_32(0x111, w26);
+ CHECK_EQUAL_32(0xffffffff, w27);
TEARDOWN();
}
@@ -3363,22 +3557,26 @@ TEST(add_sub_wide_imm) {
__ Add(w12, w0, Operand(0x12345678));
__ Add(w13, w1, Operand(0xffffffff));
- __ Sub(x20, x0, Operand(0x1234567890abcdefUL));
+ __ Add(w18, w0, Operand(kWMinInt));
+ __ Sub(w19, w0, Operand(kWMinInt));
+ __ Sub(x20, x0, Operand(0x1234567890abcdefUL));
__ Sub(w21, w0, Operand(0x12345678));
END();
RUN();
- ASSERT_EQUAL_64(0x1234567890abcdefUL, x10);
- ASSERT_EQUAL_64(0x100000000UL, x11);
+ CHECK_EQUAL_64(0x1234567890abcdefUL, x10);
+ CHECK_EQUAL_64(0x100000000UL, x11);
- ASSERT_EQUAL_32(0x12345678, w12);
- ASSERT_EQUAL_64(0x0, x13);
+ CHECK_EQUAL_32(0x12345678, w12);
+ CHECK_EQUAL_64(0x0, x13);
- ASSERT_EQUAL_64(-0x1234567890abcdefUL, x20);
+ CHECK_EQUAL_32(kWMinInt, w18);
+ CHECK_EQUAL_32(kWMinInt, w19);
- ASSERT_EQUAL_32(-0x12345678, w21);
+ CHECK_EQUAL_64(-0x1234567890abcdefUL, x20);
+ CHECK_EQUAL_32(-0x12345678, w21);
TEARDOWN();
}
@@ -3415,23 +3613,23 @@ TEST(add_sub_shifted) {
RUN();
- ASSERT_EQUAL_64(0xffffffffffffffffL, x10);
- ASSERT_EQUAL_64(0x23456789abcdef00L, x11);
- ASSERT_EQUAL_64(0x000123456789abcdL, x12);
- ASSERT_EQUAL_64(0x000123456789abcdL, x13);
- ASSERT_EQUAL_64(0xfffedcba98765432L, x14);
- ASSERT_EQUAL_64(0xff89abcd, x15);
- ASSERT_EQUAL_64(0xef89abcc, x18);
- ASSERT_EQUAL_64(0xef0123456789abccL, x19);
+ CHECK_EQUAL_64(0xffffffffffffffffL, x10);
+ CHECK_EQUAL_64(0x23456789abcdef00L, x11);
+ CHECK_EQUAL_64(0x000123456789abcdL, x12);
+ CHECK_EQUAL_64(0x000123456789abcdL, x13);
+ CHECK_EQUAL_64(0xfffedcba98765432L, x14);
+ CHECK_EQUAL_64(0xff89abcd, x15);
+ CHECK_EQUAL_64(0xef89abcc, x18);
+ CHECK_EQUAL_64(0xef0123456789abccL, x19);
- ASSERT_EQUAL_64(0x0123456789abcdefL, x20);
- ASSERT_EQUAL_64(0xdcba9876543210ffL, x21);
- ASSERT_EQUAL_64(0xfffedcba98765432L, x22);
- ASSERT_EQUAL_64(0xfffedcba98765432L, x23);
- ASSERT_EQUAL_64(0x000123456789abcdL, x24);
- ASSERT_EQUAL_64(0x00765432, x25);
- ASSERT_EQUAL_64(0x10765432, x26);
- ASSERT_EQUAL_64(0x10fedcba98765432L, x27);
+ CHECK_EQUAL_64(0x0123456789abcdefL, x20);
+ CHECK_EQUAL_64(0xdcba9876543210ffL, x21);
+ CHECK_EQUAL_64(0xfffedcba98765432L, x22);
+ CHECK_EQUAL_64(0xfffedcba98765432L, x23);
+ CHECK_EQUAL_64(0x000123456789abcdL, x24);
+ CHECK_EQUAL_64(0x00765432, x25);
+ CHECK_EQUAL_64(0x10765432, x26);
+ CHECK_EQUAL_64(0x10fedcba98765432L, x27);
TEARDOWN();
}
@@ -3477,32 +3675,32 @@ TEST(add_sub_extended) {
RUN();
- ASSERT_EQUAL_64(0xefL, x10);
- ASSERT_EQUAL_64(0x1deL, x11);
- ASSERT_EQUAL_64(0x337bcL, x12);
- ASSERT_EQUAL_64(0x89abcdef0L, x13);
+ CHECK_EQUAL_64(0xefL, x10);
+ CHECK_EQUAL_64(0x1deL, x11);
+ CHECK_EQUAL_64(0x337bcL, x12);
+ CHECK_EQUAL_64(0x89abcdef0L, x13);
- ASSERT_EQUAL_64(0xffffffffffffffefL, x14);
- ASSERT_EQUAL_64(0xffffffffffffffdeL, x15);
- ASSERT_EQUAL_64(0xffffffffffff37bcL, x16);
- ASSERT_EQUAL_64(0xfffffffc4d5e6f78L, x17);
- ASSERT_EQUAL_64(0x10L, x18);
- ASSERT_EQUAL_64(0x20L, x19);
- ASSERT_EQUAL_64(0xc840L, x20);
- ASSERT_EQUAL_64(0x3b2a19080L, x21);
+ CHECK_EQUAL_64(0xffffffffffffffefL, x14);
+ CHECK_EQUAL_64(0xffffffffffffffdeL, x15);
+ CHECK_EQUAL_64(0xffffffffffff37bcL, x16);
+ CHECK_EQUAL_64(0xfffffffc4d5e6f78L, x17);
+ CHECK_EQUAL_64(0x10L, x18);
+ CHECK_EQUAL_64(0x20L, x19);
+ CHECK_EQUAL_64(0xc840L, x20);
+ CHECK_EQUAL_64(0x3b2a19080L, x21);
- ASSERT_EQUAL_64(0x0123456789abce0fL, x22);
- ASSERT_EQUAL_64(0x0123456789abcdcfL, x23);
+ CHECK_EQUAL_64(0x0123456789abce0fL, x22);
+ CHECK_EQUAL_64(0x0123456789abcdcfL, x23);
- ASSERT_EQUAL_32(0x89abce2f, w24);
- ASSERT_EQUAL_32(0xffffffef, w25);
- ASSERT_EQUAL_32(0xffffffde, w26);
- ASSERT_EQUAL_32(0xc3b2a188, w27);
+ CHECK_EQUAL_32(0x89abce2f, w24);
+ CHECK_EQUAL_32(0xffffffef, w25);
+ CHECK_EQUAL_32(0xffffffde, w26);
+ CHECK_EQUAL_32(0xc3b2a188, w27);
- ASSERT_EQUAL_32(0x4d5e6f78, w28);
- ASSERT_EQUAL_64(0xfffffffc4d5e6f78L, x29);
+ CHECK_EQUAL_32(0x4d5e6f78, w28);
+ CHECK_EQUAL_64(0xfffffffc4d5e6f78L, x29);
- ASSERT_EQUAL_64(256, x30);
+ CHECK_EQUAL_64(256, x30);
TEARDOWN();
}
@@ -3536,19 +3734,19 @@ TEST(add_sub_negative) {
RUN();
- ASSERT_EQUAL_64(-42, x10);
- ASSERT_EQUAL_64(4000, x11);
- ASSERT_EQUAL_64(0x1122334455667700, x12);
+ CHECK_EQUAL_64(-42, x10);
+ CHECK_EQUAL_64(4000, x11);
+ CHECK_EQUAL_64(0x1122334455667700, x12);
- ASSERT_EQUAL_64(600, x13);
- ASSERT_EQUAL_64(5000, x14);
- ASSERT_EQUAL_64(0x1122334455667cdd, x15);
+ CHECK_EQUAL_64(600, x13);
+ CHECK_EQUAL_64(5000, x14);
+ CHECK_EQUAL_64(0x1122334455667cdd, x15);
- ASSERT_EQUAL_32(0x11223000, w19);
- ASSERT_EQUAL_32(398000, w20);
+ CHECK_EQUAL_32(0x11223000, w19);
+ CHECK_EQUAL_32(398000, w20);
- ASSERT_EQUAL_32(0x11223400, w21);
- ASSERT_EQUAL_32(402000, w22);
+ CHECK_EQUAL_32(0x11223400, w21);
+ CHECK_EQUAL_32(402000, w22);
TEARDOWN();
}
@@ -3584,9 +3782,9 @@ TEST(add_sub_zero) {
RUN();
- ASSERT_EQUAL_64(0, x0);
- ASSERT_EQUAL_64(0, x1);
- ASSERT_EQUAL_64(0, x2);
+ CHECK_EQUAL_64(0, x0);
+ CHECK_EQUAL_64(0, x1);
+ CHECK_EQUAL_64(0, x2);
TEARDOWN();
}
@@ -3652,20 +3850,20 @@ TEST(neg) {
RUN();
- ASSERT_EQUAL_64(0xfffffffffffffeddUL, x1);
- ASSERT_EQUAL_64(0xfffffedd, x2);
- ASSERT_EQUAL_64(0x1db97530eca86422UL, x3);
- ASSERT_EQUAL_64(0xd950c844, x4);
- ASSERT_EQUAL_64(0xe1db97530eca8643UL, x5);
- ASSERT_EQUAL_64(0xf7654322, x6);
- ASSERT_EQUAL_64(0x0076e5d4c3b2a191UL, x7);
- ASSERT_EQUAL_64(0x01d950c9, x8);
- ASSERT_EQUAL_64(0xffffff11, x9);
- ASSERT_EQUAL_64(0x0000000000000022UL, x10);
- ASSERT_EQUAL_64(0xfffcc844, x11);
- ASSERT_EQUAL_64(0x0000000000019088UL, x12);
- ASSERT_EQUAL_64(0x65432110, x13);
- ASSERT_EQUAL_64(0x0000000765432110UL, x14);
+ CHECK_EQUAL_64(0xfffffffffffffeddUL, x1);
+ CHECK_EQUAL_64(0xfffffedd, x2);
+ CHECK_EQUAL_64(0x1db97530eca86422UL, x3);
+ CHECK_EQUAL_64(0xd950c844, x4);
+ CHECK_EQUAL_64(0xe1db97530eca8643UL, x5);
+ CHECK_EQUAL_64(0xf7654322, x6);
+ CHECK_EQUAL_64(0x0076e5d4c3b2a191UL, x7);
+ CHECK_EQUAL_64(0x01d950c9, x8);
+ CHECK_EQUAL_64(0xffffff11, x9);
+ CHECK_EQUAL_64(0x0000000000000022UL, x10);
+ CHECK_EQUAL_64(0xfffcc844, x11);
+ CHECK_EQUAL_64(0x0000000000019088UL, x12);
+ CHECK_EQUAL_64(0x65432110, x13);
+ CHECK_EQUAL_64(0x0000000765432110UL, x14);
TEARDOWN();
}
@@ -3715,29 +3913,29 @@ TEST(adc_sbc_shift) {
RUN();
- ASSERT_EQUAL_64(0xffffffffffffffffL, x5);
- ASSERT_EQUAL_64(1L << 60, x6);
- ASSERT_EQUAL_64(0xf0123456789abcddL, x7);
- ASSERT_EQUAL_64(0x0111111111111110L, x8);
- ASSERT_EQUAL_64(0x1222222222222221L, x9);
+ CHECK_EQUAL_64(0xffffffffffffffffL, x5);
+ CHECK_EQUAL_64(1L << 60, x6);
+ CHECK_EQUAL_64(0xf0123456789abcddL, x7);
+ CHECK_EQUAL_64(0x0111111111111110L, x8);
+ CHECK_EQUAL_64(0x1222222222222221L, x9);
- ASSERT_EQUAL_32(0xffffffff, w10);
- ASSERT_EQUAL_32(1 << 30, w11);
- ASSERT_EQUAL_32(0xf89abcdd, w12);
- ASSERT_EQUAL_32(0x91111110, w13);
- ASSERT_EQUAL_32(0x9a222221, w14);
+ CHECK_EQUAL_32(0xffffffff, w10);
+ CHECK_EQUAL_32(1 << 30, w11);
+ CHECK_EQUAL_32(0xf89abcdd, w12);
+ CHECK_EQUAL_32(0x91111110, w13);
+ CHECK_EQUAL_32(0x9a222221, w14);
- ASSERT_EQUAL_64(0xffffffffffffffffL + 1, x18);
- ASSERT_EQUAL_64((1L << 60) + 1, x19);
- ASSERT_EQUAL_64(0xf0123456789abcddL + 1, x20);
- ASSERT_EQUAL_64(0x0111111111111110L + 1, x21);
- ASSERT_EQUAL_64(0x1222222222222221L + 1, x22);
+ CHECK_EQUAL_64(0xffffffffffffffffL + 1, x18);
+ CHECK_EQUAL_64((1L << 60) + 1, x19);
+ CHECK_EQUAL_64(0xf0123456789abcddL + 1, x20);
+ CHECK_EQUAL_64(0x0111111111111110L + 1, x21);
+ CHECK_EQUAL_64(0x1222222222222221L + 1, x22);
- ASSERT_EQUAL_32(0xffffffff + 1, w23);
- ASSERT_EQUAL_32((1 << 30) + 1, w24);
- ASSERT_EQUAL_32(0xf89abcdd + 1, w25);
- ASSERT_EQUAL_32(0x91111110 + 1, w26);
- ASSERT_EQUAL_32(0x9a222221 + 1, w27);
+ CHECK_EQUAL_32(0xffffffff + 1, w23);
+ CHECK_EQUAL_32((1 << 30) + 1, w24);
+ CHECK_EQUAL_32(0xf89abcdd + 1, w25);
+ CHECK_EQUAL_32(0x91111110 + 1, w26);
+ CHECK_EQUAL_32(0x9a222221 + 1, w27);
// Check that adc correctly sets the condition flags.
START();
@@ -3750,8 +3948,8 @@ TEST(adc_sbc_shift) {
RUN();
- ASSERT_EQUAL_NZCV(ZCFlag);
- ASSERT_EQUAL_64(0, x10);
+ CHECK_EQUAL_NZCV(ZCFlag);
+ CHECK_EQUAL_64(0, x10);
START();
__ Mov(x0, 1);
@@ -3763,8 +3961,8 @@ TEST(adc_sbc_shift) {
RUN();
- ASSERT_EQUAL_NZCV(ZCFlag);
- ASSERT_EQUAL_64(0, x10);
+ CHECK_EQUAL_NZCV(ZCFlag);
+ CHECK_EQUAL_64(0, x10);
START();
__ Mov(x0, 0x10);
@@ -3776,8 +3974,8 @@ TEST(adc_sbc_shift) {
RUN();
- ASSERT_EQUAL_NZCV(NVFlag);
- ASSERT_EQUAL_64(0x8000000000000000L, x10);
+ CHECK_EQUAL_NZCV(NVFlag);
+ CHECK_EQUAL_64(0x8000000000000000L, x10);
// Check that sbc correctly sets the condition flags.
START();
@@ -3790,8 +3988,8 @@ TEST(adc_sbc_shift) {
RUN();
- ASSERT_EQUAL_NZCV(ZFlag);
- ASSERT_EQUAL_64(0, x10);
+ CHECK_EQUAL_NZCV(ZFlag);
+ CHECK_EQUAL_64(0, x10);
START();
__ Mov(x0, 1);
@@ -3803,8 +4001,8 @@ TEST(adc_sbc_shift) {
RUN();
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0x8000000000000001L, x10);
+ CHECK_EQUAL_NZCV(NFlag);
+ CHECK_EQUAL_64(0x8000000000000001L, x10);
START();
__ Mov(x0, 0);
@@ -3815,8 +4013,8 @@ TEST(adc_sbc_shift) {
RUN();
- ASSERT_EQUAL_NZCV(ZFlag);
- ASSERT_EQUAL_64(0, x10);
+ CHECK_EQUAL_NZCV(ZFlag);
+ CHECK_EQUAL_64(0, x10);
START()
__ Mov(w0, 0x7fffffff);
@@ -3827,8 +4025,8 @@ TEST(adc_sbc_shift) {
RUN();
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0x80000000, x10);
+ CHECK_EQUAL_NZCV(NFlag);
+ CHECK_EQUAL_64(0x80000000, x10);
START();
// Clear the C flag.
@@ -3838,8 +4036,8 @@ TEST(adc_sbc_shift) {
RUN();
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0x8000000000000000L, x10);
+ CHECK_EQUAL_NZCV(NFlag);
+ CHECK_EQUAL_64(0x8000000000000000L, x10);
START()
__ Mov(x0, 0);
@@ -3850,8 +4048,8 @@ TEST(adc_sbc_shift) {
RUN();
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0xffffffffffffffffL, x10);
+ CHECK_EQUAL_NZCV(NFlag);
+ CHECK_EQUAL_64(0xffffffffffffffffL, x10);
START()
__ Mov(x0, 0);
@@ -3862,8 +4060,8 @@ TEST(adc_sbc_shift) {
RUN();
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0x8000000000000001L, x10);
+ CHECK_EQUAL_NZCV(NFlag);
+ CHECK_EQUAL_64(0x8000000000000001L, x10);
TEARDOWN();
}
@@ -3905,23 +4103,23 @@ TEST(adc_sbc_extend) {
RUN();
- ASSERT_EQUAL_64(0x1df, x10);
- ASSERT_EQUAL_64(0xffffffffffff37bdL, x11);
- ASSERT_EQUAL_64(0xfffffff765432110L, x12);
- ASSERT_EQUAL_64(0x123456789abcdef1L, x13);
+ CHECK_EQUAL_64(0x1df, x10);
+ CHECK_EQUAL_64(0xffffffffffff37bdL, x11);
+ CHECK_EQUAL_64(0xfffffff765432110L, x12);
+ CHECK_EQUAL_64(0x123456789abcdef1L, x13);
- ASSERT_EQUAL_32(0x1df, w14);
- ASSERT_EQUAL_32(0xffff37bd, w15);
- ASSERT_EQUAL_32(0x9abcdef1, w9);
+ CHECK_EQUAL_32(0x1df, w14);
+ CHECK_EQUAL_32(0xffff37bd, w15);
+ CHECK_EQUAL_32(0x9abcdef1, w9);
- ASSERT_EQUAL_64(0x1df + 1, x20);
- ASSERT_EQUAL_64(0xffffffffffff37bdL + 1, x21);
- ASSERT_EQUAL_64(0xfffffff765432110L + 1, x22);
- ASSERT_EQUAL_64(0x123456789abcdef1L + 1, x23);
+ CHECK_EQUAL_64(0x1df + 1, x20);
+ CHECK_EQUAL_64(0xffffffffffff37bdL + 1, x21);
+ CHECK_EQUAL_64(0xfffffff765432110L + 1, x22);
+ CHECK_EQUAL_64(0x123456789abcdef1L + 1, x23);
- ASSERT_EQUAL_32(0x1df + 1, w24);
- ASSERT_EQUAL_32(0xffff37bd + 1, w25);
- ASSERT_EQUAL_32(0x9abcdef1 + 1, w26);
+ CHECK_EQUAL_32(0x1df + 1, w24);
+ CHECK_EQUAL_32(0xffff37bd + 1, w25);
+ CHECK_EQUAL_32(0x9abcdef1 + 1, w26);
// Check that adc correctly sets the condition flags.
START();
@@ -3934,7 +4132,7 @@ TEST(adc_sbc_extend) {
RUN();
- ASSERT_EQUAL_NZCV(CFlag);
+ CHECK_EQUAL_NZCV(CFlag);
START();
__ Mov(x0, 0x7fffffffffffffffL);
@@ -3946,7 +4144,7 @@ TEST(adc_sbc_extend) {
RUN();
- ASSERT_EQUAL_NZCV(NVFlag);
+ CHECK_EQUAL_NZCV(NVFlag);
START();
__ Mov(x0, 0x7fffffffffffffffL);
@@ -3957,7 +4155,7 @@ TEST(adc_sbc_extend) {
RUN();
- ASSERT_EQUAL_NZCV(NVFlag);
+ CHECK_EQUAL_NZCV(NVFlag);
TEARDOWN();
}
@@ -3993,19 +4191,19 @@ TEST(adc_sbc_wide_imm) {
RUN();
- ASSERT_EQUAL_64(0x1234567890abcdefUL, x7);
- ASSERT_EQUAL_64(0xffffffff, x8);
- ASSERT_EQUAL_64(0xedcba9876f543210UL, x9);
- ASSERT_EQUAL_64(0, x10);
- ASSERT_EQUAL_64(0xffffffff, x11);
- ASSERT_EQUAL_64(0xffff, x12);
+ CHECK_EQUAL_64(0x1234567890abcdefUL, x7);
+ CHECK_EQUAL_64(0xffffffff, x8);
+ CHECK_EQUAL_64(0xedcba9876f543210UL, x9);
+ CHECK_EQUAL_64(0, x10);
+ CHECK_EQUAL_64(0xffffffff, x11);
+ CHECK_EQUAL_64(0xffff, x12);
- ASSERT_EQUAL_64(0x1234567890abcdefUL + 1, x18);
- ASSERT_EQUAL_64(0, x19);
- ASSERT_EQUAL_64(0xedcba9876f543211UL, x20);
- ASSERT_EQUAL_64(1, x21);
- ASSERT_EQUAL_64(0x100000000UL, x22);
- ASSERT_EQUAL_64(0x10000, x23);
+ CHECK_EQUAL_64(0x1234567890abcdefUL + 1, x18);
+ CHECK_EQUAL_64(0, x19);
+ CHECK_EQUAL_64(0xedcba9876f543211UL, x20);
+ CHECK_EQUAL_64(1, x21);
+ CHECK_EQUAL_64(0x100000000UL, x22);
+ CHECK_EQUAL_64(0x10000, x23);
TEARDOWN();
}
@@ -4031,11 +4229,11 @@ TEST(flags) {
RUN();
- ASSERT_EQUAL_64(0, x10);
- ASSERT_EQUAL_64(-0x1111111111111111L, x11);
- ASSERT_EQUAL_32(-0x11111111, w12);
- ASSERT_EQUAL_64(-1L, x13);
- ASSERT_EQUAL_32(0, w14);
+ CHECK_EQUAL_64(0, x10);
+ CHECK_EQUAL_64(-0x1111111111111111L, x11);
+ CHECK_EQUAL_32(-0x11111111, w12);
+ CHECK_EQUAL_64(-1L, x13);
+ CHECK_EQUAL_32(0, w14);
START();
__ Mov(x0, 0);
@@ -4044,7 +4242,7 @@ TEST(flags) {
RUN();
- ASSERT_EQUAL_NZCV(ZCFlag);
+ CHECK_EQUAL_NZCV(ZCFlag);
START();
__ Mov(w0, 0);
@@ -4053,7 +4251,7 @@ TEST(flags) {
RUN();
- ASSERT_EQUAL_NZCV(ZCFlag);
+ CHECK_EQUAL_NZCV(ZCFlag);
START();
__ Mov(x0, 0);
@@ -4063,7 +4261,7 @@ TEST(flags) {
RUN();
- ASSERT_EQUAL_NZCV(NFlag);
+ CHECK_EQUAL_NZCV(NFlag);
START();
__ Mov(w0, 0);
@@ -4073,7 +4271,7 @@ TEST(flags) {
RUN();
- ASSERT_EQUAL_NZCV(NFlag);
+ CHECK_EQUAL_NZCV(NFlag);
START();
__ Mov(x1, 0x1111111111111111L);
@@ -4082,7 +4280,7 @@ TEST(flags) {
RUN();
- ASSERT_EQUAL_NZCV(CFlag);
+ CHECK_EQUAL_NZCV(CFlag);
START();
__ Mov(w1, 0x11111111);
@@ -4091,7 +4289,7 @@ TEST(flags) {
RUN();
- ASSERT_EQUAL_NZCV(CFlag);
+ CHECK_EQUAL_NZCV(CFlag);
START();
__ Mov(x0, 1);
@@ -4101,7 +4299,7 @@ TEST(flags) {
RUN();
- ASSERT_EQUAL_NZCV(NVFlag);
+ CHECK_EQUAL_NZCV(NVFlag);
START();
__ Mov(w0, 1);
@@ -4111,7 +4309,7 @@ TEST(flags) {
RUN();
- ASSERT_EQUAL_NZCV(NVFlag);
+ CHECK_EQUAL_NZCV(NVFlag);
START();
__ Mov(x0, 1);
@@ -4121,7 +4319,7 @@ TEST(flags) {
RUN();
- ASSERT_EQUAL_NZCV(ZCFlag);
+ CHECK_EQUAL_NZCV(ZCFlag);
START();
__ Mov(w0, 1);
@@ -4131,7 +4329,7 @@ TEST(flags) {
RUN();
- ASSERT_EQUAL_NZCV(ZCFlag);
+ CHECK_EQUAL_NZCV(ZCFlag);
START();
__ Mov(w0, 0);
@@ -4143,7 +4341,7 @@ TEST(flags) {
RUN();
- ASSERT_EQUAL_NZCV(NFlag);
+ CHECK_EQUAL_NZCV(NFlag);
START();
__ Mov(w0, 0);
@@ -4155,7 +4353,7 @@ TEST(flags) {
RUN();
- ASSERT_EQUAL_NZCV(ZCFlag);
+ CHECK_EQUAL_NZCV(ZCFlag);
TEARDOWN();
}
@@ -4204,14 +4402,14 @@ TEST(cmp_shift) {
RUN();
- ASSERT_EQUAL_32(ZCFlag, w0);
- ASSERT_EQUAL_32(ZCFlag, w1);
- ASSERT_EQUAL_32(ZCFlag, w2);
- ASSERT_EQUAL_32(ZCFlag, w3);
- ASSERT_EQUAL_32(ZCFlag, w4);
- ASSERT_EQUAL_32(ZCFlag, w5);
- ASSERT_EQUAL_32(ZCFlag, w6);
- ASSERT_EQUAL_32(ZCFlag, w7);
+ CHECK_EQUAL_32(ZCFlag, w0);
+ CHECK_EQUAL_32(ZCFlag, w1);
+ CHECK_EQUAL_32(ZCFlag, w2);
+ CHECK_EQUAL_32(ZCFlag, w3);
+ CHECK_EQUAL_32(ZCFlag, w4);
+ CHECK_EQUAL_32(ZCFlag, w5);
+ CHECK_EQUAL_32(ZCFlag, w6);
+ CHECK_EQUAL_32(ZCFlag, w7);
TEARDOWN();
}
@@ -4257,14 +4455,14 @@ TEST(cmp_extend) {
RUN();
- ASSERT_EQUAL_32(ZCFlag, w0);
- ASSERT_EQUAL_32(ZCFlag, w1);
- ASSERT_EQUAL_32(ZCFlag, w2);
- ASSERT_EQUAL_32(NCFlag, w3);
- ASSERT_EQUAL_32(NCFlag, w4);
- ASSERT_EQUAL_32(ZCFlag, w5);
- ASSERT_EQUAL_32(NCFlag, w6);
- ASSERT_EQUAL_32(ZCFlag, w7);
+ CHECK_EQUAL_32(ZCFlag, w0);
+ CHECK_EQUAL_32(ZCFlag, w1);
+ CHECK_EQUAL_32(ZCFlag, w2);
+ CHECK_EQUAL_32(NCFlag, w3);
+ CHECK_EQUAL_32(NCFlag, w4);
+ CHECK_EQUAL_32(ZCFlag, w5);
+ CHECK_EQUAL_32(NCFlag, w6);
+ CHECK_EQUAL_32(ZCFlag, w7);
TEARDOWN();
}
@@ -4303,12 +4501,12 @@ TEST(ccmp) {
RUN();
- ASSERT_EQUAL_32(NFlag, w0);
- ASSERT_EQUAL_32(NCFlag, w1);
- ASSERT_EQUAL_32(NoFlag, w2);
- ASSERT_EQUAL_32(NZCVFlag, w3);
- ASSERT_EQUAL_32(ZCFlag, w4);
- ASSERT_EQUAL_32(ZCFlag, w5);
+ CHECK_EQUAL_32(NFlag, w0);
+ CHECK_EQUAL_32(NCFlag, w1);
+ CHECK_EQUAL_32(NoFlag, w2);
+ CHECK_EQUAL_32(NZCVFlag, w3);
+ CHECK_EQUAL_32(ZCFlag, w4);
+ CHECK_EQUAL_32(ZCFlag, w5);
TEARDOWN();
}
@@ -4332,8 +4530,8 @@ TEST(ccmp_wide_imm) {
RUN();
- ASSERT_EQUAL_32(NFlag, w0);
- ASSERT_EQUAL_32(NoFlag, w1);
+ CHECK_EQUAL_32(NFlag, w0);
+ CHECK_EQUAL_32(NoFlag, w1);
TEARDOWN();
}
@@ -4373,11 +4571,11 @@ TEST(ccmp_shift_extend) {
RUN();
- ASSERT_EQUAL_32(ZCFlag, w0);
- ASSERT_EQUAL_32(ZCFlag, w1);
- ASSERT_EQUAL_32(ZCFlag, w2);
- ASSERT_EQUAL_32(NCFlag, w3);
- ASSERT_EQUAL_32(NZCVFlag, w4);
+ CHECK_EQUAL_32(ZCFlag, w0);
+ CHECK_EQUAL_32(ZCFlag, w1);
+ CHECK_EQUAL_32(ZCFlag, w2);
+ CHECK_EQUAL_32(NCFlag, w3);
+ CHECK_EQUAL_32(NZCVFlag, w4);
TEARDOWN();
}
@@ -4427,27 +4625,27 @@ TEST(csel) {
RUN();
- ASSERT_EQUAL_64(0x0000000f, x0);
- ASSERT_EQUAL_64(0x0000001f, x1);
- ASSERT_EQUAL_64(0x00000020, x2);
- ASSERT_EQUAL_64(0x0000000f, x3);
- ASSERT_EQUAL_64(0xffffffe0ffffffe0UL, x4);
- ASSERT_EQUAL_64(0x0000000f0000000fUL, x5);
- ASSERT_EQUAL_64(0xffffffe0ffffffe1UL, x6);
- ASSERT_EQUAL_64(0x0000000f0000000fUL, x7);
- ASSERT_EQUAL_64(0x00000001, x8);
- ASSERT_EQUAL_64(0xffffffff, x9);
- ASSERT_EQUAL_64(0x0000001f00000020UL, x10);
- ASSERT_EQUAL_64(0xfffffff0fffffff0UL, x11);
- ASSERT_EQUAL_64(0xfffffff0fffffff1UL, x12);
- ASSERT_EQUAL_64(0x0000000f, x13);
- ASSERT_EQUAL_64(0x0000000f0000000fUL, x14);
- ASSERT_EQUAL_64(0x0000000f, x15);
- ASSERT_EQUAL_64(0x0000000f0000000fUL, x18);
- ASSERT_EQUAL_64(0, x24);
- ASSERT_EQUAL_64(0x0000001f0000001fUL, x25);
- ASSERT_EQUAL_64(0x0000001f0000001fUL, x26);
- ASSERT_EQUAL_64(0, x27);
+ CHECK_EQUAL_64(0x0000000f, x0);
+ CHECK_EQUAL_64(0x0000001f, x1);
+ CHECK_EQUAL_64(0x00000020, x2);
+ CHECK_EQUAL_64(0x0000000f, x3);
+ CHECK_EQUAL_64(0xffffffe0ffffffe0UL, x4);
+ CHECK_EQUAL_64(0x0000000f0000000fUL, x5);
+ CHECK_EQUAL_64(0xffffffe0ffffffe1UL, x6);
+ CHECK_EQUAL_64(0x0000000f0000000fUL, x7);
+ CHECK_EQUAL_64(0x00000001, x8);
+ CHECK_EQUAL_64(0xffffffff, x9);
+ CHECK_EQUAL_64(0x0000001f00000020UL, x10);
+ CHECK_EQUAL_64(0xfffffff0fffffff0UL, x11);
+ CHECK_EQUAL_64(0xfffffff0fffffff1UL, x12);
+ CHECK_EQUAL_64(0x0000000f, x13);
+ CHECK_EQUAL_64(0x0000000f0000000fUL, x14);
+ CHECK_EQUAL_64(0x0000000f, x15);
+ CHECK_EQUAL_64(0x0000000f0000000fUL, x18);
+ CHECK_EQUAL_64(0, x24);
+ CHECK_EQUAL_64(0x0000001f0000001fUL, x25);
+ CHECK_EQUAL_64(0x0000001f0000001fUL, x26);
+ CHECK_EQUAL_64(0, x27);
TEARDOWN();
}
@@ -4485,23 +4683,23 @@ TEST(csel_imm) {
RUN();
- ASSERT_EQUAL_32(-2, w0);
- ASSERT_EQUAL_32(-1, w1);
- ASSERT_EQUAL_32(0, w2);
- ASSERT_EQUAL_32(1, w3);
- ASSERT_EQUAL_32(2, w4);
- ASSERT_EQUAL_32(-1, w5);
- ASSERT_EQUAL_32(0x40000000, w6);
- ASSERT_EQUAL_32(0x80000000, w7);
+ CHECK_EQUAL_32(-2, w0);
+ CHECK_EQUAL_32(-1, w1);
+ CHECK_EQUAL_32(0, w2);
+ CHECK_EQUAL_32(1, w3);
+ CHECK_EQUAL_32(2, w4);
+ CHECK_EQUAL_32(-1, w5);
+ CHECK_EQUAL_32(0x40000000, w6);
+ CHECK_EQUAL_32(0x80000000, w7);
- ASSERT_EQUAL_64(-2, x8);
- ASSERT_EQUAL_64(-1, x9);
- ASSERT_EQUAL_64(0, x10);
- ASSERT_EQUAL_64(1, x11);
- ASSERT_EQUAL_64(2, x12);
- ASSERT_EQUAL_64(-1, x13);
- ASSERT_EQUAL_64(0x4000000000000000UL, x14);
- ASSERT_EQUAL_64(0x8000000000000000UL, x15);
+ CHECK_EQUAL_64(-2, x8);
+ CHECK_EQUAL_64(-1, x9);
+ CHECK_EQUAL_64(0, x10);
+ CHECK_EQUAL_64(1, x11);
+ CHECK_EQUAL_64(2, x12);
+ CHECK_EQUAL_64(-1, x13);
+ CHECK_EQUAL_64(0x4000000000000000UL, x14);
+ CHECK_EQUAL_64(0x8000000000000000UL, x15);
TEARDOWN();
}
@@ -4542,19 +4740,19 @@ TEST(lslv) {
RUN();
- ASSERT_EQUAL_64(value, x0);
- ASSERT_EQUAL_64(value << (shift[0] & 63), x16);
- ASSERT_EQUAL_64(value << (shift[1] & 63), x17);
- ASSERT_EQUAL_64(value << (shift[2] & 63), x18);
- ASSERT_EQUAL_64(value << (shift[3] & 63), x19);
- ASSERT_EQUAL_64(value << (shift[4] & 63), x20);
- ASSERT_EQUAL_64(value << (shift[5] & 63), x21);
- ASSERT_EQUAL_32(value << (shift[0] & 31), w22);
- ASSERT_EQUAL_32(value << (shift[1] & 31), w23);
- ASSERT_EQUAL_32(value << (shift[2] & 31), w24);
- ASSERT_EQUAL_32(value << (shift[3] & 31), w25);
- ASSERT_EQUAL_32(value << (shift[4] & 31), w26);
- ASSERT_EQUAL_32(value << (shift[5] & 31), w27);
+ CHECK_EQUAL_64(value, x0);
+ CHECK_EQUAL_64(value << (shift[0] & 63), x16);
+ CHECK_EQUAL_64(value << (shift[1] & 63), x17);
+ CHECK_EQUAL_64(value << (shift[2] & 63), x18);
+ CHECK_EQUAL_64(value << (shift[3] & 63), x19);
+ CHECK_EQUAL_64(value << (shift[4] & 63), x20);
+ CHECK_EQUAL_64(value << (shift[5] & 63), x21);
+ CHECK_EQUAL_32(value << (shift[0] & 31), w22);
+ CHECK_EQUAL_32(value << (shift[1] & 31), w23);
+ CHECK_EQUAL_32(value << (shift[2] & 31), w24);
+ CHECK_EQUAL_32(value << (shift[3] & 31), w25);
+ CHECK_EQUAL_32(value << (shift[4] & 31), w26);
+ CHECK_EQUAL_32(value << (shift[5] & 31), w27);
TEARDOWN();
}
@@ -4595,21 +4793,21 @@ TEST(lsrv) {
RUN();
- ASSERT_EQUAL_64(value, x0);
- ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
- ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
- ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
- ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
- ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
- ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
+ CHECK_EQUAL_64(value, x0);
+ CHECK_EQUAL_64(value >> (shift[0] & 63), x16);
+ CHECK_EQUAL_64(value >> (shift[1] & 63), x17);
+ CHECK_EQUAL_64(value >> (shift[2] & 63), x18);
+ CHECK_EQUAL_64(value >> (shift[3] & 63), x19);
+ CHECK_EQUAL_64(value >> (shift[4] & 63), x20);
+ CHECK_EQUAL_64(value >> (shift[5] & 63), x21);
value &= 0xffffffffUL;
- ASSERT_EQUAL_32(value >> (shift[0] & 31), w22);
- ASSERT_EQUAL_32(value >> (shift[1] & 31), w23);
- ASSERT_EQUAL_32(value >> (shift[2] & 31), w24);
- ASSERT_EQUAL_32(value >> (shift[3] & 31), w25);
- ASSERT_EQUAL_32(value >> (shift[4] & 31), w26);
- ASSERT_EQUAL_32(value >> (shift[5] & 31), w27);
+ CHECK_EQUAL_32(value >> (shift[0] & 31), w22);
+ CHECK_EQUAL_32(value >> (shift[1] & 31), w23);
+ CHECK_EQUAL_32(value >> (shift[2] & 31), w24);
+ CHECK_EQUAL_32(value >> (shift[3] & 31), w25);
+ CHECK_EQUAL_32(value >> (shift[4] & 31), w26);
+ CHECK_EQUAL_32(value >> (shift[5] & 31), w27);
TEARDOWN();
}
@@ -4650,21 +4848,21 @@ TEST(asrv) {
RUN();
- ASSERT_EQUAL_64(value, x0);
- ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
- ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
- ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
- ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
- ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
- ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
+ CHECK_EQUAL_64(value, x0);
+ CHECK_EQUAL_64(value >> (shift[0] & 63), x16);
+ CHECK_EQUAL_64(value >> (shift[1] & 63), x17);
+ CHECK_EQUAL_64(value >> (shift[2] & 63), x18);
+ CHECK_EQUAL_64(value >> (shift[3] & 63), x19);
+ CHECK_EQUAL_64(value >> (shift[4] & 63), x20);
+ CHECK_EQUAL_64(value >> (shift[5] & 63), x21);
int32_t value32 = static_cast<int32_t>(value & 0xffffffffUL);
- ASSERT_EQUAL_32(value32 >> (shift[0] & 31), w22);
- ASSERT_EQUAL_32(value32 >> (shift[1] & 31), w23);
- ASSERT_EQUAL_32(value32 >> (shift[2] & 31), w24);
- ASSERT_EQUAL_32(value32 >> (shift[3] & 31), w25);
- ASSERT_EQUAL_32(value32 >> (shift[4] & 31), w26);
- ASSERT_EQUAL_32(value32 >> (shift[5] & 31), w27);
+ CHECK_EQUAL_32(value32 >> (shift[0] & 31), w22);
+ CHECK_EQUAL_32(value32 >> (shift[1] & 31), w23);
+ CHECK_EQUAL_32(value32 >> (shift[2] & 31), w24);
+ CHECK_EQUAL_32(value32 >> (shift[3] & 31), w25);
+ CHECK_EQUAL_32(value32 >> (shift[4] & 31), w26);
+ CHECK_EQUAL_32(value32 >> (shift[5] & 31), w27);
TEARDOWN();
}
@@ -4705,19 +4903,19 @@ TEST(rorv) {
RUN();
- ASSERT_EQUAL_64(value, x0);
- ASSERT_EQUAL_64(0xf0123456789abcdeUL, x16);
- ASSERT_EQUAL_64(0xef0123456789abcdUL, x17);
- ASSERT_EQUAL_64(0xdef0123456789abcUL, x18);
- ASSERT_EQUAL_64(0xcdef0123456789abUL, x19);
- ASSERT_EQUAL_64(0xabcdef0123456789UL, x20);
- ASSERT_EQUAL_64(0x789abcdef0123456UL, x21);
- ASSERT_EQUAL_32(0xf89abcde, w22);
- ASSERT_EQUAL_32(0xef89abcd, w23);
- ASSERT_EQUAL_32(0xdef89abc, w24);
- ASSERT_EQUAL_32(0xcdef89ab, w25);
- ASSERT_EQUAL_32(0xabcdef89, w26);
- ASSERT_EQUAL_32(0xf89abcde, w27);
+ CHECK_EQUAL_64(value, x0);
+ CHECK_EQUAL_64(0xf0123456789abcdeUL, x16);
+ CHECK_EQUAL_64(0xef0123456789abcdUL, x17);
+ CHECK_EQUAL_64(0xdef0123456789abcUL, x18);
+ CHECK_EQUAL_64(0xcdef0123456789abUL, x19);
+ CHECK_EQUAL_64(0xabcdef0123456789UL, x20);
+ CHECK_EQUAL_64(0x789abcdef0123456UL, x21);
+ CHECK_EQUAL_32(0xf89abcde, w22);
+ CHECK_EQUAL_32(0xef89abcd, w23);
+ CHECK_EQUAL_32(0xdef89abc, w24);
+ CHECK_EQUAL_32(0xcdef89ab, w25);
+ CHECK_EQUAL_32(0xabcdef89, w26);
+ CHECK_EQUAL_32(0xf89abcde, w27);
TEARDOWN();
}
@@ -4751,14 +4949,14 @@ TEST(bfm) {
RUN();
- ASSERT_EQUAL_64(0x88888888888889abL, x10);
- ASSERT_EQUAL_64(0x8888cdef88888888L, x11);
+ CHECK_EQUAL_64(0x88888888888889abL, x10);
+ CHECK_EQUAL_64(0x8888cdef88888888L, x11);
- ASSERT_EQUAL_32(0x888888ab, w20);
- ASSERT_EQUAL_32(0x88cdef88, w21);
+ CHECK_EQUAL_32(0x888888ab, w20);
+ CHECK_EQUAL_32(0x88cdef88, w21);
- ASSERT_EQUAL_64(0x8888888888ef8888L, x12);
- ASSERT_EQUAL_64(0x88888888888888abL, x13);
+ CHECK_EQUAL_64(0x8888888888ef8888L, x12);
+ CHECK_EQUAL_64(0x88888888888888abL, x13);
TEARDOWN();
}
@@ -4800,28 +4998,28 @@ TEST(sbfm) {
RUN();
- ASSERT_EQUAL_64(0xffffffffffff89abL, x10);
- ASSERT_EQUAL_64(0xffffcdef00000000L, x11);
- ASSERT_EQUAL_64(0x4567L, x12);
- ASSERT_EQUAL_64(0x789abcdef0000L, x13);
+ CHECK_EQUAL_64(0xffffffffffff89abL, x10);
+ CHECK_EQUAL_64(0xffffcdef00000000L, x11);
+ CHECK_EQUAL_64(0x4567L, x12);
+ CHECK_EQUAL_64(0x789abcdef0000L, x13);
- ASSERT_EQUAL_32(0xffffffab, w14);
- ASSERT_EQUAL_32(0xffcdef00, w15);
- ASSERT_EQUAL_32(0x54, w16);
- ASSERT_EQUAL_32(0x00321000, w17);
+ CHECK_EQUAL_32(0xffffffab, w14);
+ CHECK_EQUAL_32(0xffcdef00, w15);
+ CHECK_EQUAL_32(0x54, w16);
+ CHECK_EQUAL_32(0x00321000, w17);
- ASSERT_EQUAL_64(0x01234567L, x18);
- ASSERT_EQUAL_64(0xfffffffffedcba98L, x19);
- ASSERT_EQUAL_64(0xffffffffffcdef00L, x20);
- ASSERT_EQUAL_64(0x321000L, x21);
- ASSERT_EQUAL_64(0xffffffffffffabcdL, x22);
- ASSERT_EQUAL_64(0x5432L, x23);
- ASSERT_EQUAL_64(0xffffffffffffffefL, x24);
- ASSERT_EQUAL_64(0x10, x25);
- ASSERT_EQUAL_64(0xffffffffffffcdefL, x26);
- ASSERT_EQUAL_64(0x3210, x27);
- ASSERT_EQUAL_64(0xffffffff89abcdefL, x28);
- ASSERT_EQUAL_64(0x76543210, x29);
+ CHECK_EQUAL_64(0x01234567L, x18);
+ CHECK_EQUAL_64(0xfffffffffedcba98L, x19);
+ CHECK_EQUAL_64(0xffffffffffcdef00L, x20);
+ CHECK_EQUAL_64(0x321000L, x21);
+ CHECK_EQUAL_64(0xffffffffffffabcdL, x22);
+ CHECK_EQUAL_64(0x5432L, x23);
+ CHECK_EQUAL_64(0xffffffffffffffefL, x24);
+ CHECK_EQUAL_64(0x10, x25);
+ CHECK_EQUAL_64(0xffffffffffffcdefL, x26);
+ CHECK_EQUAL_64(0x3210, x27);
+ CHECK_EQUAL_64(0xffffffff89abcdefL, x28);
+ CHECK_EQUAL_64(0x76543210, x29);
TEARDOWN();
}
@@ -4861,24 +5059,24 @@ TEST(ubfm) {
RUN();
- ASSERT_EQUAL_64(0x00000000000089abL, x10);
- ASSERT_EQUAL_64(0x0000cdef00000000L, x11);
- ASSERT_EQUAL_64(0x4567L, x12);
- ASSERT_EQUAL_64(0x789abcdef0000L, x13);
+ CHECK_EQUAL_64(0x00000000000089abL, x10);
+ CHECK_EQUAL_64(0x0000cdef00000000L, x11);
+ CHECK_EQUAL_64(0x4567L, x12);
+ CHECK_EQUAL_64(0x789abcdef0000L, x13);
- ASSERT_EQUAL_32(0x000000ab, w25);
- ASSERT_EQUAL_32(0x00cdef00, w26);
- ASSERT_EQUAL_32(0x54, w27);
- ASSERT_EQUAL_32(0x00321000, w28);
+ CHECK_EQUAL_32(0x000000ab, w25);
+ CHECK_EQUAL_32(0x00cdef00, w26);
+ CHECK_EQUAL_32(0x54, w27);
+ CHECK_EQUAL_32(0x00321000, w28);
- ASSERT_EQUAL_64(0x8000000000000000L, x15);
- ASSERT_EQUAL_64(0x0123456789abcdefL, x16);
- ASSERT_EQUAL_64(0x01234567L, x17);
- ASSERT_EQUAL_64(0xcdef00L, x18);
- ASSERT_EQUAL_64(0xabcdL, x19);
- ASSERT_EQUAL_64(0xefL, x20);
- ASSERT_EQUAL_64(0xcdefL, x21);
- ASSERT_EQUAL_64(0x89abcdefL, x22);
+ CHECK_EQUAL_64(0x8000000000000000L, x15);
+ CHECK_EQUAL_64(0x0123456789abcdefL, x16);
+ CHECK_EQUAL_64(0x01234567L, x17);
+ CHECK_EQUAL_64(0xcdef00L, x18);
+ CHECK_EQUAL_64(0xabcdL, x19);
+ CHECK_EQUAL_64(0xefL, x20);
+ CHECK_EQUAL_64(0xcdefL, x21);
+ CHECK_EQUAL_64(0x89abcdefL, x22);
TEARDOWN();
}
@@ -4893,26 +5091,30 @@ TEST(extr) {
__ Mov(x2, 0xfedcba9876543210L);
__ Extr(w10, w1, w2, 0);
- __ Extr(w11, w1, w2, 1);
- __ Extr(x12, x2, x1, 2);
+ __ Extr(x11, x1, x2, 0);
+ __ Extr(w12, w1, w2, 1);
+ __ Extr(x13, x2, x1, 2);
- __ Ror(w13, w1, 0);
- __ Ror(w14, w2, 17);
- __ Ror(w15, w1, 31);
- __ Ror(x18, x2, 1);
- __ Ror(x19, x1, 63);
+ __ Ror(w20, w1, 0);
+ __ Ror(x21, x1, 0);
+ __ Ror(w22, w2, 17);
+ __ Ror(w23, w1, 31);
+ __ Ror(x24, x2, 1);
+ __ Ror(x25, x1, 63);
END();
RUN();
- ASSERT_EQUAL_64(0x76543210, x10);
- ASSERT_EQUAL_64(0xbb2a1908, x11);
- ASSERT_EQUAL_64(0x0048d159e26af37bUL, x12);
- ASSERT_EQUAL_64(0x89abcdef, x13);
- ASSERT_EQUAL_64(0x19083b2a, x14);
- ASSERT_EQUAL_64(0x13579bdf, x15);
- ASSERT_EQUAL_64(0x7f6e5d4c3b2a1908UL, x18);
- ASSERT_EQUAL_64(0x02468acf13579bdeUL, x19);
+ CHECK_EQUAL_64(0x76543210, x10);
+ CHECK_EQUAL_64(0xfedcba9876543210L, x11);
+ CHECK_EQUAL_64(0xbb2a1908, x12);
+ CHECK_EQUAL_64(0x0048d159e26af37bUL, x13);
+ CHECK_EQUAL_64(0x89abcdef, x20);
+ CHECK_EQUAL_64(0x0123456789abcdefL, x21);
+ CHECK_EQUAL_64(0x19083b2a, x22);
+ CHECK_EQUAL_64(0x13579bdf, x23);
+ CHECK_EQUAL_64(0x7f6e5d4c3b2a1908UL, x24);
+ CHECK_EQUAL_64(0x02468acf13579bdeUL, x25);
TEARDOWN();
}
@@ -4935,14 +5137,14 @@ TEST(fmov_imm) {
RUN();
- ASSERT_EQUAL_FP32(1.0, s11);
- ASSERT_EQUAL_FP64(-13.0, d22);
- ASSERT_EQUAL_FP32(255.0, s1);
- ASSERT_EQUAL_FP64(12.34567, d2);
- ASSERT_EQUAL_FP32(0.0, s3);
- ASSERT_EQUAL_FP64(0.0, d4);
- ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
- ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d6);
+ CHECK_EQUAL_FP32(1.0, s11);
+ CHECK_EQUAL_FP64(-13.0, d22);
+ CHECK_EQUAL_FP32(255.0, s1);
+ CHECK_EQUAL_FP64(12.34567, d2);
+ CHECK_EQUAL_FP32(0.0, s3);
+ CHECK_EQUAL_FP64(0.0, d4);
+ CHECK_EQUAL_FP32(kFP32PositiveInfinity, s5);
+ CHECK_EQUAL_FP64(kFP64NegativeInfinity, d6);
TEARDOWN();
}
@@ -4967,13 +5169,13 @@ TEST(fmov_reg) {
RUN();
- ASSERT_EQUAL_32(float_to_rawbits(1.0), w10);
- ASSERT_EQUAL_FP32(1.0, s30);
- ASSERT_EQUAL_FP32(1.0, s5);
- ASSERT_EQUAL_64(double_to_rawbits(-13.0), x1);
- ASSERT_EQUAL_FP64(-13.0, d2);
- ASSERT_EQUAL_FP64(-13.0, d4);
- ASSERT_EQUAL_FP32(rawbits_to_float(0x89abcdef), s6);
+ CHECK_EQUAL_32(float_to_rawbits(1.0), w10);
+ CHECK_EQUAL_FP32(1.0, s30);
+ CHECK_EQUAL_FP32(1.0, s5);
+ CHECK_EQUAL_64(double_to_rawbits(-13.0), x1);
+ CHECK_EQUAL_FP64(-13.0, d2);
+ CHECK_EQUAL_FP64(-13.0, d4);
+ CHECK_EQUAL_FP32(rawbits_to_float(0x89abcdef), s6);
TEARDOWN();
}
@@ -5017,20 +5219,20 @@ TEST(fadd) {
RUN();
- ASSERT_EQUAL_FP32(4.25, s0);
- ASSERT_EQUAL_FP32(1.0, s1);
- ASSERT_EQUAL_FP32(1.0, s2);
- ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
- ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
- ASSERT_EQUAL_FP64(0.25, d7);
- ASSERT_EQUAL_FP64(2.25, d8);
- ASSERT_EQUAL_FP64(2.25, d9);
- ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d10);
- ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d11);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
+ CHECK_EQUAL_FP32(4.25, s0);
+ CHECK_EQUAL_FP32(1.0, s1);
+ CHECK_EQUAL_FP32(1.0, s2);
+ CHECK_EQUAL_FP32(kFP32PositiveInfinity, s3);
+ CHECK_EQUAL_FP32(kFP32NegativeInfinity, s4);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s5);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s6);
+ CHECK_EQUAL_FP64(0.25, d7);
+ CHECK_EQUAL_FP64(2.25, d8);
+ CHECK_EQUAL_FP64(2.25, d9);
+ CHECK_EQUAL_FP64(kFP64PositiveInfinity, d10);
+ CHECK_EQUAL_FP64(kFP64NegativeInfinity, d11);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d12);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d13);
TEARDOWN();
}
@@ -5074,20 +5276,20 @@ TEST(fsub) {
RUN();
- ASSERT_EQUAL_FP32(2.25, s0);
- ASSERT_EQUAL_FP32(1.0, s1);
- ASSERT_EQUAL_FP32(-1.0, s2);
- ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
- ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
- ASSERT_EQUAL_FP64(-4.25, d7);
- ASSERT_EQUAL_FP64(-2.25, d8);
- ASSERT_EQUAL_FP64(-2.25, d9);
- ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
- ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
+ CHECK_EQUAL_FP32(2.25, s0);
+ CHECK_EQUAL_FP32(1.0, s1);
+ CHECK_EQUAL_FP32(-1.0, s2);
+ CHECK_EQUAL_FP32(kFP32NegativeInfinity, s3);
+ CHECK_EQUAL_FP32(kFP32PositiveInfinity, s4);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s5);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s6);
+ CHECK_EQUAL_FP64(-4.25, d7);
+ CHECK_EQUAL_FP64(-2.25, d8);
+ CHECK_EQUAL_FP64(-2.25, d9);
+ CHECK_EQUAL_FP64(kFP64NegativeInfinity, d10);
+ CHECK_EQUAL_FP64(kFP64PositiveInfinity, d11);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d12);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d13);
TEARDOWN();
}
@@ -5132,20 +5334,20 @@ TEST(fmul) {
RUN();
- ASSERT_EQUAL_FP32(6.5, s0);
- ASSERT_EQUAL_FP32(0.0, s1);
- ASSERT_EQUAL_FP32(0.0, s2);
- ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
- ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
- ASSERT_EQUAL_FP64(-4.5, d7);
- ASSERT_EQUAL_FP64(0.0, d8);
- ASSERT_EQUAL_FP64(0.0, d9);
- ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
- ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
+ CHECK_EQUAL_FP32(6.5, s0);
+ CHECK_EQUAL_FP32(0.0, s1);
+ CHECK_EQUAL_FP32(0.0, s2);
+ CHECK_EQUAL_FP32(kFP32NegativeInfinity, s3);
+ CHECK_EQUAL_FP32(kFP32PositiveInfinity, s4);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s5);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s6);
+ CHECK_EQUAL_FP64(-4.5, d7);
+ CHECK_EQUAL_FP64(0.0, d8);
+ CHECK_EQUAL_FP64(0.0, d9);
+ CHECK_EQUAL_FP64(kFP64NegativeInfinity, d10);
+ CHECK_EQUAL_FP64(kFP64PositiveInfinity, d11);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d12);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d13);
TEARDOWN();
}
@@ -5168,10 +5370,10 @@ static void FmaddFmsubHelper(double n, double m, double a,
END();
RUN();
- ASSERT_EQUAL_FP64(fmadd, d28);
- ASSERT_EQUAL_FP64(fmsub, d29);
- ASSERT_EQUAL_FP64(fnmadd, d30);
- ASSERT_EQUAL_FP64(fnmsub, d31);
+ CHECK_EQUAL_FP64(fmadd, d28);
+ CHECK_EQUAL_FP64(fmsub, d29);
+ CHECK_EQUAL_FP64(fnmadd, d30);
+ CHECK_EQUAL_FP64(fnmsub, d31);
TEARDOWN();
}
@@ -5236,10 +5438,10 @@ static void FmaddFmsubHelper(float n, float m, float a,
END();
RUN();
- ASSERT_EQUAL_FP32(fmadd, s28);
- ASSERT_EQUAL_FP32(fmsub, s29);
- ASSERT_EQUAL_FP32(fnmadd, s30);
- ASSERT_EQUAL_FP32(fnmsub, s31);
+ CHECK_EQUAL_FP32(fmadd, s28);
+ CHECK_EQUAL_FP32(fmsub, s29);
+ CHECK_EQUAL_FP32(fnmadd, s30);
+ CHECK_EQUAL_FP32(fnmsub, s31);
TEARDOWN();
}
@@ -5295,12 +5497,12 @@ TEST(fmadd_fmsub_double_nans) {
double q1 = rawbits_to_double(0x7ffaaaaa11111111);
double q2 = rawbits_to_double(0x7ffaaaaa22222222);
double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
- ASSERT(IsSignallingNaN(s1));
- ASSERT(IsSignallingNaN(s2));
- ASSERT(IsSignallingNaN(sa));
- ASSERT(IsQuietNaN(q1));
- ASSERT(IsQuietNaN(q2));
- ASSERT(IsQuietNaN(qa));
+ DCHECK(IsSignallingNaN(s1));
+ DCHECK(IsSignallingNaN(s2));
+ DCHECK(IsSignallingNaN(sa));
+ DCHECK(IsQuietNaN(q1));
+ DCHECK(IsQuietNaN(q2));
+ DCHECK(IsQuietNaN(qa));
// The input NaNs after passing through ProcessNaN.
double s1_proc = rawbits_to_double(0x7ffd555511111111);
@@ -5309,22 +5511,22 @@ TEST(fmadd_fmsub_double_nans) {
double q1_proc = q1;
double q2_proc = q2;
double qa_proc = qa;
- ASSERT(IsQuietNaN(s1_proc));
- ASSERT(IsQuietNaN(s2_proc));
- ASSERT(IsQuietNaN(sa_proc));
- ASSERT(IsQuietNaN(q1_proc));
- ASSERT(IsQuietNaN(q2_proc));
- ASSERT(IsQuietNaN(qa_proc));
+ DCHECK(IsQuietNaN(s1_proc));
+ DCHECK(IsQuietNaN(s2_proc));
+ DCHECK(IsQuietNaN(sa_proc));
+ DCHECK(IsQuietNaN(q1_proc));
+ DCHECK(IsQuietNaN(q2_proc));
+ DCHECK(IsQuietNaN(qa_proc));
// Negated NaNs as it would be done on ARMv8 hardware.
double s1_proc_neg = rawbits_to_double(0xfffd555511111111);
double sa_proc_neg = rawbits_to_double(0xfffd5555aaaaaaaa);
double q1_proc_neg = rawbits_to_double(0xfffaaaaa11111111);
double qa_proc_neg = rawbits_to_double(0xfffaaaaaaaaaaaaa);
- ASSERT(IsQuietNaN(s1_proc_neg));
- ASSERT(IsQuietNaN(sa_proc_neg));
- ASSERT(IsQuietNaN(q1_proc_neg));
- ASSERT(IsQuietNaN(qa_proc_neg));
+ DCHECK(IsQuietNaN(s1_proc_neg));
+ DCHECK(IsQuietNaN(sa_proc_neg));
+ DCHECK(IsQuietNaN(q1_proc_neg));
+ DCHECK(IsQuietNaN(qa_proc_neg));
// Quiet NaNs are propagated.
FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
@@ -5378,12 +5580,12 @@ TEST(fmadd_fmsub_float_nans) {
float q1 = rawbits_to_float(0x7fea1111);
float q2 = rawbits_to_float(0x7fea2222);
float qa = rawbits_to_float(0x7feaaaaa);
- ASSERT(IsSignallingNaN(s1));
- ASSERT(IsSignallingNaN(s2));
- ASSERT(IsSignallingNaN(sa));
- ASSERT(IsQuietNaN(q1));
- ASSERT(IsQuietNaN(q2));
- ASSERT(IsQuietNaN(qa));
+ DCHECK(IsSignallingNaN(s1));
+ DCHECK(IsSignallingNaN(s2));
+ DCHECK(IsSignallingNaN(sa));
+ DCHECK(IsQuietNaN(q1));
+ DCHECK(IsQuietNaN(q2));
+ DCHECK(IsQuietNaN(qa));
// The input NaNs after passing through ProcessNaN.
float s1_proc = rawbits_to_float(0x7fd51111);
@@ -5392,22 +5594,22 @@ TEST(fmadd_fmsub_float_nans) {
float q1_proc = q1;
float q2_proc = q2;
float qa_proc = qa;
- ASSERT(IsQuietNaN(s1_proc));
- ASSERT(IsQuietNaN(s2_proc));
- ASSERT(IsQuietNaN(sa_proc));
- ASSERT(IsQuietNaN(q1_proc));
- ASSERT(IsQuietNaN(q2_proc));
- ASSERT(IsQuietNaN(qa_proc));
+ DCHECK(IsQuietNaN(s1_proc));
+ DCHECK(IsQuietNaN(s2_proc));
+ DCHECK(IsQuietNaN(sa_proc));
+ DCHECK(IsQuietNaN(q1_proc));
+ DCHECK(IsQuietNaN(q2_proc));
+ DCHECK(IsQuietNaN(qa_proc));
// Negated NaNs as it would be done on ARMv8 hardware.
float s1_proc_neg = rawbits_to_float(0xffd51111);
float sa_proc_neg = rawbits_to_float(0xffd5aaaa);
float q1_proc_neg = rawbits_to_float(0xffea1111);
float qa_proc_neg = rawbits_to_float(0xffeaaaaa);
- ASSERT(IsQuietNaN(s1_proc_neg));
- ASSERT(IsQuietNaN(sa_proc_neg));
- ASSERT(IsQuietNaN(q1_proc_neg));
- ASSERT(IsQuietNaN(qa_proc_neg));
+ DCHECK(IsQuietNaN(s1_proc_neg));
+ DCHECK(IsQuietNaN(sa_proc_neg));
+ DCHECK(IsQuietNaN(q1_proc_neg));
+ DCHECK(IsQuietNaN(qa_proc_neg));
// Quiet NaNs are propagated.
FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
@@ -5491,20 +5693,20 @@ TEST(fdiv) {
RUN();
- ASSERT_EQUAL_FP32(1.625f, s0);
- ASSERT_EQUAL_FP32(1.0f, s1);
- ASSERT_EQUAL_FP32(-0.0f, s2);
- ASSERT_EQUAL_FP32(0.0f, s3);
- ASSERT_EQUAL_FP32(-0.0f, s4);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
- ASSERT_EQUAL_FP64(-1.125, d7);
- ASSERT_EQUAL_FP64(0.0, d8);
- ASSERT_EQUAL_FP64(-0.0, d9);
- ASSERT_EQUAL_FP64(0.0, d10);
- ASSERT_EQUAL_FP64(-0.0, d11);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
+ CHECK_EQUAL_FP32(1.625f, s0);
+ CHECK_EQUAL_FP32(1.0f, s1);
+ CHECK_EQUAL_FP32(-0.0f, s2);
+ CHECK_EQUAL_FP32(0.0f, s3);
+ CHECK_EQUAL_FP32(-0.0f, s4);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s5);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s6);
+ CHECK_EQUAL_FP64(-1.125, d7);
+ CHECK_EQUAL_FP64(0.0, d8);
+ CHECK_EQUAL_FP64(-0.0, d9);
+ CHECK_EQUAL_FP64(0.0, d10);
+ CHECK_EQUAL_FP64(-0.0, d11);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d12);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d13);
TEARDOWN();
}
@@ -5607,10 +5809,10 @@ static void FminFmaxDoubleHelper(double n, double m, double min, double max,
RUN();
- ASSERT_EQUAL_FP64(min, d28);
- ASSERT_EQUAL_FP64(max, d29);
- ASSERT_EQUAL_FP64(minnm, d30);
- ASSERT_EQUAL_FP64(maxnm, d31);
+ CHECK_EQUAL_FP64(min, d28);
+ CHECK_EQUAL_FP64(max, d29);
+ CHECK_EQUAL_FP64(minnm, d30);
+ CHECK_EQUAL_FP64(maxnm, d31);
TEARDOWN();
}
@@ -5625,10 +5827,10 @@ TEST(fmax_fmin_d) {
double snan_processed = rawbits_to_double(0x7ffd555512345678);
double qnan_processed = qnan;
- ASSERT(IsSignallingNaN(snan));
- ASSERT(IsQuietNaN(qnan));
- ASSERT(IsQuietNaN(snan_processed));
- ASSERT(IsQuietNaN(qnan_processed));
+ DCHECK(IsSignallingNaN(snan));
+ DCHECK(IsQuietNaN(qnan));
+ DCHECK(IsQuietNaN(snan_processed));
+ DCHECK(IsQuietNaN(qnan_processed));
// Bootstrap tests.
FminFmaxDoubleHelper(0, 0, 0, 0, 0, 0);
@@ -5692,10 +5894,10 @@ static void FminFmaxFloatHelper(float n, float m, float min, float max,
RUN();
- ASSERT_EQUAL_FP32(min, s28);
- ASSERT_EQUAL_FP32(max, s29);
- ASSERT_EQUAL_FP32(minnm, s30);
- ASSERT_EQUAL_FP32(maxnm, s31);
+ CHECK_EQUAL_FP32(min, s28);
+ CHECK_EQUAL_FP32(max, s29);
+ CHECK_EQUAL_FP32(minnm, s30);
+ CHECK_EQUAL_FP32(maxnm, s31);
TEARDOWN();
}
@@ -5710,10 +5912,10 @@ TEST(fmax_fmin_s) {
float snan_processed = rawbits_to_float(0x7fd51234);
float qnan_processed = qnan;
- ASSERT(IsSignallingNaN(snan));
- ASSERT(IsQuietNaN(qnan));
- ASSERT(IsQuietNaN(snan_processed));
- ASSERT(IsQuietNaN(qnan_processed));
+ DCHECK(IsSignallingNaN(snan));
+ DCHECK(IsQuietNaN(qnan));
+ DCHECK(IsQuietNaN(snan_processed));
+ DCHECK(IsQuietNaN(qnan_processed));
// Bootstrap tests.
FminFmaxFloatHelper(0, 0, 0, 0, 0, 0);
@@ -5815,16 +6017,16 @@ TEST(fccmp) {
RUN();
- ASSERT_EQUAL_32(ZCFlag, w0);
- ASSERT_EQUAL_32(VFlag, w1);
- ASSERT_EQUAL_32(NFlag, w2);
- ASSERT_EQUAL_32(CVFlag, w3);
- ASSERT_EQUAL_32(ZCFlag, w4);
- ASSERT_EQUAL_32(ZVFlag, w5);
- ASSERT_EQUAL_32(CFlag, w6);
- ASSERT_EQUAL_32(NFlag, w7);
- ASSERT_EQUAL_32(ZCFlag, w8);
- ASSERT_EQUAL_32(ZCFlag, w9);
+ CHECK_EQUAL_32(ZCFlag, w0);
+ CHECK_EQUAL_32(VFlag, w1);
+ CHECK_EQUAL_32(NFlag, w2);
+ CHECK_EQUAL_32(CVFlag, w3);
+ CHECK_EQUAL_32(ZCFlag, w4);
+ CHECK_EQUAL_32(ZVFlag, w5);
+ CHECK_EQUAL_32(CFlag, w6);
+ CHECK_EQUAL_32(NFlag, w7);
+ CHECK_EQUAL_32(ZCFlag, w8);
+ CHECK_EQUAL_32(ZCFlag, w9);
TEARDOWN();
}
@@ -5894,20 +6096,20 @@ TEST(fcmp) {
RUN();
- ASSERT_EQUAL_32(ZCFlag, w0);
- ASSERT_EQUAL_32(NFlag, w1);
- ASSERT_EQUAL_32(CFlag, w2);
- ASSERT_EQUAL_32(CVFlag, w3);
- ASSERT_EQUAL_32(CVFlag, w4);
- ASSERT_EQUAL_32(ZCFlag, w5);
- ASSERT_EQUAL_32(NFlag, w6);
- ASSERT_EQUAL_32(ZCFlag, w10);
- ASSERT_EQUAL_32(NFlag, w11);
- ASSERT_EQUAL_32(CFlag, w12);
- ASSERT_EQUAL_32(CVFlag, w13);
- ASSERT_EQUAL_32(CVFlag, w14);
- ASSERT_EQUAL_32(ZCFlag, w15);
- ASSERT_EQUAL_32(NFlag, w16);
+ CHECK_EQUAL_32(ZCFlag, w0);
+ CHECK_EQUAL_32(NFlag, w1);
+ CHECK_EQUAL_32(CFlag, w2);
+ CHECK_EQUAL_32(CVFlag, w3);
+ CHECK_EQUAL_32(CVFlag, w4);
+ CHECK_EQUAL_32(ZCFlag, w5);
+ CHECK_EQUAL_32(NFlag, w6);
+ CHECK_EQUAL_32(ZCFlag, w10);
+ CHECK_EQUAL_32(NFlag, w11);
+ CHECK_EQUAL_32(CFlag, w12);
+ CHECK_EQUAL_32(CVFlag, w13);
+ CHECK_EQUAL_32(CVFlag, w14);
+ CHECK_EQUAL_32(ZCFlag, w15);
+ CHECK_EQUAL_32(NFlag, w16);
TEARDOWN();
}
@@ -5935,12 +6137,12 @@ TEST(fcsel) {
RUN();
- ASSERT_EQUAL_FP32(1.0, s0);
- ASSERT_EQUAL_FP32(2.0, s1);
- ASSERT_EQUAL_FP64(3.0, d2);
- ASSERT_EQUAL_FP64(4.0, d3);
- ASSERT_EQUAL_FP32(1.0, s4);
- ASSERT_EQUAL_FP64(3.0, d5);
+ CHECK_EQUAL_FP32(1.0, s0);
+ CHECK_EQUAL_FP32(2.0, s1);
+ CHECK_EQUAL_FP64(3.0, d2);
+ CHECK_EQUAL_FP64(4.0, d3);
+ CHECK_EQUAL_FP32(1.0, s4);
+ CHECK_EQUAL_FP64(3.0, d5);
TEARDOWN();
}
@@ -5974,18 +6176,18 @@ TEST(fneg) {
RUN();
- ASSERT_EQUAL_FP32(-1.0, s0);
- ASSERT_EQUAL_FP32(1.0, s1);
- ASSERT_EQUAL_FP32(-0.0, s2);
- ASSERT_EQUAL_FP32(0.0, s3);
- ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
- ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
- ASSERT_EQUAL_FP64(-1.0, d6);
- ASSERT_EQUAL_FP64(1.0, d7);
- ASSERT_EQUAL_FP64(-0.0, d8);
- ASSERT_EQUAL_FP64(0.0, d9);
- ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
- ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
+ CHECK_EQUAL_FP32(-1.0, s0);
+ CHECK_EQUAL_FP32(1.0, s1);
+ CHECK_EQUAL_FP32(-0.0, s2);
+ CHECK_EQUAL_FP32(0.0, s3);
+ CHECK_EQUAL_FP32(kFP32NegativeInfinity, s4);
+ CHECK_EQUAL_FP32(kFP32PositiveInfinity, s5);
+ CHECK_EQUAL_FP64(-1.0, d6);
+ CHECK_EQUAL_FP64(1.0, d7);
+ CHECK_EQUAL_FP64(-0.0, d8);
+ CHECK_EQUAL_FP64(0.0, d9);
+ CHECK_EQUAL_FP64(kFP64NegativeInfinity, d10);
+ CHECK_EQUAL_FP64(kFP64PositiveInfinity, d11);
TEARDOWN();
}
@@ -6015,14 +6217,14 @@ TEST(fabs) {
RUN();
- ASSERT_EQUAL_FP32(1.0, s0);
- ASSERT_EQUAL_FP32(1.0, s1);
- ASSERT_EQUAL_FP32(0.0, s2);
- ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
- ASSERT_EQUAL_FP64(1.0, d4);
- ASSERT_EQUAL_FP64(1.0, d5);
- ASSERT_EQUAL_FP64(0.0, d6);
- ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
+ CHECK_EQUAL_FP32(1.0, s0);
+ CHECK_EQUAL_FP32(1.0, s1);
+ CHECK_EQUAL_FP32(0.0, s2);
+ CHECK_EQUAL_FP32(kFP32PositiveInfinity, s3);
+ CHECK_EQUAL_FP64(1.0, d4);
+ CHECK_EQUAL_FP64(1.0, d5);
+ CHECK_EQUAL_FP64(0.0, d6);
+ CHECK_EQUAL_FP64(kFP64PositiveInfinity, d7);
TEARDOWN();
}
@@ -6066,20 +6268,20 @@ TEST(fsqrt) {
RUN();
- ASSERT_EQUAL_FP32(0.0, s0);
- ASSERT_EQUAL_FP32(1.0, s1);
- ASSERT_EQUAL_FP32(0.5, s2);
- ASSERT_EQUAL_FP32(256.0, s3);
- ASSERT_EQUAL_FP32(-0.0, s4);
- ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
- ASSERT_EQUAL_FP64(0.0, d7);
- ASSERT_EQUAL_FP64(1.0, d8);
- ASSERT_EQUAL_FP64(0.5, d9);
- ASSERT_EQUAL_FP64(65536.0, d10);
- ASSERT_EQUAL_FP64(-0.0, d11);
- ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d12);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
+ CHECK_EQUAL_FP32(0.0, s0);
+ CHECK_EQUAL_FP32(1.0, s1);
+ CHECK_EQUAL_FP32(0.5, s2);
+ CHECK_EQUAL_FP32(256.0, s3);
+ CHECK_EQUAL_FP32(-0.0, s4);
+ CHECK_EQUAL_FP32(kFP32PositiveInfinity, s5);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s6);
+ CHECK_EQUAL_FP64(0.0, d7);
+ CHECK_EQUAL_FP64(1.0, d8);
+ CHECK_EQUAL_FP64(0.5, d9);
+ CHECK_EQUAL_FP64(65536.0, d10);
+ CHECK_EQUAL_FP64(-0.0, d11);
+ CHECK_EQUAL_FP64(kFP32PositiveInfinity, d12);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d13);
TEARDOWN();
}
@@ -6145,30 +6347,30 @@ TEST(frinta) {
RUN();
- ASSERT_EQUAL_FP32(1.0, s0);
- ASSERT_EQUAL_FP32(1.0, s1);
- ASSERT_EQUAL_FP32(2.0, s2);
- ASSERT_EQUAL_FP32(2.0, s3);
- ASSERT_EQUAL_FP32(3.0, s4);
- ASSERT_EQUAL_FP32(-2.0, s5);
- ASSERT_EQUAL_FP32(-3.0, s6);
- ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
- ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
- ASSERT_EQUAL_FP32(0.0, s9);
- ASSERT_EQUAL_FP32(-0.0, s10);
- ASSERT_EQUAL_FP32(-0.0, s11);
- ASSERT_EQUAL_FP64(1.0, d12);
- ASSERT_EQUAL_FP64(1.0, d13);
- ASSERT_EQUAL_FP64(2.0, d14);
- ASSERT_EQUAL_FP64(2.0, d15);
- ASSERT_EQUAL_FP64(3.0, d16);
- ASSERT_EQUAL_FP64(-2.0, d17);
- ASSERT_EQUAL_FP64(-3.0, d18);
- ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
- ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
- ASSERT_EQUAL_FP64(0.0, d21);
- ASSERT_EQUAL_FP64(-0.0, d22);
- ASSERT_EQUAL_FP64(-0.0, d23);
+ CHECK_EQUAL_FP32(1.0, s0);
+ CHECK_EQUAL_FP32(1.0, s1);
+ CHECK_EQUAL_FP32(2.0, s2);
+ CHECK_EQUAL_FP32(2.0, s3);
+ CHECK_EQUAL_FP32(3.0, s4);
+ CHECK_EQUAL_FP32(-2.0, s5);
+ CHECK_EQUAL_FP32(-3.0, s6);
+ CHECK_EQUAL_FP32(kFP32PositiveInfinity, s7);
+ CHECK_EQUAL_FP32(kFP32NegativeInfinity, s8);
+ CHECK_EQUAL_FP32(0.0, s9);
+ CHECK_EQUAL_FP32(-0.0, s10);
+ CHECK_EQUAL_FP32(-0.0, s11);
+ CHECK_EQUAL_FP64(1.0, d12);
+ CHECK_EQUAL_FP64(1.0, d13);
+ CHECK_EQUAL_FP64(2.0, d14);
+ CHECK_EQUAL_FP64(2.0, d15);
+ CHECK_EQUAL_FP64(3.0, d16);
+ CHECK_EQUAL_FP64(-2.0, d17);
+ CHECK_EQUAL_FP64(-3.0, d18);
+ CHECK_EQUAL_FP64(kFP64PositiveInfinity, d19);
+ CHECK_EQUAL_FP64(kFP64NegativeInfinity, d20);
+ CHECK_EQUAL_FP64(0.0, d21);
+ CHECK_EQUAL_FP64(-0.0, d22);
+ CHECK_EQUAL_FP64(-0.0, d23);
TEARDOWN();
}
@@ -6234,30 +6436,30 @@ TEST(frintm) {
RUN();
- ASSERT_EQUAL_FP32(1.0, s0);
- ASSERT_EQUAL_FP32(1.0, s1);
- ASSERT_EQUAL_FP32(1.0, s2);
- ASSERT_EQUAL_FP32(1.0, s3);
- ASSERT_EQUAL_FP32(2.0, s4);
- ASSERT_EQUAL_FP32(-2.0, s5);
- ASSERT_EQUAL_FP32(-3.0, s6);
- ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
- ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
- ASSERT_EQUAL_FP32(0.0, s9);
- ASSERT_EQUAL_FP32(-0.0, s10);
- ASSERT_EQUAL_FP32(-1.0, s11);
- ASSERT_EQUAL_FP64(1.0, d12);
- ASSERT_EQUAL_FP64(1.0, d13);
- ASSERT_EQUAL_FP64(1.0, d14);
- ASSERT_EQUAL_FP64(1.0, d15);
- ASSERT_EQUAL_FP64(2.0, d16);
- ASSERT_EQUAL_FP64(-2.0, d17);
- ASSERT_EQUAL_FP64(-3.0, d18);
- ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
- ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
- ASSERT_EQUAL_FP64(0.0, d21);
- ASSERT_EQUAL_FP64(-0.0, d22);
- ASSERT_EQUAL_FP64(-1.0, d23);
+ CHECK_EQUAL_FP32(1.0, s0);
+ CHECK_EQUAL_FP32(1.0, s1);
+ CHECK_EQUAL_FP32(1.0, s2);
+ CHECK_EQUAL_FP32(1.0, s3);
+ CHECK_EQUAL_FP32(2.0, s4);
+ CHECK_EQUAL_FP32(-2.0, s5);
+ CHECK_EQUAL_FP32(-3.0, s6);
+ CHECK_EQUAL_FP32(kFP32PositiveInfinity, s7);
+ CHECK_EQUAL_FP32(kFP32NegativeInfinity, s8);
+ CHECK_EQUAL_FP32(0.0, s9);
+ CHECK_EQUAL_FP32(-0.0, s10);
+ CHECK_EQUAL_FP32(-1.0, s11);
+ CHECK_EQUAL_FP64(1.0, d12);
+ CHECK_EQUAL_FP64(1.0, d13);
+ CHECK_EQUAL_FP64(1.0, d14);
+ CHECK_EQUAL_FP64(1.0, d15);
+ CHECK_EQUAL_FP64(2.0, d16);
+ CHECK_EQUAL_FP64(-2.0, d17);
+ CHECK_EQUAL_FP64(-3.0, d18);
+ CHECK_EQUAL_FP64(kFP64PositiveInfinity, d19);
+ CHECK_EQUAL_FP64(kFP64NegativeInfinity, d20);
+ CHECK_EQUAL_FP64(0.0, d21);
+ CHECK_EQUAL_FP64(-0.0, d22);
+ CHECK_EQUAL_FP64(-1.0, d23);
TEARDOWN();
}
@@ -6323,30 +6525,30 @@ TEST(frintn) {
RUN();
- ASSERT_EQUAL_FP32(1.0, s0);
- ASSERT_EQUAL_FP32(1.0, s1);
- ASSERT_EQUAL_FP32(2.0, s2);
- ASSERT_EQUAL_FP32(2.0, s3);
- ASSERT_EQUAL_FP32(2.0, s4);
- ASSERT_EQUAL_FP32(-2.0, s5);
- ASSERT_EQUAL_FP32(-2.0, s6);
- ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
- ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
- ASSERT_EQUAL_FP32(0.0, s9);
- ASSERT_EQUAL_FP32(-0.0, s10);
- ASSERT_EQUAL_FP32(-0.0, s11);
- ASSERT_EQUAL_FP64(1.0, d12);
- ASSERT_EQUAL_FP64(1.0, d13);
- ASSERT_EQUAL_FP64(2.0, d14);
- ASSERT_EQUAL_FP64(2.0, d15);
- ASSERT_EQUAL_FP64(2.0, d16);
- ASSERT_EQUAL_FP64(-2.0, d17);
- ASSERT_EQUAL_FP64(-2.0, d18);
- ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
- ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
- ASSERT_EQUAL_FP64(0.0, d21);
- ASSERT_EQUAL_FP64(-0.0, d22);
- ASSERT_EQUAL_FP64(-0.0, d23);
+ CHECK_EQUAL_FP32(1.0, s0);
+ CHECK_EQUAL_FP32(1.0, s1);
+ CHECK_EQUAL_FP32(2.0, s2);
+ CHECK_EQUAL_FP32(2.0, s3);
+ CHECK_EQUAL_FP32(2.0, s4);
+ CHECK_EQUAL_FP32(-2.0, s5);
+ CHECK_EQUAL_FP32(-2.0, s6);
+ CHECK_EQUAL_FP32(kFP32PositiveInfinity, s7);
+ CHECK_EQUAL_FP32(kFP32NegativeInfinity, s8);
+ CHECK_EQUAL_FP32(0.0, s9);
+ CHECK_EQUAL_FP32(-0.0, s10);
+ CHECK_EQUAL_FP32(-0.0, s11);
+ CHECK_EQUAL_FP64(1.0, d12);
+ CHECK_EQUAL_FP64(1.0, d13);
+ CHECK_EQUAL_FP64(2.0, d14);
+ CHECK_EQUAL_FP64(2.0, d15);
+ CHECK_EQUAL_FP64(2.0, d16);
+ CHECK_EQUAL_FP64(-2.0, d17);
+ CHECK_EQUAL_FP64(-2.0, d18);
+ CHECK_EQUAL_FP64(kFP64PositiveInfinity, d19);
+ CHECK_EQUAL_FP64(kFP64NegativeInfinity, d20);
+ CHECK_EQUAL_FP64(0.0, d21);
+ CHECK_EQUAL_FP64(-0.0, d22);
+ CHECK_EQUAL_FP64(-0.0, d23);
TEARDOWN();
}
@@ -6408,28 +6610,28 @@ TEST(frintz) {
RUN();
- ASSERT_EQUAL_FP32(1.0, s0);
- ASSERT_EQUAL_FP32(1.0, s1);
- ASSERT_EQUAL_FP32(1.0, s2);
- ASSERT_EQUAL_FP32(1.0, s3);
- ASSERT_EQUAL_FP32(2.0, s4);
- ASSERT_EQUAL_FP32(-1.0, s5);
- ASSERT_EQUAL_FP32(-2.0, s6);
- ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
- ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
- ASSERT_EQUAL_FP32(0.0, s9);
- ASSERT_EQUAL_FP32(-0.0, s10);
- ASSERT_EQUAL_FP64(1.0, d11);
- ASSERT_EQUAL_FP64(1.0, d12);
- ASSERT_EQUAL_FP64(1.0, d13);
- ASSERT_EQUAL_FP64(1.0, d14);
- ASSERT_EQUAL_FP64(2.0, d15);
- ASSERT_EQUAL_FP64(-1.0, d16);
- ASSERT_EQUAL_FP64(-2.0, d17);
- ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18);
- ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19);
- ASSERT_EQUAL_FP64(0.0, d20);
- ASSERT_EQUAL_FP64(-0.0, d21);
+ CHECK_EQUAL_FP32(1.0, s0);
+ CHECK_EQUAL_FP32(1.0, s1);
+ CHECK_EQUAL_FP32(1.0, s2);
+ CHECK_EQUAL_FP32(1.0, s3);
+ CHECK_EQUAL_FP32(2.0, s4);
+ CHECK_EQUAL_FP32(-1.0, s5);
+ CHECK_EQUAL_FP32(-2.0, s6);
+ CHECK_EQUAL_FP32(kFP32PositiveInfinity, s7);
+ CHECK_EQUAL_FP32(kFP32NegativeInfinity, s8);
+ CHECK_EQUAL_FP32(0.0, s9);
+ CHECK_EQUAL_FP32(-0.0, s10);
+ CHECK_EQUAL_FP64(1.0, d11);
+ CHECK_EQUAL_FP64(1.0, d12);
+ CHECK_EQUAL_FP64(1.0, d13);
+ CHECK_EQUAL_FP64(1.0, d14);
+ CHECK_EQUAL_FP64(2.0, d15);
+ CHECK_EQUAL_FP64(-1.0, d16);
+ CHECK_EQUAL_FP64(-2.0, d17);
+ CHECK_EQUAL_FP64(kFP64PositiveInfinity, d18);
+ CHECK_EQUAL_FP64(kFP64NegativeInfinity, d19);
+ CHECK_EQUAL_FP64(0.0, d20);
+ CHECK_EQUAL_FP64(-0.0, d21);
TEARDOWN();
}
@@ -6475,19 +6677,19 @@ TEST(fcvt_ds) {
RUN();
- ASSERT_EQUAL_FP64(1.0f, d0);
- ASSERT_EQUAL_FP64(1.1f, d1);
- ASSERT_EQUAL_FP64(1.5f, d2);
- ASSERT_EQUAL_FP64(1.9f, d3);
- ASSERT_EQUAL_FP64(2.5f, d4);
- ASSERT_EQUAL_FP64(-1.5f, d5);
- ASSERT_EQUAL_FP64(-2.5f, d6);
- ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
- ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8);
- ASSERT_EQUAL_FP64(0.0f, d9);
- ASSERT_EQUAL_FP64(-0.0f, d10);
- ASSERT_EQUAL_FP64(FLT_MAX, d11);
- ASSERT_EQUAL_FP64(FLT_MIN, d12);
+ CHECK_EQUAL_FP64(1.0f, d0);
+ CHECK_EQUAL_FP64(1.1f, d1);
+ CHECK_EQUAL_FP64(1.5f, d2);
+ CHECK_EQUAL_FP64(1.9f, d3);
+ CHECK_EQUAL_FP64(2.5f, d4);
+ CHECK_EQUAL_FP64(-1.5f, d5);
+ CHECK_EQUAL_FP64(-2.5f, d6);
+ CHECK_EQUAL_FP64(kFP64PositiveInfinity, d7);
+ CHECK_EQUAL_FP64(kFP64NegativeInfinity, d8);
+ CHECK_EQUAL_FP64(0.0f, d9);
+ CHECK_EQUAL_FP64(-0.0f, d10);
+ CHECK_EQUAL_FP64(FLT_MAX, d11);
+ CHECK_EQUAL_FP64(FLT_MIN, d12);
// Check that the NaN payload is preserved according to ARM64 conversion
// rules:
@@ -6495,8 +6697,8 @@ TEST(fcvt_ds) {
// - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
// - The remaining mantissa bits are copied until they run out.
// - The low-order bits that haven't already been assigned are set to 0.
- ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d13);
- ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d14);
+ CHECK_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d13);
+ CHECK_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d14);
TEARDOWN();
}
@@ -6596,8 +6798,8 @@ TEST(fcvt_sd) {
float expected = test[i].expected;
// We only expect positive input.
- ASSERT(std::signbit(in) == 0);
- ASSERT(std::signbit(expected) == 0);
+ DCHECK(std::signbit(in) == 0);
+ DCHECK(std::signbit(expected) == 0);
SETUP();
START();
@@ -6610,8 +6812,8 @@ TEST(fcvt_sd) {
END();
RUN();
- ASSERT_EQUAL_FP32(expected, s20);
- ASSERT_EQUAL_FP32(-expected, s21);
+ CHECK_EQUAL_FP32(expected, s20);
+ CHECK_EQUAL_FP32(-expected, s21);
TEARDOWN();
}
}
@@ -6687,36 +6889,36 @@ TEST(fcvtas) {
RUN();
- ASSERT_EQUAL_64(1, x0);
- ASSERT_EQUAL_64(1, x1);
- ASSERT_EQUAL_64(3, x2);
- ASSERT_EQUAL_64(0xfffffffd, x3);
- ASSERT_EQUAL_64(0x7fffffff, x4);
- ASSERT_EQUAL_64(0x80000000, x5);
- ASSERT_EQUAL_64(0x7fffff80, x6);
- ASSERT_EQUAL_64(0x80000080, x7);
- ASSERT_EQUAL_64(1, x8);
- ASSERT_EQUAL_64(1, x9);
- ASSERT_EQUAL_64(3, x10);
- ASSERT_EQUAL_64(0xfffffffd, x11);
- ASSERT_EQUAL_64(0x7fffffff, x12);
- ASSERT_EQUAL_64(0x80000000, x13);
- ASSERT_EQUAL_64(0x7ffffffe, x14);
- ASSERT_EQUAL_64(0x80000001, x15);
- ASSERT_EQUAL_64(1, x17);
- ASSERT_EQUAL_64(3, x18);
- ASSERT_EQUAL_64(0xfffffffffffffffdUL, x19);
- ASSERT_EQUAL_64(0x7fffffffffffffffUL, x20);
- ASSERT_EQUAL_64(0x8000000000000000UL, x21);
- ASSERT_EQUAL_64(0x7fffff8000000000UL, x22);
- ASSERT_EQUAL_64(0x8000008000000000UL, x23);
- ASSERT_EQUAL_64(1, x24);
- ASSERT_EQUAL_64(3, x25);
- ASSERT_EQUAL_64(0xfffffffffffffffdUL, x26);
- ASSERT_EQUAL_64(0x7fffffffffffffffUL, x27);
- ASSERT_EQUAL_64(0x8000000000000000UL, x28);
- ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29);
- ASSERT_EQUAL_64(0x8000000000000400UL, x30);
+ CHECK_EQUAL_64(1, x0);
+ CHECK_EQUAL_64(1, x1);
+ CHECK_EQUAL_64(3, x2);
+ CHECK_EQUAL_64(0xfffffffd, x3);
+ CHECK_EQUAL_64(0x7fffffff, x4);
+ CHECK_EQUAL_64(0x80000000, x5);
+ CHECK_EQUAL_64(0x7fffff80, x6);
+ CHECK_EQUAL_64(0x80000080, x7);
+ CHECK_EQUAL_64(1, x8);
+ CHECK_EQUAL_64(1, x9);
+ CHECK_EQUAL_64(3, x10);
+ CHECK_EQUAL_64(0xfffffffd, x11);
+ CHECK_EQUAL_64(0x7fffffff, x12);
+ CHECK_EQUAL_64(0x80000000, x13);
+ CHECK_EQUAL_64(0x7ffffffe, x14);
+ CHECK_EQUAL_64(0x80000001, x15);
+ CHECK_EQUAL_64(1, x17);
+ CHECK_EQUAL_64(3, x18);
+ CHECK_EQUAL_64(0xfffffffffffffffdUL, x19);
+ CHECK_EQUAL_64(0x7fffffffffffffffUL, x20);
+ CHECK_EQUAL_64(0x8000000000000000UL, x21);
+ CHECK_EQUAL_64(0x7fffff8000000000UL, x22);
+ CHECK_EQUAL_64(0x8000008000000000UL, x23);
+ CHECK_EQUAL_64(1, x24);
+ CHECK_EQUAL_64(3, x25);
+ CHECK_EQUAL_64(0xfffffffffffffffdUL, x26);
+ CHECK_EQUAL_64(0x7fffffffffffffffUL, x27);
+ CHECK_EQUAL_64(0x8000000000000000UL, x28);
+ CHECK_EQUAL_64(0x7ffffffffffffc00UL, x29);
+ CHECK_EQUAL_64(0x8000000000000400UL, x30);
TEARDOWN();
}
@@ -6789,34 +6991,34 @@ TEST(fcvtau) {
RUN();
- ASSERT_EQUAL_64(1, x0);
- ASSERT_EQUAL_64(1, x1);
- ASSERT_EQUAL_64(3, x2);
- ASSERT_EQUAL_64(0, x3);
- ASSERT_EQUAL_64(0xffffffff, x4);
- ASSERT_EQUAL_64(0, x5);
- ASSERT_EQUAL_64(0xffffff00, x6);
- ASSERT_EQUAL_64(1, x8);
- ASSERT_EQUAL_64(1, x9);
- ASSERT_EQUAL_64(3, x10);
- ASSERT_EQUAL_64(0, x11);
- ASSERT_EQUAL_64(0xffffffff, x12);
- ASSERT_EQUAL_64(0, x13);
- ASSERT_EQUAL_64(0xfffffffe, x14);
- ASSERT_EQUAL_64(1, x16);
- ASSERT_EQUAL_64(1, x17);
- ASSERT_EQUAL_64(3, x18);
- ASSERT_EQUAL_64(0, x19);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x20);
- ASSERT_EQUAL_64(0, x21);
- ASSERT_EQUAL_64(0xffffff0000000000UL, x22);
- ASSERT_EQUAL_64(1, x24);
- ASSERT_EQUAL_64(3, x25);
- ASSERT_EQUAL_64(0, x26);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x27);
- ASSERT_EQUAL_64(0, x28);
- ASSERT_EQUAL_64(0xfffffffffffff800UL, x29);
- ASSERT_EQUAL_64(0xffffffff, x30);
+ CHECK_EQUAL_64(1, x0);
+ CHECK_EQUAL_64(1, x1);
+ CHECK_EQUAL_64(3, x2);
+ CHECK_EQUAL_64(0, x3);
+ CHECK_EQUAL_64(0xffffffff, x4);
+ CHECK_EQUAL_64(0, x5);
+ CHECK_EQUAL_64(0xffffff00, x6);
+ CHECK_EQUAL_64(1, x8);
+ CHECK_EQUAL_64(1, x9);
+ CHECK_EQUAL_64(3, x10);
+ CHECK_EQUAL_64(0, x11);
+ CHECK_EQUAL_64(0xffffffff, x12);
+ CHECK_EQUAL_64(0, x13);
+ CHECK_EQUAL_64(0xfffffffe, x14);
+ CHECK_EQUAL_64(1, x16);
+ CHECK_EQUAL_64(1, x17);
+ CHECK_EQUAL_64(3, x18);
+ CHECK_EQUAL_64(0, x19);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x20);
+ CHECK_EQUAL_64(0, x21);
+ CHECK_EQUAL_64(0xffffff0000000000UL, x22);
+ CHECK_EQUAL_64(1, x24);
+ CHECK_EQUAL_64(3, x25);
+ CHECK_EQUAL_64(0, x26);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x27);
+ CHECK_EQUAL_64(0, x28);
+ CHECK_EQUAL_64(0xfffffffffffff800UL, x29);
+ CHECK_EQUAL_64(0xffffffff, x30);
TEARDOWN();
}
@@ -6892,36 +7094,36 @@ TEST(fcvtms) {
RUN();
- ASSERT_EQUAL_64(1, x0);
- ASSERT_EQUAL_64(1, x1);
- ASSERT_EQUAL_64(1, x2);
- ASSERT_EQUAL_64(0xfffffffe, x3);
- ASSERT_EQUAL_64(0x7fffffff, x4);
- ASSERT_EQUAL_64(0x80000000, x5);
- ASSERT_EQUAL_64(0x7fffff80, x6);
- ASSERT_EQUAL_64(0x80000080, x7);
- ASSERT_EQUAL_64(1, x8);
- ASSERT_EQUAL_64(1, x9);
- ASSERT_EQUAL_64(1, x10);
- ASSERT_EQUAL_64(0xfffffffe, x11);
- ASSERT_EQUAL_64(0x7fffffff, x12);
- ASSERT_EQUAL_64(0x80000000, x13);
- ASSERT_EQUAL_64(0x7ffffffe, x14);
- ASSERT_EQUAL_64(0x80000001, x15);
- ASSERT_EQUAL_64(1, x17);
- ASSERT_EQUAL_64(1, x18);
- ASSERT_EQUAL_64(0xfffffffffffffffeUL, x19);
- ASSERT_EQUAL_64(0x7fffffffffffffffUL, x20);
- ASSERT_EQUAL_64(0x8000000000000000UL, x21);
- ASSERT_EQUAL_64(0x7fffff8000000000UL, x22);
- ASSERT_EQUAL_64(0x8000008000000000UL, x23);
- ASSERT_EQUAL_64(1, x24);
- ASSERT_EQUAL_64(1, x25);
- ASSERT_EQUAL_64(0xfffffffffffffffeUL, x26);
- ASSERT_EQUAL_64(0x7fffffffffffffffUL, x27);
- ASSERT_EQUAL_64(0x8000000000000000UL, x28);
- ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29);
- ASSERT_EQUAL_64(0x8000000000000400UL, x30);
+ CHECK_EQUAL_64(1, x0);
+ CHECK_EQUAL_64(1, x1);
+ CHECK_EQUAL_64(1, x2);
+ CHECK_EQUAL_64(0xfffffffe, x3);
+ CHECK_EQUAL_64(0x7fffffff, x4);
+ CHECK_EQUAL_64(0x80000000, x5);
+ CHECK_EQUAL_64(0x7fffff80, x6);
+ CHECK_EQUAL_64(0x80000080, x7);
+ CHECK_EQUAL_64(1, x8);
+ CHECK_EQUAL_64(1, x9);
+ CHECK_EQUAL_64(1, x10);
+ CHECK_EQUAL_64(0xfffffffe, x11);
+ CHECK_EQUAL_64(0x7fffffff, x12);
+ CHECK_EQUAL_64(0x80000000, x13);
+ CHECK_EQUAL_64(0x7ffffffe, x14);
+ CHECK_EQUAL_64(0x80000001, x15);
+ CHECK_EQUAL_64(1, x17);
+ CHECK_EQUAL_64(1, x18);
+ CHECK_EQUAL_64(0xfffffffffffffffeUL, x19);
+ CHECK_EQUAL_64(0x7fffffffffffffffUL, x20);
+ CHECK_EQUAL_64(0x8000000000000000UL, x21);
+ CHECK_EQUAL_64(0x7fffff8000000000UL, x22);
+ CHECK_EQUAL_64(0x8000008000000000UL, x23);
+ CHECK_EQUAL_64(1, x24);
+ CHECK_EQUAL_64(1, x25);
+ CHECK_EQUAL_64(0xfffffffffffffffeUL, x26);
+ CHECK_EQUAL_64(0x7fffffffffffffffUL, x27);
+ CHECK_EQUAL_64(0x8000000000000000UL, x28);
+ CHECK_EQUAL_64(0x7ffffffffffffc00UL, x29);
+ CHECK_EQUAL_64(0x8000000000000400UL, x30);
TEARDOWN();
}
@@ -6996,35 +7198,35 @@ TEST(fcvtmu) {
RUN();
- ASSERT_EQUAL_64(1, x0);
- ASSERT_EQUAL_64(1, x1);
- ASSERT_EQUAL_64(1, x2);
- ASSERT_EQUAL_64(0, x3);
- ASSERT_EQUAL_64(0xffffffff, x4);
- ASSERT_EQUAL_64(0, x5);
- ASSERT_EQUAL_64(0x7fffff80, x6);
- ASSERT_EQUAL_64(0, x7);
- ASSERT_EQUAL_64(1, x8);
- ASSERT_EQUAL_64(1, x9);
- ASSERT_EQUAL_64(1, x10);
- ASSERT_EQUAL_64(0, x11);
- ASSERT_EQUAL_64(0xffffffff, x12);
- ASSERT_EQUAL_64(0, x13);
- ASSERT_EQUAL_64(0x7ffffffe, x14);
- ASSERT_EQUAL_64(1, x17);
- ASSERT_EQUAL_64(1, x18);
- ASSERT_EQUAL_64(0x0UL, x19);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x20);
- ASSERT_EQUAL_64(0x0UL, x21);
- ASSERT_EQUAL_64(0x7fffff8000000000UL, x22);
- ASSERT_EQUAL_64(0x0UL, x23);
- ASSERT_EQUAL_64(1, x24);
- ASSERT_EQUAL_64(1, x25);
- ASSERT_EQUAL_64(0x0UL, x26);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x27);
- ASSERT_EQUAL_64(0x0UL, x28);
- ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29);
- ASSERT_EQUAL_64(0x0UL, x30);
+ CHECK_EQUAL_64(1, x0);
+ CHECK_EQUAL_64(1, x1);
+ CHECK_EQUAL_64(1, x2);
+ CHECK_EQUAL_64(0, x3);
+ CHECK_EQUAL_64(0xffffffff, x4);
+ CHECK_EQUAL_64(0, x5);
+ CHECK_EQUAL_64(0x7fffff80, x6);
+ CHECK_EQUAL_64(0, x7);
+ CHECK_EQUAL_64(1, x8);
+ CHECK_EQUAL_64(1, x9);
+ CHECK_EQUAL_64(1, x10);
+ CHECK_EQUAL_64(0, x11);
+ CHECK_EQUAL_64(0xffffffff, x12);
+ CHECK_EQUAL_64(0, x13);
+ CHECK_EQUAL_64(0x7ffffffe, x14);
+ CHECK_EQUAL_64(1, x17);
+ CHECK_EQUAL_64(1, x18);
+ CHECK_EQUAL_64(0x0UL, x19);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x20);
+ CHECK_EQUAL_64(0x0UL, x21);
+ CHECK_EQUAL_64(0x7fffff8000000000UL, x22);
+ CHECK_EQUAL_64(0x0UL, x23);
+ CHECK_EQUAL_64(1, x24);
+ CHECK_EQUAL_64(1, x25);
+ CHECK_EQUAL_64(0x0UL, x26);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x27);
+ CHECK_EQUAL_64(0x0UL, x28);
+ CHECK_EQUAL_64(0x7ffffffffffffc00UL, x29);
+ CHECK_EQUAL_64(0x0UL, x30);
TEARDOWN();
}
@@ -7100,36 +7302,36 @@ TEST(fcvtns) {
RUN();
- ASSERT_EQUAL_64(1, x0);
- ASSERT_EQUAL_64(1, x1);
- ASSERT_EQUAL_64(2, x2);
- ASSERT_EQUAL_64(0xfffffffe, x3);
- ASSERT_EQUAL_64(0x7fffffff, x4);
- ASSERT_EQUAL_64(0x80000000, x5);
- ASSERT_EQUAL_64(0x7fffff80, x6);
- ASSERT_EQUAL_64(0x80000080, x7);
- ASSERT_EQUAL_64(1, x8);
- ASSERT_EQUAL_64(1, x9);
- ASSERT_EQUAL_64(2, x10);
- ASSERT_EQUAL_64(0xfffffffe, x11);
- ASSERT_EQUAL_64(0x7fffffff, x12);
- ASSERT_EQUAL_64(0x80000000, x13);
- ASSERT_EQUAL_64(0x7ffffffe, x14);
- ASSERT_EQUAL_64(0x80000001, x15);
- ASSERT_EQUAL_64(1, x17);
- ASSERT_EQUAL_64(2, x18);
- ASSERT_EQUAL_64(0xfffffffffffffffeUL, x19);
- ASSERT_EQUAL_64(0x7fffffffffffffffUL, x20);
- ASSERT_EQUAL_64(0x8000000000000000UL, x21);
- ASSERT_EQUAL_64(0x7fffff8000000000UL, x22);
- ASSERT_EQUAL_64(0x8000008000000000UL, x23);
- ASSERT_EQUAL_64(1, x24);
- ASSERT_EQUAL_64(2, x25);
- ASSERT_EQUAL_64(0xfffffffffffffffeUL, x26);
- ASSERT_EQUAL_64(0x7fffffffffffffffUL, x27);
-// ASSERT_EQUAL_64(0x8000000000000000UL, x28);
- ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29);
- ASSERT_EQUAL_64(0x8000000000000400UL, x30);
+ CHECK_EQUAL_64(1, x0);
+ CHECK_EQUAL_64(1, x1);
+ CHECK_EQUAL_64(2, x2);
+ CHECK_EQUAL_64(0xfffffffe, x3);
+ CHECK_EQUAL_64(0x7fffffff, x4);
+ CHECK_EQUAL_64(0x80000000, x5);
+ CHECK_EQUAL_64(0x7fffff80, x6);
+ CHECK_EQUAL_64(0x80000080, x7);
+ CHECK_EQUAL_64(1, x8);
+ CHECK_EQUAL_64(1, x9);
+ CHECK_EQUAL_64(2, x10);
+ CHECK_EQUAL_64(0xfffffffe, x11);
+ CHECK_EQUAL_64(0x7fffffff, x12);
+ CHECK_EQUAL_64(0x80000000, x13);
+ CHECK_EQUAL_64(0x7ffffffe, x14);
+ CHECK_EQUAL_64(0x80000001, x15);
+ CHECK_EQUAL_64(1, x17);
+ CHECK_EQUAL_64(2, x18);
+ CHECK_EQUAL_64(0xfffffffffffffffeUL, x19);
+ CHECK_EQUAL_64(0x7fffffffffffffffUL, x20);
+ CHECK_EQUAL_64(0x8000000000000000UL, x21);
+ CHECK_EQUAL_64(0x7fffff8000000000UL, x22);
+ CHECK_EQUAL_64(0x8000008000000000UL, x23);
+ CHECK_EQUAL_64(1, x24);
+ CHECK_EQUAL_64(2, x25);
+ CHECK_EQUAL_64(0xfffffffffffffffeUL, x26);
+ CHECK_EQUAL_64(0x7fffffffffffffffUL, x27);
+// CHECK_EQUAL_64(0x8000000000000000UL, x28);
+ CHECK_EQUAL_64(0x7ffffffffffffc00UL, x29);
+ CHECK_EQUAL_64(0x8000000000000400UL, x30);
TEARDOWN();
}
@@ -7202,34 +7404,34 @@ TEST(fcvtnu) {
RUN();
- ASSERT_EQUAL_64(1, x0);
- ASSERT_EQUAL_64(1, x1);
- ASSERT_EQUAL_64(2, x2);
- ASSERT_EQUAL_64(0, x3);
- ASSERT_EQUAL_64(0xffffffff, x4);
- ASSERT_EQUAL_64(0, x5);
- ASSERT_EQUAL_64(0xffffff00, x6);
- ASSERT_EQUAL_64(1, x8);
- ASSERT_EQUAL_64(1, x9);
- ASSERT_EQUAL_64(2, x10);
- ASSERT_EQUAL_64(0, x11);
- ASSERT_EQUAL_64(0xffffffff, x12);
- ASSERT_EQUAL_64(0, x13);
- ASSERT_EQUAL_64(0xfffffffe, x14);
- ASSERT_EQUAL_64(1, x16);
- ASSERT_EQUAL_64(1, x17);
- ASSERT_EQUAL_64(2, x18);
- ASSERT_EQUAL_64(0, x19);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x20);
- ASSERT_EQUAL_64(0, x21);
- ASSERT_EQUAL_64(0xffffff0000000000UL, x22);
- ASSERT_EQUAL_64(1, x24);
- ASSERT_EQUAL_64(2, x25);
- ASSERT_EQUAL_64(0, x26);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x27);
-// ASSERT_EQUAL_64(0, x28);
- ASSERT_EQUAL_64(0xfffffffffffff800UL, x29);
- ASSERT_EQUAL_64(0xffffffff, x30);
+ CHECK_EQUAL_64(1, x0);
+ CHECK_EQUAL_64(1, x1);
+ CHECK_EQUAL_64(2, x2);
+ CHECK_EQUAL_64(0, x3);
+ CHECK_EQUAL_64(0xffffffff, x4);
+ CHECK_EQUAL_64(0, x5);
+ CHECK_EQUAL_64(0xffffff00, x6);
+ CHECK_EQUAL_64(1, x8);
+ CHECK_EQUAL_64(1, x9);
+ CHECK_EQUAL_64(2, x10);
+ CHECK_EQUAL_64(0, x11);
+ CHECK_EQUAL_64(0xffffffff, x12);
+ CHECK_EQUAL_64(0, x13);
+ CHECK_EQUAL_64(0xfffffffe, x14);
+ CHECK_EQUAL_64(1, x16);
+ CHECK_EQUAL_64(1, x17);
+ CHECK_EQUAL_64(2, x18);
+ CHECK_EQUAL_64(0, x19);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x20);
+ CHECK_EQUAL_64(0, x21);
+ CHECK_EQUAL_64(0xffffff0000000000UL, x22);
+ CHECK_EQUAL_64(1, x24);
+ CHECK_EQUAL_64(2, x25);
+ CHECK_EQUAL_64(0, x26);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x27);
+// CHECK_EQUAL_64(0, x28);
+ CHECK_EQUAL_64(0xfffffffffffff800UL, x29);
+ CHECK_EQUAL_64(0xffffffff, x30);
TEARDOWN();
}
@@ -7305,36 +7507,36 @@ TEST(fcvtzs) {
RUN();
- ASSERT_EQUAL_64(1, x0);
- ASSERT_EQUAL_64(1, x1);
- ASSERT_EQUAL_64(1, x2);
- ASSERT_EQUAL_64(0xffffffff, x3);
- ASSERT_EQUAL_64(0x7fffffff, x4);
- ASSERT_EQUAL_64(0x80000000, x5);
- ASSERT_EQUAL_64(0x7fffff80, x6);
- ASSERT_EQUAL_64(0x80000080, x7);
- ASSERT_EQUAL_64(1, x8);
- ASSERT_EQUAL_64(1, x9);
- ASSERT_EQUAL_64(1, x10);
- ASSERT_EQUAL_64(0xffffffff, x11);
- ASSERT_EQUAL_64(0x7fffffff, x12);
- ASSERT_EQUAL_64(0x80000000, x13);
- ASSERT_EQUAL_64(0x7ffffffe, x14);
- ASSERT_EQUAL_64(0x80000001, x15);
- ASSERT_EQUAL_64(1, x17);
- ASSERT_EQUAL_64(1, x18);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x19);
- ASSERT_EQUAL_64(0x7fffffffffffffffUL, x20);
- ASSERT_EQUAL_64(0x8000000000000000UL, x21);
- ASSERT_EQUAL_64(0x7fffff8000000000UL, x22);
- ASSERT_EQUAL_64(0x8000008000000000UL, x23);
- ASSERT_EQUAL_64(1, x24);
- ASSERT_EQUAL_64(1, x25);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x26);
- ASSERT_EQUAL_64(0x7fffffffffffffffUL, x27);
- ASSERT_EQUAL_64(0x8000000000000000UL, x28);
- ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29);
- ASSERT_EQUAL_64(0x8000000000000400UL, x30);
+ CHECK_EQUAL_64(1, x0);
+ CHECK_EQUAL_64(1, x1);
+ CHECK_EQUAL_64(1, x2);
+ CHECK_EQUAL_64(0xffffffff, x3);
+ CHECK_EQUAL_64(0x7fffffff, x4);
+ CHECK_EQUAL_64(0x80000000, x5);
+ CHECK_EQUAL_64(0x7fffff80, x6);
+ CHECK_EQUAL_64(0x80000080, x7);
+ CHECK_EQUAL_64(1, x8);
+ CHECK_EQUAL_64(1, x9);
+ CHECK_EQUAL_64(1, x10);
+ CHECK_EQUAL_64(0xffffffff, x11);
+ CHECK_EQUAL_64(0x7fffffff, x12);
+ CHECK_EQUAL_64(0x80000000, x13);
+ CHECK_EQUAL_64(0x7ffffffe, x14);
+ CHECK_EQUAL_64(0x80000001, x15);
+ CHECK_EQUAL_64(1, x17);
+ CHECK_EQUAL_64(1, x18);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x19);
+ CHECK_EQUAL_64(0x7fffffffffffffffUL, x20);
+ CHECK_EQUAL_64(0x8000000000000000UL, x21);
+ CHECK_EQUAL_64(0x7fffff8000000000UL, x22);
+ CHECK_EQUAL_64(0x8000008000000000UL, x23);
+ CHECK_EQUAL_64(1, x24);
+ CHECK_EQUAL_64(1, x25);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x26);
+ CHECK_EQUAL_64(0x7fffffffffffffffUL, x27);
+ CHECK_EQUAL_64(0x8000000000000000UL, x28);
+ CHECK_EQUAL_64(0x7ffffffffffffc00UL, x29);
+ CHECK_EQUAL_64(0x8000000000000400UL, x30);
TEARDOWN();
}
@@ -7409,35 +7611,35 @@ TEST(fcvtzu) {
RUN();
- ASSERT_EQUAL_64(1, x0);
- ASSERT_EQUAL_64(1, x1);
- ASSERT_EQUAL_64(1, x2);
- ASSERT_EQUAL_64(0, x3);
- ASSERT_EQUAL_64(0xffffffff, x4);
- ASSERT_EQUAL_64(0, x5);
- ASSERT_EQUAL_64(0x7fffff80, x6);
- ASSERT_EQUAL_64(0, x7);
- ASSERT_EQUAL_64(1, x8);
- ASSERT_EQUAL_64(1, x9);
- ASSERT_EQUAL_64(1, x10);
- ASSERT_EQUAL_64(0, x11);
- ASSERT_EQUAL_64(0xffffffff, x12);
- ASSERT_EQUAL_64(0, x13);
- ASSERT_EQUAL_64(0x7ffffffe, x14);
- ASSERT_EQUAL_64(1, x17);
- ASSERT_EQUAL_64(1, x18);
- ASSERT_EQUAL_64(0x0UL, x19);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x20);
- ASSERT_EQUAL_64(0x0UL, x21);
- ASSERT_EQUAL_64(0x7fffff8000000000UL, x22);
- ASSERT_EQUAL_64(0x0UL, x23);
- ASSERT_EQUAL_64(1, x24);
- ASSERT_EQUAL_64(1, x25);
- ASSERT_EQUAL_64(0x0UL, x26);
- ASSERT_EQUAL_64(0xffffffffffffffffUL, x27);
- ASSERT_EQUAL_64(0x0UL, x28);
- ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29);
- ASSERT_EQUAL_64(0x0UL, x30);
+ CHECK_EQUAL_64(1, x0);
+ CHECK_EQUAL_64(1, x1);
+ CHECK_EQUAL_64(1, x2);
+ CHECK_EQUAL_64(0, x3);
+ CHECK_EQUAL_64(0xffffffff, x4);
+ CHECK_EQUAL_64(0, x5);
+ CHECK_EQUAL_64(0x7fffff80, x6);
+ CHECK_EQUAL_64(0, x7);
+ CHECK_EQUAL_64(1, x8);
+ CHECK_EQUAL_64(1, x9);
+ CHECK_EQUAL_64(1, x10);
+ CHECK_EQUAL_64(0, x11);
+ CHECK_EQUAL_64(0xffffffff, x12);
+ CHECK_EQUAL_64(0, x13);
+ CHECK_EQUAL_64(0x7ffffffe, x14);
+ CHECK_EQUAL_64(1, x17);
+ CHECK_EQUAL_64(1, x18);
+ CHECK_EQUAL_64(0x0UL, x19);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x20);
+ CHECK_EQUAL_64(0x0UL, x21);
+ CHECK_EQUAL_64(0x7fffff8000000000UL, x22);
+ CHECK_EQUAL_64(0x0UL, x23);
+ CHECK_EQUAL_64(1, x24);
+ CHECK_EQUAL_64(1, x25);
+ CHECK_EQUAL_64(0x0UL, x26);
+ CHECK_EQUAL_64(0xffffffffffffffffUL, x27);
+ CHECK_EQUAL_64(0x0UL, x28);
+ CHECK_EQUAL_64(0x7ffffffffffffc00UL, x29);
+ CHECK_EQUAL_64(0x0UL, x30);
TEARDOWN();
}
@@ -7525,16 +7727,16 @@ static void TestUScvtfHelper(uint64_t in,
for (int fbits = 0; fbits <= 32; fbits++) {
double expected_scvtf = expected_scvtf_base / pow(2.0, fbits);
double expected_ucvtf = expected_ucvtf_base / pow(2.0, fbits);
- ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
- ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
- if (cvtf_s32) ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_w[fbits]);
- if (cvtf_u32) ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_w[fbits]);
+ CHECK_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
+ CHECK_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
+ if (cvtf_s32) CHECK_EQUAL_FP64(expected_scvtf, results_scvtf_w[fbits]);
+ if (cvtf_u32) CHECK_EQUAL_FP64(expected_ucvtf, results_ucvtf_w[fbits]);
}
for (int fbits = 33; fbits <= 64; fbits++) {
double expected_scvtf = expected_scvtf_base / pow(2.0, fbits);
double expected_ucvtf = expected_ucvtf_base / pow(2.0, fbits);
- ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
- ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
+ CHECK_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
+ CHECK_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
}
TEARDOWN();
@@ -7680,18 +7882,18 @@ static void TestUScvtf32Helper(uint64_t in,
for (int fbits = 0; fbits <= 32; fbits++) {
float expected_scvtf = expected_scvtf_base / powf(2, fbits);
float expected_ucvtf = expected_ucvtf_base / powf(2, fbits);
- ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
- ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
- if (cvtf_s32) ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_w[fbits]);
- if (cvtf_u32) ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_w[fbits]);
+ CHECK_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
+ CHECK_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
+ if (cvtf_s32) CHECK_EQUAL_FP32(expected_scvtf, results_scvtf_w[fbits]);
+ if (cvtf_u32) CHECK_EQUAL_FP32(expected_ucvtf, results_ucvtf_w[fbits]);
break;
}
for (int fbits = 33; fbits <= 64; fbits++) {
break;
float expected_scvtf = expected_scvtf_base / powf(2, fbits);
float expected_ucvtf = expected_ucvtf_base / powf(2, fbits);
- ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
- ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
+ CHECK_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
+ CHECK_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
}
TEARDOWN();
@@ -7795,13 +7997,13 @@ TEST(system_mrs) {
RUN();
// NZCV
- ASSERT_EQUAL_32(ZCFlag, w3);
- ASSERT_EQUAL_32(NFlag, w4);
- ASSERT_EQUAL_32(ZCVFlag, w5);
+ CHECK_EQUAL_32(ZCFlag, w3);
+ CHECK_EQUAL_32(NFlag, w4);
+ CHECK_EQUAL_32(ZCVFlag, w5);
// FPCR
// The default FPCR on Linux-based platforms is 0.
- ASSERT_EQUAL_32(0, w6);
+ CHECK_EQUAL_32(0, w6);
TEARDOWN();
}
@@ -7869,11 +8071,11 @@ TEST(system_msr) {
RUN();
// We should have incremented x7 (from 0) exactly 8 times.
- ASSERT_EQUAL_64(8, x7);
+ CHECK_EQUAL_64(8, x7);
- ASSERT_EQUAL_64(fpcr_core, x8);
- ASSERT_EQUAL_64(fpcr_core, x9);
- ASSERT_EQUAL_64(0, x10);
+ CHECK_EQUAL_64(fpcr_core, x8);
+ CHECK_EQUAL_64(fpcr_core, x9);
+ CHECK_EQUAL_64(0, x10);
TEARDOWN();
}
@@ -7891,8 +8093,8 @@ TEST(system_nop) {
RUN();
- ASSERT_EQUAL_REGISTERS(before);
- ASSERT_EQUAL_NZCV(before.flags_nzcv());
+ CHECK_EQUAL_REGISTERS(before);
+ CHECK_EQUAL_NZCV(before.flags_nzcv());
TEARDOWN();
}
@@ -7958,8 +8160,8 @@ TEST(zero_dest) {
RUN();
- ASSERT_EQUAL_REGISTERS(before);
- ASSERT_EQUAL_NZCV(before.flags_nzcv());
+ CHECK_EQUAL_REGISTERS(before);
+ CHECK_EQUAL_NZCV(before.flags_nzcv());
TEARDOWN();
}
@@ -8023,7 +8225,7 @@ TEST(zero_dest_setflags) {
RUN();
- ASSERT_EQUAL_REGISTERS(before);
+ CHECK_EQUAL_REGISTERS(before);
TEARDOWN();
}
@@ -8136,15 +8338,15 @@ TEST(peek_poke_simple) {
END();
RUN();
- ASSERT_EQUAL_64(literal_base * 1, x0);
- ASSERT_EQUAL_64(literal_base * 2, x1);
- ASSERT_EQUAL_64(literal_base * 3, x2);
- ASSERT_EQUAL_64(literal_base * 4, x3);
+ CHECK_EQUAL_64(literal_base * 1, x0);
+ CHECK_EQUAL_64(literal_base * 2, x1);
+ CHECK_EQUAL_64(literal_base * 3, x2);
+ CHECK_EQUAL_64(literal_base * 4, x3);
- ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
- ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
- ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
- ASSERT_EQUAL_64((literal_base * 4) & 0xffffffff, x13);
+ CHECK_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
+ CHECK_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
+ CHECK_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
+ CHECK_EQUAL_64((literal_base * 4) & 0xffffffff, x13);
TEARDOWN();
}
@@ -8214,17 +8416,17 @@ TEST(peek_poke_unaligned) {
END();
RUN();
- ASSERT_EQUAL_64(literal_base * 1, x0);
- ASSERT_EQUAL_64(literal_base * 2, x1);
- ASSERT_EQUAL_64(literal_base * 3, x2);
- ASSERT_EQUAL_64(literal_base * 4, x3);
- ASSERT_EQUAL_64(literal_base * 5, x4);
- ASSERT_EQUAL_64(literal_base * 6, x5);
- ASSERT_EQUAL_64(literal_base * 7, x6);
+ CHECK_EQUAL_64(literal_base * 1, x0);
+ CHECK_EQUAL_64(literal_base * 2, x1);
+ CHECK_EQUAL_64(literal_base * 3, x2);
+ CHECK_EQUAL_64(literal_base * 4, x3);
+ CHECK_EQUAL_64(literal_base * 5, x4);
+ CHECK_EQUAL_64(literal_base * 6, x5);
+ CHECK_EQUAL_64(literal_base * 7, x6);
- ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
- ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
- ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
+ CHECK_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
+ CHECK_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
+ CHECK_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
TEARDOWN();
}
@@ -8271,10 +8473,10 @@ TEST(peek_poke_endianness) {
uint64_t x5_expected = ((x1_expected << 16) & 0xffff0000) |
((x1_expected >> 16) & 0x0000ffff);
- ASSERT_EQUAL_64(x0_expected, x0);
- ASSERT_EQUAL_64(x1_expected, x1);
- ASSERT_EQUAL_64(x4_expected, x4);
- ASSERT_EQUAL_64(x5_expected, x5);
+ CHECK_EQUAL_64(x0_expected, x0);
+ CHECK_EQUAL_64(x1_expected, x1);
+ CHECK_EQUAL_64(x4_expected, x4);
+ CHECK_EQUAL_64(x5_expected, x5);
TEARDOWN();
}
@@ -8308,7 +8510,7 @@ TEST(peek_poke_mixed) {
__ Poke(x1, 8);
__ Poke(x0, 0);
{
- ASSERT(__ StackPointer().Is(csp));
+ DCHECK(__ StackPointer().Is(csp));
__ Mov(x4, __ StackPointer());
__ SetStackPointer(x4);
@@ -8340,12 +8542,12 @@ TEST(peek_poke_mixed) {
uint64_t x7_expected = ((x1_expected << 16) & 0xffff0000) |
((x0_expected >> 48) & 0x0000ffff);
- ASSERT_EQUAL_64(x0_expected, x0);
- ASSERT_EQUAL_64(x1_expected, x1);
- ASSERT_EQUAL_64(x2_expected, x2);
- ASSERT_EQUAL_64(x3_expected, x3);
- ASSERT_EQUAL_64(x6_expected, x6);
- ASSERT_EQUAL_64(x7_expected, x7);
+ CHECK_EQUAL_64(x0_expected, x0);
+ CHECK_EQUAL_64(x1_expected, x1);
+ CHECK_EQUAL_64(x2_expected, x2);
+ CHECK_EQUAL_64(x3_expected, x3);
+ CHECK_EQUAL_64(x6_expected, x6);
+ CHECK_EQUAL_64(x7_expected, x7);
TEARDOWN();
}
@@ -8384,10 +8586,10 @@ static void PushPopJsspSimpleHelper(int reg_count,
START();
- // Registers x8 and x9 are used by the macro assembler for debug code (for
- // example in 'Pop'), so we can't use them here. We can't use jssp because it
- // will be the stack pointer for this test.
- static RegList const allowed = ~(x8.Bit() | x9.Bit() | jssp.Bit());
+ // Registers in the TmpList can be used by the macro assembler for debug code
+ // (for example in 'Pop'), so we can't use them here. We can't use jssp
+ // because it will be the stack pointer for this test.
+ static RegList const allowed = ~(masm.TmpList()->list() | jssp.Bit());
if (reg_count == kPushPopJsspMaxRegCount) {
reg_count = CountSetBits(allowed, kNumberOfRegisters);
}
@@ -8405,7 +8607,7 @@ static void PushPopJsspSimpleHelper(int reg_count,
uint64_t literal_base = 0x0100001000100101UL;
{
- ASSERT(__ StackPointer().Is(csp));
+ DCHECK(__ StackPointer().Is(csp));
__ Mov(jssp, __ StackPointer());
__ SetStackPointer(jssp);
@@ -8434,7 +8636,7 @@ static void PushPopJsspSimpleHelper(int reg_count,
case 3: __ Push(r[2], r[1], r[0]); break;
case 2: __ Push(r[1], r[0]); break;
case 1: __ Push(r[0]); break;
- default: ASSERT(i == 0); break;
+ default: DCHECK(i == 0); break;
}
break;
case PushPopRegList:
@@ -8456,7 +8658,7 @@ static void PushPopJsspSimpleHelper(int reg_count,
case 3: __ Pop(r[i], r[i+1], r[i+2]); break;
case 2: __ Pop(r[i], r[i+1]); break;
case 1: __ Pop(r[i]); break;
- default: ASSERT(i == reg_count); break;
+ default: DCHECK(i == reg_count); break;
}
break;
case PushPopRegList:
@@ -8476,14 +8678,14 @@ static void PushPopJsspSimpleHelper(int reg_count,
RUN();
// Check that the register contents were preserved.
- // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
+ // Always use CHECK_EQUAL_64, even when testing W registers, so we can test
// that the upper word was properly cleared by Pop.
literal_base &= (0xffffffffffffffffUL >> (64-reg_size));
for (int i = 0; i < reg_count; i++) {
if (x[i].IsZero()) {
- ASSERT_EQUAL_64(0, x[i]);
+ CHECK_EQUAL_64(0, x[i]);
} else {
- ASSERT_EQUAL_64(literal_base * i, x[i]);
+ CHECK_EQUAL_64(literal_base * i, x[i]);
}
}
@@ -8587,7 +8789,7 @@ static void PushPopFPJsspSimpleHelper(int reg_count,
uint64_t literal_base = 0x0100001000100101UL;
{
- ASSERT(__ StackPointer().Is(csp));
+ DCHECK(__ StackPointer().Is(csp));
__ Mov(jssp, __ StackPointer());
__ SetStackPointer(jssp);
@@ -8618,7 +8820,7 @@ static void PushPopFPJsspSimpleHelper(int reg_count,
case 3: __ Push(v[2], v[1], v[0]); break;
case 2: __ Push(v[1], v[0]); break;
case 1: __ Push(v[0]); break;
- default: ASSERT(i == 0); break;
+ default: DCHECK(i == 0); break;
}
break;
case PushPopRegList:
@@ -8640,7 +8842,7 @@ static void PushPopFPJsspSimpleHelper(int reg_count,
case 3: __ Pop(v[i], v[i+1], v[i+2]); break;
case 2: __ Pop(v[i], v[i+1]); break;
case 1: __ Pop(v[i]); break;
- default: ASSERT(i == reg_count); break;
+ default: DCHECK(i == reg_count); break;
}
break;
case PushPopRegList:
@@ -8660,14 +8862,14 @@ static void PushPopFPJsspSimpleHelper(int reg_count,
RUN();
// Check that the register contents were preserved.
- // Always use ASSERT_EQUAL_FP64, even when testing S registers, so we can
+ // Always use CHECK_EQUAL_FP64, even when testing S registers, so we can
// test that the upper word was properly cleared by Pop.
literal_base &= (0xffffffffffffffffUL >> (64-reg_size));
for (int i = 0; i < reg_count; i++) {
uint64_t literal = literal_base * i;
double expected;
memcpy(&expected, &literal, sizeof(expected));
- ASSERT_EQUAL_FP64(expected, d[i]);
+ CHECK_EQUAL_FP64(expected, d[i]);
}
TEARDOWN();
@@ -8764,7 +8966,7 @@ static void PushPopJsspMixedMethodsHelper(int claim, int reg_size) {
START();
{
- ASSERT(__ StackPointer().Is(csp));
+ DCHECK(__ StackPointer().Is(csp));
__ Mov(jssp, __ StackPointer());
__ SetStackPointer(jssp);
@@ -8800,16 +9002,16 @@ static void PushPopJsspMixedMethodsHelper(int claim, int reg_size) {
RUN();
- // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
+ // Always use CHECK_EQUAL_64, even when testing W registers, so we can test
// that the upper word was properly cleared by Pop.
literal_base &= (0xffffffffffffffffUL >> (64-reg_size));
- ASSERT_EQUAL_64(literal_base * 3, x[9]);
- ASSERT_EQUAL_64(literal_base * 2, x[8]);
- ASSERT_EQUAL_64(literal_base * 0, x[7]);
- ASSERT_EQUAL_64(literal_base * 3, x[6]);
- ASSERT_EQUAL_64(literal_base * 1, x[5]);
- ASSERT_EQUAL_64(literal_base * 2, x[4]);
+ CHECK_EQUAL_64(literal_base * 3, x[9]);
+ CHECK_EQUAL_64(literal_base * 2, x[8]);
+ CHECK_EQUAL_64(literal_base * 0, x[7]);
+ CHECK_EQUAL_64(literal_base * 3, x[6]);
+ CHECK_EQUAL_64(literal_base * 1, x[5]);
+ CHECK_EQUAL_64(literal_base * 2, x[4]);
TEARDOWN();
}
@@ -8869,7 +9071,7 @@ static void PushPopJsspWXOverlapHelper(int reg_count, int claim) {
START();
{
- ASSERT(__ StackPointer().Is(csp));
+ DCHECK(__ StackPointer().Is(csp));
__ Mov(jssp, __ StackPointer());
__ SetStackPointer(jssp);
@@ -8917,7 +9119,7 @@ static void PushPopJsspWXOverlapHelper(int reg_count, int claim) {
int active_w_slots = 0;
for (int i = 0; active_w_slots < requested_w_slots; i++) {
- ASSERT(i < reg_count);
+ DCHECK(i < reg_count);
// In order to test various arguments to PushMultipleTimes, and to try to
// exercise different alignment and overlap effects, we push each
// register a different number of times.
@@ -8990,7 +9192,7 @@ static void PushPopJsspWXOverlapHelper(int reg_count, int claim) {
}
next_is_64 = !next_is_64;
}
- ASSERT(active_w_slots == 0);
+ DCHECK(active_w_slots == 0);
// Drop memory to restore jssp.
__ Drop(claim, kByteSizeInBytes);
@@ -9018,15 +9220,15 @@ static void PushPopJsspWXOverlapHelper(int reg_count, int claim) {
expected = stack[slot++];
}
- // Always use ASSERT_EQUAL_64, even when testing W registers, so we can
+ // Always use CHECK_EQUAL_64, even when testing W registers, so we can
// test that the upper word was properly cleared by Pop.
if (x[i].IsZero()) {
- ASSERT_EQUAL_64(0, x[i]);
+ CHECK_EQUAL_64(0, x[i]);
} else {
- ASSERT_EQUAL_64(expected, x[i]);
+ CHECK_EQUAL_64(expected, x[i]);
}
}
- ASSERT(slot == requested_w_slots);
+ DCHECK(slot == requested_w_slots);
TEARDOWN();
}
@@ -9056,7 +9258,7 @@ TEST(push_pop_csp) {
START();
- ASSERT(csp.Is(__ StackPointer()));
+ DCHECK(csp.Is(__ StackPointer()));
__ Mov(x3, 0x3333333333333333UL);
__ Mov(x2, 0x2222222222222222UL);
@@ -9101,40 +9303,40 @@ TEST(push_pop_csp) {
RUN();
- ASSERT_EQUAL_64(0x1111111111111111UL, x3);
- ASSERT_EQUAL_64(0x0000000000000000UL, x2);
- ASSERT_EQUAL_64(0x3333333333333333UL, x1);
- ASSERT_EQUAL_64(0x2222222222222222UL, x0);
- ASSERT_EQUAL_64(0x3333333333333333UL, x9);
- ASSERT_EQUAL_64(0x2222222222222222UL, x8);
- ASSERT_EQUAL_64(0x0000000000000000UL, x7);
- ASSERT_EQUAL_64(0x3333333333333333UL, x6);
- ASSERT_EQUAL_64(0x1111111111111111UL, x5);
- ASSERT_EQUAL_64(0x2222222222222222UL, x4);
+ CHECK_EQUAL_64(0x1111111111111111UL, x3);
+ CHECK_EQUAL_64(0x0000000000000000UL, x2);
+ CHECK_EQUAL_64(0x3333333333333333UL, x1);
+ CHECK_EQUAL_64(0x2222222222222222UL, x0);
+ CHECK_EQUAL_64(0x3333333333333333UL, x9);
+ CHECK_EQUAL_64(0x2222222222222222UL, x8);
+ CHECK_EQUAL_64(0x0000000000000000UL, x7);
+ CHECK_EQUAL_64(0x3333333333333333UL, x6);
+ CHECK_EQUAL_64(0x1111111111111111UL, x5);
+ CHECK_EQUAL_64(0x2222222222222222UL, x4);
- ASSERT_EQUAL_32(0x11111111U, w13);
- ASSERT_EQUAL_32(0x33333333U, w12);
- ASSERT_EQUAL_32(0x00000000U, w11);
- ASSERT_EQUAL_32(0x22222222U, w10);
- ASSERT_EQUAL_32(0x11111111U, w17);
- ASSERT_EQUAL_32(0x00000000U, w16);
- ASSERT_EQUAL_32(0x33333333U, w15);
- ASSERT_EQUAL_32(0x22222222U, w14);
+ CHECK_EQUAL_32(0x11111111U, w13);
+ CHECK_EQUAL_32(0x33333333U, w12);
+ CHECK_EQUAL_32(0x00000000U, w11);
+ CHECK_EQUAL_32(0x22222222U, w10);
+ CHECK_EQUAL_32(0x11111111U, w17);
+ CHECK_EQUAL_32(0x00000000U, w16);
+ CHECK_EQUAL_32(0x33333333U, w15);
+ CHECK_EQUAL_32(0x22222222U, w14);
- ASSERT_EQUAL_32(0x11111111U, w18);
- ASSERT_EQUAL_32(0x11111111U, w19);
- ASSERT_EQUAL_32(0x11111111U, w20);
- ASSERT_EQUAL_32(0x11111111U, w21);
- ASSERT_EQUAL_64(0x3333333333333333UL, x22);
- ASSERT_EQUAL_64(0x0000000000000000UL, x23);
+ CHECK_EQUAL_32(0x11111111U, w18);
+ CHECK_EQUAL_32(0x11111111U, w19);
+ CHECK_EQUAL_32(0x11111111U, w20);
+ CHECK_EQUAL_32(0x11111111U, w21);
+ CHECK_EQUAL_64(0x3333333333333333UL, x22);
+ CHECK_EQUAL_64(0x0000000000000000UL, x23);
- ASSERT_EQUAL_64(0x3333333333333333UL, x24);
- ASSERT_EQUAL_64(0x3333333333333333UL, x26);
+ CHECK_EQUAL_64(0x3333333333333333UL, x24);
+ CHECK_EQUAL_64(0x3333333333333333UL, x26);
- ASSERT_EQUAL_32(0x33333333U, w25);
- ASSERT_EQUAL_32(0x00000000U, w27);
- ASSERT_EQUAL_32(0x22222222U, w28);
- ASSERT_EQUAL_32(0x33333333U, w29);
+ CHECK_EQUAL_32(0x33333333U, w25);
+ CHECK_EQUAL_32(0x00000000U, w27);
+ CHECK_EQUAL_32(0x22222222U, w28);
+ CHECK_EQUAL_32(0x33333333U, w29);
TEARDOWN();
}
@@ -9145,7 +9347,7 @@ TEST(push_queued) {
START();
- ASSERT(__ StackPointer().Is(csp));
+ DCHECK(__ StackPointer().Is(csp));
__ Mov(jssp, __ StackPointer());
__ SetStackPointer(jssp);
@@ -9196,19 +9398,19 @@ TEST(push_queued) {
RUN();
- ASSERT_EQUAL_64(0x1234000000000000, x0);
- ASSERT_EQUAL_64(0x1234000100010001, x1);
- ASSERT_EQUAL_64(0x1234000200020002, x2);
- ASSERT_EQUAL_64(0x1234000300030003, x3);
+ CHECK_EQUAL_64(0x1234000000000000, x0);
+ CHECK_EQUAL_64(0x1234000100010001, x1);
+ CHECK_EQUAL_64(0x1234000200020002, x2);
+ CHECK_EQUAL_64(0x1234000300030003, x3);
- ASSERT_EQUAL_32(0x12340004, w4);
- ASSERT_EQUAL_32(0x12340005, w5);
- ASSERT_EQUAL_32(0x12340006, w6);
+ CHECK_EQUAL_32(0x12340004, w4);
+ CHECK_EQUAL_32(0x12340005, w5);
+ CHECK_EQUAL_32(0x12340006, w6);
- ASSERT_EQUAL_FP64(123400.0, d0);
- ASSERT_EQUAL_FP64(123401.0, d1);
+ CHECK_EQUAL_FP64(123400.0, d0);
+ CHECK_EQUAL_FP64(123401.0, d1);
- ASSERT_EQUAL_FP32(123402.0, s2);
+ CHECK_EQUAL_FP32(123402.0, s2);
TEARDOWN();
}
@@ -9220,7 +9422,7 @@ TEST(pop_queued) {
START();
- ASSERT(__ StackPointer().Is(csp));
+ DCHECK(__ StackPointer().Is(csp));
__ Mov(jssp, __ StackPointer());
__ SetStackPointer(jssp);
@@ -9271,19 +9473,19 @@ TEST(pop_queued) {
RUN();
- ASSERT_EQUAL_64(0x1234000000000000, x0);
- ASSERT_EQUAL_64(0x1234000100010001, x1);
- ASSERT_EQUAL_64(0x1234000200020002, x2);
- ASSERT_EQUAL_64(0x1234000300030003, x3);
+ CHECK_EQUAL_64(0x1234000000000000, x0);
+ CHECK_EQUAL_64(0x1234000100010001, x1);
+ CHECK_EQUAL_64(0x1234000200020002, x2);
+ CHECK_EQUAL_64(0x1234000300030003, x3);
- ASSERT_EQUAL_64(0x0000000012340004, x4);
- ASSERT_EQUAL_64(0x0000000012340005, x5);
- ASSERT_EQUAL_64(0x0000000012340006, x6);
+ CHECK_EQUAL_64(0x0000000012340004, x4);
+ CHECK_EQUAL_64(0x0000000012340005, x5);
+ CHECK_EQUAL_64(0x0000000012340006, x6);
- ASSERT_EQUAL_FP64(123400.0, d0);
- ASSERT_EQUAL_FP64(123401.0, d1);
+ CHECK_EQUAL_FP64(123400.0, d0);
+ CHECK_EQUAL_FP64(123401.0, d1);
- ASSERT_EQUAL_FP32(123402.0, s2);
+ CHECK_EQUAL_FP32(123402.0, s2);
TEARDOWN();
}
@@ -9349,14 +9551,14 @@ TEST(jump_both_smi) {
RUN();
- ASSERT_EQUAL_64(0x5555555500000001UL, x0);
- ASSERT_EQUAL_64(0xaaaaaaaa00000001UL, x1);
- ASSERT_EQUAL_64(0x1234567800000000UL, x2);
- ASSERT_EQUAL_64(0x8765432100000000UL, x3);
- ASSERT_EQUAL_64(0, x4);
- ASSERT_EQUAL_64(0, x5);
- ASSERT_EQUAL_64(0, x6);
- ASSERT_EQUAL_64(1, x7);
+ CHECK_EQUAL_64(0x5555555500000001UL, x0);
+ CHECK_EQUAL_64(0xaaaaaaaa00000001UL, x1);
+ CHECK_EQUAL_64(0x1234567800000000UL, x2);
+ CHECK_EQUAL_64(0x8765432100000000UL, x3);
+ CHECK_EQUAL_64(0, x4);
+ CHECK_EQUAL_64(0, x5);
+ CHECK_EQUAL_64(0, x6);
+ CHECK_EQUAL_64(1, x7);
TEARDOWN();
}
@@ -9422,14 +9624,14 @@ TEST(jump_either_smi) {
RUN();
- ASSERT_EQUAL_64(0x5555555500000001UL, x0);
- ASSERT_EQUAL_64(0xaaaaaaaa00000001UL, x1);
- ASSERT_EQUAL_64(0x1234567800000000UL, x2);
- ASSERT_EQUAL_64(0x8765432100000000UL, x3);
- ASSERT_EQUAL_64(0, x4);
- ASSERT_EQUAL_64(1, x5);
- ASSERT_EQUAL_64(1, x6);
- ASSERT_EQUAL_64(1, x7);
+ CHECK_EQUAL_64(0x5555555500000001UL, x0);
+ CHECK_EQUAL_64(0xaaaaaaaa00000001UL, x1);
+ CHECK_EQUAL_64(0x1234567800000000UL, x2);
+ CHECK_EQUAL_64(0x8765432100000000UL, x3);
+ CHECK_EQUAL_64(0, x4);
+ CHECK_EQUAL_64(1, x5);
+ CHECK_EQUAL_64(1, x6);
+ CHECK_EQUAL_64(1, x7);
TEARDOWN();
}
@@ -9780,7 +9982,7 @@ TEST(cpureglist_utils_empty) {
TEST(printf) {
INIT_V8();
- SETUP();
+ SETUP_SIZE(BUF_SIZE * 2);
START();
char const * test_plain_string = "Printf with no arguments.\n";
@@ -9821,41 +10023,49 @@ TEST(printf) {
__ Mov(x11, 40);
__ Mov(x12, 500);
- // x8 and x9 are used by debug code in part of the macro assembler. However,
- // Printf guarantees to preserve them (so we can use Printf in debug code),
- // and we need to test that they are properly preserved. The above code
- // shouldn't need to use them, but we initialize x8 and x9 last to be on the
- // safe side. This test still assumes that none of the code from
- // before->Dump() to the end of the test can clobber x8 or x9, so where
- // possible we use the Assembler directly to be safe.
- __ orr(x8, xzr, 0x8888888888888888);
- __ orr(x9, xzr, 0x9999999999999999);
-
- // Check that we don't clobber any registers, except those that we explicitly
- // write results into.
+ // A single character.
+ __ Mov(w13, 'x');
+
+ // Check that we don't clobber any registers.
before.Dump(&masm);
__ Printf(test_plain_string); // NOLINT(runtime/printf)
- __ Printf("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1);
+ __ Printf("x0: %" PRId64 ", x1: 0x%08" PRIx64 "\n", x0, x1);
+ __ Printf("w5: %" PRId32 ", x5: %" PRId64"\n", w5, x5);
__ Printf("d0: %f\n", d0);
__ Printf("Test %%s: %s\n", x2);
__ Printf("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
"x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
w3, w4, x5, x6);
__ Printf("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
- __ Printf("0x%08" PRIx32 ", 0x%016" PRIx64 "\n", x28, x28);
+ __ Printf("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
__ Printf("%g\n", d10);
+ __ Printf("%%%%%s%%%c%%\n", x2, w13);
+
+ // Print the stack pointer (csp).
+ DCHECK(csp.Is(__ StackPointer()));
+ __ Printf("StackPointer(csp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
+ __ StackPointer(), __ StackPointer().W());
// Test with a different stack pointer.
const Register old_stack_pointer = __ StackPointer();
- __ mov(x29, old_stack_pointer);
+ __ Mov(x29, old_stack_pointer);
__ SetStackPointer(x29);
- __ Printf("old_stack_pointer: 0x%016" PRIx64 "\n", old_stack_pointer);
- __ mov(old_stack_pointer, __ StackPointer());
+ // Print the stack pointer (not csp).
+ __ Printf("StackPointer(not csp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
+ __ StackPointer(), __ StackPointer().W());
+ __ Mov(old_stack_pointer, __ StackPointer());
__ SetStackPointer(old_stack_pointer);
+ // Test with three arguments.
__ Printf("3=%u, 4=%u, 5=%u\n", x10, x11, x12);
+ // Mixed argument types.
+ __ Printf("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
+ w3, s1, x5, d3);
+ __ Printf("s1: %f, d3: %f, w3: %" PRId32 ", x5: %" PRId64 "\n",
+ s1, d3, w3, x5);
+
END();
RUN();
@@ -9863,7 +10073,7 @@ TEST(printf) {
// Printf preserves all registers by default, we can't look at the number of
// bytes that were printed. However, the printf_no_preserve test should check
// that, and here we just test that we didn't clobber any registers.
- ASSERT_EQUAL_REGISTERS(before);
+ CHECK_EQUAL_REGISTERS(before);
TEARDOWN();
}
@@ -9877,7 +10087,7 @@ TEST(printf_no_preserve) {
char const * test_plain_string = "Printf with no arguments.\n";
char const * test_substring = "'This is a substring.'";
- __ PrintfNoPreserve(test_plain_string); // NOLINT(runtime/printf)
+ __ PrintfNoPreserve(test_plain_string);
__ Mov(x19, x0);
// Test simple integer arguments.
@@ -9915,7 +10125,7 @@ TEST(printf_no_preserve) {
// Test printing callee-saved registers.
__ Mov(x28, 0x123456789abcdef);
- __ PrintfNoPreserve("0x%08" PRIx32 ", 0x%016" PRIx64 "\n", x28, x28);
+ __ PrintfNoPreserve("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
__ Mov(x25, x0);
__ Fmov(d10, 42.0);
@@ -9926,11 +10136,11 @@ TEST(printf_no_preserve) {
const Register old_stack_pointer = __ StackPointer();
__ Mov(x29, old_stack_pointer);
__ SetStackPointer(x29);
-
- __ PrintfNoPreserve("old_stack_pointer: 0x%016" PRIx64 "\n",
- old_stack_pointer);
+ // Print the stack pointer (not csp).
+ __ PrintfNoPreserve(
+ "StackPointer(not csp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
+ __ StackPointer(), __ StackPointer().W());
__ Mov(x27, x0);
-
__ Mov(old_stack_pointer, __ StackPointer());
__ SetStackPointer(old_stack_pointer);
@@ -9941,6 +10151,15 @@ TEST(printf_no_preserve) {
__ PrintfNoPreserve("3=%u, 4=%u, 5=%u\n", x3, x4, x5);
__ Mov(x28, x0);
+ // Mixed argument types.
+ __ Mov(w3, 0xffffffff);
+ __ Fmov(s1, 1.234);
+ __ Mov(x5, 0xffffffffffffffff);
+ __ Fmov(d3, 3.456);
+ __ PrintfNoPreserve("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
+ w3, s1, x5, d3);
+ __ Mov(x29, x0);
+
END();
RUN();
@@ -9948,33 +10167,35 @@ TEST(printf_no_preserve) {
// use the return code to check that the string length was correct.
// Printf with no arguments.
- ASSERT_EQUAL_64(strlen(test_plain_string), x19);
+ CHECK_EQUAL_64(strlen(test_plain_string), x19);
// x0: 1234, x1: 0x00001234
- ASSERT_EQUAL_64(25, x20);
+ CHECK_EQUAL_64(25, x20);
// d0: 1.234000
- ASSERT_EQUAL_64(13, x21);
+ CHECK_EQUAL_64(13, x21);
// Test %s: 'This is a substring.'
- ASSERT_EQUAL_64(32, x22);
+ CHECK_EQUAL_64(32, x22);
// w3(uint32): 4294967295
// w4(int32): -1
// x5(uint64): 18446744073709551615
// x6(int64): -1
- ASSERT_EQUAL_64(23 + 14 + 33 + 14, x23);
+ CHECK_EQUAL_64(23 + 14 + 33 + 14, x23);
// %f: 1.234000
// %g: 2.345
// %e: 3.456000e+00
// %E: 4.567000E+00
- ASSERT_EQUAL_64(13 + 10 + 17 + 17, x24);
- // 0x89abcdef, 0x0123456789abcdef
- ASSERT_EQUAL_64(31, x25);
+ CHECK_EQUAL_64(13 + 10 + 17 + 17, x24);
+ // 0x89abcdef, 0x123456789abcdef
+ CHECK_EQUAL_64(30, x25);
// 42
- ASSERT_EQUAL_64(3, x26);
- // old_stack_pointer: 0x00007fb037ae2370
+ CHECK_EQUAL_64(3, x26);
+ // StackPointer(not csp): 0x00007fb037ae2370, 0x37ae2370
// Note: This is an example value, but the field width is fixed here so the
// string length is still predictable.
- ASSERT_EQUAL_64(38, x27);
+ CHECK_EQUAL_64(54, x27);
// 3=3, 4=40, 5=500
- ASSERT_EQUAL_64(17, x28);
+ CHECK_EQUAL_64(17, x28);
+ // w3: 4294967295, s1: 1.234000, x5: 18446744073709551615, d3: 3.456000
+ CHECK_EQUAL_64(69, x29);
TEARDOWN();
}
@@ -10071,14 +10292,14 @@ static void DoSmiAbsTest(int32_t value, bool must_fail = false) {
if (must_fail) {
// We tested an invalid conversion. The code must have jump on slow.
- ASSERT_EQUAL_64(0xbad, x2);
+ CHECK_EQUAL_64(0xbad, x2);
} else {
// The conversion is valid, check the result.
int32_t result = (value >= 0) ? value : -value;
- ASSERT_EQUAL_64(result, x1);
+ CHECK_EQUAL_64(result, x1);
// Check that we didn't jump on slow.
- ASSERT_EQUAL_64(0xc001c0de, x2);
+ CHECK_EQUAL_64(0xc001c0de, x2);
}
TEARDOWN();
@@ -10125,7 +10346,7 @@ TEST(blr_lr) {
RUN();
- ASSERT_EQUAL_64(0xc001c0de, x0);
+ CHECK_EQUAL_64(0xc001c0de, x0);
TEARDOWN();
}
@@ -10196,14 +10417,14 @@ TEST(process_nan_double) {
// Make sure that NaN propagation works correctly.
double sn = rawbits_to_double(0x7ff5555511111111);
double qn = rawbits_to_double(0x7ffaaaaa11111111);
- ASSERT(IsSignallingNaN(sn));
- ASSERT(IsQuietNaN(qn));
+ DCHECK(IsSignallingNaN(sn));
+ DCHECK(IsQuietNaN(qn));
// The input NaNs after passing through ProcessNaN.
double sn_proc = rawbits_to_double(0x7ffd555511111111);
double qn_proc = qn;
- ASSERT(IsQuietNaN(sn_proc));
- ASSERT(IsQuietNaN(qn_proc));
+ DCHECK(IsQuietNaN(sn_proc));
+ DCHECK(IsQuietNaN(qn_proc));
SETUP();
START();
@@ -10244,24 +10465,24 @@ TEST(process_nan_double) {
uint64_t sn_raw = double_to_rawbits(sn);
// - Signalling NaN
- ASSERT_EQUAL_FP64(sn, d1);
- ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw & ~kDSignMask), d2);
- ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw ^ kDSignMask), d3);
+ CHECK_EQUAL_FP64(sn, d1);
+ CHECK_EQUAL_FP64(rawbits_to_double(sn_raw & ~kDSignMask), d2);
+ CHECK_EQUAL_FP64(rawbits_to_double(sn_raw ^ kDSignMask), d3);
// - Quiet NaN
- ASSERT_EQUAL_FP64(qn, d11);
- ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw & ~kDSignMask), d12);
- ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw ^ kDSignMask), d13);
+ CHECK_EQUAL_FP64(qn, d11);
+ CHECK_EQUAL_FP64(rawbits_to_double(qn_raw & ~kDSignMask), d12);
+ CHECK_EQUAL_FP64(rawbits_to_double(qn_raw ^ kDSignMask), d13);
// - Signalling NaN
- ASSERT_EQUAL_FP64(sn_proc, d4);
- ASSERT_EQUAL_FP64(sn_proc, d5);
- ASSERT_EQUAL_FP64(sn_proc, d6);
- ASSERT_EQUAL_FP64(sn_proc, d7);
+ CHECK_EQUAL_FP64(sn_proc, d4);
+ CHECK_EQUAL_FP64(sn_proc, d5);
+ CHECK_EQUAL_FP64(sn_proc, d6);
+ CHECK_EQUAL_FP64(sn_proc, d7);
// - Quiet NaN
- ASSERT_EQUAL_FP64(qn_proc, d14);
- ASSERT_EQUAL_FP64(qn_proc, d15);
- ASSERT_EQUAL_FP64(qn_proc, d16);
- ASSERT_EQUAL_FP64(qn_proc, d17);
+ CHECK_EQUAL_FP64(qn_proc, d14);
+ CHECK_EQUAL_FP64(qn_proc, d15);
+ CHECK_EQUAL_FP64(qn_proc, d16);
+ CHECK_EQUAL_FP64(qn_proc, d17);
TEARDOWN();
}
@@ -10272,14 +10493,14 @@ TEST(process_nan_float) {
// Make sure that NaN propagation works correctly.
float sn = rawbits_to_float(0x7f951111);
float qn = rawbits_to_float(0x7fea1111);
- ASSERT(IsSignallingNaN(sn));
- ASSERT(IsQuietNaN(qn));
+ DCHECK(IsSignallingNaN(sn));
+ DCHECK(IsQuietNaN(qn));
// The input NaNs after passing through ProcessNaN.
float sn_proc = rawbits_to_float(0x7fd51111);
float qn_proc = qn;
- ASSERT(IsQuietNaN(sn_proc));
- ASSERT(IsQuietNaN(qn_proc));
+ DCHECK(IsQuietNaN(sn_proc));
+ DCHECK(IsQuietNaN(qn_proc));
SETUP();
START();
@@ -10320,32 +10541,32 @@ TEST(process_nan_float) {
uint32_t sn_raw = float_to_rawbits(sn);
// - Signalling NaN
- ASSERT_EQUAL_FP32(sn, s1);
- ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw & ~kSSignMask), s2);
- ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw ^ kSSignMask), s3);
+ CHECK_EQUAL_FP32(sn, s1);
+ CHECK_EQUAL_FP32(rawbits_to_float(sn_raw & ~kSSignMask), s2);
+ CHECK_EQUAL_FP32(rawbits_to_float(sn_raw ^ kSSignMask), s3);
// - Quiet NaN
- ASSERT_EQUAL_FP32(qn, s11);
- ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw & ~kSSignMask), s12);
- ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw ^ kSSignMask), s13);
+ CHECK_EQUAL_FP32(qn, s11);
+ CHECK_EQUAL_FP32(rawbits_to_float(qn_raw & ~kSSignMask), s12);
+ CHECK_EQUAL_FP32(rawbits_to_float(qn_raw ^ kSSignMask), s13);
// - Signalling NaN
- ASSERT_EQUAL_FP32(sn_proc, s4);
- ASSERT_EQUAL_FP32(sn_proc, s5);
- ASSERT_EQUAL_FP32(sn_proc, s6);
- ASSERT_EQUAL_FP32(sn_proc, s7);
+ CHECK_EQUAL_FP32(sn_proc, s4);
+ CHECK_EQUAL_FP32(sn_proc, s5);
+ CHECK_EQUAL_FP32(sn_proc, s6);
+ CHECK_EQUAL_FP32(sn_proc, s7);
// - Quiet NaN
- ASSERT_EQUAL_FP32(qn_proc, s14);
- ASSERT_EQUAL_FP32(qn_proc, s15);
- ASSERT_EQUAL_FP32(qn_proc, s16);
- ASSERT_EQUAL_FP32(qn_proc, s17);
+ CHECK_EQUAL_FP32(qn_proc, s14);
+ CHECK_EQUAL_FP32(qn_proc, s15);
+ CHECK_EQUAL_FP32(qn_proc, s16);
+ CHECK_EQUAL_FP32(qn_proc, s17);
TEARDOWN();
}
static void ProcessNaNsHelper(double n, double m, double expected) {
- ASSERT(std::isnan(n) || std::isnan(m));
- ASSERT(isnan(expected));
+ DCHECK(std::isnan(n) || std::isnan(m));
+ DCHECK(std::isnan(expected));
SETUP();
START();
@@ -10365,12 +10586,12 @@ static void ProcessNaNsHelper(double n, double m, double expected) {
END();
RUN();
- ASSERT_EQUAL_FP64(expected, d2);
- ASSERT_EQUAL_FP64(expected, d3);
- ASSERT_EQUAL_FP64(expected, d4);
- ASSERT_EQUAL_FP64(expected, d5);
- ASSERT_EQUAL_FP64(expected, d6);
- ASSERT_EQUAL_FP64(expected, d7);
+ CHECK_EQUAL_FP64(expected, d2);
+ CHECK_EQUAL_FP64(expected, d3);
+ CHECK_EQUAL_FP64(expected, d4);
+ CHECK_EQUAL_FP64(expected, d5);
+ CHECK_EQUAL_FP64(expected, d6);
+ CHECK_EQUAL_FP64(expected, d7);
TEARDOWN();
}
@@ -10383,20 +10604,20 @@ TEST(process_nans_double) {
double sm = rawbits_to_double(0x7ff5555522222222);
double qn = rawbits_to_double(0x7ffaaaaa11111111);
double qm = rawbits_to_double(0x7ffaaaaa22222222);
- ASSERT(IsSignallingNaN(sn));
- ASSERT(IsSignallingNaN(sm));
- ASSERT(IsQuietNaN(qn));
- ASSERT(IsQuietNaN(qm));
+ DCHECK(IsSignallingNaN(sn));
+ DCHECK(IsSignallingNaN(sm));
+ DCHECK(IsQuietNaN(qn));
+ DCHECK(IsQuietNaN(qm));
// The input NaNs after passing through ProcessNaN.
double sn_proc = rawbits_to_double(0x7ffd555511111111);
double sm_proc = rawbits_to_double(0x7ffd555522222222);
double qn_proc = qn;
double qm_proc = qm;
- ASSERT(IsQuietNaN(sn_proc));
- ASSERT(IsQuietNaN(sm_proc));
- ASSERT(IsQuietNaN(qn_proc));
- ASSERT(IsQuietNaN(qm_proc));
+ DCHECK(IsQuietNaN(sn_proc));
+ DCHECK(IsQuietNaN(sm_proc));
+ DCHECK(IsQuietNaN(qn_proc));
+ DCHECK(IsQuietNaN(qm_proc));
// Quiet NaNs are propagated.
ProcessNaNsHelper(qn, 0, qn_proc);
@@ -10416,8 +10637,8 @@ TEST(process_nans_double) {
static void ProcessNaNsHelper(float n, float m, float expected) {
- ASSERT(std::isnan(n) || std::isnan(m));
- ASSERT(isnan(expected));
+ DCHECK(std::isnan(n) || std::isnan(m));
+ DCHECK(std::isnan(expected));
SETUP();
START();
@@ -10437,12 +10658,12 @@ static void ProcessNaNsHelper(float n, float m, float expected) {
END();
RUN();
- ASSERT_EQUAL_FP32(expected, s2);
- ASSERT_EQUAL_FP32(expected, s3);
- ASSERT_EQUAL_FP32(expected, s4);
- ASSERT_EQUAL_FP32(expected, s5);
- ASSERT_EQUAL_FP32(expected, s6);
- ASSERT_EQUAL_FP32(expected, s7);
+ CHECK_EQUAL_FP32(expected, s2);
+ CHECK_EQUAL_FP32(expected, s3);
+ CHECK_EQUAL_FP32(expected, s4);
+ CHECK_EQUAL_FP32(expected, s5);
+ CHECK_EQUAL_FP32(expected, s6);
+ CHECK_EQUAL_FP32(expected, s7);
TEARDOWN();
}
@@ -10455,20 +10676,20 @@ TEST(process_nans_float) {
float sm = rawbits_to_float(0x7f952222);
float qn = rawbits_to_float(0x7fea1111);
float qm = rawbits_to_float(0x7fea2222);
- ASSERT(IsSignallingNaN(sn));
- ASSERT(IsSignallingNaN(sm));
- ASSERT(IsQuietNaN(qn));
- ASSERT(IsQuietNaN(qm));
+ DCHECK(IsSignallingNaN(sn));
+ DCHECK(IsSignallingNaN(sm));
+ DCHECK(IsQuietNaN(qn));
+ DCHECK(IsQuietNaN(qm));
// The input NaNs after passing through ProcessNaN.
float sn_proc = rawbits_to_float(0x7fd51111);
float sm_proc = rawbits_to_float(0x7fd52222);
float qn_proc = qn;
float qm_proc = qm;
- ASSERT(IsQuietNaN(sn_proc));
- ASSERT(IsQuietNaN(sm_proc));
- ASSERT(IsQuietNaN(qn_proc));
- ASSERT(IsQuietNaN(qm_proc));
+ DCHECK(IsQuietNaN(sn_proc));
+ DCHECK(IsQuietNaN(sm_proc));
+ DCHECK(IsQuietNaN(qn_proc));
+ DCHECK(IsQuietNaN(qm_proc));
// Quiet NaNs are propagated.
ProcessNaNsHelper(qn, 0, qn_proc);
@@ -10488,7 +10709,7 @@ TEST(process_nans_float) {
static void DefaultNaNHelper(float n, float m, float a) {
- ASSERT(std::isnan(n) || std::isnan(m) || isnan(a));
+ DCHECK(std::isnan(n) || std::isnan(m) || std::isnan(a));
bool test_1op = std::isnan(n);
bool test_2op = std::isnan(n) || std::isnan(m);
@@ -10545,29 +10766,29 @@ static void DefaultNaNHelper(float n, float m, float a) {
if (test_1op) {
uint32_t n_raw = float_to_rawbits(n);
- ASSERT_EQUAL_FP32(n, s10);
- ASSERT_EQUAL_FP32(rawbits_to_float(n_raw & ~kSSignMask), s11);
- ASSERT_EQUAL_FP32(rawbits_to_float(n_raw ^ kSSignMask), s12);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s13);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s14);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s15);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s16);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d17);
+ CHECK_EQUAL_FP32(n, s10);
+ CHECK_EQUAL_FP32(rawbits_to_float(n_raw & ~kSSignMask), s11);
+ CHECK_EQUAL_FP32(rawbits_to_float(n_raw ^ kSSignMask), s12);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s13);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s14);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s15);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s16);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d17);
}
if (test_2op) {
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s18);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s19);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s20);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s21);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s22);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s23);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s18);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s19);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s20);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s21);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s22);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s23);
}
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s24);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s25);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s26);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s27);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s24);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s25);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s26);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s27);
TEARDOWN();
}
@@ -10581,12 +10802,12 @@ TEST(default_nan_float) {
float qn = rawbits_to_float(0x7fea1111);
float qm = rawbits_to_float(0x7fea2222);
float qa = rawbits_to_float(0x7feaaaaa);
- ASSERT(IsSignallingNaN(sn));
- ASSERT(IsSignallingNaN(sm));
- ASSERT(IsSignallingNaN(sa));
- ASSERT(IsQuietNaN(qn));
- ASSERT(IsQuietNaN(qm));
- ASSERT(IsQuietNaN(qa));
+ DCHECK(IsSignallingNaN(sn));
+ DCHECK(IsSignallingNaN(sm));
+ DCHECK(IsSignallingNaN(sa));
+ DCHECK(IsQuietNaN(qn));
+ DCHECK(IsQuietNaN(qm));
+ DCHECK(IsQuietNaN(qa));
// - Signalling NaNs
DefaultNaNHelper(sn, 0.0f, 0.0f);
@@ -10616,7 +10837,7 @@ TEST(default_nan_float) {
static void DefaultNaNHelper(double n, double m, double a) {
- ASSERT(std::isnan(n) || std::isnan(m) || isnan(a));
+ DCHECK(std::isnan(n) || std::isnan(m) || std::isnan(a));
bool test_1op = std::isnan(n);
bool test_2op = std::isnan(n) || std::isnan(m);
@@ -10673,29 +10894,29 @@ static void DefaultNaNHelper(double n, double m, double a) {
if (test_1op) {
uint64_t n_raw = double_to_rawbits(n);
- ASSERT_EQUAL_FP64(n, d10);
- ASSERT_EQUAL_FP64(rawbits_to_double(n_raw & ~kDSignMask), d11);
- ASSERT_EQUAL_FP64(rawbits_to_double(n_raw ^ kDSignMask), d12);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d14);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d15);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d16);
- ASSERT_EQUAL_FP32(kFP32DefaultNaN, s17);
+ CHECK_EQUAL_FP64(n, d10);
+ CHECK_EQUAL_FP64(rawbits_to_double(n_raw & ~kDSignMask), d11);
+ CHECK_EQUAL_FP64(rawbits_to_double(n_raw ^ kDSignMask), d12);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d13);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d14);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d15);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d16);
+ CHECK_EQUAL_FP32(kFP32DefaultNaN, s17);
}
if (test_2op) {
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d18);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d19);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d20);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d21);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d22);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d23);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d18);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d19);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d20);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d21);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d22);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d23);
}
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d24);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d25);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d26);
- ASSERT_EQUAL_FP64(kFP64DefaultNaN, d27);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d24);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d25);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d26);
+ CHECK_EQUAL_FP64(kFP64DefaultNaN, d27);
TEARDOWN();
}
@@ -10709,12 +10930,12 @@ TEST(default_nan_double) {
double qn = rawbits_to_double(0x7ffaaaaa11111111);
double qm = rawbits_to_double(0x7ffaaaaa22222222);
double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
- ASSERT(IsSignallingNaN(sn));
- ASSERT(IsSignallingNaN(sm));
- ASSERT(IsSignallingNaN(sa));
- ASSERT(IsQuietNaN(qn));
- ASSERT(IsQuietNaN(qm));
- ASSERT(IsQuietNaN(qa));
+ DCHECK(IsSignallingNaN(sn));
+ DCHECK(IsSignallingNaN(sm));
+ DCHECK(IsSignallingNaN(sa));
+ DCHECK(IsQuietNaN(qn));
+ DCHECK(IsQuietNaN(qm));
+ DCHECK(IsQuietNaN(qa));
// - Signalling NaNs
DefaultNaNHelper(sn, 0.0, 0.0);
@@ -10775,7 +10996,7 @@ TEST(call_no_relocation) {
RUN();
- ASSERT_EQUAL_64(1, x0);
+ CHECK_EQUAL_64(1, x0);
// The return_address_from_call_start function doesn't currently encounter any
// non-relocatable sequences, so we check it here to make sure it works.
@@ -10832,12 +11053,12 @@ static void AbsHelperX(int64_t value) {
END();
RUN();
- ASSERT_EQUAL_64(0, x0);
- ASSERT_EQUAL_64(value, x1);
- ASSERT_EQUAL_64(expected, x10);
- ASSERT_EQUAL_64(expected, x11);
- ASSERT_EQUAL_64(expected, x12);
- ASSERT_EQUAL_64(expected, x13);
+ CHECK_EQUAL_64(0, x0);
+ CHECK_EQUAL_64(value, x1);
+ CHECK_EQUAL_64(expected, x10);
+ CHECK_EQUAL_64(expected, x11);
+ CHECK_EQUAL_64(expected, x12);
+ CHECK_EQUAL_64(expected, x13);
TEARDOWN();
}
@@ -10889,12 +11110,12 @@ static void AbsHelperW(int32_t value) {
END();
RUN();
- ASSERT_EQUAL_32(0, w0);
- ASSERT_EQUAL_32(value, w1);
- ASSERT_EQUAL_32(expected, w10);
- ASSERT_EQUAL_32(expected, w11);
- ASSERT_EQUAL_32(expected, w12);
- ASSERT_EQUAL_32(expected, w13);
+ CHECK_EQUAL_32(0, w0);
+ CHECK_EQUAL_32(value, w1);
+ CHECK_EQUAL_32(expected, w10);
+ CHECK_EQUAL_32(expected, w11);
+ CHECK_EQUAL_32(expected, w12);
+ CHECK_EQUAL_32(expected, w13);
TEARDOWN();
}
@@ -10952,16 +11173,16 @@ TEST(pool_size) {
for (RelocIterator it(*code, pool_mask); !it.done(); it.next()) {
RelocInfo* info = it.rinfo();
if (RelocInfo::IsConstPool(info->rmode())) {
- ASSERT(info->data() == constant_pool_size);
+ DCHECK(info->data() == constant_pool_size);
++pool_count;
}
if (RelocInfo::IsVeneerPool(info->rmode())) {
- ASSERT(info->data() == veneer_pool_size);
+ DCHECK(info->data() == veneer_pool_size);
++pool_count;
}
}
- ASSERT(pool_count == 2);
+ DCHECK(pool_count == 2);
TEARDOWN();
}
diff --git a/deps/v8/test/cctest/test-assembler-ia32.cc b/deps/v8/test/cctest/test-assembler-ia32.cc
index ba83b3d7e..e8c7f951f 100644
--- a/deps/v8/test/cctest/test-assembler-ia32.cc
+++ b/deps/v8/test/cctest/test-assembler-ia32.cc
@@ -27,14 +27,15 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "disassembler.h"
-#include "factory.h"
-#include "macro-assembler.h"
-#include "platform.h"
-#include "serialize.h"
-#include "cctest.h"
+#include "src/base/platform/platform.h"
+#include "src/disassembler.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "src/ostreams.h"
+#include "src/serialize.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -63,7 +64,8 @@ TEST(AssemblerIa320) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F2 f = FUNCTION_CAST<F2>(code->entry());
int res = f(3, 4);
@@ -99,7 +101,8 @@ TEST(AssemblerIa321) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
int res = f(100);
@@ -139,7 +142,8 @@ TEST(AssemblerIa322) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
int res = f(10);
@@ -152,7 +156,6 @@ typedef int (*F3)(float x);
TEST(AssemblerIa323) {
CcTest::InitializeVM();
- if (!CpuFeatures::IsSupported(SSE2)) return;
Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
HandleScope scope(isolate);
@@ -160,11 +163,8 @@ TEST(AssemblerIa323) {
v8::internal::byte buffer[256];
Assembler assm(isolate, buffer, sizeof buffer);
- CHECK(CpuFeatures::IsSupported(SSE2));
- { CpuFeatureScope fscope(&assm, SSE2);
- __ cvttss2si(eax, Operand(esp, 4));
- __ ret(0);
- }
+ __ cvttss2si(eax, Operand(esp, 4));
+ __ ret(0);
CodeDesc desc;
assm.GetCode(&desc);
@@ -186,7 +186,6 @@ typedef int (*F4)(double x);
TEST(AssemblerIa324) {
CcTest::InitializeVM();
- if (!CpuFeatures::IsSupported(SSE2)) return;
Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
HandleScope scope(isolate);
@@ -194,8 +193,6 @@ TEST(AssemblerIa324) {
v8::internal::byte buffer[256];
Assembler assm(isolate, buffer, sizeof buffer);
- CHECK(CpuFeatures::IsSupported(SSE2));
- CpuFeatureScope fscope(&assm, SSE2);
__ cvttsd2si(eax, Operand(esp, 4));
__ ret(0);
@@ -241,14 +238,12 @@ typedef double (*F5)(double x, double y);
TEST(AssemblerIa326) {
CcTest::InitializeVM();
- if (!CpuFeatures::IsSupported(SSE2)) return;
Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
HandleScope scope(isolate);
v8::internal::byte buffer[256];
Assembler assm(isolate, buffer, sizeof buffer);
- CpuFeatureScope fscope(&assm, SSE2);
__ movsd(xmm0, Operand(esp, 1 * kPointerSize));
__ movsd(xmm1, Operand(esp, 3 * kPointerSize));
__ addsd(xmm0, xmm1);
@@ -285,13 +280,11 @@ typedef double (*F6)(int x);
TEST(AssemblerIa328) {
CcTest::InitializeVM();
- if (!CpuFeatures::IsSupported(SSE2)) return;
Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
HandleScope scope(isolate);
v8::internal::byte buffer[256];
Assembler assm(isolate, buffer, sizeof buffer);
- CpuFeatureScope fscope(&assm, SSE2);
__ mov(eax, Operand(esp, 4));
__ cvtsi2sd(xmm0, eax);
// Copy xmm0 to st(0) using eight bytes of stack.
@@ -305,7 +298,8 @@ TEST(AssemblerIa328) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F6 f = FUNCTION_CAST<F6>(code->entry());
double res = f(12);
@@ -358,14 +352,15 @@ TEST(AssemblerIa329) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F7 f = FUNCTION_CAST<F7>(code->entry());
CHECK_EQ(kLess, f(1.1, 2.2));
CHECK_EQ(kEqual, f(2.2, 2.2));
CHECK_EQ(kGreater, f(3.3, 2.2));
- CHECK_EQ(kNaN, f(OS::nan_value(), 1.1));
+ CHECK_EQ(kNaN, f(v8::base::OS::nan_value(), 1.1));
}
@@ -462,9 +457,6 @@ void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::internal::byte buffer[256];
Assembler assm(isolate, buffer, sizeof buffer);
- ASSERT(CpuFeatures::IsSupported(SSE2));
- CpuFeatureScope fscope(&assm, SSE2);
-
// Remove return address from the stack for fix stack frame alignment.
__ pop(ecx);
@@ -500,9 +492,7 @@ void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) {
TEST(StackAlignmentForSSE2) {
CcTest::InitializeVM();
- if (!CpuFeatures::IsSupported(SSE2)) return;
-
- CHECK_EQ(0, OS::ActivationFrameAlignment() % 16);
+ CHECK_EQ(0, v8::base::OS::ActivationFrameAlignment() % 16);
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
@@ -540,15 +530,13 @@ TEST(StackAlignmentForSSE2) {
TEST(AssemblerIa32Extractps) {
CcTest::InitializeVM();
- if (!CpuFeatures::IsSupported(SSE2) ||
- !CpuFeatures::IsSupported(SSE4_1)) return;
+ if (!CpuFeatures::IsSupported(SSE4_1)) return;
Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
HandleScope scope(isolate);
v8::internal::byte buffer[256];
MacroAssembler assm(isolate, buffer, sizeof buffer);
- { CpuFeatureScope fscope2(&assm, SSE2);
- CpuFeatureScope fscope41(&assm, SSE4_1);
+ { CpuFeatureScope fscope41(&assm, SSE4_1);
__ movsd(xmm1, Operand(esp, 4));
__ extractps(eax, xmm1, 0x1);
__ ret(0);
@@ -559,7 +547,8 @@ TEST(AssemblerIa32Extractps) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F4 f = FUNCTION_CAST<F4>(code->entry());
@@ -573,14 +562,12 @@ TEST(AssemblerIa32Extractps) {
typedef int (*F8)(float x, float y);
TEST(AssemblerIa32SSE) {
CcTest::InitializeVM();
- if (!CpuFeatures::IsSupported(SSE2)) return;
Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
HandleScope scope(isolate);
v8::internal::byte buffer[256];
MacroAssembler assm(isolate, buffer, sizeof buffer);
{
- CpuFeatureScope fscope(&assm, SSE2);
__ movss(xmm0, Operand(esp, kPointerSize));
__ movss(xmm1, Operand(esp, 2 * kPointerSize));
__ shufps(xmm0, xmm0, 0x0);
@@ -599,7 +586,8 @@ TEST(AssemblerIa32SSE) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F8 f = FUNCTION_CAST<F8>(code->entry());
diff --git a/deps/v8/test/cctest/test-assembler-mips.cc b/deps/v8/test/cctest/test-assembler-mips.cc
index e93c1ca45..cd1d5d6cc 100644
--- a/deps/v8/test/cctest/test-assembler-mips.cc
+++ b/deps/v8/test/cctest/test-assembler-mips.cc
@@ -25,15 +25,15 @@
// (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 "src/v8.h"
-#include "disassembler.h"
-#include "factory.h"
-#include "macro-assembler.h"
-#include "mips/macro-assembler-mips.h"
-#include "mips/simulator-mips.h"
+#include "src/disassembler.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "src/mips/macro-assembler-mips.h"
+#include "src/mips/simulator-mips.h"
-#include "cctest.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-assembler-mips64.cc b/deps/v8/test/cctest/test-assembler-mips64.cc
new file mode 100644
index 000000000..4e9238930
--- /dev/null
+++ b/deps/v8/test/cctest/test-assembler-mips64.cc
@@ -0,0 +1,1375 @@
+// 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 "src/v8.h"
+
+#include "src/disassembler.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "src/mips64/macro-assembler-mips64.h"
+#include "src/mips64/simulator-mips64.h"
+
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+
+
+// Define these function prototypes to match JSEntryFunction in execution.cc.
+typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
+typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
+typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
+
+
+#define __ assm.
+
+
+TEST(MIPS0) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ // Addition.
+ __ addu(v0, a0, a1);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+ int64_t res =
+ reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
+ ::printf("f() = %ld\n", res);
+ CHECK_EQ(0xabcL, res);
+}
+
+
+TEST(MIPS1) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+ Label L, C;
+
+ __ mov(a1, a0);
+ __ li(v0, 0);
+ __ b(&C);
+ __ nop();
+
+ __ bind(&L);
+ __ addu(v0, v0, a1);
+ __ addiu(a1, a1, -1);
+
+ __ bind(&C);
+ __ xori(v1, a1, 0);
+ __ Branch(&L, ne, v1, Operand((int64_t)0));
+ __ nop();
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F1 f = FUNCTION_CAST<F1>(code->entry());
+ int64_t res =
+ reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 50, 0, 0, 0, 0));
+ ::printf("f() = %ld\n", res);
+ CHECK_EQ(1275L, res);
+}
+
+
+TEST(MIPS2) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label exit, error;
+
+ // ----- Test all instructions.
+
+ // Test lui, ori, and addiu, used in the li pseudo-instruction.
+ // This way we can then safely load registers with chosen values.
+
+ __ ori(a4, zero_reg, 0);
+ __ lui(a4, 0x1234);
+ __ ori(a4, a4, 0);
+ __ ori(a4, a4, 0x0f0f);
+ __ ori(a4, a4, 0xf0f0);
+ __ addiu(a5, a4, 1);
+ __ addiu(a6, a5, -0x10);
+
+ // Load values in temporary registers.
+ __ li(a4, 0x00000004);
+ __ li(a5, 0x00001234);
+ __ li(a6, 0x12345678);
+ __ li(a7, 0x7fffffff);
+ __ li(t0, 0xfffffffc);
+ __ li(t1, 0xffffedcc);
+ __ li(t2, 0xedcba988);
+ __ li(t3, 0x80000000);
+
+ // SPECIAL class.
+ __ srl(v0, a6, 8); // 0x00123456
+ __ sll(v0, v0, 11); // 0x91a2b000
+ __ sra(v0, v0, 3); // 0xf2345600
+ __ srav(v0, v0, a4); // 0xff234560
+ __ sllv(v0, v0, a4); // 0xf2345600
+ __ srlv(v0, v0, a4); // 0x0f234560
+ __ Branch(&error, ne, v0, Operand(0x0f234560));
+ __ nop();
+
+ __ addu(v0, a4, a5); // 0x00001238
+ __ subu(v0, v0, a4); // 0x00001234
+ __ Branch(&error, ne, v0, Operand(0x00001234));
+ __ nop();
+ __ addu(v1, a7, a4); // 32bit addu result is sign-extended into 64bit reg.
+ __ Branch(&error, ne, v1, Operand(0xffffffff80000003));
+ __ nop();
+ __ subu(v1, t3, a4); // 0x7ffffffc
+ __ Branch(&error, ne, v1, Operand(0x7ffffffc));
+ __ nop();
+
+ __ and_(v0, a5, a6); // 0x0000000000001230
+ __ or_(v0, v0, a5); // 0x0000000000001234
+ __ xor_(v0, v0, a6); // 0x000000001234444c
+ __ nor(v0, v0, a6); // 0xffffffffedcba987
+ __ Branch(&error, ne, v0, Operand(0xffffffffedcba983));
+ __ nop();
+
+ // Shift both 32bit number to left, to preserve meaning of next comparison.
+ __ dsll32(a7, a7, 0);
+ __ dsll32(t3, t3, 0);
+
+ __ slt(v0, t3, a7);
+ __ Branch(&error, ne, v0, Operand(0x1));
+ __ nop();
+ __ sltu(v0, t3, a7);
+ __ Branch(&error, ne, v0, Operand(zero_reg));
+ __ nop();
+
+ // Restore original values in registers.
+ __ dsrl32(a7, a7, 0);
+ __ dsrl32(t3, t3, 0);
+ // End of SPECIAL class.
+
+ __ addiu(v0, zero_reg, 0x7421); // 0x00007421
+ __ addiu(v0, v0, -0x1); // 0x00007420
+ __ addiu(v0, v0, -0x20); // 0x00007400
+ __ Branch(&error, ne, v0, Operand(0x00007400));
+ __ nop();
+ __ addiu(v1, a7, 0x1); // 0x80000000 - result is sign-extended.
+ __ Branch(&error, ne, v1, Operand(0xffffffff80000000));
+ __ nop();
+
+ __ slti(v0, a5, 0x00002000); // 0x1
+ __ slti(v0, v0, 0xffff8000); // 0x0
+ __ Branch(&error, ne, v0, Operand(zero_reg));
+ __ nop();
+ __ sltiu(v0, a5, 0x00002000); // 0x1
+ __ sltiu(v0, v0, 0x00008000); // 0x1
+ __ Branch(&error, ne, v0, Operand(0x1));
+ __ nop();
+
+ __ andi(v0, a5, 0xf0f0); // 0x00001030
+ __ ori(v0, v0, 0x8a00); // 0x00009a30
+ __ xori(v0, v0, 0x83cc); // 0x000019fc
+ __ Branch(&error, ne, v0, Operand(0x000019fc));
+ __ nop();
+ __ lui(v1, 0x8123); // Result is sign-extended into 64bit register.
+ __ Branch(&error, ne, v1, Operand(0xffffffff81230000));
+ __ nop();
+
+ // Bit twiddling instructions & conditional moves.
+ // Uses a4-t3 as set above.
+ __ Clz(v0, a4); // 29
+ __ Clz(v1, a5); // 19
+ __ addu(v0, v0, v1); // 48
+ __ Clz(v1, a6); // 3
+ __ addu(v0, v0, v1); // 51
+ __ Clz(v1, t3); // 0
+ __ addu(v0, v0, v1); // 51
+ __ Branch(&error, ne, v0, Operand(51));
+ __ Movn(a0, a7, a4); // Move a0<-a7 (a4 is NOT 0).
+ __ Ins(a0, a5, 12, 8); // 0x7ff34fff
+ __ Branch(&error, ne, a0, Operand(0x7ff34fff));
+ __ Movz(a0, t2, t3); // a0 not updated (t3 is NOT 0).
+ __ Ext(a1, a0, 8, 12); // 0x34f
+ __ Branch(&error, ne, a1, Operand(0x34f));
+ __ Movz(a0, t2, v1); // a0<-t2, v0 is 0, from 8 instr back.
+ __ Branch(&error, ne, a0, Operand(t2));
+
+ // Everything was correctly executed. Load the expected result.
+ __ li(v0, 0x31415926);
+ __ b(&exit);
+ __ nop();
+
+ __ bind(&error);
+ // Got an error. Return a wrong result.
+ __ li(v0, 666);
+
+ __ bind(&exit);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+ int64_t res =
+ reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
+ ::printf("f() = %ld\n", res);
+
+ CHECK_EQ(0x31415926L, res);
+}
+
+
+TEST(MIPS3) {
+ // Test floating point instructions.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+ double i;
+ } T;
+ T t;
+
+ // Create a function that accepts &t, and loads, manipulates, and stores
+ // the doubles t.a ... t.f.
+ MacroAssembler assm(isolate, NULL, 0);
+ Label L, C;
+
+ __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
+ __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ add_d(f8, f4, f6);
+ __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, c)) ); // c = a + b.
+
+ __ mov_d(f10, f8); // c
+ __ neg_d(f12, f6); // -b
+ __ sub_d(f10, f10, f12);
+ __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, d)) ); // d = c - (-b).
+
+ __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, b)) ); // b = a.
+
+ __ li(a4, 120);
+ __ mtc1(a4, f14);
+ __ cvt_d_w(f14, f14); // f14 = 120.0.
+ __ mul_d(f10, f10, f14);
+ __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, e)) ); // e = d * 120 = 1.8066e16.
+
+ __ div_d(f12, f10, f4);
+ __ sdc1(f12, MemOperand(a0, OFFSET_OF(T, f)) ); // f = e / a = 120.44.
+
+ __ sqrt_d(f14, f12);
+ __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, g)) );
+ // g = sqrt(f) = 10.97451593465515908537
+
+ if (kArchVariant == kMips64r2) {
+ __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, h)) );
+ __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, i)) );
+ __ madd_d(f14, f6, f4, f6);
+ __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, h)) );
+ }
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ t.a = 1.5e14;
+ t.b = 2.75e11;
+ t.c = 0.0;
+ t.d = 0.0;
+ t.e = 0.0;
+ t.f = 0.0;
+ t.h = 1.5;
+ t.i = 2.75;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+ CHECK_EQ(1.5e14, t.a);
+ CHECK_EQ(1.5e14, t.b);
+ CHECK_EQ(1.50275e14, t.c);
+ CHECK_EQ(1.50550e14, t.d);
+ CHECK_EQ(1.8066e16, t.e);
+ CHECK_EQ(120.44, t.f);
+ CHECK_EQ(10.97451593465515908537, t.g);
+ if (kArchVariant == kMips64r2) {
+ CHECK_EQ(6.875, t.h);
+ }
+}
+
+
+TEST(MIPS4) {
+ // Test moves between floating point and integer registers.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ double a;
+ double b;
+ double c;
+ } T;
+ T t;
+
+ Assembler assm(isolate, NULL, 0);
+ Label L, C;
+
+ __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
+ __ ldc1(f5, MemOperand(a0, OFFSET_OF(T, b)) );
+
+ // Swap f4 and f5, by using 3 integer registers, a4-a6,
+ // both two 32-bit chunks, and one 64-bit chunk.
+ // mXhc1 is mips32/64-r2 only, not r1,
+ // but we will not support r1 in practice.
+ __ mfc1(a4, f4);
+ __ mfhc1(a5, f4);
+ __ dmfc1(a6, f5);
+
+ __ mtc1(a4, f5);
+ __ mthc1(a5, f5);
+ __ dmtc1(a6, f4);
+
+ // Store the swapped f4 and f5 back to memory.
+ __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
+ __ sdc1(f5, MemOperand(a0, OFFSET_OF(T, c)) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ t.a = 1.5e22;
+ t.b = 2.75e11;
+ t.c = 17.17;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(2.75e11, t.a);
+ CHECK_EQ(2.75e11, t.b);
+ CHECK_EQ(1.5e22, t.c);
+}
+
+
+TEST(MIPS5) {
+ // Test conversions between doubles and integers.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ double a;
+ double b;
+ int i;
+ int j;
+ } T;
+ T t;
+
+ Assembler assm(isolate, NULL, 0);
+ Label L, C;
+
+ // Load all structure elements to registers.
+ __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
+ __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ lw(a4, MemOperand(a0, OFFSET_OF(T, i)) );
+ __ lw(a5, MemOperand(a0, OFFSET_OF(T, j)) );
+
+ // Convert double in f4 to int in element i.
+ __ cvt_w_d(f8, f4);
+ __ mfc1(a6, f8);
+ __ sw(a6, MemOperand(a0, OFFSET_OF(T, i)) );
+
+ // Convert double in f6 to int in element j.
+ __ cvt_w_d(f10, f6);
+ __ mfc1(a7, f10);
+ __ sw(a7, MemOperand(a0, OFFSET_OF(T, j)) );
+
+ // Convert int in original i (a4) to double in a.
+ __ mtc1(a4, f12);
+ __ cvt_d_w(f0, f12);
+ __ sdc1(f0, MemOperand(a0, OFFSET_OF(T, a)) );
+
+ // Convert int in original j (a5) to double in b.
+ __ mtc1(a5, f14);
+ __ cvt_d_w(f2, f14);
+ __ sdc1(f2, MemOperand(a0, OFFSET_OF(T, b)) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ t.a = 1.5e4;
+ t.b = 2.75e8;
+ t.i = 12345678;
+ t.j = -100000;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(12345678.0, t.a);
+ CHECK_EQ(-100000.0, t.b);
+ CHECK_EQ(15000, t.i);
+ CHECK_EQ(275000000, t.j);
+}
+
+
+TEST(MIPS6) {
+ // Test simple memory loads and stores.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ uint32_t ui;
+ int32_t si;
+ int32_t r1;
+ int32_t r2;
+ int32_t r3;
+ int32_t r4;
+ int32_t r5;
+ int32_t r6;
+ } T;
+ T t;
+
+ Assembler assm(isolate, NULL, 0);
+ Label L, C;
+
+ // Basic word load/store.
+ __ lw(a4, MemOperand(a0, OFFSET_OF(T, ui)) );
+ __ sw(a4, MemOperand(a0, OFFSET_OF(T, r1)) );
+
+ // lh with positive data.
+ __ lh(a5, MemOperand(a0, OFFSET_OF(T, ui)) );
+ __ sw(a5, MemOperand(a0, OFFSET_OF(T, r2)) );
+
+ // lh with negative data.
+ __ lh(a6, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sw(a6, MemOperand(a0, OFFSET_OF(T, r3)) );
+
+ // lhu with negative data.
+ __ lhu(a7, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sw(a7, MemOperand(a0, OFFSET_OF(T, r4)) );
+
+ // lb with negative data.
+ __ lb(t0, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, r5)) );
+
+ // sh writes only 1/2 of word.
+ __ lui(t1, 0x3333);
+ __ ori(t1, t1, 0x3333);
+ __ sw(t1, MemOperand(a0, OFFSET_OF(T, r6)) );
+ __ lhu(t1, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sh(t1, MemOperand(a0, OFFSET_OF(T, r6)) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ t.ui = 0x11223344;
+ t.si = 0x99aabbcc;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(0x11223344, t.r1);
+ CHECK_EQ(0x3344, t.r2);
+ CHECK_EQ(0xffffbbcc, t.r3);
+ CHECK_EQ(0x0000bbcc, t.r4);
+ CHECK_EQ(0xffffffcc, t.r5);
+ CHECK_EQ(0x3333bbcc, t.r6);
+}
+
+
+TEST(MIPS7) {
+ // Test floating point compare and branch instructions.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ int32_t result;
+ } T;
+ T t;
+
+ // Create a function that accepts &t, and loads, manipulates, and stores
+ // the doubles t.a ... t.f.
+ MacroAssembler assm(isolate, NULL, 0);
+ Label neither_is_nan, less_than, outa_here;
+
+ __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
+ __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ if (kArchVariant != kMips64r6) {
+ __ c(UN, D, f4, f6);
+ __ bc1f(&neither_is_nan);
+ } else {
+ __ cmp(UN, L, f2, f4, f6);
+ __ bc1eqz(&neither_is_nan, f2);
+ }
+ __ nop();
+ __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
+ __ Branch(&outa_here);
+
+ __ bind(&neither_is_nan);
+
+ if (kArchVariant == kMips64r6) {
+ __ cmp(OLT, L, f2, f6, f4);
+ __ bc1nez(&less_than, f2);
+ } else {
+ __ c(OLT, D, f6, f4, 2);
+ __ bc1t(&less_than, 2);
+ }
+
+ __ nop();
+ __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
+ __ Branch(&outa_here);
+
+ __ bind(&less_than);
+ __ Addu(a4, zero_reg, Operand(1));
+ __ sw(a4, MemOperand(a0, OFFSET_OF(T, result)) ); // Set true.
+
+
+ // This test-case should have additional tests.
+
+ __ bind(&outa_here);
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ t.a = 1.5e14;
+ t.b = 2.75e11;
+ t.c = 2.0;
+ t.d = -4.0;
+ t.e = 0.0;
+ t.f = 0.0;
+ t.result = 0;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+ CHECK_EQ(1.5e14, t.a);
+ CHECK_EQ(2.75e11, t.b);
+ CHECK_EQ(1, t.result);
+}
+
+
+TEST(MIPS8) {
+ // Test ROTR and ROTRV instructions.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ int32_t input;
+ int32_t result_rotr_4;
+ int32_t result_rotr_8;
+ int32_t result_rotr_12;
+ int32_t result_rotr_16;
+ int32_t result_rotr_20;
+ int32_t result_rotr_24;
+ int32_t result_rotr_28;
+ int32_t result_rotrv_4;
+ int32_t result_rotrv_8;
+ int32_t result_rotrv_12;
+ int32_t result_rotrv_16;
+ int32_t result_rotrv_20;
+ int32_t result_rotrv_24;
+ int32_t result_rotrv_28;
+ } T;
+ T t;
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ // Basic word load.
+ __ lw(a4, MemOperand(a0, OFFSET_OF(T, input)) );
+
+ // ROTR instruction (called through the Ror macro).
+ __ Ror(a5, a4, 0x0004);
+ __ Ror(a6, a4, 0x0008);
+ __ Ror(a7, a4, 0x000c);
+ __ Ror(t0, a4, 0x0010);
+ __ Ror(t1, a4, 0x0014);
+ __ Ror(t2, a4, 0x0018);
+ __ Ror(t3, a4, 0x001c);
+
+ // Basic word store.
+ __ sw(a5, MemOperand(a0, OFFSET_OF(T, result_rotr_4)) );
+ __ sw(a6, MemOperand(a0, OFFSET_OF(T, result_rotr_8)) );
+ __ sw(a7, MemOperand(a0, OFFSET_OF(T, result_rotr_12)) );
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, result_rotr_16)) );
+ __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotr_20)) );
+ __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotr_24)) );
+ __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotr_28)) );
+
+ // ROTRV instruction (called through the Ror macro).
+ __ li(t3, 0x0004);
+ __ Ror(a5, a4, t3);
+ __ li(t3, 0x0008);
+ __ Ror(a6, a4, t3);
+ __ li(t3, 0x000C);
+ __ Ror(a7, a4, t3);
+ __ li(t3, 0x0010);
+ __ Ror(t0, a4, t3);
+ __ li(t3, 0x0014);
+ __ Ror(t1, a4, t3);
+ __ li(t3, 0x0018);
+ __ Ror(t2, a4, t3);
+ __ li(t3, 0x001C);
+ __ Ror(t3, a4, t3);
+
+ // Basic word store.
+ __ sw(a5, MemOperand(a0, OFFSET_OF(T, result_rotrv_4)) );
+ __ sw(a6, MemOperand(a0, OFFSET_OF(T, result_rotrv_8)) );
+ __ sw(a7, MemOperand(a0, OFFSET_OF(T, result_rotrv_12)) );
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, result_rotrv_16)) );
+ __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotrv_20)) );
+ __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotrv_24)) );
+ __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotrv_28)) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ t.input = 0x12345678;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0x0, 0, 0, 0);
+ USE(dummy);
+ CHECK_EQ(0x81234567, t.result_rotr_4);
+ CHECK_EQ(0x78123456, t.result_rotr_8);
+ CHECK_EQ(0x67812345, t.result_rotr_12);
+ CHECK_EQ(0x56781234, t.result_rotr_16);
+ CHECK_EQ(0x45678123, t.result_rotr_20);
+ CHECK_EQ(0x34567812, t.result_rotr_24);
+ CHECK_EQ(0x23456781, t.result_rotr_28);
+
+ CHECK_EQ(0x81234567, t.result_rotrv_4);
+ CHECK_EQ(0x78123456, t.result_rotrv_8);
+ CHECK_EQ(0x67812345, t.result_rotrv_12);
+ CHECK_EQ(0x56781234, t.result_rotrv_16);
+ CHECK_EQ(0x45678123, t.result_rotrv_20);
+ CHECK_EQ(0x34567812, t.result_rotrv_24);
+ CHECK_EQ(0x23456781, t.result_rotrv_28);
+}
+
+
+TEST(MIPS9) {
+ // Test BRANCH improvements.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+ Label exit, exit2, exit3;
+
+ __ Branch(&exit, ge, a0, Operand(zero_reg));
+ __ Branch(&exit2, ge, a0, Operand(0x00001FFF));
+ __ Branch(&exit3, ge, a0, Operand(0x0001FFFF));
+
+ __ bind(&exit);
+ __ bind(&exit2);
+ __ bind(&exit3);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+}
+
+
+TEST(MIPS10) {
+ // Test conversions between doubles and long integers.
+ // Test hos the long ints map to FP regs pairs.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ double a;
+ double a_converted;
+ double b;
+ int32_t dbl_mant;
+ int32_t dbl_exp;
+ int32_t long_hi;
+ int32_t long_lo;
+ int64_t long_as_int64;
+ int32_t b_long_hi;
+ int32_t b_long_lo;
+ int64_t b_long_as_int64;
+ } T;
+ T t;
+
+ Assembler assm(isolate, NULL, 0);
+ Label L, C;
+
+ if (kArchVariant == kMips64r2) {
+ // Rewritten for FR=1 FPU mode:
+ // - 32 FP regs of 64-bits each, no odd/even pairs.
+ // - Note that cvt_l_d/cvt_d_l ARE legal in FR=1 mode.
+ // Load all structure elements to registers.
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, a)));
+
+ // Save the raw bits of the double.
+ __ mfc1(a4, f0);
+ __ mfhc1(a5, f0);
+ __ sw(a4, MemOperand(a0, OFFSET_OF(T, dbl_mant)));
+ __ sw(a5, MemOperand(a0, OFFSET_OF(T, dbl_exp)));
+
+ // Convert double in f0 to long, save hi/lo parts.
+ __ cvt_l_d(f0, f0);
+ __ mfc1(a4, f0); // f0 LS 32 bits of long.
+ __ mfhc1(a5, f0); // f0 MS 32 bits of long.
+ __ sw(a4, MemOperand(a0, OFFSET_OF(T, long_lo)));
+ __ sw(a5, MemOperand(a0, OFFSET_OF(T, long_hi)));
+
+ // Combine the high/low ints, convert back to double.
+ __ dsll32(a6, a5, 0); // Move a5 to high bits of a6.
+ __ or_(a6, a6, a4);
+ __ dmtc1(a6, f1);
+ __ cvt_d_l(f1, f1);
+ __ sdc1(f1, MemOperand(a0, OFFSET_OF(T, a_converted)));
+
+
+ // Convert the b long integers to double b.
+ __ lw(a4, MemOperand(a0, OFFSET_OF(T, b_long_lo)));
+ __ lw(a5, MemOperand(a0, OFFSET_OF(T, b_long_hi)));
+ __ mtc1(a4, f8); // f8 LS 32-bits.
+ __ mthc1(a5, f8); // f8 MS 32-bits.
+ __ cvt_d_l(f10, f8);
+ __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, b)));
+
+ // Convert double b back to long-int.
+ __ ldc1(f31, MemOperand(a0, OFFSET_OF(T, b)));
+ __ cvt_l_d(f31, f31);
+ __ dmfc1(a7, f31);
+ __ sd(a7, MemOperand(a0, OFFSET_OF(T, b_long_as_int64)));
+
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ t.a = 2.147483647e9; // 0x7fffffff -> 0x41DFFFFFFFC00000 as double.
+ t.b_long_hi = 0x000000ff; // 0xFF00FF00FF -> 0x426FE01FE01FE000 as double.
+ t.b_long_lo = 0x00ff00ff;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(0x41DFFFFF, t.dbl_exp);
+ CHECK_EQ(0xFFC00000, t.dbl_mant);
+ CHECK_EQ(0, t.long_hi);
+ CHECK_EQ(0x7fffffff, t.long_lo);
+ CHECK_EQ(2.147483647e9, t.a_converted);
+
+ // 0xFF00FF00FF -> 1.095233372415e12.
+ CHECK_EQ(1.095233372415e12, t.b);
+ CHECK_EQ(0xFF00FF00FF, t.b_long_as_int64);
+ }
+}
+
+
+TEST(MIPS11) {
+ // Do not run test on MIPS64r6, as these instructions are removed.
+ if (kArchVariant != kMips64r6) {
+ // Test LWL, LWR, SWL and SWR instructions.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ int32_t reg_init;
+ int32_t mem_init;
+ int32_t lwl_0;
+ int32_t lwl_1;
+ int32_t lwl_2;
+ int32_t lwl_3;
+ int32_t lwr_0;
+ int32_t lwr_1;
+ int32_t lwr_2;
+ int32_t lwr_3;
+ int32_t swl_0;
+ int32_t swl_1;
+ int32_t swl_2;
+ int32_t swl_3;
+ int32_t swr_0;
+ int32_t swr_1;
+ int32_t swr_2;
+ int32_t swr_3;
+ } T;
+ T t;
+
+ Assembler assm(isolate, NULL, 0);
+
+ // Test all combinations of LWL and vAddr.
+ __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwl(a4, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(a4, MemOperand(a0, OFFSET_OF(T, lwl_0)) );
+
+ __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwl(a5, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) );
+ __ sw(a5, MemOperand(a0, OFFSET_OF(T, lwl_1)) );
+
+ __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwl(a6, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) );
+ __ sw(a6, MemOperand(a0, OFFSET_OF(T, lwl_2)) );
+
+ __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwl(a7, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) );
+ __ sw(a7, MemOperand(a0, OFFSET_OF(T, lwl_3)) );
+
+ // Test all combinations of LWR and vAddr.
+ __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwr(a4, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(a4, MemOperand(a0, OFFSET_OF(T, lwr_0)) );
+
+ __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwr(a5, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) );
+ __ sw(a5, MemOperand(a0, OFFSET_OF(T, lwr_1)) );
+
+ __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwr(a6, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) );
+ __ sw(a6, MemOperand(a0, OFFSET_OF(T, lwr_2)) );
+
+ __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwr(a7, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) );
+ __ sw(a7, MemOperand(a0, OFFSET_OF(T, lwr_3)) );
+
+ // Test all combinations of SWL and vAddr.
+ __ lw(a4, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(a4, MemOperand(a0, OFFSET_OF(T, swl_0)) );
+ __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swl(a4, MemOperand(a0, OFFSET_OF(T, swl_0)) );
+
+ __ lw(a5, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(a5, MemOperand(a0, OFFSET_OF(T, swl_1)) );
+ __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swl(a5, MemOperand(a0, OFFSET_OF(T, swl_1) + 1) );
+
+ __ lw(a6, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(a6, MemOperand(a0, OFFSET_OF(T, swl_2)) );
+ __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swl(a6, MemOperand(a0, OFFSET_OF(T, swl_2) + 2) );
+
+ __ lw(a7, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(a7, MemOperand(a0, OFFSET_OF(T, swl_3)) );
+ __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swl(a7, MemOperand(a0, OFFSET_OF(T, swl_3) + 3) );
+
+ // Test all combinations of SWR and vAddr.
+ __ lw(a4, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(a4, MemOperand(a0, OFFSET_OF(T, swr_0)) );
+ __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swr(a4, MemOperand(a0, OFFSET_OF(T, swr_0)) );
+
+ __ lw(a5, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(a5, MemOperand(a0, OFFSET_OF(T, swr_1)) );
+ __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swr(a5, MemOperand(a0, OFFSET_OF(T, swr_1) + 1) );
+
+ __ lw(a6, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(a6, MemOperand(a0, OFFSET_OF(T, swr_2)) );
+ __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swr(a6, MemOperand(a0, OFFSET_OF(T, swr_2) + 2) );
+
+ __ lw(a7, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(a7, MemOperand(a0, OFFSET_OF(T, swr_3)) );
+ __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swr(a7, MemOperand(a0, OFFSET_OF(T, swr_3) + 3) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ t.reg_init = 0xaabbccdd;
+ t.mem_init = 0x11223344;
+
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(0x44bbccdd, t.lwl_0);
+ CHECK_EQ(0x3344ccdd, t.lwl_1);
+ CHECK_EQ(0x223344dd, t.lwl_2);
+ CHECK_EQ(0x11223344, t.lwl_3);
+
+ CHECK_EQ(0x11223344, t.lwr_0);
+ CHECK_EQ(0xaa112233, t.lwr_1);
+ CHECK_EQ(0xaabb1122, t.lwr_2);
+ CHECK_EQ(0xaabbcc11, t.lwr_3);
+
+ CHECK_EQ(0x112233aa, t.swl_0);
+ CHECK_EQ(0x1122aabb, t.swl_1);
+ CHECK_EQ(0x11aabbcc, t.swl_2);
+ CHECK_EQ(0xaabbccdd, t.swl_3);
+
+ CHECK_EQ(0xaabbccdd, t.swr_0);
+ CHECK_EQ(0xbbccdd44, t.swr_1);
+ CHECK_EQ(0xccdd3344, t.swr_2);
+ CHECK_EQ(0xdd223344, t.swr_3);
+ }
+}
+
+
+TEST(MIPS12) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ int32_t x;
+ int32_t y;
+ int32_t y1;
+ int32_t y2;
+ int32_t y3;
+ int32_t y4;
+ } T;
+ T t;
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ mov(t2, fp); // Save frame pointer.
+ __ mov(fp, a0); // Access struct T by fp.
+ __ lw(a4, MemOperand(a0, OFFSET_OF(T, y)) );
+ __ lw(a7, MemOperand(a0, OFFSET_OF(T, y4)) );
+
+ __ addu(a5, a4, a7);
+ __ subu(t0, a4, a7);
+ __ nop();
+ __ push(a4); // These instructions disappear after opt.
+ __ Pop();
+ __ addu(a4, a4, a4);
+ __ nop();
+ __ Pop(); // These instructions disappear after opt.
+ __ push(a7);
+ __ nop();
+ __ push(a7); // These instructions disappear after opt.
+ __ pop(a7);
+ __ nop();
+ __ push(a7);
+ __ pop(t0);
+ __ nop();
+ __ sw(a4, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(a4, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ nop();
+ __ sw(a4, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(a5, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ nop();
+ __ push(a5);
+ __ lw(a5, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ pop(a5);
+ __ nop();
+ __ push(a5);
+ __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ pop(a5);
+ __ nop();
+ __ push(a5);
+ __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ pop(a6);
+ __ nop();
+ __ push(a6);
+ __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ pop(a5);
+ __ nop();
+ __ push(a5);
+ __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ pop(a7);
+ __ nop();
+
+ __ mov(fp, t2);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ t.x = 1;
+ t.y = 2;
+ t.y1 = 3;
+ t.y2 = 4;
+ t.y3 = 0XBABA;
+ t.y4 = 0xDEDA;
+
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(3, t.y1);
+}
+
+
+TEST(MIPS13) {
+ // Test Cvt_d_uw and Trunc_uw_d macros.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ double cvt_big_out;
+ double cvt_small_out;
+ uint32_t trunc_big_out;
+ uint32_t trunc_small_out;
+ uint32_t cvt_big_in;
+ uint32_t cvt_small_in;
+ } T;
+ T t;
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ sw(a4, MemOperand(a0, OFFSET_OF(T, cvt_small_in)));
+ __ Cvt_d_uw(f10, a4, f22);
+ __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out)));
+
+ __ Trunc_uw_d(f10, f10, f22);
+ __ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out)));
+
+ __ sw(a4, MemOperand(a0, OFFSET_OF(T, cvt_big_in)));
+ __ Cvt_d_uw(f8, a4, f22);
+ __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out)));
+
+ __ Trunc_uw_d(f8, f8, f22);
+ __ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out)));
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ t.cvt_big_in = 0xFFFFFFFF;
+ t.cvt_small_in = 333;
+
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(t.cvt_big_out, static_cast<double>(t.cvt_big_in));
+ CHECK_EQ(t.cvt_small_out, static_cast<double>(t.cvt_small_in));
+
+ CHECK_EQ(static_cast<int>(t.trunc_big_out), static_cast<int>(t.cvt_big_in));
+ CHECK_EQ(static_cast<int>(t.trunc_small_out),
+ static_cast<int>(t.cvt_small_in));
+}
+
+
+TEST(MIPS14) {
+ // Test round, floor, ceil, trunc, cvt.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+#define ROUND_STRUCT_ELEMENT(x) \
+ int32_t x##_up_out; \
+ int32_t x##_down_out; \
+ int32_t neg_##x##_up_out; \
+ int32_t neg_##x##_down_out; \
+ uint32_t x##_err1_out; \
+ uint32_t x##_err2_out; \
+ uint32_t x##_err3_out; \
+ uint32_t x##_err4_out; \
+ int32_t x##_invalid_result;
+
+ typedef struct {
+ double round_up_in;
+ double round_down_in;
+ double neg_round_up_in;
+ double neg_round_down_in;
+ double err1_in;
+ double err2_in;
+ double err3_in;
+ double err4_in;
+
+ ROUND_STRUCT_ELEMENT(round)
+ ROUND_STRUCT_ELEMENT(floor)
+ ROUND_STRUCT_ELEMENT(ceil)
+ ROUND_STRUCT_ELEMENT(trunc)
+ ROUND_STRUCT_ELEMENT(cvt)
+ } T;
+ T t;
+
+#undef ROUND_STRUCT_ELEMENT
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ // Save FCSR.
+ __ cfc1(a1, FCSR);
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+#define RUN_ROUND_TEST(x) \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_up_in))); \
+ __ x##_w_d(f0, f0); \
+ __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_up_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_down_in))); \
+ __ x##_w_d(f0, f0); \
+ __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_down_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_up_in))); \
+ __ x##_w_d(f0, f0); \
+ __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_up_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_down_in))); \
+ __ x##_w_d(f0, f0); \
+ __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_down_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err1_in))); \
+ __ ctc1(zero_reg, FCSR); \
+ __ x##_w_d(f0, f0); \
+ __ cfc1(a2, FCSR); \
+ __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err1_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err2_in))); \
+ __ ctc1(zero_reg, FCSR); \
+ __ x##_w_d(f0, f0); \
+ __ cfc1(a2, FCSR); \
+ __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err2_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err3_in))); \
+ __ ctc1(zero_reg, FCSR); \
+ __ x##_w_d(f0, f0); \
+ __ cfc1(a2, FCSR); \
+ __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err3_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err4_in))); \
+ __ ctc1(zero_reg, FCSR); \
+ __ x##_w_d(f0, f0); \
+ __ cfc1(a2, FCSR); \
+ __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err4_out))); \
+ __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_invalid_result)));
+
+ RUN_ROUND_TEST(round)
+ RUN_ROUND_TEST(floor)
+ RUN_ROUND_TEST(ceil)
+ RUN_ROUND_TEST(trunc)
+ RUN_ROUND_TEST(cvt)
+
+ // Restore FCSR.
+ __ ctc1(a1, FCSR);
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ t.round_up_in = 123.51;
+ t.round_down_in = 123.49;
+ t.neg_round_up_in = -123.5;
+ t.neg_round_down_in = -123.49;
+ t.err1_in = 123.51;
+ t.err2_in = 1;
+ t.err3_in = static_cast<double>(1) + 0xFFFFFFFF;
+ t.err4_in = NAN;
+
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+#define GET_FPU_ERR(x) (static_cast<int>(x & kFCSRFlagMask))
+#define CHECK_ROUND_RESULT(type) \
+ CHECK(GET_FPU_ERR(t.type##_err1_out) & kFCSRInexactFlagMask); \
+ CHECK_EQ(0, GET_FPU_ERR(t.type##_err2_out)); \
+ CHECK(GET_FPU_ERR(t.type##_err3_out) & kFCSRInvalidOpFlagMask); \
+ CHECK(GET_FPU_ERR(t.type##_err4_out) & kFCSRInvalidOpFlagMask); \
+ CHECK_EQ(static_cast<int32_t>(kFPUInvalidResult), t.type##_invalid_result);
+
+ CHECK_ROUND_RESULT(round);
+ CHECK_ROUND_RESULT(floor);
+ CHECK_ROUND_RESULT(ceil);
+ CHECK_ROUND_RESULT(cvt);
+}
+
+
+TEST(MIPS15) {
+ // Test chaining of label usages within instructions (issue 1644).
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ Assembler assm(isolate, NULL, 0);
+
+ Label target;
+ __ beq(v0, v1, &target);
+ __ nop();
+ __ bne(v0, v1, &target);
+ __ nop();
+ __ bind(&target);
+ __ nop();
+}
+
+
+// ----- mips64 tests -----------------------------------------------
+
+TEST(MIPS16) {
+ // Test 64-bit memory loads and stores.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ int64_t r1;
+ int64_t r2;
+ int64_t r3;
+ int64_t r4;
+ int64_t r5;
+ int64_t r6;
+ uint32_t ui;
+ int32_t si;
+ } T;
+ T t;
+
+ Assembler assm(isolate, NULL, 0);
+ Label L, C;
+
+ // Basic 32-bit word load/store, with un-signed data.
+ __ lw(a4, MemOperand(a0, OFFSET_OF(T, ui)) );
+ __ sw(a4, MemOperand(a0, OFFSET_OF(T, r1)) );
+
+ // Check that the data got zero-extended into 64-bit a4.
+ __ sd(a4, MemOperand(a0, OFFSET_OF(T, r2)) );
+
+ // Basic 32-bit word load/store, with SIGNED data.
+ __ lw(a5, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sw(a5, MemOperand(a0, OFFSET_OF(T, r3)) );
+
+ // Check that the data got sign-extended into 64-bit a4.
+ __ sd(a5, MemOperand(a0, OFFSET_OF(T, r4)) );
+
+ // 32-bit UNSIGNED word load/store, with SIGNED data.
+ __ lwu(a6, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sw(a6, MemOperand(a0, OFFSET_OF(T, r5)) );
+
+ // Check that the data got zero-extended into 64-bit a4.
+ __ sd(a6, MemOperand(a0, OFFSET_OF(T, r6)) );
+
+ // lh with positive data.
+ __ lh(a5, MemOperand(a0, OFFSET_OF(T, ui)) );
+ __ sw(a5, MemOperand(a0, OFFSET_OF(T, r2)) );
+
+ // lh with negative data.
+ __ lh(a6, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sw(a6, MemOperand(a0, OFFSET_OF(T, r3)) );
+
+ // lhu with negative data.
+ __ lhu(a7, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sw(a7, MemOperand(a0, OFFSET_OF(T, r4)) );
+
+ // lb with negative data.
+ __ lb(t0, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, r5)) );
+
+ // // sh writes only 1/2 of word.
+ __ lui(t1, 0x3333);
+ __ ori(t1, t1, 0x3333);
+ __ sw(t1, MemOperand(a0, OFFSET_OF(T, r6)) );
+ __ lhu(t1, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sh(t1, MemOperand(a0, OFFSET_OF(T, r6)) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ t.ui = 0x44332211;
+ t.si = 0x99aabbcc;
+ t.r1 = 0x1111111111111111;
+ t.r2 = 0x2222222222222222;
+ t.r3 = 0x3333333333333333;
+ t.r4 = 0x4444444444444444;
+ t.r5 = 0x5555555555555555;
+ t.r6 = 0x6666666666666666;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ // Unsigned data, 32 & 64.
+ CHECK_EQ(0x1111111144332211L, t.r1);
+ CHECK_EQ(0x0000000000002211L, t.r2);
+
+ // Signed data, 32 & 64.
+ CHECK_EQ(0x33333333ffffbbccL, t.r3);
+ CHECK_EQ(0xffffffff0000bbccL, t.r4);
+
+ // Signed data, 32 & 64.
+ CHECK_EQ(0x55555555ffffffccL, t.r5);
+ CHECK_EQ(0x000000003333bbccL, t.r6);
+}
+
+#undef __
diff --git a/deps/v8/test/cctest/test-assembler-x64.cc b/deps/v8/test/cctest/test-assembler-x64.cc
index eb9fee854..3d305b650 100644
--- a/deps/v8/test/cctest/test-assembler-x64.cc
+++ b/deps/v8/test/cctest/test-assembler-x64.cc
@@ -27,13 +27,14 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "macro-assembler.h"
-#include "factory.h"
-#include "platform.h"
-#include "serialize.h"
-#include "cctest.h"
+#include "src/base/platform/platform.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "src/ostreams.h"
+#include "src/serialize.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -66,11 +67,11 @@ static const Register arg2 = rsi;
TEST(AssemblerX64ReturnOperation) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
@@ -88,11 +89,11 @@ TEST(AssemblerX64ReturnOperation) {
TEST(AssemblerX64StackOperations) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
@@ -120,11 +121,11 @@ TEST(AssemblerX64StackOperations) {
TEST(AssemblerX64ArithmeticOperations) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
@@ -142,11 +143,11 @@ TEST(AssemblerX64ArithmeticOperations) {
TEST(AssemblerX64CmpbOperation) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
@@ -173,11 +174,11 @@ TEST(AssemblerX64CmpbOperation) {
TEST(AssemblerX64ImulOperation) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
@@ -201,11 +202,11 @@ TEST(AssemblerX64ImulOperation) {
TEST(AssemblerX64XchglOperations) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
@@ -229,11 +230,11 @@ TEST(AssemblerX64XchglOperations) {
TEST(AssemblerX64OrlOperations) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
@@ -253,11 +254,11 @@ TEST(AssemblerX64OrlOperations) {
TEST(AssemblerX64RollOperations) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
@@ -275,11 +276,11 @@ TEST(AssemblerX64RollOperations) {
TEST(AssemblerX64SublOperations) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
@@ -299,11 +300,11 @@ TEST(AssemblerX64SublOperations) {
TEST(AssemblerX64TestlOperations) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
@@ -328,11 +329,11 @@ TEST(AssemblerX64TestlOperations) {
TEST(AssemblerX64XorlOperations) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
@@ -352,11 +353,11 @@ TEST(AssemblerX64XorlOperations) {
TEST(AssemblerX64MemoryOperands) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
@@ -386,11 +387,11 @@ TEST(AssemblerX64MemoryOperands) {
TEST(AssemblerX64ControlFlow) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
@@ -415,11 +416,11 @@ TEST(AssemblerX64ControlFlow) {
TEST(AssemblerX64LoopImmediates) {
+ CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
// Assemble two loops using rax as counter, and verify the ending counts.
@@ -635,7 +636,7 @@ void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) {
TEST(StackAlignmentForSSE2) {
CcTest::InitializeVM();
- CHECK_EQ(0, OS::ActivationFrameAlignment() % 16);
+ CHECK_EQ(0, v8::base::OS::ActivationFrameAlignment() % 16);
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
@@ -689,7 +690,8 @@ TEST(AssemblerX64Extractps) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -727,7 +729,8 @@ TEST(AssemblerX64SSE) {
Code::ComputeFlags(Code::STUB),
Handle<Code>());
#ifdef OBJECT_PRINT
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
#endif
F6 f = FUNCTION_CAST<F6>(code->entry());
diff --git a/deps/v8/test/cctest/test-assembler-x87.cc b/deps/v8/test/cctest/test-assembler-x87.cc
new file mode 100644
index 000000000..8341f9b49
--- /dev/null
+++ b/deps/v8/test/cctest/test-assembler-x87.cc
@@ -0,0 +1,315 @@
+// 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 <stdlib.h>
+
+#include "src/v8.h"
+
+#include "src/base/platform/platform.h"
+#include "src/disassembler.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "src/ostreams.h"
+#include "src/serialize.h"
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+
+
+typedef int (*F0)();
+typedef int (*F1)(int x);
+typedef int (*F2)(int x, int y);
+
+
+#define __ assm.
+
+TEST(AssemblerIa320) {
+ CcTest::InitializeVM();
+ Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
+ HandleScope scope(isolate);
+
+ v8::internal::byte buffer[256];
+ Assembler assm(isolate, buffer, sizeof buffer);
+
+ __ mov(eax, Operand(esp, 4));
+ __ add(eax, Operand(esp, 8));
+ __ ret(0);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+ OFStream os(stdout);
+ code->Print(os);
+#endif
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+ int res = f(3, 4);
+ ::printf("f() = %d\n", res);
+ CHECK_EQ(7, res);
+}
+
+
+TEST(AssemblerIa321) {
+ CcTest::InitializeVM();
+ Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
+ HandleScope scope(isolate);
+
+ v8::internal::byte buffer[256];
+ Assembler assm(isolate, buffer, sizeof buffer);
+ Label L, C;
+
+ __ mov(edx, Operand(esp, 4));
+ __ xor_(eax, eax); // clear eax
+ __ jmp(&C);
+
+ __ bind(&L);
+ __ add(eax, edx);
+ __ sub(edx, Immediate(1));
+
+ __ bind(&C);
+ __ test(edx, edx);
+ __ j(not_zero, &L);
+ __ ret(0);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+ OFStream os(stdout);
+ code->Print(os);
+#endif
+ F1 f = FUNCTION_CAST<F1>(code->entry());
+ int res = f(100);
+ ::printf("f() = %d\n", res);
+ CHECK_EQ(5050, res);
+}
+
+
+TEST(AssemblerIa322) {
+ CcTest::InitializeVM();
+ Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
+ HandleScope scope(isolate);
+
+ v8::internal::byte buffer[256];
+ Assembler assm(isolate, buffer, sizeof buffer);
+ Label L, C;
+
+ __ mov(edx, Operand(esp, 4));
+ __ mov(eax, 1);
+ __ jmp(&C);
+
+ __ bind(&L);
+ __ imul(eax, edx);
+ __ sub(edx, Immediate(1));
+
+ __ bind(&C);
+ __ test(edx, edx);
+ __ j(not_zero, &L);
+ __ ret(0);
+
+ // some relocated stuff here, not executed
+ __ mov(eax, isolate->factory()->true_value());
+ __ jmp(NULL, RelocInfo::RUNTIME_ENTRY);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+ OFStream os(stdout);
+ code->Print(os);
+#endif
+ F1 f = FUNCTION_CAST<F1>(code->entry());
+ int res = f(10);
+ ::printf("f() = %d\n", res);
+ CHECK_EQ(3628800, res);
+}
+
+
+typedef int (*F3)(float x);
+
+typedef int (*F4)(double x);
+
+static int baz = 42;
+TEST(AssemblerIa325) {
+ CcTest::InitializeVM();
+ Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
+ HandleScope scope(isolate);
+
+ v8::internal::byte buffer[256];
+ Assembler assm(isolate, buffer, sizeof buffer);
+
+ __ mov(eax, Operand(reinterpret_cast<intptr_t>(&baz), RelocInfo::NONE32));
+ __ ret(0);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F0 f = FUNCTION_CAST<F0>(code->entry());
+ int res = f();
+ CHECK_EQ(42, res);
+}
+
+
+typedef int (*F7)(double x, double y);
+
+TEST(AssemblerIa329) {
+ CcTest::InitializeVM();
+ Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
+ HandleScope scope(isolate);
+ v8::internal::byte buffer[256];
+ MacroAssembler assm(isolate, buffer, sizeof buffer);
+ enum { kEqual = 0, kGreater = 1, kLess = 2, kNaN = 3, kUndefined = 4 };
+ Label equal_l, less_l, greater_l, nan_l;
+ __ fld_d(Operand(esp, 3 * kPointerSize));
+ __ fld_d(Operand(esp, 1 * kPointerSize));
+ __ FCmp();
+ __ j(parity_even, &nan_l);
+ __ j(equal, &equal_l);
+ __ j(below, &less_l);
+ __ j(above, &greater_l);
+
+ __ mov(eax, kUndefined);
+ __ ret(0);
+
+ __ bind(&equal_l);
+ __ mov(eax, kEqual);
+ __ ret(0);
+
+ __ bind(&greater_l);
+ __ mov(eax, kGreater);
+ __ ret(0);
+
+ __ bind(&less_l);
+ __ mov(eax, kLess);
+ __ ret(0);
+
+ __ bind(&nan_l);
+ __ mov(eax, kNaN);
+ __ ret(0);
+
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+ OFStream os(stdout);
+ code->Print(os);
+#endif
+
+ F7 f = FUNCTION_CAST<F7>(code->entry());
+ CHECK_EQ(kLess, f(1.1, 2.2));
+ CHECK_EQ(kEqual, f(2.2, 2.2));
+ CHECK_EQ(kGreater, f(3.3, 2.2));
+ CHECK_EQ(kNaN, f(v8::base::OS::nan_value(), 1.1));
+}
+
+
+TEST(AssemblerIa3210) {
+ // Test chaining of label usages within instructions (issue 1644).
+ CcTest::InitializeVM();
+ Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
+ HandleScope scope(isolate);
+ Assembler assm(isolate, NULL, 0);
+
+ Label target;
+ __ j(equal, &target);
+ __ j(not_equal, &target);
+ __ bind(&target);
+ __ nop();
+}
+
+
+TEST(AssemblerMultiByteNop) {
+ CcTest::InitializeVM();
+ Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
+ HandleScope scope(isolate);
+ v8::internal::byte buffer[1024];
+ Assembler assm(isolate, buffer, sizeof(buffer));
+ __ push(ebx);
+ __ push(ecx);
+ __ push(edx);
+ __ push(edi);
+ __ push(esi);
+ __ mov(eax, 1);
+ __ mov(ebx, 2);
+ __ mov(ecx, 3);
+ __ mov(edx, 4);
+ __ mov(edi, 5);
+ __ mov(esi, 6);
+ for (int i = 0; i < 16; i++) {
+ int before = assm.pc_offset();
+ __ Nop(i);
+ CHECK_EQ(assm.pc_offset() - before, i);
+ }
+
+ Label fail;
+ __ cmp(eax, 1);
+ __ j(not_equal, &fail);
+ __ cmp(ebx, 2);
+ __ j(not_equal, &fail);
+ __ cmp(ecx, 3);
+ __ j(not_equal, &fail);
+ __ cmp(edx, 4);
+ __ j(not_equal, &fail);
+ __ cmp(edi, 5);
+ __ j(not_equal, &fail);
+ __ cmp(esi, 6);
+ __ j(not_equal, &fail);
+ __ mov(eax, 42);
+ __ pop(esi);
+ __ pop(edi);
+ __ pop(edx);
+ __ pop(ecx);
+ __ pop(ebx);
+ __ ret(0);
+ __ bind(&fail);
+ __ mov(eax, 13);
+ __ pop(esi);
+ __ pop(edi);
+ __ pop(edx);
+ __ pop(ecx);
+ __ pop(ebx);
+ __ ret(0);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ CHECK(code->IsCode());
+
+ F0 f = FUNCTION_CAST<F0>(code->entry());
+ int res = f();
+ CHECK_EQ(42, res);
+}
+
+
+#undef __
diff --git a/deps/v8/test/cctest/test-ast.cc b/deps/v8/test/cctest/test-ast.cc
index d6431371a..a25ae69b6 100644
--- a/deps/v8/test/cctest/test-ast.cc
+++ b/deps/v8/test/cctest/test-ast.cc
@@ -27,10 +27,10 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "ast.h"
-#include "cctest.h"
+#include "src/ast.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -41,7 +41,7 @@ TEST(List) {
Isolate* isolate = CcTest::i_isolate();
Zone zone(isolate);
- AstNodeFactory<AstNullVisitor> factory(&zone);
+ AstNodeFactory<AstNullVisitor> factory(&zone, NULL);
AstNode* node = factory.NewEmptyStatement(RelocInfo::kNoPosition);
list->Add(node);
CHECK_EQ(1, list->length());
diff --git a/deps/v8/test/cctest/test-atomicops.cc b/deps/v8/test/cctest/test-atomicops.cc
index 53df22963..8b47208ba 100644
--- a/deps/v8/test/cctest/test-atomicops.cc
+++ b/deps/v8/test/cctest/test-atomicops.cc
@@ -25,11 +25,12 @@
// (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 "src/v8.h"
-#include "cctest.h"
-#include "atomicops.h"
+#include "src/base/atomicops.h"
+#include "test/cctest/cctest.h"
+using namespace v8::base;
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-bignum-dtoa.cc b/deps/v8/test/cctest/test-bignum-dtoa.cc
index a696ed8e3..9262e018c 100644
--- a/deps/v8/test/cctest/test-bignum-dtoa.cc
+++ b/deps/v8/test/cctest/test-bignum-dtoa.cc
@@ -27,16 +27,16 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "bignum-dtoa.h"
+#include "src/bignum-dtoa.h"
-#include "cctest.h"
-#include "double.h"
-#include "gay-fixed.h"
-#include "gay-precision.h"
-#include "gay-shortest.h"
-#include "platform.h"
+#include "src/base/platform/platform.h"
+#include "src/double.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/gay-fixed.h"
+#include "test/cctest/gay-precision.h"
+#include "test/cctest/gay-shortest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-bignum.cc b/deps/v8/test/cctest/test-bignum.cc
index 9aa5ef30d..47ce2a48a 100644
--- a/deps/v8/test/cctest/test-bignum.cc
+++ b/deps/v8/test/cctest/test-bignum.cc
@@ -27,11 +27,11 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "platform.h"
-#include "cctest.h"
-#include "bignum.h"
+#include "src/base/platform/platform.h"
+#include "src/bignum.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-checks.cc b/deps/v8/test/cctest/test-checks.cc
new file mode 100644
index 000000000..a49a7dbe2
--- /dev/null
+++ b/deps/v8/test/cctest/test-checks.cc
@@ -0,0 +1,26 @@
+// 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 "src/checks.h"
+
+#include "test/cctest/cctest.h"
+
+
+TEST(CheckEqualsZeroAndMinusZero) {
+ CHECK_EQ(0.0, 0.0);
+ CHECK_NE(0.0, -0.0);
+ CHECK_NE(-0.0, 0.0);
+ CHECK_EQ(-0.0, -0.0);
+}
+
+
+TEST(CheckEqualsReflexivity) {
+ double inf = V8_INFINITY;
+ double nan = v8::base::OS::nan_value();
+ double constants[] = {-nan, -inf, -3.1415, -1.0, -0.1, -0.0,
+ 0.0, 0.1, 1.0, 3.1415, inf, nan};
+ for (size_t i = 0; i < ARRAY_SIZE(constants); ++i) {
+ CHECK_EQ(constants[i], constants[i]);
+ }
+}
diff --git a/deps/v8/test/cctest/test-circular-queue.cc b/deps/v8/test/cctest/test-circular-queue.cc
index c900be1a6..736a9b7c8 100644
--- a/deps/v8/test/cctest/test-circular-queue.cc
+++ b/deps/v8/test/cctest/test-circular-queue.cc
@@ -27,15 +27,16 @@
//
// Tests of the circular queue.
-#include "v8.h"
-#include "circular-queue-inl.h"
-#include "cctest.h"
+#include "src/v8.h"
+
+#include "src/circular-queue-inl.h"
+#include "test/cctest/cctest.h"
using i::SamplingCircularQueue;
TEST(SamplingCircularQueue) {
- typedef i::AtomicWord Record;
+ typedef v8::base::AtomicWord Record;
const int kMaxRecordsInQueue = 4;
SamplingCircularQueue<Record, kMaxRecordsInQueue> scq;
@@ -99,20 +100,18 @@ TEST(SamplingCircularQueue) {
namespace {
-typedef i::AtomicWord Record;
+typedef v8::base::AtomicWord Record;
typedef SamplingCircularQueue<Record, 12> TestSampleQueue;
-class ProducerThread: public i::Thread {
+class ProducerThread: public v8::base::Thread {
public:
- ProducerThread(TestSampleQueue* scq,
- int records_per_chunk,
- Record value,
- i::Semaphore* finished)
- : Thread("producer"),
+ ProducerThread(TestSampleQueue* scq, int records_per_chunk, Record value,
+ v8::base::Semaphore* finished)
+ : Thread(Options("producer")),
scq_(scq),
records_per_chunk_(records_per_chunk),
value_(value),
- finished_(finished) { }
+ finished_(finished) {}
virtual void Run() {
for (Record i = value_; i < value_ + records_per_chunk_; ++i) {
@@ -129,7 +128,7 @@ class ProducerThread: public i::Thread {
TestSampleQueue* scq_;
const int records_per_chunk_;
Record value_;
- i::Semaphore* finished_;
+ v8::base::Semaphore* finished_;
};
} // namespace
@@ -142,7 +141,7 @@ TEST(SamplingCircularQueueMultithreading) {
const int kRecordsPerChunk = 4;
TestSampleQueue scq;
- i::Semaphore semaphore(0);
+ v8::base::Semaphore semaphore(0);
ProducerThread producer1(&scq, kRecordsPerChunk, 1, &semaphore);
ProducerThread producer2(&scq, kRecordsPerChunk, 10, &semaphore);
diff --git a/deps/v8/test/cctest/test-code-stubs-arm.cc b/deps/v8/test/cctest/test-code-stubs-arm.cc
index 43233472b..80403440d 100644
--- a/deps/v8/test/cctest/test-code-stubs-arm.cc
+++ b/deps/v8/test/cctest/test-code-stubs-arm.cc
@@ -27,15 +27,15 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "cctest.h"
-#include "code-stubs.h"
-#include "test-code-stubs.h"
-#include "factory.h"
-#include "macro-assembler.h"
-#include "platform.h"
-#include "simulator.h"
+#include "src/base/platform/platform.h"
+#include "src/code-stubs.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "src/simulator.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-code-stubs.h"
using namespace v8::internal;
@@ -47,9 +47,8 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
bool inline_fastpath) {
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
HandleScope handles(isolate);
MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size));
@@ -127,7 +126,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
CodeDesc desc;
masm.GetCode(&desc);
- CPU::FlushICache(buffer, actual_size);
+ CpuFeatures::FlushICache(buffer, actual_size);
return (reinterpret_cast<ConvertDToIFunc>(
reinterpret_cast<intptr_t>(buffer)));
}
diff --git a/deps/v8/test/cctest/test-code-stubs-arm64.cc b/deps/v8/test/cctest/test-code-stubs-arm64.cc
index 3ad07bf80..6d5b0f49b 100644
--- a/deps/v8/test/cctest/test-code-stubs-arm64.cc
+++ b/deps/v8/test/cctest/test-code-stubs-arm64.cc
@@ -27,15 +27,15 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "cctest.h"
-#include "code-stubs.h"
-#include "test-code-stubs.h"
-#include "factory.h"
-#include "macro-assembler.h"
-#include "platform.h"
-#include "simulator.h"
+#include "src/base/platform/platform.h"
+#include "src/code-stubs.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "src/simulator.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-code-stubs.h"
using namespace v8::internal;
@@ -46,10 +46,9 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
Register destination_reg,
bool inline_fastpath) {
// Allocate an executable page of memory.
- size_t actual_size = 2 * Assembler::kMinimalBufferSize;
- byte* buffer = static_cast<byte*>(OS::Allocate(actual_size,
- &actual_size,
- true));
+ size_t actual_size = 4 * Assembler::kMinimalBufferSize;
+ byte* buffer = static_cast<byte*>(
+ v8::base::OS::Allocate(actual_size, &actual_size, true));
CHECK(buffer);
HandleScope handles(isolate);
MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size));
@@ -123,7 +122,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
CodeDesc desc;
masm.GetCode(&desc);
- CPU::FlushICache(buffer, actual_size);
+ CpuFeatures::FlushICache(buffer, actual_size);
return (reinterpret_cast<ConvertDToIFunc>(
reinterpret_cast<intptr_t>(buffer)));
}
diff --git a/deps/v8/test/cctest/test-code-stubs-ia32.cc b/deps/v8/test/cctest/test-code-stubs-ia32.cc
index 96639577b..0b4a8d417 100644
--- a/deps/v8/test/cctest/test-code-stubs-ia32.cc
+++ b/deps/v8/test/cctest/test-code-stubs-ia32.cc
@@ -29,14 +29,14 @@
#include <limits>
-#include "v8.h"
+#include "src/v8.h"
-#include "cctest.h"
-#include "code-stubs.h"
-#include "test-code-stubs.h"
-#include "factory.h"
-#include "macro-assembler.h"
-#include "platform.h"
+#include "src/base/platform/platform.h"
+#include "src/code-stubs.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-code-stubs.h"
using namespace v8::internal;
@@ -47,9 +47,8 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
Register destination_reg) {
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
HandleScope handles(isolate);
MacroAssembler assm(isolate, buffer, static_cast<int>(actual_size));
diff --git a/deps/v8/test/cctest/test-code-stubs-mips.cc b/deps/v8/test/cctest/test-code-stubs-mips.cc
index f88979678..796aa1d61 100644
--- a/deps/v8/test/cctest/test-code-stubs-mips.cc
+++ b/deps/v8/test/cctest/test-code-stubs-mips.cc
@@ -27,16 +27,16 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "cctest.h"
-#include "code-stubs.h"
-#include "test-code-stubs.h"
-#include "mips/constants-mips.h"
-#include "factory.h"
-#include "macro-assembler.h"
-#include "platform.h"
-#include "simulator.h"
+#include "src/base/platform/platform.h"
+#include "src/code-stubs.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "src/mips/constants-mips.h"
+#include "src/simulator.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-code-stubs.h"
using namespace v8::internal;
@@ -48,9 +48,8 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
bool inline_fastpath) {
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
HandleScope handles(isolate);
MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size));
@@ -128,7 +127,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
CodeDesc desc;
masm.GetCode(&desc);
- CPU::FlushICache(buffer, actual_size);
+ CpuFeatures::FlushICache(buffer, actual_size);
return (reinterpret_cast<ConvertDToIFunc>(
reinterpret_cast<intptr_t>(buffer)));
}
diff --git a/deps/v8/test/cctest/test-code-stubs-mips64.cc b/deps/v8/test/cctest/test-code-stubs-mips64.cc
new file mode 100644
index 000000000..025a8ba04
--- /dev/null
+++ b/deps/v8/test/cctest/test-code-stubs-mips64.cc
@@ -0,0 +1,188 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Rrdistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Rrdistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Rrdistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 "src/v8.h"
+
+#include "src/base/platform/platform.h"
+#include "src/code-stubs.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "src/mips64/constants-mips64.h"
+#include "src/simulator.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-code-stubs.h"
+
+using namespace v8::internal;
+
+#define __ masm.
+
+ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
+ Register source_reg,
+ Register destination_reg,
+ bool inline_fastpath) {
+ // Allocate an executable page of memory.
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
+ CHECK(buffer);
+ HandleScope handles(isolate);
+ MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size));
+ DoubleToIStub stub(isolate, source_reg, destination_reg, 0, true,
+ inline_fastpath);
+
+ byte* start = stub.GetCode()->instruction_start();
+ Label done;
+
+ // Save callee save registers.
+ __ MultiPush(kCalleeSaved | ra.bit());
+
+ // For softfp, move the input value into f12.
+ if (IsMipsSoftFloatABI) {
+ __ Move(f12, a0, a1);
+ }
+ // Push the double argument.
+ __ Dsubu(sp, sp, Operand(kDoubleSize));
+ __ sdc1(f12, MemOperand(sp));
+ __ Move(source_reg, sp);
+
+ // Save registers make sure they don't get clobbered.
+ int source_reg_offset = kDoubleSize;
+ int reg_num = 2;
+ for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) {
+ Register reg = Register::from_code(reg_num);
+ if (!reg.is(destination_reg)) {
+ __ push(reg);
+ source_reg_offset += kPointerSize;
+ }
+ }
+
+ // Re-push the double argument.
+ __ Dsubu(sp, sp, Operand(kDoubleSize));
+ __ sdc1(f12, MemOperand(sp));
+
+ // Call through to the actual stub
+ if (inline_fastpath) {
+ __ ldc1(f12, MemOperand(source_reg));
+ __ TryInlineTruncateDoubleToI(destination_reg, f12, &done);
+ if (destination_reg.is(source_reg) && !source_reg.is(sp)) {
+ // Restore clobbered source_reg.
+ __ Daddu(source_reg, sp, Operand(source_reg_offset));
+ }
+ }
+ __ Call(start, RelocInfo::EXTERNAL_REFERENCE);
+ __ bind(&done);
+
+ __ Daddu(sp, sp, Operand(kDoubleSize));
+
+ // Make sure no registers have been unexpectedly clobbered
+ for (--reg_num; reg_num >= 2; --reg_num) {
+ Register reg = Register::from_code(reg_num);
+ if (!reg.is(destination_reg)) {
+ __ lw(at, MemOperand(sp, 0));
+ __ Assert(eq, kRegisterWasClobbered, reg, Operand(at));
+ __ Daddu(sp, sp, Operand(kPointerSize));
+ }
+ }
+
+ __ Daddu(sp, sp, Operand(kDoubleSize));
+
+ __ Move(v0, destination_reg);
+ Label ok;
+ __ Branch(&ok, eq, v0, Operand(zero_reg));
+ __ bind(&ok);
+
+ // Restore callee save registers.
+ __ MultiPop(kCalleeSaved | ra.bit());
+
+ Label ok1;
+ __ Branch(&ok1, eq, v0, Operand(zero_reg));
+ __ bind(&ok1);
+ __ Ret();
+
+ CodeDesc desc;
+ masm.GetCode(&desc);
+ CpuFeatures::FlushICache(buffer, actual_size);
+ return (reinterpret_cast<ConvertDToIFunc>(
+ reinterpret_cast<intptr_t>(buffer)));
+}
+
+#undef __
+
+
+static Isolate* GetIsolateFrom(LocalContext* context) {
+ return reinterpret_cast<Isolate*>((*context)->GetIsolate());
+}
+
+
+int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func,
+ double from) {
+#ifdef USE_SIMULATOR
+ Simulator::current(Isolate::Current())->CallFP(FUNCTION_ADDR(func), from, 0.);
+ return Simulator::current(Isolate::Current())->get_register(v0.code());
+#else
+ return (*func)(from);
+#endif
+}
+
+
+TEST(ConvertDToI) {
+ CcTest::InitializeVM();
+ LocalContext context;
+ Isolate* isolate = GetIsolateFrom(&context);
+ HandleScope scope(isolate);
+
+#if DEBUG
+ // Verify that the tests actually work with the C version. In the release
+ // code, the compiler optimizes it away because it's all constant, but does it
+ // wrong, triggering an assert on gcc.
+ RunAllTruncationTests(&ConvertDToICVersion);
+#endif
+
+ Register source_registers[] = {
+ sp, v0, v1, a0, a1, a2, a3, a4, a5, a6, a7, t0, t1};
+ Register dest_registers[] = {
+ v0, v1, a0, a1, a2, a3, a4, a5, a6, a7, t0, t1};
+
+ for (size_t s = 0; s < sizeof(source_registers) / sizeof(Register); s++) {
+ for (size_t d = 0; d < sizeof(dest_registers) / sizeof(Register); d++) {
+ RunAllTruncationTests(
+ RunGeneratedCodeCallWrapper,
+ MakeConvertDToIFuncTrampoline(isolate,
+ source_registers[s],
+ dest_registers[d],
+ false));
+ RunAllTruncationTests(
+ RunGeneratedCodeCallWrapper,
+ MakeConvertDToIFuncTrampoline(isolate,
+ source_registers[s],
+ dest_registers[d],
+ true));
+ }
+ }
+}
diff --git a/deps/v8/test/cctest/test-code-stubs-x64.cc b/deps/v8/test/cctest/test-code-stubs-x64.cc
index 3ffd292c5..b58b073f3 100644
--- a/deps/v8/test/cctest/test-code-stubs-x64.cc
+++ b/deps/v8/test/cctest/test-code-stubs-x64.cc
@@ -27,14 +27,14 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "cctest.h"
-#include "code-stubs.h"
-#include "test-code-stubs.h"
-#include "factory.h"
-#include "macro-assembler.h"
-#include "platform.h"
+#include "src/base/platform/platform.h"
+#include "src/code-stubs.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-code-stubs.h"
using namespace v8::internal;
@@ -46,9 +46,8 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
Register destination_reg) {
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
HandleScope handles(isolate);
MacroAssembler assm(isolate, buffer, static_cast<int>(actual_size));
diff --git a/deps/v8/test/cctest/test-code-stubs-x87.cc b/deps/v8/test/cctest/test-code-stubs-x87.cc
new file mode 100644
index 000000000..0b4a8d417
--- /dev/null
+++ b/deps/v8/test/cctest/test-code-stubs-x87.cc
@@ -0,0 +1,148 @@
+// 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 <stdlib.h>
+
+#include <limits>
+
+#include "src/v8.h"
+
+#include "src/base/platform/platform.h"
+#include "src/code-stubs.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-code-stubs.h"
+
+using namespace v8::internal;
+
+#define __ assm.
+
+ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
+ Register source_reg,
+ Register destination_reg) {
+ // Allocate an executable page of memory.
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
+ CHECK(buffer);
+ HandleScope handles(isolate);
+ MacroAssembler assm(isolate, buffer, static_cast<int>(actual_size));
+ int offset =
+ source_reg.is(esp) ? 0 : (HeapNumber::kValueOffset - kSmiTagSize);
+ DoubleToIStub stub(isolate, source_reg, destination_reg, offset, true);
+ byte* start = stub.GetCode()->instruction_start();
+
+ __ push(ebx);
+ __ push(ecx);
+ __ push(edx);
+ __ push(esi);
+ __ push(edi);
+
+ if (!source_reg.is(esp)) {
+ __ lea(source_reg, MemOperand(esp, 6 * kPointerSize - offset));
+ }
+
+ int param_offset = 7 * kPointerSize;
+ // Save registers make sure they don't get clobbered.
+ int reg_num = 0;
+ for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) {
+ Register reg = Register::FromAllocationIndex(reg_num);
+ if (!reg.is(esp) && !reg.is(ebp) && !reg.is(destination_reg)) {
+ __ push(reg);
+ param_offset += kPointerSize;
+ }
+ }
+
+ // Re-push the double argument
+ __ push(MemOperand(esp, param_offset));
+ __ push(MemOperand(esp, param_offset));
+
+ // Call through to the actual stub
+ __ call(start, RelocInfo::EXTERNAL_REFERENCE);
+
+ __ add(esp, Immediate(kDoubleSize));
+
+ // Make sure no registers have been unexpectedly clobbered
+ for (--reg_num; reg_num >= 0; --reg_num) {
+ Register reg = Register::FromAllocationIndex(reg_num);
+ if (!reg.is(esp) && !reg.is(ebp) && !reg.is(destination_reg)) {
+ __ cmp(reg, MemOperand(esp, 0));
+ __ Assert(equal, kRegisterWasClobbered);
+ __ add(esp, Immediate(kPointerSize));
+ }
+ }
+
+ __ mov(eax, destination_reg);
+
+ __ pop(edi);
+ __ pop(esi);
+ __ pop(edx);
+ __ pop(ecx);
+ __ pop(ebx);
+
+ __ ret(kDoubleSize);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ return reinterpret_cast<ConvertDToIFunc>(
+ reinterpret_cast<intptr_t>(buffer));
+}
+
+#undef __
+
+
+static Isolate* GetIsolateFrom(LocalContext* context) {
+ return reinterpret_cast<Isolate*>((*context)->GetIsolate());
+}
+
+
+TEST(ConvertDToI) {
+ CcTest::InitializeVM();
+ LocalContext context;
+ Isolate* isolate = GetIsolateFrom(&context);
+ HandleScope scope(isolate);
+
+#if DEBUG
+ // Verify that the tests actually work with the C version. In the release
+ // code, the compiler optimizes it away because it's all constant, but does it
+ // wrong, triggering an assert on gcc.
+ RunAllTruncationTests(&ConvertDToICVersion);
+#endif
+
+ Register source_registers[] = {esp, eax, ebx, ecx, edx, edi, esi};
+ Register dest_registers[] = {eax, ebx, ecx, edx, edi, esi};
+
+ for (size_t s = 0; s < sizeof(source_registers) / sizeof(Register); s++) {
+ for (size_t d = 0; d < sizeof(dest_registers) / sizeof(Register); d++) {
+ RunAllTruncationTests(
+ MakeConvertDToIFuncTrampoline(isolate,
+ source_registers[s],
+ dest_registers[d]));
+ }
+ }
+}
diff --git a/deps/v8/test/cctest/test-code-stubs.cc b/deps/v8/test/cctest/test-code-stubs.cc
index 999febf77..0784aac78 100644
--- a/deps/v8/test/cctest/test-code-stubs.cc
+++ b/deps/v8/test/cctest/test-code-stubs.cc
@@ -29,14 +29,14 @@
#include <limits>
-#include "v8.h"
+#include "src/v8.h"
-#include "cctest.h"
-#include "code-stubs.h"
-#include "test-code-stubs.h"
-#include "factory.h"
-#include "macro-assembler.h"
-#include "platform.h"
+#include "src/base/platform/platform.h"
+#include "src/code-stubs.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-code-stubs.h"
using namespace v8::internal;
@@ -92,7 +92,7 @@ int32_t DefaultCallWrapper(ConvertDToIFunc func,
// #define NaN and Infinity so that it's possible to cut-and-paste these tests
// directly to a .js file and run them.
-#define NaN (OS::nan_value())
+#define NaN (v8::base::OS::nan_value())
#define Infinity (std::numeric_limits<double>::infinity())
#define RunOneTruncationTest(p1, p2) \
RunOneTruncationTestWithTest(callWrapper, func, p1, p2)
diff --git a/deps/v8/test/cctest/test-code-stubs.h b/deps/v8/test/cctest/test-code-stubs.h
index 910e0d170..0cfa0ec7c 100644
--- a/deps/v8/test/cctest/test-code-stubs.h
+++ b/deps/v8/test/cctest/test-code-stubs.h
@@ -28,7 +28,7 @@
#ifndef V8_TEST_CODE_STUBS_H_
#define V8_TEST_CODE_STUBS_H_
-#if V8_TARGET_ARCH_IA32
+#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
#if __GNUC__
#define STDCALL __attribute__((stdcall))
#else
diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc
index 9974ff570..2d913715e 100644
--- a/deps/v8/test/cctest/test-compiler.cc
+++ b/deps/v8/test/cctest/test-compiler.cc
@@ -28,11 +28,12 @@
#include <stdlib.h>
#include <wchar.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "compiler.h"
-#include "disasm.h"
-#include "cctest.h"
+#include "src/compiler.h"
+#include "src/disasm.h"
+#include "src/parser.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -49,7 +50,7 @@ static void SetGlobalProperty(const char* name, Object* value) {
Handle<String> internalized_name =
isolate->factory()->InternalizeUtf8String(name);
Handle<JSObject> global(isolate->context()->global_object());
- Runtime::SetObjectProperty(isolate, global, internalized_name, object, NONE,
+ Runtime::SetObjectProperty(isolate, global, internalized_name, object,
SLOPPY).Check();
}
@@ -58,15 +59,10 @@ static Handle<JSFunction> Compile(const char* source) {
Isolate* isolate = CcTest::i_isolate();
Handle<String> source_code = isolate->factory()->NewStringFromUtf8(
CStrVector(source)).ToHandleChecked();
- Handle<SharedFunctionInfo> shared_function =
- Compiler::CompileScript(source_code,
- Handle<String>(),
- 0,
- 0,
- false,
- Handle<Context>(isolate->native_context()),
- NULL, NULL, NO_CACHED_DATA,
- NOT_NATIVES_CODE);
+ Handle<SharedFunctionInfo> shared_function = Compiler::CompileScript(
+ source_code, Handle<String>(), 0, 0, false,
+ Handle<Context>(isolate->native_context()), NULL, NULL,
+ v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE);
return isolate->factory()->NewFunctionFromSharedFunctionInfo(
shared_function, isolate->native_context());
}
@@ -75,7 +71,7 @@ static Handle<JSFunction> Compile(const char* source) {
static double Inc(Isolate* isolate, int x) {
const char* source = "result = %d + 1;";
EmbeddedVector<char, 512> buffer;
- OS::SNPrintF(buffer, source, x);
+ SNPrintF(buffer, source, x);
Handle<JSFunction> fun = Compile(buffer.start());
if (fun.is_null()) return -1;
@@ -278,7 +274,7 @@ TEST(GetScriptLineNumber) {
for (int i = 0; i < max_rows; ++i) {
if (i > 0)
buffer[i - 1] = '\n';
- OS::MemCopy(&buffer[i], function_f, sizeof(function_f) - 1);
+ MemCopy(&buffer[i], function_f, sizeof(function_f) - 1);
v8::Handle<v8::String> script_body =
v8::String::NewFromUtf8(CcTest::isolate(), buffer.start());
v8::Script::Compile(script_body, &origin)->Run();
@@ -313,8 +309,9 @@ TEST(FeedbackVectorPreservedAcrossRecompiles) {
Handle<FixedArray> feedback_vector(f->shared()->feedback_vector());
// Verify that we gathered feedback.
- CHECK_EQ(1, feedback_vector->length());
- CHECK(feedback_vector->get(0)->IsJSFunction());
+ int expected_count = FLAG_vector_ics ? 2 : 1;
+ CHECK_EQ(expected_count, feedback_vector->length());
+ CHECK(feedback_vector->get(expected_count - 1)->IsJSFunction());
CompileRun("%OptimizeFunctionOnNextCall(f); f(fun1);");
@@ -322,7 +319,8 @@ TEST(FeedbackVectorPreservedAcrossRecompiles) {
// of the full code.
CHECK(f->IsOptimized());
CHECK(f->shared()->has_deoptimization_support());
- CHECK(f->shared()->feedback_vector()->get(0)->IsJSFunction());
+ CHECK(f->shared()->feedback_vector()->
+ get(expected_count - 1)->IsJSFunction());
}
@@ -348,16 +346,15 @@ TEST(FeedbackVectorUnaffectedByScopeChanges) {
*v8::Handle<v8::Function>::Cast(
CcTest::global()->Get(v8_str("morphing_call"))));
- // morphing_call should have one feedback vector slot for the call to
- // call_target().
- CHECK_EQ(1, f->shared()->feedback_vector()->length());
+ int expected_count = FLAG_vector_ics ? 2 : 1;
+ CHECK_EQ(expected_count, f->shared()->feedback_vector()->length());
// And yet it's not compiled.
CHECK(!f->shared()->is_compiled());
CompileRun("morphing_call();");
// The vector should have the same size despite the new scoping.
- CHECK_EQ(1, f->shared()->feedback_vector()->length());
+ CHECK_EQ(expected_count, f->shared()->feedback_vector()->length());
CHECK(f->shared()->is_compiled());
}
@@ -422,7 +419,7 @@ static void CheckCodeForUnsafeLiteral(Handle<JSFunction> f) {
v8::internal::EmbeddedVector<char, 128> decode_buffer;
v8::internal::EmbeddedVector<char, 128> smi_hex_buffer;
Smi* smi = Smi::FromInt(12345678);
- OS::SNPrintF(smi_hex_buffer, "0x%lx", reinterpret_cast<intptr_t>(smi));
+ SNPrintF(smi_hex_buffer, "0x%" V8PRIxPTR, reinterpret_cast<intptr_t>(smi));
while (pc < end) {
int num_const = d.ConstantPoolSizeAt(pc);
if (num_const >= 0) {
diff --git a/deps/v8/test/cctest/test-constantpool.cc b/deps/v8/test/cctest/test-constantpool.cc
index e16e45a57..453657609 100644
--- a/deps/v8/test/cctest/test-constantpool.cc
+++ b/deps/v8/test/cctest/test-constantpool.cc
@@ -2,14 +2,22 @@
// Test constant pool array code.
-#include "v8.h"
+#include "src/v8.h"
-#include "factory.h"
-#include "objects.h"
-#include "cctest.h"
+#include "src/factory.h"
+#include "src/objects.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
+static ConstantPoolArray::Type kTypes[] = { ConstantPoolArray::INT64,
+ ConstantPoolArray::CODE_PTR,
+ ConstantPoolArray::HEAP_PTR,
+ ConstantPoolArray::INT32 };
+static ConstantPoolArray::LayoutSection kSmall =
+ ConstantPoolArray::SMALL_SECTION;
+static ConstantPoolArray::LayoutSection kExtended =
+ ConstantPoolArray::EXTENDED_SECTION;
Code* DummyCode(LocalContext* context) {
CompileRun("function foo() {};");
@@ -20,28 +28,29 @@ Code* DummyCode(LocalContext* context) {
}
-TEST(ConstantPool) {
+TEST(ConstantPoolSmall) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
- Heap* heap = isolate->heap();
Factory* factory = isolate->factory();
v8::HandleScope scope(context->GetIsolate());
// Check construction.
- Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(3, 1, 2, 1);
- CHECK_EQ(array->count_of_int64_entries(), 3);
- CHECK_EQ(array->count_of_code_ptr_entries(), 1);
- CHECK_EQ(array->count_of_heap_ptr_entries(), 2);
- CHECK_EQ(array->count_of_int32_entries(), 1);
- CHECK_EQ(array->length(), 7);
- CHECK_EQ(array->first_int64_index(), 0);
- CHECK_EQ(array->first_code_ptr_index(), 3);
- CHECK_EQ(array->first_heap_ptr_index(), 4);
- CHECK_EQ(array->first_int32_index(), 6);
+ ConstantPoolArray::NumberOfEntries small(3, 1, 2, 1);
+ Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(small);
+
+ int expected_counts[] = { 3, 1, 2, 1 };
+ int expected_first_idx[] = { 0, 3, 4, 6 };
+ int expected_last_idx[] = { 2, 3, 5, 6 };
+ for (int i = 0; i < 4; i++) {
+ CHECK_EQ(expected_counts[i], array->number_of_entries(kTypes[i], kSmall));
+ CHECK_EQ(expected_first_idx[i], array->first_index(kTypes[i], kSmall));
+ CHECK_EQ(expected_last_idx[i], array->last_index(kTypes[i], kSmall));
+ }
+ CHECK(!array->is_extended_layout());
// Check getters and setters.
int64_t big_number = V8_2PART_UINT64_C(0x12345678, 9ABCDEF0);
- Handle<Object> object = factory->NewHeapNumber(4.0);
+ Handle<Object> object = factory->NewHeapNumber(4.0, IMMUTABLE, TENURED);
Code* code = DummyCode(&context);
array->set(0, big_number);
array->set(1, 0.5);
@@ -50,19 +59,253 @@ TEST(ConstantPool) {
array->set(4, code);
array->set(5, *object);
array->set(6, 50);
- CHECK_EQ(array->get_int64_entry(0), big_number);
- CHECK_EQ(array->get_int64_entry_as_double(1), 0.5);
- CHECK_EQ(array->get_int64_entry_as_double(2), 3e-24);
- CHECK_EQ(array->get_code_ptr_entry(3), code->entry());
- CHECK_EQ(array->get_heap_ptr_entry(4), code);
- CHECK_EQ(array->get_heap_ptr_entry(5), *object);
- CHECK_EQ(array->get_int32_entry(6), 50);
-
- // Check pointers are updated on GC.
- Object* old_ptr = array->get_heap_ptr_entry(5);
- CHECK_EQ(*object, old_ptr);
+ CHECK_EQ(big_number, array->get_int64_entry(0));
+ CHECK_EQ(0.5, array->get_int64_entry_as_double(1));
+ CHECK_EQ(3e-24, array->get_int64_entry_as_double(2));
+ CHECK_EQ(code->entry(), array->get_code_ptr_entry(3));
+ CHECK_EQ(code, array->get_heap_ptr_entry(4));
+ CHECK_EQ(*object, array->get_heap_ptr_entry(5));
+ CHECK_EQ(50, array->get_int32_entry(6));
+}
+
+
+TEST(ConstantPoolExtended) {
+ LocalContext context;
+ Isolate* isolate = CcTest::i_isolate();
+ Factory* factory = isolate->factory();
+ v8::HandleScope scope(context->GetIsolate());
+
+ // Check construction.
+ ConstantPoolArray::NumberOfEntries small(1, 2, 3, 4);
+ ConstantPoolArray::NumberOfEntries extended(5, 6, 7, 8);
+ Handle<ConstantPoolArray> array =
+ factory->NewExtendedConstantPoolArray(small, extended);
+
+ // Check small section.
+ int small_counts[] = { 1, 2, 3, 4 };
+ int small_first_idx[] = { 0, 1, 3, 6 };
+ int small_last_idx[] = { 0, 2, 5, 9 };
+ for (int i = 0; i < 4; i++) {
+ CHECK_EQ(small_counts[i], array->number_of_entries(kTypes[i], kSmall));
+ CHECK_EQ(small_first_idx[i], array->first_index(kTypes[i], kSmall));
+ CHECK_EQ(small_last_idx[i], array->last_index(kTypes[i], kSmall));
+ }
+
+ // Check extended layout.
+ CHECK(array->is_extended_layout());
+ int extended_counts[] = { 5, 6, 7, 8 };
+ int extended_first_idx[] = { 10, 15, 21, 28 };
+ int extended_last_idx[] = { 14, 20, 27, 35 };
+ for (int i = 0; i < 4; i++) {
+ CHECK_EQ(extended_counts[i],
+ array->number_of_entries(kTypes[i], kExtended));
+ CHECK_EQ(extended_first_idx[i], array->first_index(kTypes[i], kExtended));
+ CHECK_EQ(extended_last_idx[i], array->last_index(kTypes[i], kExtended));
+ }
+
+ // Check small and large section's don't overlap.
+ int64_t small_section_int64 = V8_2PART_UINT64_C(0x56781234, DEF09ABC);
+ Code* small_section_code_ptr = DummyCode(&context);
+ Handle<Object> small_section_heap_ptr =
+ factory->NewHeapNumber(4.0, IMMUTABLE, TENURED);
+ int32_t small_section_int32 = 0xab12cd45;
+
+ int64_t extended_section_int64 = V8_2PART_UINT64_C(0x12345678, 9ABCDEF0);
+ Code* extended_section_code_ptr = DummyCode(&context);
+ Handle<Object> extended_section_heap_ptr =
+ factory->NewHeapNumber(5.0, IMMUTABLE, TENURED);
+ int32_t extended_section_int32 = 0xef67ab89;
+
+ for (int i = array->first_index(ConstantPoolArray::INT64, kSmall);
+ i <= array->last_index(ConstantPoolArray::INT32, kSmall); i++) {
+ if (i <= array->last_index(ConstantPoolArray::INT64, kSmall)) {
+ array->set(i, small_section_int64);
+ } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kSmall)) {
+ array->set(i, small_section_code_ptr->entry());
+ } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kSmall)) {
+ array->set(i, *small_section_heap_ptr);
+ } else {
+ CHECK(i <= array->last_index(ConstantPoolArray::INT32, kSmall));
+ array->set(i, small_section_int32);
+ }
+ }
+ for (int i = array->first_index(ConstantPoolArray::INT64, kExtended);
+ i <= array->last_index(ConstantPoolArray::INT32, kExtended); i++) {
+ if (i <= array->last_index(ConstantPoolArray::INT64, kExtended)) {
+ array->set(i, extended_section_int64);
+ } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kExtended)) {
+ array->set(i, extended_section_code_ptr->entry());
+ } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kExtended)) {
+ array->set(i, *extended_section_heap_ptr);
+ } else {
+ CHECK(i <= array->last_index(ConstantPoolArray::INT32, kExtended));
+ array->set(i, extended_section_int32);
+ }
+ }
+
+ for (int i = array->first_index(ConstantPoolArray::INT64, kSmall);
+ i <= array->last_index(ConstantPoolArray::INT32, kSmall); i++) {
+ if (i <= array->last_index(ConstantPoolArray::INT64, kSmall)) {
+ CHECK_EQ(small_section_int64, array->get_int64_entry(i));
+ } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kSmall)) {
+ CHECK_EQ(small_section_code_ptr->entry(), array->get_code_ptr_entry(i));
+ } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kSmall)) {
+ CHECK_EQ(*small_section_heap_ptr, array->get_heap_ptr_entry(i));
+ } else {
+ CHECK(i <= array->last_index(ConstantPoolArray::INT32, kSmall));
+ CHECK_EQ(small_section_int32, array->get_int32_entry(i));
+ }
+ }
+ for (int i = array->first_index(ConstantPoolArray::INT64, kExtended);
+ i <= array->last_index(ConstantPoolArray::INT32, kExtended); i++) {
+ if (i <= array->last_index(ConstantPoolArray::INT64, kExtended)) {
+ CHECK_EQ(extended_section_int64, array->get_int64_entry(i));
+ } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kExtended)) {
+ CHECK_EQ(extended_section_code_ptr->entry(),
+ array->get_code_ptr_entry(i));
+ } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kExtended)) {
+ CHECK_EQ(*extended_section_heap_ptr, array->get_heap_ptr_entry(i));
+ } else {
+ CHECK(i <= array->last_index(ConstantPoolArray::INT32, kExtended));
+ CHECK_EQ(extended_section_int32, array->get_int32_entry(i));
+ }
+ }
+}
+
+
+static void CheckIterator(Handle<ConstantPoolArray> array,
+ ConstantPoolArray::Type type,
+ int expected_indexes[],
+ int count) {
+ int i = 0;
+ ConstantPoolArray::Iterator iter(*array, type);
+ while (!iter.is_finished()) {
+ CHECK_EQ(expected_indexes[i++], iter.next_index());
+ }
+ CHECK_EQ(count, i);
+}
+
+
+TEST(ConstantPoolIteratorSmall) {
+ LocalContext context;
+ Isolate* isolate = CcTest::i_isolate();
+ Factory* factory = isolate->factory();
+ v8::HandleScope scope(context->GetIsolate());
+
+ ConstantPoolArray::NumberOfEntries small(1, 5, 2, 0);
+ Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(small);
+
+ int expected_int64_indexs[] = { 0 };
+ CheckIterator(array, ConstantPoolArray::INT64, expected_int64_indexs, 1);
+ int expected_code_indexs[] = { 1, 2, 3, 4, 5 };
+ CheckIterator(array, ConstantPoolArray::CODE_PTR, expected_code_indexs, 5);
+ int expected_heap_indexs[] = { 6, 7 };
+ CheckIterator(array, ConstantPoolArray::HEAP_PTR, expected_heap_indexs, 2);
+ int expected_int32_indexs[1];
+ CheckIterator(array, ConstantPoolArray::INT32, expected_int32_indexs, 0);
+}
+
+
+TEST(ConstantPoolIteratorExtended) {
+ LocalContext context;
+ Isolate* isolate = CcTest::i_isolate();
+ Factory* factory = isolate->factory();
+ v8::HandleScope scope(context->GetIsolate());
+
+ ConstantPoolArray::NumberOfEntries small(1, 0, 0, 4);
+ ConstantPoolArray::NumberOfEntries extended(5, 0, 3, 0);
+ Handle<ConstantPoolArray> array =
+ factory->NewExtendedConstantPoolArray(small, extended);
+
+ int expected_int64_indexs[] = { 0, 5, 6, 7, 8, 9 };
+ CheckIterator(array, ConstantPoolArray::INT64, expected_int64_indexs, 6);
+ int expected_code_indexs[1];
+ CheckIterator(array, ConstantPoolArray::CODE_PTR, expected_code_indexs, 0);
+ int expected_heap_indexs[] = { 10, 11, 12 };
+ CheckIterator(array, ConstantPoolArray::HEAP_PTR, expected_heap_indexs, 3);
+ int expected_int32_indexs[] = { 1, 2, 3, 4 };
+ CheckIterator(array, ConstantPoolArray::INT32, expected_int32_indexs, 4);
+}
+
+
+TEST(ConstantPoolPreciseGC) {
+ LocalContext context;
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ Factory* factory = isolate->factory();
+ v8::HandleScope scope(context->GetIsolate());
+
+ ConstantPoolArray::NumberOfEntries small(1, 0, 0, 1);
+ Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(small);
+
+ // Check that the store buffer knows which entries are pointers and which are
+ // not. To do this, make non-pointer entries which look like new space
+ // pointers but are actually invalid and ensure the GC doesn't try to move
+ // them.
+ Handle<HeapObject> object = factory->NewHeapNumber(4.0);
+ Object* raw_ptr = *object;
+ // If interpreted as a pointer, this should be right inside the heap number
+ // which will cause a crash when trying to lookup the 'map' pointer.
+ intptr_t invalid_ptr = reinterpret_cast<intptr_t>(raw_ptr) + kInt32Size;
+ int32_t invalid_ptr_int32 = static_cast<int32_t>(invalid_ptr);
+ int64_t invalid_ptr_int64 = static_cast<int64_t>(invalid_ptr);
+ array->set(0, invalid_ptr_int64);
+ array->set(1, invalid_ptr_int32);
+
+ // Ensure we perform a scan on scavenge for the constant pool's page.
+ MemoryChunk::FromAddress(array->address())->set_scan_on_scavenge(true);
heap->CollectGarbage(NEW_SPACE);
- Object* new_ptr = array->get_heap_ptr_entry(5);
- CHECK_NE(*object, old_ptr);
- CHECK_EQ(*object, new_ptr);
+
+ // Check the object was moved by GC.
+ CHECK_NE(*object, raw_ptr);
+
+ // Check the non-pointer entries weren't changed.
+ CHECK_EQ(invalid_ptr_int64, array->get_int64_entry(0));
+ CHECK_EQ(invalid_ptr_int32, array->get_int32_entry(1));
+}
+
+
+TEST(ConstantPoolCompacting) {
+ if (i::FLAG_never_compact) return;
+ i::FLAG_always_compact = true;
+ LocalContext context;
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ Factory* factory = isolate->factory();
+ v8::HandleScope scope(context->GetIsolate());
+
+ ConstantPoolArray::NumberOfEntries small(0, 0, 1, 0);
+ ConstantPoolArray::NumberOfEntries extended(0, 0, 1, 0);
+ Handle<ConstantPoolArray> array =
+ factory->NewExtendedConstantPoolArray(small, extended);
+
+ // Start a second old-space page so that the heap pointer added to the
+ // constant pool array ends up on the an evacuation candidate page.
+ Page* first_page = heap->old_data_space()->anchor()->next_page();
+ {
+ HandleScope scope(isolate);
+ Handle<HeapObject> temp =
+ factory->NewFixedDoubleArray(900 * KB / kDoubleSize, TENURED);
+ CHECK(heap->InOldDataSpace(temp->address()));
+ Handle<HeapObject> heap_ptr =
+ factory->NewHeapNumber(5.0, IMMUTABLE, TENURED);
+ CHECK(heap->InOldDataSpace(heap_ptr->address()));
+ CHECK(!first_page->Contains(heap_ptr->address()));
+ array->set(0, *heap_ptr);
+ array->set(1, *heap_ptr);
+ }
+
+ // Check heap pointers are correctly updated on GC.
+ Object* old_ptr = array->get_heap_ptr_entry(0);
+ Handle<Object> object(old_ptr, isolate);
+ CHECK_EQ(old_ptr, *object);
+ CHECK_EQ(old_ptr, array->get_heap_ptr_entry(1));
+
+ // Force compacting garbage collection.
+ CHECK(FLAG_always_compact);
+ heap->CollectAllGarbage(Heap::kNoGCFlags);
+
+ CHECK_NE(old_ptr, *object);
+ CHECK_EQ(*object, array->get_heap_ptr_entry(0));
+ CHECK_EQ(*object, array->get_heap_ptr_entry(1));
}
diff --git a/deps/v8/test/cctest/test-conversions.cc b/deps/v8/test/cctest/test-conversions.cc
index 9e194eaff..93bed7f4d 100644
--- a/deps/v8/test/cctest/test-conversions.cc
+++ b/deps/v8/test/cctest/test-conversions.cc
@@ -27,10 +27,10 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "platform.h"
-#include "cctest.h"
+#include "src/base/platform/platform.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -172,9 +172,12 @@ TEST(TrailingJunk) {
TEST(NonStrDecimalLiteral) {
UnicodeCache uc;
- CHECK(std::isnan(StringToDouble(&uc, " ", NO_FLAGS, OS::nan_value())));
- CHECK(std::isnan(StringToDouble(&uc, "", NO_FLAGS, OS::nan_value())));
- CHECK(std::isnan(StringToDouble(&uc, " ", NO_FLAGS, OS::nan_value())));
+ CHECK(std::isnan(
+ StringToDouble(&uc, " ", NO_FLAGS, v8::base::OS::nan_value())));
+ CHECK(
+ std::isnan(StringToDouble(&uc, "", NO_FLAGS, v8::base::OS::nan_value())));
+ CHECK(std::isnan(
+ StringToDouble(&uc, " ", NO_FLAGS, v8::base::OS::nan_value())));
CHECK_EQ(0.0, StringToDouble(&uc, "", NO_FLAGS));
CHECK_EQ(0.0, StringToDouble(&uc, " ", NO_FLAGS));
}
diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc
index 6cff7424b..6051c3fd7 100644
--- a/deps/v8/test/cctest/test-cpu-profiler.cc
+++ b/deps/v8/test/cctest/test-cpu-profiler.cc
@@ -27,14 +27,15 @@
//
// Tests of profiles generator and utilities.
-#include "v8.h"
-#include "cpu-profiler-inl.h"
-#include "cctest.h"
-#include "platform.h"
-#include "profiler-extension.h"
-#include "smart-pointers.h"
-#include "utils.h"
-#include "../include/v8-profiler.h"
+#include "src/v8.h"
+
+#include "include/v8-profiler.h"
+#include "src/base/platform/platform.h"
+#include "src/cpu-profiler-inl.h"
+#include "src/smart-pointers.h"
+#include "src/utils.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/profiler-extension.h"
using i::CodeEntry;
using i::CpuProfile;
using i::CpuProfiler;
@@ -45,7 +46,6 @@ using i::ProfileNode;
using i::ProfilerEventsProcessor;
using i::ScopedVector;
using i::SmartPointer;
-using i::TimeDelta;
using i::Vector;
@@ -54,7 +54,7 @@ TEST(StartStop) {
CpuProfilesCollection profiles(isolate->heap());
ProfileGenerator generator(&profiles);
SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor(
- &generator, NULL, TimeDelta::FromMicroseconds(100)));
+ &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100)));
processor->Start();
processor->StopSynchronously();
}
@@ -104,9 +104,9 @@ i::Code* CreateCode(LocalContext* env) {
i::EmbeddedVector<char, 256> script;
i::EmbeddedVector<char, 32> name;
- i::OS::SNPrintF(name, "function_%d", ++counter);
+ i::SNPrintF(name, "function_%d", ++counter);
const char* name_start = name.start();
- i::OS::SNPrintF(script,
+ i::SNPrintF(script,
"function %s() {\n"
"var counter = 0;\n"
"for (var i = 0; i < %d; ++i) counter += i;\n"
@@ -142,7 +142,7 @@ TEST(CodeEvents) {
profiles->StartProfiling("", false);
ProfileGenerator generator(profiles);
SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor(
- &generator, NULL, TimeDelta::FromMicroseconds(100)));
+ &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100)));
processor->Start();
CpuProfiler profiler(isolate, profiles, &generator, processor.get());
@@ -203,7 +203,7 @@ TEST(TickEvents) {
profiles->StartProfiling("", false);
ProfileGenerator generator(profiles);
SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor(
- &generator, NULL, TimeDelta::FromMicroseconds(100)));
+ &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100)));
processor->Start();
CpuProfiler profiler(isolate, profiles, &generator, processor.get());
@@ -272,7 +272,7 @@ TEST(Issue1398) {
profiles->StartProfiling("", false);
ProfileGenerator generator(profiles);
SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor(
- &generator, NULL, TimeDelta::FromMicroseconds(100)));
+ &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100)));
processor->Start();
CpuProfiler profiler(isolate, profiles, &generator, processor.get());
@@ -282,7 +282,7 @@ TEST(Issue1398) {
sample->pc = code->address();
sample->tos = 0;
sample->frames_count = i::TickSample::kMaxFramesCount;
- for (int i = 0; i < sample->frames_count; ++i) {
+ for (unsigned i = 0; i < sample->frames_count; ++i) {
sample->stack[i] = code->address();
}
processor->FinishTickSample();
@@ -469,8 +469,8 @@ static const v8::CpuProfileNode* GetChild(v8::Isolate* isolate,
const v8::CpuProfileNode* result = FindChild(isolate, node, name);
if (!result) {
char buffer[100];
- i::OS::SNPrintF(Vector<char>(buffer, ARRAY_SIZE(buffer)),
- "Failed to GetChild: %s", name);
+ i::SNPrintF(Vector<char>(buffer, ARRAY_SIZE(buffer)),
+ "Failed to GetChild: %s", name);
FATAL(buffer);
}
return result;
@@ -587,6 +587,72 @@ TEST(CollectCpuProfile) {
}
+static const char* hot_deopt_no_frame_entry_test_source =
+"function foo(a, b) {\n"
+" try {\n"
+" return a + b;\n"
+" } catch (e) { }\n"
+"}\n"
+"function start(timeout) {\n"
+" var start = Date.now();\n"
+" do {\n"
+" for (var i = 1; i < 1000; ++i) foo(1, i);\n"
+" var duration = Date.now() - start;\n"
+" } while (duration < timeout);\n"
+" return duration;\n"
+"}\n";
+
+// Check that the profile tree for the script above will look like the
+// following:
+//
+// [Top down]:
+// 1062 0 (root) [-1]
+// 1054 0 start [-1]
+// 1054 1 foo [-1]
+// 2 2 (program) [-1]
+// 6 6 (garbage collector) [-1]
+//
+// The test checks no FP ranges are present in a deoptimized funcion.
+// If 'foo' has no ranges the samples falling into the prologue will miss the
+// 'start' function on the stack, so 'foo' will be attached to the (root).
+TEST(HotDeoptNoFrameEntry) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ v8::Script::Compile(v8::String::NewFromUtf8(
+ env->GetIsolate(),
+ hot_deopt_no_frame_entry_test_source))->Run();
+ v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start")));
+
+ int32_t profiling_interval_ms = 200;
+ v8::Handle<v8::Value> args[] = {
+ v8::Integer::New(env->GetIsolate(), profiling_interval_ms)
+ };
+ v8::CpuProfile* profile =
+ RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 200);
+ function->Call(env->Global(), ARRAY_SIZE(args), args);
+
+ const v8::CpuProfileNode* root = profile->GetTopDownRoot();
+
+ ScopedVector<v8::Handle<v8::String> > names(3);
+ names[0] = v8::String::NewFromUtf8(
+ env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName);
+ names[1] = v8::String::NewFromUtf8(env->GetIsolate(),
+ ProfileGenerator::kProgramEntryName);
+ names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "start");
+ CheckChildrenNames(root, names);
+
+ const v8::CpuProfileNode* startNode =
+ GetChild(env->GetIsolate(), root, "start");
+ CHECK_EQ(1, startNode->GetChildrenCount());
+
+ GetChild(env->GetIsolate(), startNode, "foo");
+
+ profile->Delete();
+}
+
+
TEST(CollectCpuProfileSamples) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -724,11 +790,11 @@ class TestApiCallbacks {
private:
void Wait() {
if (is_warming_up_) return;
- double start = i::OS::TimeCurrentMillis();
+ double start = v8::base::OS::TimeCurrentMillis();
double duration = 0;
while (duration < min_duration_ms_) {
- i::OS::Sleep(1);
- duration = i::OS::TimeCurrentMillis() - start;
+ v8::base::OS::Sleep(1);
+ duration = v8::base::OS::TimeCurrentMillis() - start;
}
}
@@ -957,23 +1023,20 @@ TEST(NativeMethodMonomorphicIC) {
}
-static const char* bound_function_test_source = "function foo(iterations) {\n"
-" var r = 0;\n"
-" for (var i = 0; i < iterations; i++) { r += i; }\n"
-" return r;\n"
-"}\n"
-"function start(duration) {\n"
-" var callback = foo.bind(this);\n"
-" var start = Date.now();\n"
-" while (Date.now() - start < duration) {\n"
-" callback(10 * 1000);\n"
-" }\n"
-"}";
+static const char* bound_function_test_source =
+ "function foo() {\n"
+ " startProfiling('my_profile');\n"
+ "}\n"
+ "function start() {\n"
+ " var callback = foo.bind(this);\n"
+ " callback();\n"
+ "}";
TEST(BoundFunctionCall) {
- LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Context::Scope context_scope(env);
v8::Script::Compile(
v8::String::NewFromUtf8(env->GetIsolate(), bound_function_test_source))
@@ -981,12 +1044,7 @@ TEST(BoundFunctionCall) {
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start")));
- int32_t duration_ms = 100;
- v8::Handle<v8::Value> args[] = {
- v8::Integer::New(env->GetIsolate(), duration_ms)
- };
- v8::CpuProfile* profile =
- RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100);
+ v8::CpuProfile* profile = RunProfiler(env, function, NULL, 0, 0);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
ScopedVector<v8::Handle<v8::String> > names(3);
@@ -1158,9 +1216,12 @@ TEST(FunctionApplySample) {
const v8::CpuProfileNode* testNode =
FindChild(env->GetIsolate(), startNode, "test");
if (testNode) {
- ScopedVector<v8::Handle<v8::String> > names(2);
+ ScopedVector<v8::Handle<v8::String> > names(3);
names[0] = v8::String::NewFromUtf8(env->GetIsolate(), "bar");
names[1] = v8::String::NewFromUtf8(env->GetIsolate(), "apply");
+ // apply calls "get length" before invoking the function itself
+ // and we may get hit into it.
+ names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "get length");
CheckChildrenNames(testNode, names);
}
@@ -1178,28 +1239,84 @@ TEST(FunctionApplySample) {
}
-static const char* js_native_js_test_source =
-"var is_profiling = false;\n"
-"function foo(iterations) {\n"
-" if (!is_profiling) {\n"
-" is_profiling = true;\n"
+static const char* cpu_profiler_deep_stack_test_source =
+"function foo(n) {\n"
+" if (n)\n"
+" foo(n - 1);\n"
+" else\n"
" startProfiling('my_profile');\n"
-" }\n"
-" var r = 0;\n"
-" for (var i = 0; i < iterations; i++) { r += i; }\n"
-" return r;\n"
"}\n"
-"function bar(iterations) {\n"
-" try { foo(iterations); } catch(e) {}\n"
-"}\n"
-"function start(duration) {\n"
-" var start = Date.now();\n"
-" while (Date.now() - start < duration) {\n"
-" try {\n"
-" CallJsFunction(bar, 10 * 1000);\n"
-" } catch(e) {}\n"
-" }\n"
-"}";
+"function start() {\n"
+" foo(250);\n"
+"}\n";
+
+
+// Check a deep stack
+//
+// [Top down]:
+// 0 (root) 0 #1
+// 2 (program) 0 #2
+// 0 start 21 #3 no reason
+// 0 foo 21 #4 no reason
+// 0 foo 21 #5 no reason
+// ....
+// 0 foo 21 #253 no reason
+// 1 startProfiling 0 #254
+TEST(CpuProfileDeepStack) {
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Context::Scope context_scope(env);
+
+ v8::Script::Compile(v8::String::NewFromUtf8(
+ env->GetIsolate(), cpu_profiler_deep_stack_test_source))->Run();
+ v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start")));
+
+ v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
+ v8::Local<v8::String> profile_name =
+ v8::String::NewFromUtf8(env->GetIsolate(), "my_profile");
+ function->Call(env->Global(), 0, NULL);
+ v8::CpuProfile* profile = cpu_profiler->StopProfiling(profile_name);
+ CHECK_NE(NULL, profile);
+ // Dump collected profile to have a better diagnostic in case of failure.
+ reinterpret_cast<i::CpuProfile*>(profile)->Print();
+
+ const v8::CpuProfileNode* root = profile->GetTopDownRoot();
+ {
+ ScopedVector<v8::Handle<v8::String> > names(3);
+ names[0] = v8::String::NewFromUtf8(
+ env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName);
+ names[1] = v8::String::NewFromUtf8(env->GetIsolate(),
+ ProfileGenerator::kProgramEntryName);
+ names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "start");
+ CheckChildrenNames(root, names);
+ }
+
+ const v8::CpuProfileNode* node =
+ GetChild(env->GetIsolate(), root, "start");
+ for (int i = 0; i < 250; ++i) {
+ node = GetChild(env->GetIsolate(), node, "foo");
+ }
+ // TODO(alph):
+ // In theory there must be one more 'foo' and a 'startProfiling' nodes,
+ // but due to unstable top frame extraction these might be missing.
+
+ profile->Delete();
+}
+
+
+static const char* js_native_js_test_source =
+ "function foo() {\n"
+ " startProfiling('my_profile');\n"
+ "}\n"
+ "function bar() {\n"
+ " try { foo(); } catch(e) {}\n"
+ "}\n"
+ "function start() {\n"
+ " try {\n"
+ " CallJsFunction(bar);\n"
+ " } catch(e) {}\n"
+ "}";
static void CallJsFunction(const v8::FunctionCallbackInfo<v8::Value>& info) {
v8::Handle<v8::Function> function = info[0].As<v8::Function>();
@@ -1232,12 +1349,7 @@ TEST(JsNativeJsSample) {
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start")));
- int32_t duration_ms = 20;
- v8::Handle<v8::Value> args[] = {
- v8::Integer::New(env->GetIsolate(), duration_ms)
- };
- v8::CpuProfile* profile =
- RunProfiler(env, function, args, ARRAY_SIZE(args), 10);
+ v8::CpuProfile* profile = RunProfiler(env, function, NULL, 0, 0);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
{
@@ -1268,28 +1380,18 @@ TEST(JsNativeJsSample) {
static const char* js_native_js_runtime_js_test_source =
-"var is_profiling = false;\n"
-"function foo(iterations) {\n"
-" if (!is_profiling) {\n"
-" is_profiling = true;\n"
-" startProfiling('my_profile');\n"
-" }\n"
-" var r = 0;\n"
-" for (var i = 0; i < iterations; i++) { r += i; }\n"
-" return r;\n"
-"}\n"
-"var bound = foo.bind(this);\n"
-"function bar(iterations) {\n"
-" try { bound(iterations); } catch(e) {}\n"
-"}\n"
-"function start(duration) {\n"
-" var start = Date.now();\n"
-" while (Date.now() - start < duration) {\n"
-" try {\n"
-" CallJsFunction(bar, 10 * 1000);\n"
-" } catch(e) {}\n"
-" }\n"
-"}";
+ "function foo() {\n"
+ " startProfiling('my_profile');\n"
+ "}\n"
+ "var bound = foo.bind(this);\n"
+ "function bar() {\n"
+ " try { bound(); } catch(e) {}\n"
+ "}\n"
+ "function start() {\n"
+ " try {\n"
+ " CallJsFunction(bar);\n"
+ " } catch(e) {}\n"
+ "}";
// [Top down]:
@@ -1317,12 +1419,7 @@ TEST(JsNativeJsRuntimeJsSample) {
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start")));
- int32_t duration_ms = 20;
- v8::Handle<v8::Value> args[] = {
- v8::Integer::New(env->GetIsolate(), duration_ms)
- };
- v8::CpuProfile* profile =
- RunProfiler(env, function, args, ARRAY_SIZE(args), 10);
+ v8::CpuProfile* profile = RunProfiler(env, function, NULL, 0, 0);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
ScopedVector<v8::Handle<v8::String> > names(3);
@@ -1343,7 +1440,11 @@ TEST(JsNativeJsRuntimeJsSample) {
const v8::CpuProfileNode* barNode =
GetChild(env->GetIsolate(), nativeFunctionNode, "bar");
- CHECK_EQ(1, barNode->GetChildrenCount());
+ // The child is in fact a bound foo.
+ // A bound function has a wrapper that may make calls to
+ // other functions e.g. "get length".
+ CHECK_LE(1, barNode->GetChildrenCount());
+ CHECK_GE(2, barNode->GetChildrenCount());
GetChild(env->GetIsolate(), barNode, "foo");
profile->Delete();
@@ -1351,32 +1452,25 @@ TEST(JsNativeJsRuntimeJsSample) {
static void CallJsFunction2(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::base::OS::Print("In CallJsFunction2\n");
CallJsFunction(info);
}
static const char* js_native1_js_native2_js_test_source =
-"var is_profiling = false;\n"
-"function foo(iterations) {\n"
-" if (!is_profiling) {\n"
-" is_profiling = true;\n"
-" startProfiling('my_profile');\n"
-" }\n"
-" var r = 0;\n"
-" for (var i = 0; i < iterations; i++) { r += i; }\n"
-" return r;\n"
-"}\n"
-"function bar(iterations) {\n"
-" CallJsFunction2(foo, iterations);\n"
-"}\n"
-"function start(duration) {\n"
-" var start = Date.now();\n"
-" while (Date.now() - start < duration) {\n"
-" try {\n"
-" CallJsFunction1(bar, 10 * 1000);\n"
-" } catch(e) {}\n"
-" }\n"
-"}";
+ "function foo() {\n"
+ " try {\n"
+ " startProfiling('my_profile');\n"
+ " } catch(e) {}\n"
+ "}\n"
+ "function bar() {\n"
+ " CallJsFunction2(foo);\n"
+ "}\n"
+ "function start() {\n"
+ " try {\n"
+ " CallJsFunction1(bar);\n"
+ " } catch(e) {}\n"
+ "}";
// [Top down]:
@@ -1411,12 +1505,7 @@ TEST(JsNative1JsNative2JsSample) {
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start")));
- int32_t duration_ms = 20;
- v8::Handle<v8::Value> args[] = {
- v8::Integer::New(env->GetIsolate(), duration_ms)
- };
- v8::CpuProfile* profile =
- RunProfiler(env, function, args, ARRAY_SIZE(args), 10);
+ v8::CpuProfile* profile = RunProfiler(env, function, NULL, 0, 0);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
ScopedVector<v8::Handle<v8::String> > names(3);
@@ -1540,25 +1629,23 @@ TEST(FunctionDetails) {
const_cast<v8::CpuProfileNode*>(current))->Print(0);
// The tree should look like this:
// 0 (root) 0 #1
- // 0 (anonymous function) 19 #2 no reason script_b:1
+ // 0 "" 19 #2 no reason script_b:1
// 0 baz 19 #3 TryCatchStatement script_b:3
// 0 foo 18 #4 TryCatchStatement script_a:2
// 1 bar 18 #5 no reason script_a:3
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
- const v8::CpuProfileNode* script = GetChild(env->GetIsolate(), root,
- ProfileGenerator::kAnonymousFunctionName);
- CheckFunctionDetails(env->GetIsolate(), script,
- ProfileGenerator::kAnonymousFunctionName, "script_b",
- script_b->GetId(), 1, 1);
+ const v8::CpuProfileNode* script = GetChild(env->GetIsolate(), root, "");
+ CheckFunctionDetails(env->GetIsolate(), script, "", "script_b",
+ script_b->GetUnboundScript()->GetId(), 1, 1);
const v8::CpuProfileNode* baz = GetChild(env->GetIsolate(), script, "baz");
CheckFunctionDetails(env->GetIsolate(), baz, "baz", "script_b",
- script_b->GetId(), 3, 16);
+ script_b->GetUnboundScript()->GetId(), 3, 16);
const v8::CpuProfileNode* foo = GetChild(env->GetIsolate(), baz, "foo");
CheckFunctionDetails(env->GetIsolate(), foo, "foo", "script_a",
- script_a->GetId(), 2, 1);
+ script_a->GetUnboundScript()->GetId(), 2, 1);
const v8::CpuProfileNode* bar = GetChild(env->GetIsolate(), foo, "bar");
CheckFunctionDetails(env->GetIsolate(), bar, "bar", "script_a",
- script_a->GetId(), 3, 14);
+ script_a->GetUnboundScript()->GetId(), 3, 14);
}
diff --git a/deps/v8/test/cctest/test-dataflow.cc b/deps/v8/test/cctest/test-dataflow.cc
index 532c9207b..fc1a7fa13 100644
--- a/deps/v8/test/cctest/test-dataflow.cc
+++ b/deps/v8/test/cctest/test-dataflow.cc
@@ -27,10 +27,10 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "data-flow.h"
-#include "cctest.h"
+#include "src/data-flow.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-date.cc b/deps/v8/test/cctest/test-date.cc
index 5190729fa..f2187955a 100644
--- a/deps/v8/test/cctest/test-date.cc
+++ b/deps/v8/test/cctest/test-date.cc
@@ -25,11 +25,11 @@
// (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 "src/v8.h"
-#include "global-handles.h"
-#include "snapshot.h"
-#include "cctest.h"
+#include "src/global-handles.h"
+#include "src/snapshot.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index 85e4512ea..5c0b0f392 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -27,28 +27,27 @@
#include <stdlib.h>
-#include "v8.h"
-
-#include "api.h"
-#include "cctest.h"
-#include "compilation-cache.h"
-#include "debug.h"
-#include "deoptimizer.h"
-#include "frames.h"
-#include "platform.h"
-#include "platform/condition-variable.h"
-#include "platform/socket.h"
-#include "stub-cache.h"
-#include "utils.h"
-
-
-using ::v8::internal::Mutex;
-using ::v8::internal::LockGuard;
-using ::v8::internal::ConditionVariable;
-using ::v8::internal::Semaphore;
+#include "src/v8.h"
+
+#include "src/api.h"
+#include "src/base/platform/condition-variable.h"
+#include "src/base/platform/platform.h"
+#include "src/compilation-cache.h"
+#include "src/debug.h"
+#include "src/deoptimizer.h"
+#include "src/frames.h"
+#include "src/stub-cache.h"
+#include "src/utils.h"
+#include "test/cctest/cctest.h"
+
+
+using ::v8::base::Mutex;
+using ::v8::base::LockGuard;
+using ::v8::base::ConditionVariable;
+using ::v8::base::OS;
+using ::v8::base::Semaphore;
using ::v8::internal::EmbeddedVector;
using ::v8::internal::Object;
-using ::v8::internal::OS;
using ::v8::internal::Handle;
using ::v8::internal::Heap;
using ::v8::internal::JSGlobalProxy;
@@ -99,20 +98,19 @@ class DebugLocalContext {
v8::internal::Isolate* isolate =
reinterpret_cast<v8::internal::Isolate*>(context_->GetIsolate());
v8::internal::Factory* factory = isolate->factory();
- v8::internal::Debug* debug = isolate->debug();
// Expose the debug context global object in the global object for testing.
- debug->Load();
- debug->debug_context()->set_security_token(
+ CHECK(isolate->debug()->Load());
+ Handle<v8::internal::Context> debug_context =
+ isolate->debug()->debug_context();
+ debug_context->set_security_token(
v8::Utils::OpenHandle(*context_)->security_token());
Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast(
v8::Utils::OpenHandle(*context_->Global())));
Handle<v8::internal::String> debug_string =
factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("debug"));
- v8::internal::Runtime::SetObjectProperty(isolate, global, debug_string,
- Handle<Object>(debug->debug_context()->global_proxy(), isolate),
- DONT_ENUM,
- ::v8::internal::SLOPPY).Check();
+ v8::internal::Runtime::DefineObjectProperty(global, debug_string,
+ handle(debug_context->global_proxy(), isolate), DONT_ENUM).Check();
}
private:
@@ -182,9 +180,9 @@ static int SetBreakPointFromJS(v8::Isolate* isolate,
const char* function_name,
int line, int position) {
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
- OS::SNPrintF(buffer,
- "debug.Debug.setBreakPoint(%s,%d,%d)",
- function_name, line, position);
+ SNPrintF(buffer,
+ "debug.Debug.setBreakPoint(%s,%d,%d)",
+ function_name, line, position);
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
v8::Handle<v8::String> str = v8::String::NewFromUtf8(isolate, buffer.start());
return v8::Script::Compile(str)->Run()->Int32Value();
@@ -197,14 +195,14 @@ static int SetScriptBreakPointByIdFromJS(v8::Isolate* isolate, int script_id,
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
if (column >= 0) {
// Column specified set script break point on precise location.
- OS::SNPrintF(buffer,
- "debug.Debug.setScriptBreakPointById(%d,%d,%d)",
- script_id, line, column);
+ SNPrintF(buffer,
+ "debug.Debug.setScriptBreakPointById(%d,%d,%d)",
+ script_id, line, column);
} else {
// Column not specified set script break point on line.
- OS::SNPrintF(buffer,
- "debug.Debug.setScriptBreakPointById(%d,%d)",
- script_id, line);
+ SNPrintF(buffer,
+ "debug.Debug.setScriptBreakPointById(%d,%d)",
+ script_id, line);
}
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
{
@@ -226,14 +224,14 @@ static int SetScriptBreakPointByNameFromJS(v8::Isolate* isolate,
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
if (column >= 0) {
// Column specified set script break point on precise location.
- OS::SNPrintF(buffer,
- "debug.Debug.setScriptBreakPointByName(\"%s\",%d,%d)",
- script_name, line, column);
+ SNPrintF(buffer,
+ "debug.Debug.setScriptBreakPointByName(\"%s\",%d,%d)",
+ script_name, line, column);
} else {
// Column not specified set script break point on line.
- OS::SNPrintF(buffer,
- "debug.Debug.setScriptBreakPointByName(\"%s\",%d)",
- script_name, line);
+ SNPrintF(buffer,
+ "debug.Debug.setScriptBreakPointByName(\"%s\",%d)",
+ script_name, line);
}
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
{
@@ -260,9 +258,9 @@ static void ClearBreakPoint(int break_point) {
static void ClearBreakPointFromJS(v8::Isolate* isolate,
int break_point_number) {
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
- OS::SNPrintF(buffer,
- "debug.Debug.clearBreakPoint(%d)",
- break_point_number);
+ SNPrintF(buffer,
+ "debug.Debug.clearBreakPoint(%d)",
+ break_point_number);
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run();
}
@@ -271,9 +269,9 @@ static void ClearBreakPointFromJS(v8::Isolate* isolate,
static void EnableScriptBreakPointFromJS(v8::Isolate* isolate,
int break_point_number) {
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
- OS::SNPrintF(buffer,
- "debug.Debug.enableScriptBreakPoint(%d)",
- break_point_number);
+ SNPrintF(buffer,
+ "debug.Debug.enableScriptBreakPoint(%d)",
+ break_point_number);
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run();
}
@@ -282,9 +280,9 @@ static void EnableScriptBreakPointFromJS(v8::Isolate* isolate,
static void DisableScriptBreakPointFromJS(v8::Isolate* isolate,
int break_point_number) {
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
- OS::SNPrintF(buffer,
- "debug.Debug.disableScriptBreakPoint(%d)",
- break_point_number);
+ SNPrintF(buffer,
+ "debug.Debug.disableScriptBreakPoint(%d)",
+ break_point_number);
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run();
}
@@ -294,9 +292,9 @@ static void ChangeScriptBreakPointConditionFromJS(v8::Isolate* isolate,
int break_point_number,
const char* condition) {
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
- OS::SNPrintF(buffer,
- "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")",
- break_point_number, condition);
+ SNPrintF(buffer,
+ "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")",
+ break_point_number, condition);
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run();
}
@@ -306,9 +304,9 @@ static void ChangeScriptBreakPointIgnoreCountFromJS(v8::Isolate* isolate,
int break_point_number,
int ignoreCount) {
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
- OS::SNPrintF(buffer,
- "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)",
- break_point_number, ignoreCount);
+ SNPrintF(buffer,
+ "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)",
+ break_point_number, ignoreCount);
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run();
}
@@ -422,12 +420,6 @@ void CheckDebuggerUnloaded(bool check_functions) {
}
-void ForceUnloadDebugger() {
- CcTest::i_isolate()->debugger()->never_unload_debugger_ = false;
- CcTest::i_isolate()->debugger()->UnloadDebugger();
-}
-
-
} } // namespace v8::internal
@@ -1094,7 +1086,7 @@ TEST(BreakPointICStore) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
"function foo(){bar=0;}"))->Run();
v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
@@ -1116,7 +1108,7 @@ TEST(BreakPointICStore) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -1126,7 +1118,7 @@ TEST(BreakPointICLoad) {
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "bar=1"))
->Run();
v8::Script::Compile(
@@ -1151,7 +1143,7 @@ TEST(BreakPointICLoad) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -1161,7 +1153,7 @@ TEST(BreakPointICCall) {
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Script::Compile(
v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){}"))->Run();
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
@@ -1185,7 +1177,7 @@ TEST(BreakPointICCall) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -1195,7 +1187,7 @@ TEST(BreakPointICCallWithGC) {
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage);
v8::Script::Compile(
v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){return 1;}"))
->Run();
@@ -1221,7 +1213,7 @@ TEST(BreakPointICCallWithGC) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -1231,7 +1223,7 @@ TEST(BreakPointConstructCallWithGC) {
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage);
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
"function bar(){ this.x = 1;}"))
->Run();
@@ -1257,7 +1249,7 @@ TEST(BreakPointConstructCallWithGC) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -1278,7 +1270,7 @@ TEST(BreakPointReturn) {
"frame_source_column");
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Script::Compile(
v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){}"))->Run();
v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
@@ -1304,7 +1296,7 @@ TEST(BreakPointReturn) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -1327,7 +1319,7 @@ TEST(GCDuringBreakPointProcessing) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage);
v8::Local<v8::Function> foo;
// Test IC store break point with garbage collection.
@@ -1355,7 +1347,7 @@ TEST(GCDuringBreakPointProcessing) {
SetBreakPoint(foo, 0);
CallWithBreakPoints(env->Global(), foo, 1, 25);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -1390,7 +1382,7 @@ TEST(BreakPointSurviveGC) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::Function> foo;
// Test IC store break point with garbage collection.
@@ -1436,7 +1428,7 @@ TEST(BreakPointSurviveGC) {
CallAndGC(env->Global(), foo);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -1448,7 +1440,7 @@ TEST(BreakPointThroughJavaScript) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Script::Compile(
v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){}"))->Run();
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
@@ -1490,7 +1482,7 @@ TEST(BreakPointThroughJavaScript) {
foo->Run();
CHECK_EQ(8, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
// Make sure that the break point numbers are consecutive.
@@ -1507,7 +1499,7 @@ TEST(ScriptBreakPointByNameThroughJavaScript) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::NewFromUtf8(
env->GetIsolate(),
@@ -1592,7 +1584,7 @@ TEST(ScriptBreakPointByNameThroughJavaScript) {
g->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
// Make sure that the break point numbers are consecutive.
@@ -1611,7 +1603,7 @@ TEST(ScriptBreakPointByIdThroughJavaScript) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::String> source = v8::String::NewFromUtf8(
env->GetIsolate(),
@@ -1644,7 +1636,7 @@ TEST(ScriptBreakPointByIdThroughJavaScript) {
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g")));
// Get the script id knowing that internally it is a 32 integer.
- int script_id = script->GetId();
+ int script_id = script->GetUnboundScript()->GetId();
// Call f and g without break points.
break_point_hit_count = 0;
@@ -1700,7 +1692,7 @@ TEST(ScriptBreakPointByIdThroughJavaScript) {
g->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
// Make sure that the break point numbers are consecutive.
@@ -1720,7 +1712,7 @@ TEST(EnableDisableScriptBreakPoint) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::NewFromUtf8(
env->GetIsolate(),
@@ -1766,7 +1758,7 @@ TEST(EnableDisableScriptBreakPoint) {
f->Call(env->Global(), 0, NULL);
CHECK_EQ(3, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -1778,7 +1770,7 @@ TEST(ConditionalScriptBreakPoint) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::NewFromUtf8(
env->GetIsolate(),
@@ -1829,7 +1821,7 @@ TEST(ConditionalScriptBreakPoint) {
}
CHECK_EQ(5, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -1841,7 +1833,7 @@ TEST(ScriptBreakPointIgnoreCount) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::NewFromUtf8(
env->GetIsolate(),
@@ -1885,7 +1877,7 @@ TEST(ScriptBreakPointIgnoreCount) {
}
CHECK_EQ(5, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -1897,7 +1889,7 @@ TEST(ScriptBreakPointReload) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::Function> f;
v8::Local<v8::String> script = v8::String::NewFromUtf8(
@@ -1949,7 +1941,7 @@ TEST(ScriptBreakPointReload) {
f->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -1961,7 +1953,7 @@ TEST(ScriptBreakPointMultiple) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::Function> f;
v8::Local<v8::String> script_f =
@@ -2018,7 +2010,7 @@ TEST(ScriptBreakPointMultiple) {
g->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2030,7 +2022,7 @@ TEST(ScriptBreakPointLineOffset) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::Function> f;
v8::Local<v8::String> script = v8::String::NewFromUtf8(
@@ -2078,7 +2070,7 @@ TEST(ScriptBreakPointLineOffset) {
f->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2094,7 +2086,7 @@ TEST(ScriptBreakPointLine) {
frame_function_name_source,
"frame_function_name");
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::Function> f;
v8::Local<v8::Function> g;
@@ -2194,7 +2186,7 @@ TEST(ScriptBreakPointLine) {
v8::Script::Compile(script, &origin)->Run();
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2205,7 +2197,7 @@ TEST(ScriptBreakPointLineTopLevel) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::String> script =
v8::String::NewFromUtf8(env->GetIsolate(),
@@ -2241,7 +2233,7 @@ TEST(ScriptBreakPointLineTopLevel) {
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2253,7 +2245,7 @@ TEST(ScriptBreakPointTopLevelCrash) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::String> script_source =
v8::String::NewFromUtf8(env->GetIsolate(),
@@ -2276,7 +2268,7 @@ TEST(ScriptBreakPointTopLevelCrash) {
ClearBreakPointFromJS(env->GetIsolate(), sbp1);
ClearBreakPointFromJS(env->GetIsolate(), sbp2);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2292,7 +2284,7 @@ TEST(RemoveBreakPointInBreak) {
debug_event_remove_break_point = SetBreakPoint(foo, 0);
// Register the debug event listener pasing the function
- v8::Debug::SetDebugEventListener2(DebugEventRemoveBreakPoint, foo);
+ v8::Debug::SetDebugEventListener(DebugEventRemoveBreakPoint, foo);
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -2302,7 +2294,7 @@ TEST(RemoveBreakPointInBreak) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2312,7 +2304,7 @@ TEST(DebuggerStatement) {
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Script::Compile(
v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){debugger}"))
->Run();
@@ -2332,7 +2324,7 @@ TEST(DebuggerStatement) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(3, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2342,7 +2334,7 @@ TEST(DebuggerStatementBreakpoint) {
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Script::Compile(
v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){debugger;}"))
->Run();
@@ -2360,7 +2352,7 @@ TEST(DebuggerStatementBreakpoint) {
CHECK_EQ(2, break_point_hit_count);
ClearBreakPoint(bp);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2378,7 +2370,7 @@ TEST(DebugEvaluate) {
evaluate_check_source,
"evaluate_check");
// Register the debug event listener
- v8::Debug::SetDebugEventListener2(DebugEventEvaluate);
+ v8::Debug::SetDebugEventListener(DebugEventEvaluate);
// Different expected vaules of x and a when in a break point (u = undefined,
// d = Hello, world!).
@@ -2479,7 +2471,7 @@ TEST(DebugEvaluate) {
};
bar->Call(env->Global(), 2, argv_bar_3);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2497,7 +2489,7 @@ TEST(ConditionalBreakpointWithCodeGenerationDisallowed) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(CheckDebugEvent);
+ v8::Debug::SetDebugEventListener(CheckDebugEvent);
v8::Local<v8::Function> foo = CompileFunction(&env,
"function foo(x) {\n"
@@ -2514,7 +2506,7 @@ TEST(ConditionalBreakpointWithCodeGenerationDisallowed) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, debugEventCount);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2544,7 +2536,7 @@ TEST(DebugEvaluateWithCodeGenerationDisallowed) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(CheckDebugEval);
+ v8::Debug::SetDebugEventListener(CheckDebugEval);
v8::Local<v8::Function> foo = CompileFunction(&env,
"var global = 'Global';\n"
@@ -2572,7 +2564,7 @@ TEST(DebugEvaluateWithCodeGenerationDisallowed) {
checkGlobalEvalFunction.Clear();
checkFrameEvalFunction.Clear();
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2630,7 +2622,7 @@ bool GetEvaluateStringResult(char *message, char* buffer, int buffer_size) {
if (len > buffer_size - 1) {
len = buffer_size - 1;
}
- OS::StrNCpy(buf, pos1, len);
+ StrNCpy(buf, pos1, len);
buffer[buffer_size - 1] = '\0';
return true;
}
@@ -2677,7 +2669,7 @@ static void DebugProcessDebugMessagesHandler(
// Test that the evaluation of expressions works even from ProcessDebugMessages
// i.e. with empty stack.
TEST(DebugEvaluateWithoutStack) {
- v8::Debug::SetMessageHandler2(DebugProcessDebugMessagesHandler);
+ v8::Debug::SetMessageHandler(DebugProcessDebugMessagesHandler);
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -2733,8 +2725,8 @@ TEST(DebugEvaluateWithoutStack) {
0);
CHECK_EQ(strcmp("805", process_debug_messages_data.results[2].buffer), 0);
- v8::Debug::SetMessageHandler2(NULL);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2755,7 +2747,7 @@ TEST(DebugStepLinear) {
SetBreakPoint(foo, 3);
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
step_action = StepIn;
break_point_hit_count = 0;
@@ -2764,11 +2756,11 @@ TEST(DebugStepLinear) {
// With stepping all break locations are hit.
CHECK_EQ(4, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
SetBreakPoint(foo, 3);
break_point_hit_count = 0;
@@ -2777,7 +2769,7 @@ TEST(DebugStepLinear) {
// Without stepping only active break points are hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2788,7 +2780,7 @@ TEST(DebugStepKeyedLoadLoop) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping of keyed load. The statement 'y=1'
// is there to have more than one breakable statement in the loop, TODO(315).
@@ -2826,7 +2818,7 @@ TEST(DebugStepKeyedLoadLoop) {
// With stepping all break locations are hit.
CHECK_EQ(35, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2837,7 +2829,7 @@ TEST(DebugStepKeyedStoreLoop) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping of keyed store. The statement 'y=1'
// is there to have more than one breakable statement in the loop, TODO(315).
@@ -2874,7 +2866,7 @@ TEST(DebugStepKeyedStoreLoop) {
// With stepping all break locations are hit.
CHECK_EQ(34, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2885,7 +2877,7 @@ TEST(DebugStepNamedLoadLoop) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping of named load.
v8::Local<v8::Function> foo = CompileFunction(
@@ -2918,7 +2910,7 @@ TEST(DebugStepNamedLoadLoop) {
// With stepping all break locations are hit.
CHECK_EQ(55, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2928,7 +2920,7 @@ static void DoDebugStepNamedStoreLoop(int expected) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping of named store.
v8::Local<v8::Function> foo = CompileFunction(
@@ -2953,7 +2945,7 @@ static void DoDebugStepNamedStoreLoop(int expected) {
// With stepping all expected break locations are hit.
CHECK_EQ(expected, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -2970,7 +2962,7 @@ TEST(DebugStepLinearMixedICs) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping.
v8::Local<v8::Function> foo = CompileFunction(&env,
@@ -2993,11 +2985,11 @@ TEST(DebugStepLinearMixedICs) {
// With stepping all break locations are hit.
CHECK_EQ(11, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
SetBreakPoint(foo, 0);
break_point_hit_count = 0;
@@ -3006,7 +2998,7 @@ TEST(DebugStepLinearMixedICs) {
// Without stepping only active break points are hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3016,7 +3008,7 @@ TEST(DebugStepDeclarations) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3039,7 +3031,7 @@ TEST(DebugStepDeclarations) {
CHECK_EQ(6, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3049,7 +3041,7 @@ TEST(DebugStepLocals) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3072,7 +3064,7 @@ TEST(DebugStepLocals) {
CHECK_EQ(6, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3083,7 +3075,7 @@ TEST(DebugStepIf) {
v8::HandleScope scope(isolate);
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3116,7 +3108,7 @@ TEST(DebugStepIf) {
CHECK_EQ(5, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3127,7 +3119,7 @@ TEST(DebugStepSwitch) {
v8::HandleScope scope(isolate);
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3173,7 +3165,7 @@ TEST(DebugStepSwitch) {
CHECK_EQ(7, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3184,7 +3176,7 @@ TEST(DebugStepWhile) {
v8::HandleScope scope(isolate);
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3199,22 +3191,29 @@ TEST(DebugStepWhile) {
v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
SetBreakPoint(foo, 8); // "var a = 0;"
+ // Looping 0 times. We still should break at the while-condition once.
+ step_action = StepIn;
+ break_point_hit_count = 0;
+ v8::Handle<v8::Value> argv_0[argc] = { v8::Number::New(isolate, 0) };
+ foo->Call(env->Global(), argc, argv_0);
+ CHECK_EQ(3, break_point_hit_count);
+
// Looping 10 times.
step_action = StepIn;
break_point_hit_count = 0;
v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) };
foo->Call(env->Global(), argc, argv_10);
- CHECK_EQ(22, break_point_hit_count);
+ CHECK_EQ(23, break_point_hit_count);
// Looping 100 times.
step_action = StepIn;
break_point_hit_count = 0;
v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) };
foo->Call(env->Global(), argc, argv_100);
- CHECK_EQ(202, break_point_hit_count);
+ CHECK_EQ(203, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3225,7 +3224,7 @@ TEST(DebugStepDoWhile) {
v8::HandleScope scope(isolate);
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3255,7 +3254,7 @@ TEST(DebugStepDoWhile) {
CHECK_EQ(202, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3266,7 +3265,7 @@ TEST(DebugStepFor) {
v8::HandleScope scope(isolate);
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3297,7 +3296,7 @@ TEST(DebugStepFor) {
CHECK_EQ(203, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3308,7 +3307,7 @@ TEST(DebugStepForContinue) {
v8::HandleScope scope(isolate);
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3349,7 +3348,7 @@ TEST(DebugStepForContinue) {
CHECK_EQ(457, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3360,7 +3359,7 @@ TEST(DebugStepForBreak) {
v8::HandleScope scope(isolate);
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3402,7 +3401,7 @@ TEST(DebugStepForBreak) {
CHECK_EQ(505, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3412,7 +3411,7 @@ TEST(DebugStepForIn) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3450,7 +3449,7 @@ TEST(DebugStepForIn) {
CHECK_EQ(8, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3460,7 +3459,7 @@ TEST(DebugStepWith) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3482,7 +3481,7 @@ TEST(DebugStepWith) {
CHECK_EQ(4, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3493,7 +3492,7 @@ TEST(DebugConditional) {
v8::HandleScope scope(isolate);
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3519,7 +3518,7 @@ TEST(DebugConditional) {
CHECK_EQ(5, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3534,7 +3533,7 @@ TEST(StepInOutSimple) {
"frame_function_name");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
+ v8::Debug::SetDebugEventListener(DebugEventStepSequence);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3570,7 +3569,7 @@ TEST(StepInOutSimple) {
break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3585,7 +3584,7 @@ TEST(StepInOutTree) {
"frame_function_name");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
+ v8::Debug::SetDebugEventListener(DebugEventStepSequence);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3622,7 +3621,7 @@ TEST(StepInOutTree) {
break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded(true);
}
@@ -3637,7 +3636,7 @@ TEST(StepInOutBranch) {
"frame_function_name");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
+ v8::Debug::SetDebugEventListener(DebugEventStepSequence);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3657,7 +3656,7 @@ TEST(StepInOutBranch) {
break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3674,7 +3673,7 @@ TEST(DebugStepNatives) {
"foo");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
step_action = StepIn;
break_point_hit_count = 0;
@@ -3683,11 +3682,11 @@ TEST(DebugStepNatives) {
// With stepping all break locations are hit.
CHECK_EQ(3, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -3695,7 +3694,7 @@ TEST(DebugStepNatives) {
// Without stepping only active break points are hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3713,7 +3712,7 @@ TEST(DebugStepFunctionApply) {
"foo");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
step_action = StepIn;
break_point_hit_count = 0;
@@ -3722,11 +3721,11 @@ TEST(DebugStepFunctionApply) {
// With stepping all break locations are hit.
CHECK_EQ(7, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -3734,7 +3733,7 @@ TEST(DebugStepFunctionApply) {
// Without stepping only the debugger statement is hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3759,7 +3758,7 @@ TEST(DebugStepFunctionCall) {
"foo");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStep);
+ v8::Debug::SetDebugEventListener(DebugEventStep);
step_action = StepIn;
// Check stepping where the if condition in bar is false.
@@ -3774,11 +3773,11 @@ TEST(DebugStepFunctionCall) {
foo->Call(env->Global(), argc, argv);
CHECK_EQ(8, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -3786,7 +3785,7 @@ TEST(DebugStepFunctionCall) {
// Without stepping only the debugger statement is hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3798,7 +3797,7 @@ TEST(PauseInScript) {
env.ExposeDebug();
// Register a debug event listener which counts.
- v8::Debug::SetDebugEventListener2(DebugEventCounter);
+ v8::Debug::SetDebugEventListener(DebugEventCounter);
// Create a script that returns a function.
const char* src = "(function (evt) {})";
@@ -3819,7 +3818,7 @@ TEST(PauseInScript) {
CHECK_EQ(1, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -3845,7 +3844,7 @@ TEST(BreakOnException) {
CompileFunction(&env, "function notCaught(){throws();}", "notCaught");
v8::V8::AddMessageListener(MessageCallbackCount);
- v8::Debug::SetDebugEventListener2(DebugEventCounter);
+ v8::Debug::SetDebugEventListener(DebugEventCounter);
// Initial state should be no break on exceptions.
DebugEventCounterClear();
@@ -3963,7 +3962,7 @@ TEST(BreakOnException) {
CHECK_EQ(1, uncaught_exception_hit_count);
CHECK_EQ(1, message_callback_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
v8::V8::RemoveMessageListeners(MessageCallbackCount);
}
@@ -3983,7 +3982,7 @@ TEST(BreakOnCompileException) {
frame_count = CompileFunction(&env, frame_count_source, "frame_count");
v8::V8::AddMessageListener(MessageCallbackCount);
- v8::Debug::SetDebugEventListener2(DebugEventCounter);
+ v8::Debug::SetDebugEventListener(DebugEventCounter);
DebugEventCounterClear();
MessageCallbackCountClear();
@@ -4039,7 +4038,7 @@ TEST(StepWithException) {
"frame_function_name");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
+ v8::Debug::SetDebugEventListener(DebugEventStepSequence);
// Create functions for testing stepping.
const char* src = "function a() { n(); }; "
@@ -4111,7 +4110,7 @@ TEST(StepWithException) {
break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -4126,7 +4125,7 @@ TEST(DebugBreak) {
v8::HandleScope scope(isolate);
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetDebugEventListener2(DebugEventBreak);
+ v8::Debug::SetDebugEventListener(DebugEventBreak);
// Create a function for testing stepping.
const char* src = "function f0() {}"
@@ -4166,7 +4165,7 @@ TEST(DebugBreak) {
CHECK_EQ(4 * ARRAY_SIZE(argv), break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -4178,7 +4177,7 @@ TEST(DisableBreak) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetDebugEventListener2(DebugEventCounter);
+ v8::Debug::SetDebugEventListener(DebugEventCounter);
// Create a function for testing stepping.
const char* src = "function f() {g()};function g(){i=0; while(i<10){i++}}";
@@ -4195,7 +4194,7 @@ TEST(DisableBreak) {
{
v8::Debug::DebugBreak(env->GetIsolate());
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate());
- v8::internal::DisableBreak disable_break(isolate, true);
+ v8::internal::DisableBreak disable_break(isolate->debug(), true);
f->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
}
@@ -4204,7 +4203,7 @@ TEST(DisableBreak) {
CHECK_EQ(2, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -4220,7 +4219,7 @@ TEST(NoBreakWhenBootstrapping) {
v8::HandleScope scope(isolate);
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetDebugEventListener2(DebugEventCounter);
+ v8::Debug::SetDebugEventListener(DebugEventCounter);
// Set the debug break flag.
v8::Debug::DebugBreak(isolate);
@@ -4239,7 +4238,7 @@ TEST(NoBreakWhenBootstrapping) {
CHECK_EQ(0, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -4374,15 +4373,15 @@ TEST(InterceptorPropertyMirror) {
// Check that the properties are interceptor properties.
for (int i = 0; i < 3; i++) {
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
- OS::SNPrintF(buffer,
- "named_values[%d] instanceof debug.PropertyMirror", i);
+ SNPrintF(buffer,
+ "named_values[%d] instanceof debug.PropertyMirror", i);
CHECK(CompileRun(buffer.start())->BooleanValue());
- OS::SNPrintF(buffer, "named_values[%d].propertyType()", i);
+ SNPrintF(buffer, "named_values[%d].propertyType()", i);
CHECK_EQ(v8::internal::INTERCEPTOR,
CompileRun(buffer.start())->Int32Value());
- OS::SNPrintF(buffer, "named_values[%d].isNative()", i);
+ SNPrintF(buffer, "named_values[%d].isNative()", i);
CHECK(CompileRun(buffer.start())->BooleanValue());
}
@@ -4393,8 +4392,8 @@ TEST(InterceptorPropertyMirror) {
// Check that the properties are interceptor properties.
for (int i = 0; i < 2; i++) {
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
- OS::SNPrintF(buffer,
- "indexed_values[%d] instanceof debug.PropertyMirror", i);
+ SNPrintF(buffer,
+ "indexed_values[%d] instanceof debug.PropertyMirror", i);
CHECK(CompileRun(buffer.start())->BooleanValue());
}
@@ -4405,7 +4404,7 @@ TEST(InterceptorPropertyMirror) {
// Check that the properties are interceptor properties.
for (int i = 0; i < 5; i++) {
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
- OS::SNPrintF(buffer, "both_values[%d] instanceof debug.PropertyMirror", i);
+ SNPrintF(buffer, "both_values[%d] instanceof debug.PropertyMirror", i);
CHECK(CompileRun(buffer.start())->BooleanValue());
}
@@ -4730,7 +4729,7 @@ class ThreadBarrier V8_FINAL {
Mutex mutex_;
int num_blocked_;
- STATIC_CHECK(N > 0);
+ STATIC_ASSERT(N > 0);
DISALLOW_COPY_AND_ASSIGN(ThreadBarrier);
};
@@ -4745,8 +4744,8 @@ class Barriers {
ThreadBarrier<2> barrier_3;
ThreadBarrier<2> barrier_4;
ThreadBarrier<2> barrier_5;
- v8::internal::Semaphore semaphore_1;
- v8::internal::Semaphore semaphore_2;
+ v8::base::Semaphore semaphore_1;
+ v8::base::Semaphore semaphore_2;
};
@@ -4846,10 +4845,10 @@ Barriers message_queue_barriers;
// This is the debugger thread, that executes no v8 calls except
// placing JSON debugger commands in the queue.
-class MessageQueueDebuggerThread : public v8::internal::Thread {
+class MessageQueueDebuggerThread : public v8::base::Thread {
public:
MessageQueueDebuggerThread()
- : Thread("MessageQueueDebuggerThread") { }
+ : Thread(Options("MessageQueueDebuggerThread")) {}
void Run();
};
@@ -4961,7 +4960,7 @@ TEST(MessageQueues) {
// Create a V8 environment
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetMessageHandler2(MessageHandler);
+ v8::Debug::SetMessageHandler(MessageHandler);
message_queue_debugger_thread.Start();
const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;";
@@ -5055,7 +5054,7 @@ TEST(SendClientDataToHandler) {
v8::HandleScope scope(isolate);
TestClientData::ResetCounters();
handled_client_data_instances_count = 0;
- v8::Debug::SetMessageHandler2(MessageHandlerCountingClientData);
+ v8::Debug::SetMessageHandler(MessageHandlerCountingClientData);
const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;";
const int kBufferSize = 1000;
uint16_t buffer[kBufferSize];
@@ -5103,15 +5102,15 @@ TEST(SendClientDataToHandler) {
Barriers threaded_debugging_barriers;
-class V8Thread : public v8::internal::Thread {
+class V8Thread : public v8::base::Thread {
public:
- V8Thread() : Thread("V8Thread") { }
+ V8Thread() : Thread(Options("V8Thread")) {}
void Run();
};
-class DebuggerThread : public v8::internal::Thread {
+class DebuggerThread : public v8::base::Thread {
public:
- DebuggerThread() : Thread("DebuggerThread") { }
+ DebuggerThread() : Thread(Options("DebuggerThread")) {}
void Run();
};
@@ -5129,10 +5128,7 @@ static void ThreadedMessageHandler(const v8::Debug::Message& message) {
if (IsBreakEventMessage(print_buffer)) {
// Check that we are inside the while loop.
int source_line = GetSourceLineFromBreakEventMessage(print_buffer);
- // TODO(2047): This should really be 8 <= source_line <= 13; but we
- // currently have an off-by-one error when calculating the source
- // position corresponding to the program counter at the debug break.
- CHECK(7 <= source_line && source_line <= 13);
+ CHECK(8 <= source_line && source_line <= 13);
threaded_debugging_barriers.barrier_2.Wait();
}
}
@@ -5162,7 +5158,7 @@ void V8Thread::Run() {
v8::Isolate::Scope isolate_scope(isolate);
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetMessageHandler2(&ThreadedMessageHandler);
+ v8::Debug::SetMessageHandler(&ThreadedMessageHandler);
v8::Handle<v8::ObjectTemplate> global_template =
v8::ObjectTemplate::New(env->GetIsolate());
global_template->Set(
@@ -5218,16 +5214,16 @@ TEST(ThreadedDebugging) {
* breakpoint is hit when enabled, and missed when disabled.
*/
-class BreakpointsV8Thread : public v8::internal::Thread {
+class BreakpointsV8Thread : public v8::base::Thread {
public:
- BreakpointsV8Thread() : Thread("BreakpointsV8Thread") { }
+ BreakpointsV8Thread() : Thread(Options("BreakpointsV8Thread")) {}
void Run();
};
-class BreakpointsDebuggerThread : public v8::internal::Thread {
+class BreakpointsDebuggerThread : public v8::base::Thread {
public:
explicit BreakpointsDebuggerThread(bool global_evaluate)
- : Thread("BreakpointsDebuggerThread"),
+ : Thread(Options("BreakpointsDebuggerThread")),
global_evaluate_(global_evaluate) {}
void Run();
@@ -5281,7 +5277,7 @@ void BreakpointsV8Thread::Run() {
v8::Isolate::Scope isolate_scope(isolate);
DebugLocalContext env;
v8::HandleScope scope(isolate);
- v8::Debug::SetMessageHandler2(&BreakpointsMessageHandler);
+ v8::Debug::SetMessageHandler(&BreakpointsMessageHandler);
CompileRun(source_1);
breakpoints_barriers->barrier_1.Wait();
@@ -5438,7 +5434,7 @@ static void DummyDebugEventListener(
TEST(SetDebugEventListenerOnUninitializedVM) {
- v8::Debug::SetDebugEventListener2(DummyDebugEventListener);
+ v8::Debug::SetDebugEventListener(DummyDebugEventListener);
}
@@ -5447,7 +5443,7 @@ static void DummyMessageHandler(const v8::Debug::Message& message) {
TEST(SetMessageHandlerOnUninitializedVM) {
- v8::Debug::SetMessageHandler2(DummyMessageHandler);
+ v8::Debug::SetMessageHandler(DummyMessageHandler);
}
@@ -5501,13 +5497,12 @@ static void CheckDataParameter(
v8::String::NewFromUtf8(args.GetIsolate(), "Test");
CHECK(v8::Debug::Call(debugger_call_with_data, data)->IsString());
- CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty());
- CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty());
-
- v8::TryCatch catcher;
- v8::Debug::Call(debugger_call_with_data);
- CHECK(catcher.HasCaught());
- CHECK(catcher.Exception()->IsString());
+ for (int i = 0; i < 3; i++) {
+ v8::TryCatch catcher;
+ CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty());
+ CHECK(catcher.HasCaught());
+ CHECK(catcher.Exception()->IsString());
+ }
}
@@ -5639,7 +5634,7 @@ TEST(DebuggerUnload) {
// Set a debug event listener.
break_point_hit_count = 0;
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
{
v8::HandleScope scope(env->GetIsolate());
// Create a couple of functions for the test.
@@ -5664,12 +5659,12 @@ TEST(DebuggerUnload) {
// Remove the debug event listener without clearing breakpoints. Do this
// outside a handle scope.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded(true);
// Now set a debug message handler.
break_point_hit_count = 0;
- v8::Debug::SetMessageHandler2(MessageHandlerBreakPointHitCount);
+ v8::Debug::SetMessageHandler(MessageHandlerBreakPointHitCount);
{
v8::HandleScope scope(env->GetIsolate());
@@ -5689,7 +5684,7 @@ TEST(DebuggerUnload) {
// Remove the debug message handler without clearing breakpoints. Do this
// outside a handle scope.
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
CheckDebuggerUnloaded(true);
}
@@ -5732,7 +5727,7 @@ TEST(DebuggerClearMessageHandler) {
CheckDebuggerUnloaded();
// Set a debug message handler.
- v8::Debug::SetMessageHandler2(MessageHandlerHitCount);
+ v8::Debug::SetMessageHandler(MessageHandlerHitCount);
// Run code to throw a unhandled exception. This should end up in the message
// handler.
@@ -5743,7 +5738,7 @@ TEST(DebuggerClearMessageHandler) {
// Clear debug message handler.
message_handler_hit_count = 0;
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
// Run code to throw a unhandled exception. This should end up in the message
// handler.
@@ -5762,7 +5757,7 @@ static void MessageHandlerClearingMessageHandler(
message_handler_hit_count++;
// Clear debug message handler.
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
}
@@ -5775,7 +5770,7 @@ TEST(DebuggerClearMessageHandlerWhileActive) {
CheckDebuggerUnloaded();
// Set a debug message handler.
- v8::Debug::SetMessageHandler2(MessageHandlerClearingMessageHandler);
+ v8::Debug::SetMessageHandler(MessageHandlerClearingMessageHandler);
// Run code to throw a unhandled exception. This should end up in the message
// handler.
@@ -5788,344 +5783,6 @@ TEST(DebuggerClearMessageHandlerWhileActive) {
}
-/* Test DebuggerHostDispatch */
-/* In this test, the debugger waits for a command on a breakpoint
- * and is dispatching host commands while in the infinite loop.
- */
-
-class HostDispatchV8Thread : public v8::internal::Thread {
- public:
- HostDispatchV8Thread() : Thread("HostDispatchV8Thread") { }
- void Run();
-};
-
-class HostDispatchDebuggerThread : public v8::internal::Thread {
- public:
- HostDispatchDebuggerThread() : Thread("HostDispatchDebuggerThread") { }
- void Run();
-};
-
-Barriers* host_dispatch_barriers;
-
-static void HostDispatchMessageHandler(const v8::Debug::Message& message) {
- static char print_buffer[1000];
- v8::String::Value json(message.GetJSON());
- Utf16ToAscii(*json, json.length(), print_buffer);
-}
-
-
-static void HostDispatchDispatchHandler() {
- host_dispatch_barriers->semaphore_1.Signal();
-}
-
-
-void HostDispatchV8Thread::Run() {
- const char* source_1 = "var y_global = 3;\n"
- "function cat( new_value ) {\n"
- " var x = new_value;\n"
- " y_global = 4;\n"
- " x = 3 * x + 1;\n"
- " y_global = 5;\n"
- " return x;\n"
- "}\n"
- "\n";
- const char* source_2 = "cat(17);\n";
-
- v8::Isolate::Scope isolate_scope(CcTest::isolate());
- DebugLocalContext env;
- v8::HandleScope scope(env->GetIsolate());
-
- // Set up message and host dispatch handlers.
- v8::Debug::SetMessageHandler2(HostDispatchMessageHandler);
- v8::Debug::SetHostDispatchHandler(HostDispatchDispatchHandler, 10 /* ms */);
-
- CompileRun(source_1);
- host_dispatch_barriers->barrier_1.Wait();
- host_dispatch_barriers->barrier_2.Wait();
- CompileRun(source_2);
-}
-
-
-void HostDispatchDebuggerThread::Run() {
- const int kBufSize = 1000;
- uint16_t buffer[kBufSize];
-
- const char* command_1 = "{\"seq\":101,"
- "\"type\":\"request\","
- "\"command\":\"setbreakpoint\","
- "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}";
- const char* command_2 = "{\"seq\":102,"
- "\"type\":\"request\","
- "\"command\":\"continue\"}";
-
- v8::Isolate* isolate = CcTest::isolate();
- // v8 thread initializes, runs source_1
- host_dispatch_barriers->barrier_1.Wait();
- // 1: Set breakpoint in cat().
- v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer));
-
- host_dispatch_barriers->barrier_2.Wait();
- // v8 thread starts compiling source_2.
- // Break happens, to run queued commands and host dispatches.
- // Wait for host dispatch to be processed.
- host_dispatch_barriers->semaphore_1.Wait();
- // 2: Continue evaluation
- v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer));
-}
-
-
-TEST(DebuggerHostDispatch) {
- HostDispatchDebuggerThread host_dispatch_debugger_thread;
- HostDispatchV8Thread host_dispatch_v8_thread;
-
- // Create a V8 environment
- Barriers stack_allocated_host_dispatch_barriers;
- host_dispatch_barriers = &stack_allocated_host_dispatch_barriers;
-
- host_dispatch_v8_thread.Start();
- host_dispatch_debugger_thread.Start();
-
- host_dispatch_v8_thread.Join();
- host_dispatch_debugger_thread.Join();
-}
-
-
-/* Test DebugMessageDispatch */
-/* In this test, the V8 thread waits for a message from the debug thread.
- * The DebugMessageDispatchHandler is executed from the debugger thread
- * which signals the V8 thread to wake up.
- */
-
-class DebugMessageDispatchV8Thread : public v8::internal::Thread {
- public:
- DebugMessageDispatchV8Thread() : Thread("DebugMessageDispatchV8Thread") { }
- void Run();
-};
-
-class DebugMessageDispatchDebuggerThread : public v8::internal::Thread {
- public:
- DebugMessageDispatchDebuggerThread()
- : Thread("DebugMessageDispatchDebuggerThread") { }
- void Run();
-};
-
-Barriers* debug_message_dispatch_barriers;
-
-
-static void DebugMessageHandler() {
- debug_message_dispatch_barriers->semaphore_1.Signal();
-}
-
-
-void DebugMessageDispatchV8Thread::Run() {
- v8::Isolate::Scope isolate_scope(CcTest::isolate());
- DebugLocalContext env;
- v8::HandleScope scope(env->GetIsolate());
-
- // Set up debug message dispatch handler.
- v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler);
-
- CompileRun("var y = 1 + 2;\n");
- debug_message_dispatch_barriers->barrier_1.Wait();
- debug_message_dispatch_barriers->semaphore_1.Wait();
- debug_message_dispatch_barriers->barrier_2.Wait();
-}
-
-
-void DebugMessageDispatchDebuggerThread::Run() {
- debug_message_dispatch_barriers->barrier_1.Wait();
- SendContinueCommand();
- debug_message_dispatch_barriers->barrier_2.Wait();
-}
-
-
-TEST(DebuggerDebugMessageDispatch) {
- DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread;
- DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread;
-
- // Create a V8 environment
- Barriers stack_allocated_debug_message_dispatch_barriers;
- debug_message_dispatch_barriers =
- &stack_allocated_debug_message_dispatch_barriers;
-
- debug_message_dispatch_v8_thread.Start();
- debug_message_dispatch_debugger_thread.Start();
-
- debug_message_dispatch_v8_thread.Join();
- debug_message_dispatch_debugger_thread.Join();
-}
-
-
-TEST(DebuggerAgent) {
- v8::V8::Initialize();
- i::Debugger* debugger = CcTest::i_isolate()->debugger();
- // Make sure these ports is not used by other tests to allow tests to run in
- // parallel.
- const int kPort1 = 5858 + FlagDependentPortOffset();
- const int kPort2 = 5857 + FlagDependentPortOffset();
- const int kPort3 = 5856 + FlagDependentPortOffset();
-
- // Make a string with the port2 number.
- const int kPortBufferLen = 6;
- char port2_str[kPortBufferLen];
- OS::SNPrintF(i::Vector<char>(port2_str, kPortBufferLen), "%d", kPort2);
-
- bool ok;
-
- // Test starting and stopping the agent without any client connection.
- debugger->StartAgent("test", kPort1);
- debugger->StopAgent();
- // Test starting the agent, connecting a client and shutting down the agent
- // with the client connected.
- ok = debugger->StartAgent("test", kPort2);
- CHECK(ok);
- debugger->WaitForAgent();
- i::Socket* client = new i::Socket;
- ok = client->Connect("localhost", port2_str);
- CHECK(ok);
- // It is important to wait for a message from the agent. Otherwise,
- // we can close the server socket during "accept" syscall, making it failing
- // (at least on Linux), and the test will work incorrectly.
- char buf;
- ok = client->Receive(&buf, 1) == 1;
- CHECK(ok);
- debugger->StopAgent();
- delete client;
-
- // Test starting and stopping the agent with the required port already
- // occoupied.
- i::Socket* server = new i::Socket;
- ok = server->Bind(kPort3);
- CHECK(ok);
-
- debugger->StartAgent("test", kPort3);
- debugger->StopAgent();
-
- delete server;
-}
-
-
-class DebuggerAgentProtocolServerThread : public i::Thread {
- public:
- explicit DebuggerAgentProtocolServerThread(int port)
- : Thread("DebuggerAgentProtocolServerThread"),
- port_(port),
- server_(NULL),
- client_(NULL),
- listening_(0) {
- }
- ~DebuggerAgentProtocolServerThread() {
- // Close both sockets.
- delete client_;
- delete server_;
- }
-
- void Run();
- void WaitForListening() { listening_.Wait(); }
- char* body() { return body_.get(); }
-
- private:
- int port_;
- i::SmartArrayPointer<char> body_;
- i::Socket* server_; // Server socket used for bind/accept.
- i::Socket* client_; // Single client connection used by the test.
- i::Semaphore listening_; // Signalled when the server is in listen mode.
-};
-
-
-void DebuggerAgentProtocolServerThread::Run() {
- bool ok;
-
- // Create the server socket and bind it to the requested port.
- server_ = new i::Socket;
- CHECK(server_ != NULL);
- ok = server_->Bind(port_);
- CHECK(ok);
-
- // Listen for new connections.
- ok = server_->Listen(1);
- CHECK(ok);
- listening_.Signal();
-
- // Accept a connection.
- client_ = server_->Accept();
- CHECK(client_ != NULL);
-
- // Receive a debugger agent protocol message.
- i::DebuggerAgentUtil::ReceiveMessage(client_);
-}
-
-
-TEST(DebuggerAgentProtocolOverflowHeader) {
- // Make sure this port is not used by other tests to allow tests to run in
- // parallel.
- const int kPort = 5860 + FlagDependentPortOffset();
- static const char* kLocalhost = "localhost";
-
- // Make a string with the port number.
- const int kPortBufferLen = 6;
- char port_str[kPortBufferLen];
- OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort);
-
- // Create a socket server to receive a debugger agent message.
- DebuggerAgentProtocolServerThread* server =
- new DebuggerAgentProtocolServerThread(kPort);
- server->Start();
- server->WaitForListening();
-
- // Connect.
- i::Socket* client = new i::Socket;
- CHECK(client != NULL);
- bool ok = client->Connect(kLocalhost, port_str);
- CHECK(ok);
-
- // Send headers which overflow the receive buffer.
- static const int kBufferSize = 1000;
- char buffer[kBufferSize];
-
- // Long key and short value: XXXX....XXXX:0\r\n.
- for (int i = 0; i < kBufferSize - 4; i++) {
- buffer[i] = 'X';
- }
- buffer[kBufferSize - 4] = ':';
- buffer[kBufferSize - 3] = '0';
- buffer[kBufferSize - 2] = '\r';
- buffer[kBufferSize - 1] = '\n';
- int result = client->Send(buffer, kBufferSize);
- CHECK_EQ(kBufferSize, result);
-
- // Short key and long value: X:XXXX....XXXX\r\n.
- buffer[0] = 'X';
- buffer[1] = ':';
- for (int i = 2; i < kBufferSize - 2; i++) {
- buffer[i] = 'X';
- }
- buffer[kBufferSize - 2] = '\r';
- buffer[kBufferSize - 1] = '\n';
- result = client->Send(buffer, kBufferSize);
- CHECK_EQ(kBufferSize, result);
-
- // Add empty body to request.
- const char* content_length_zero_header = "Content-Length:0\r\n";
- int length = StrLength(content_length_zero_header);
- result = client->Send(content_length_zero_header, length);
- CHECK_EQ(length, result);
- result = client->Send("\r\n", 2);
- CHECK_EQ(2, result);
-
- // Wait until data is received.
- server->Join();
-
- // Check for empty body.
- CHECK(server->body() == NULL);
-
- // Close the client before the server to avoid TIME_WAIT issues.
- client->Shutdown();
- delete client;
- delete server;
-}
-
-
// Test for issue http://code.google.com/p/v8/issues/detail?id=289.
// Make sure that DebugGetLoadedScripts doesn't return scripts
// with disposed external source.
@@ -6189,7 +5846,7 @@ TEST(ScriptNameAndData) {
frame_script_name_source,
"frame_script_name");
- v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
// Test function source.
v8::Local<v8::String> script = v8::String::NewFromUtf8(env->GetIsolate(),
@@ -6282,7 +5939,7 @@ TEST(ContextData) {
context_1 = v8::Context::New(isolate, NULL, global_template, global_object);
context_2 = v8::Context::New(isolate, NULL, global_template, global_object);
- v8::Debug::SetMessageHandler2(ContextCheckMessageHandler);
+ v8::Debug::SetMessageHandler(ContextCheckMessageHandler);
// Default data value is undefined.
CHECK(context_1->GetEmbedderData(0)->IsUndefined());
@@ -6321,7 +5978,7 @@ TEST(ContextData) {
// Two times compile event and two times break event.
CHECK_GT(message_handler_hit_count, 4);
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
CheckDebuggerUnloaded();
}
@@ -6350,7 +6007,7 @@ TEST(DebugBreakInMessageHandler) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetMessageHandler2(DebugBreakMessageHandler);
+ v8::Debug::SetMessageHandler(DebugBreakMessageHandler);
// Test functions.
const char* script = "function f() { debugger; g(); } function g() { }";
@@ -6430,7 +6087,7 @@ TEST(RegExpDebugBreak) {
v8::Local<v8::Value> result = f->Call(env->Global(), argc, argv);
CHECK_EQ(12, result->Int32Value());
- v8::Debug::SetDebugEventListener2(DebugEventDebugBreak);
+ v8::Debug::SetDebugEventListener(DebugEventDebugBreak);
v8::Debug::DebugBreak(env->GetIsolate());
result = f->Call(env->Global(), argc, argv);
@@ -6444,7 +6101,7 @@ TEST(RegExpDebugBreak) {
// Common part of EvalContextData and NestedBreakEventContextData tests.
static void ExecuteScriptForContextCheck(
- v8::Debug::MessageHandler2 message_handler) {
+ v8::Debug::MessageHandler message_handler) {
// Create a context.
v8::Handle<v8::Context> context_1;
v8::Handle<v8::ObjectTemplate> global_template =
@@ -6452,7 +6109,7 @@ static void ExecuteScriptForContextCheck(
context_1 =
v8::Context::New(CcTest::isolate(), NULL, global_template);
- v8::Debug::SetMessageHandler2(message_handler);
+ v8::Debug::SetMessageHandler(message_handler);
// Default data value is undefined.
CHECK(context_1->GetEmbedderData(0)->IsUndefined());
@@ -6475,7 +6132,7 @@ static void ExecuteScriptForContextCheck(
f->Call(context_1->Global(), 0, NULL);
}
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
}
@@ -6562,120 +6219,6 @@ TEST(NestedBreakEventContextData) {
}
-// Debug event listener which counts the script collected events.
-int script_collected_count = 0;
-static void DebugEventScriptCollectedEvent(
- const v8::Debug::EventDetails& event_details) {
- v8::DebugEvent event = event_details.GetEvent();
- // Count the number of breaks.
- if (event == v8::ScriptCollected) {
- script_collected_count++;
- }
-}
-
-
-// Test that scripts collected are reported through the debug event listener.
-TEST(ScriptCollectedEvent) {
- v8::internal::Debug* debug = CcTest::i_isolate()->debug();
- break_point_hit_count = 0;
- script_collected_count = 0;
- DebugLocalContext env;
- v8::HandleScope scope(env->GetIsolate());
-
- // Request the loaded scripts to initialize the debugger script cache.
- debug->GetLoadedScripts();
-
- // Do garbage collection to ensure that only the script in this test will be
- // collected afterwards.
- CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
-
- script_collected_count = 0;
- v8::Debug::SetDebugEventListener2(DebugEventScriptCollectedEvent);
- {
- v8::Script::Compile(
- v8::String::NewFromUtf8(env->GetIsolate(), "eval('a=1')"))->Run();
- v8::Script::Compile(
- v8::String::NewFromUtf8(env->GetIsolate(), "eval('a=2')"))->Run();
- }
-
- // Do garbage collection to collect the script above which is no longer
- // referenced.
- CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
-
- CHECK_EQ(2, script_collected_count);
-
- v8::Debug::SetDebugEventListener2(NULL);
- CheckDebuggerUnloaded();
-}
-
-
-// Debug event listener which counts the script collected events.
-int script_collected_message_count = 0;
-static void ScriptCollectedMessageHandler(const v8::Debug::Message& message) {
- // Count the number of scripts collected.
- if (message.IsEvent() && message.GetEvent() == v8::ScriptCollected) {
- script_collected_message_count++;
- v8::Handle<v8::Context> context = message.GetEventContext();
- CHECK(context.IsEmpty());
- }
-}
-
-
-// Test that GetEventContext doesn't fail and return empty handle for
-// ScriptCollected events.
-TEST(ScriptCollectedEventContext) {
- i::FLAG_stress_compaction = false;
- v8::Isolate* isolate = CcTest::isolate();
- v8::internal::Debug* debug =
- reinterpret_cast<v8::internal::Isolate*>(isolate)->debug();
- script_collected_message_count = 0;
- v8::HandleScope scope(isolate);
-
- v8::Persistent<v8::Context> context;
- {
- v8::HandleScope scope(isolate);
- context.Reset(isolate, v8::Context::New(isolate));
- }
-
- // Enter context. We can't have a handle to the context in the outer
- // scope, so we have to do it the hard way.
- {
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> local_context =
- v8::Local<v8::Context>::New(isolate, context);
- local_context->Enter();
- }
-
- // Request the loaded scripts to initialize the debugger script cache.
- debug->GetLoadedScripts();
-
- // Do garbage collection to ensure that only the script in this test will be
- // collected afterwards.
- CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
-
- v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler);
- v8::Script::Compile(v8::String::NewFromUtf8(isolate, "eval('a=1')"))->Run();
- v8::Script::Compile(v8::String::NewFromUtf8(isolate, "eval('a=2')"))->Run();
-
- // Leave context
- {
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> local_context =
- v8::Local<v8::Context>::New(isolate, context);
- local_context->Exit();
- }
- context.Reset();
-
- // Do garbage collection to collect the script above which is no longer
- // referenced.
- CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
-
- CHECK_EQ(2, script_collected_message_count);
-
- v8::Debug::SetMessageHandler2(NULL);
-}
-
-
// Debug event listener which counts the after compile events.
int after_compile_message_count = 0;
static void AfterCompileMessageHandler(const v8::Debug::Message& message) {
@@ -6698,18 +6241,18 @@ TEST(AfterCompileMessageWhenMessageHandlerIsReset) {
after_compile_message_count = 0;
const char* script = "var a=1";
- v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
+ v8::Debug::SetMessageHandler(AfterCompileMessageHandler);
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script))
->Run();
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
- v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
+ v8::Debug::SetMessageHandler(AfterCompileMessageHandler);
v8::Debug::DebugBreak(env->GetIsolate());
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script))
->Run();
// Setting listener to NULL should cause debugger unload.
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
CheckDebuggerUnloaded();
// Compilation cache should be disabled when debugger is active.
@@ -6717,6 +6260,60 @@ TEST(AfterCompileMessageWhenMessageHandlerIsReset) {
}
+// Syntax error event handler which counts a number of events.
+int compile_error_event_count = 0;
+
+static void CompileErrorEventCounterClear() {
+ compile_error_event_count = 0;
+}
+
+static void CompileErrorEventCounter(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+
+ if (event == v8::CompileError) {
+ compile_error_event_count++;
+ }
+}
+
+
+// Tests that syntax error event is sent as many times as there are scripts
+// with syntax error compiled.
+TEST(SyntaxErrorMessageOnSyntaxException) {
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ // For this test, we want to break on uncaught exceptions:
+ ChangeBreakOnException(false, true);
+
+ v8::Debug::SetDebugEventListener(CompileErrorEventCounter);
+
+ CompileErrorEventCounterClear();
+
+ // Check initial state.
+ CHECK_EQ(0, compile_error_event_count);
+
+ // Throws SyntaxError: Unexpected end of input
+ v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "+++"));
+ CHECK_EQ(1, compile_error_event_count);
+
+ v8::Script::Compile(
+ v8::String::NewFromUtf8(env->GetIsolate(), "/sel\\/: \\"));
+ CHECK_EQ(2, compile_error_event_count);
+
+ v8::Script::Compile(
+ v8::String::NewFromUtf8(env->GetIsolate(), "JSON.parse('1234:')"));
+ CHECK_EQ(2, compile_error_event_count);
+
+ v8::Script::Compile(
+ v8::String::NewFromUtf8(env->GetIsolate(), "new RegExp('/\\/\\\\');"));
+ CHECK_EQ(2, compile_error_event_count);
+
+ v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "throw 1;"));
+ CHECK_EQ(2, compile_error_event_count);
+}
+
+
// Tests that break event is sent when message handler is reset.
TEST(BreakMessageWhenMessageHandlerIsReset) {
DebugLocalContext env;
@@ -6724,19 +6321,19 @@ TEST(BreakMessageWhenMessageHandlerIsReset) {
after_compile_message_count = 0;
const char* script = "function f() {};";
- v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
+ v8::Debug::SetMessageHandler(AfterCompileMessageHandler);
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script))
->Run();
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
- v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
+ v8::Debug::SetMessageHandler(AfterCompileMessageHandler);
v8::Debug::DebugBreak(env->GetIsolate());
v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
f->Call(env->Global(), 0, NULL);
// Setting message handler to NULL should cause debugger unload.
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
CheckDebuggerUnloaded();
// Compilation cache should be disabled when debugger is active.
@@ -6764,18 +6361,18 @@ TEST(ExceptionMessageWhenMessageHandlerIsReset) {
exception_event_count = 0;
const char* script = "function f() {throw new Error()};";
- v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
+ v8::Debug::SetMessageHandler(AfterCompileMessageHandler);
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script))
->Run();
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
- v8::Debug::SetMessageHandler2(ExceptionMessageHandler);
+ v8::Debug::SetMessageHandler(ExceptionMessageHandler);
v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
f->Call(env->Global(), 0, NULL);
// Setting message handler to NULL should cause debugger unload.
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
CheckDebuggerUnloaded();
CHECK_EQ(1, exception_event_count);
@@ -6799,7 +6396,7 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) {
SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, 5, 5);
after_compile_message_count = 0;
- v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
+ v8::Debug::SetMessageHandler(AfterCompileMessageHandler);
v8::ScriptOrigin origin(
v8::String::NewFromUtf8(env->GetIsolate(), resource_name),
@@ -6817,7 +6414,7 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) {
ClearBreakPointFromJS(env->GetIsolate(), sbp1);
ClearBreakPointFromJS(env->GetIsolate(), sbp2);
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
}
@@ -6834,19 +6431,12 @@ static void BreakMessageHandler(const v8::Debug::Message& message) {
} else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) {
i::HandleScope scope(isolate);
- bool is_debug_break = isolate->stack_guard()->IsDebugBreak();
- // Force DebugBreak flag while serializer is working.
- isolate->stack_guard()->DebugBreak();
+ int current_count = break_point_hit_count;
// Force serialization to trigger some internal JS execution.
message.GetJSON();
- // Restore previous state.
- if (is_debug_break) {
- isolate->stack_guard()->DebugBreak();
- } else {
- isolate->stack_guard()->Continue(i::DEBUGBREAK);
- }
+ CHECK_EQ(current_count, break_point_hit_count);
}
}
@@ -6858,7 +6448,7 @@ TEST(NoDebugBreakInAfterCompileMessageHandler) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetMessageHandler2(BreakMessageHandler);
+ v8::Debug::SetMessageHandler(BreakMessageHandler);
// Set the debug break flag.
v8::Debug::DebugBreak(env->GetIsolate());
@@ -6877,7 +6467,7 @@ TEST(NoDebugBreakInAfterCompileMessageHandler) {
CHECK_EQ(2, break_point_hit_count);
// Get rid of the debug message handler.
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
CheckDebuggerUnloaded();
}
@@ -6885,7 +6475,7 @@ TEST(NoDebugBreakInAfterCompileMessageHandler) {
static int counting_message_handler_counter;
static void CountingMessageHandler(const v8::Debug::Message& message) {
- counting_message_handler_counter++;
+ if (message.IsResponse()) counting_message_handler_counter++;
}
@@ -6897,7 +6487,7 @@ TEST(ProcessDebugMessages) {
counting_message_handler_counter = 0;
- v8::Debug::SetMessageHandler2(CountingMessageHandler);
+ v8::Debug::SetMessageHandler(CountingMessageHandler);
const int kBufferSize = 1000;
uint16_t buffer[kBufferSize];
@@ -6927,7 +6517,84 @@ TEST(ProcessDebugMessages) {
CHECK_GE(counting_message_handler_counter, 2);
// Get rid of the debug message handler.
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
+ CheckDebuggerUnloaded();
+}
+
+
+class SendCommandThread : public v8::base::Thread {
+ public:
+ explicit SendCommandThread(v8::Isolate* isolate)
+ : Thread(Options("SendCommandThread")),
+ semaphore_(0),
+ isolate_(isolate) {}
+
+ static void ProcessDebugMessages(v8::Isolate* isolate, void* data) {
+ v8::Debug::ProcessDebugMessages();
+ reinterpret_cast<v8::base::Semaphore*>(data)->Signal();
+ }
+
+ virtual void Run() {
+ semaphore_.Wait();
+ const int kBufferSize = 1000;
+ uint16_t buffer[kBufferSize];
+ const char* scripts_command =
+ "{\"seq\":0,"
+ "\"type\":\"request\","
+ "\"command\":\"scripts\"}";
+ int length = AsciiToUtf16(scripts_command, buffer);
+ // Send scripts command.
+
+ for (int i = 0; i < 100; i++) {
+ CHECK_EQ(i, counting_message_handler_counter);
+ // Queue debug message.
+ v8::Debug::SendCommand(isolate_, buffer, length);
+ // Synchronize with the main thread to force message processing.
+ isolate_->RequestInterrupt(ProcessDebugMessages, &semaphore_);
+ semaphore_.Wait();
+ }
+
+ v8::V8::TerminateExecution(isolate_);
+ }
+
+ void StartSending() {
+ semaphore_.Signal();
+ }
+
+ private:
+ v8::base::Semaphore semaphore_;
+ v8::Isolate* isolate_;
+};
+
+
+static SendCommandThread* send_command_thread_ = NULL;
+
+static void StartSendingCommands(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ send_command_thread_->StartSending();
+}
+
+
+TEST(ProcessDebugMessagesThreaded) {
+ DebugLocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ counting_message_handler_counter = 0;
+
+ v8::Debug::SetMessageHandler(CountingMessageHandler);
+ send_command_thread_ = new SendCommandThread(isolate);
+ send_command_thread_->Start();
+
+ v8::Handle<v8::FunctionTemplate> start =
+ v8::FunctionTemplate::New(isolate, StartSendingCommands);
+ env->Global()->Set(v8_str("start"), start->GetFunction());
+
+ CompileRun("start(); while (true) { }");
+
+ CHECK_EQ(100, counting_message_handler_counter);
+
+ v8::Debug::SetMessageHandler(NULL);
CheckDebuggerUnloaded();
}
@@ -6955,7 +6622,7 @@ TEST(Backtrace) {
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
- v8::Debug::SetMessageHandler2(BacktraceData::MessageHandler);
+ v8::Debug::SetMessageHandler(BacktraceData::MessageHandler);
const int kBufferSize = 1000;
uint16_t buffer[kBufferSize];
@@ -6989,7 +6656,7 @@ TEST(Backtrace) {
CHECK_EQ(BacktraceData::frame_counter, 1);
// Get rid of the debug message handler.
- v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetMessageHandler(NULL);
CheckDebuggerUnloaded();
}
@@ -7029,7 +6696,7 @@ TEST(DebugBreakFunctionApply) {
"foo");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener2(DebugEventBreakMax);
+ v8::Debug::SetDebugEventListener(DebugEventBreakMax);
// Set the debug break flag before calling the code using function.apply.
v8::Debug::DebugBreak(env->GetIsolate());
@@ -7043,7 +6710,7 @@ TEST(DebugBreakFunctionApply) {
// When keeping the debug break several break will happen.
CHECK_GT(break_point_hit_count, 1);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -7112,7 +6779,7 @@ TEST(CallingContextIsNotDebugContext) {
named->NewInstance());
// Register the debug event listener
- v8::Debug::SetDebugEventListener2(DebugEventGetAtgumentPropertyValue);
+ v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue);
// Create a function that invokes debugger.
v8::Local<v8::Function> foo = CompileFunction(
@@ -7125,7 +6792,7 @@ TEST(CallingContextIsNotDebugContext) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
debugee_context = v8::Handle<v8::Context>();
debugger_context = v8::Handle<v8::Context>();
CheckDebuggerUnloaded();
@@ -7134,9 +6801,12 @@ TEST(CallingContextIsNotDebugContext) {
TEST(DebugContextIsPreservedBetweenAccesses) {
v8::HandleScope scope(CcTest::isolate());
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::Context> context1 = v8::Debug::GetDebugContext();
v8::Local<v8::Context> context2 = v8::Debug::GetDebugContext();
- CHECK_EQ(*context1, *context2);
+ CHECK(v8::Utils::OpenHandle(*context1).is_identical_to(
+ v8::Utils::OpenHandle(*context2)));
+ v8::Debug::SetDebugEventListener(NULL);
}
@@ -7153,13 +6823,13 @@ TEST(DebugEventContext) {
v8::HandleScope scope(isolate);
expected_context = v8::Context::New(isolate);
expected_callback_data = v8::Int32::New(isolate, 2010);
- v8::Debug::SetDebugEventListener2(DebugEventContextChecker,
+ v8::Debug::SetDebugEventListener(DebugEventContextChecker,
expected_callback_data);
v8::Context::Scope context_scope(expected_context);
v8::Script::Compile(
v8::String::NewFromUtf8(isolate, "(function(){debugger;})();"))->Run();
expected_context.Clear();
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
expected_context_data = v8::Handle<v8::Value>();
CheckDebuggerUnloaded();
}
@@ -7183,7 +6853,7 @@ TEST(DebugEventBreakData) {
DebugLocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
- v8::Debug::SetDebugEventListener2(DebugEventBreakDataChecker);
+ v8::Debug::SetDebugEventListener(DebugEventBreakDataChecker);
TestClientData::constructor_call_counter = 0;
TestClientData::destructor_call_counter = 0;
@@ -7191,7 +6861,7 @@ TEST(DebugEventBreakData) {
expected_break_data = NULL;
was_debug_event_called = false;
was_debug_break_called = false;
- v8::Debug::DebugBreakForCommand(NULL, isolate);
+ v8::Debug::DebugBreakForCommand(isolate, NULL);
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
"(function(x){return x;})(1);"))
->Run();
@@ -7202,7 +6872,7 @@ TEST(DebugEventBreakData) {
expected_break_data = data1;
was_debug_event_called = false;
was_debug_break_called = false;
- v8::Debug::DebugBreakForCommand(data1, isolate);
+ v8::Debug::DebugBreakForCommand(isolate, data1);
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
"(function(x){return x+1;})(1);"))
->Run();
@@ -7224,7 +6894,7 @@ TEST(DebugEventBreakData) {
was_debug_event_called = false;
was_debug_break_called = false;
v8::Debug::DebugBreak(isolate);
- v8::Debug::DebugBreakForCommand(data2, isolate);
+ v8::Debug::DebugBreakForCommand(isolate, data2);
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
"(function(x){return x+3;})(1);"))
->Run();
@@ -7235,7 +6905,7 @@ TEST(DebugEventBreakData) {
CHECK_EQ(TestClientData::constructor_call_counter,
TestClientData::destructor_call_counter);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -7289,7 +6959,7 @@ TEST(DeoptimizeDuringDebugBreak) {
// This tests lazy deoptimization bailout for the stack check, as the first
// time in function bar when using debug break and no break points will be at
// the initial stack check.
- v8::Debug::SetDebugEventListener2(DebugEventBreakDeoptimize);
+ v8::Debug::SetDebugEventListener(DebugEventBreakDeoptimize);
// Compile and run function bar which will optimize it for some flag settings.
v8::Script::Compile(v8::String::NewFromUtf8(
@@ -7302,7 +6972,7 @@ TEST(DeoptimizeDuringDebugBreak) {
CHECK(debug_event_break_deoptimize_done);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
}
@@ -7357,7 +7027,7 @@ static void DebugEventBreakWithOptimizedStack(
static void ScheduleBreak(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::Debug::SetDebugEventListener2(DebugEventBreakWithOptimizedStack);
+ v8::Debug::SetDebugEventListener(DebugEventBreakWithOptimizedStack);
v8::Debug::DebugBreak(args.GetIsolate());
}
@@ -7415,9 +7085,9 @@ static void TestDebugBreakInLoop(const char* loop_head,
terminate_after_max_break_point_hit = true;
EmbeddedVector<char, 1024> buffer;
- OS::SNPrintF(buffer,
- "function f() {%s%s%s}",
- loop_head, loop_bodies[i], loop_tail);
+ SNPrintF(buffer,
+ "function f() {%s%s%s}",
+ loop_head, loop_bodies[i], loop_tail);
// Function with infinite loop.
CompileRun(buffer.start());
@@ -7440,7 +7110,7 @@ TEST(DebugBreakLoop) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetDebugEventListener2(DebugEventBreakMax);
+ v8::Debug::SetDebugEventListener(DebugEventBreakMax);
// Create a function for getting the frame count when hitting the break.
frame_count = CompileFunction(&env, frame_count_source, "frame_count");
@@ -7474,7 +7144,7 @@ TEST(DebugBreakLoop) {
TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}");
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -7496,7 +7166,7 @@ static void DebugBreakInlineListener(
int break_id = CcTest::i_isolate()->debug()->break_id();
char script[128];
i::Vector<char> script_vector(script, sizeof(script));
- OS::SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id);
+ SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id);
v8::Local<v8::Value> result = CompileRun(script);
int frame_count = result->Int32Value();
@@ -7505,12 +7175,12 @@ static void DebugBreakInlineListener(
for (int i = 0; i < frame_count; i++) {
// The 5. element in the returned array of GetFrameDetails contains the
// source position of that frame.
- OS::SNPrintF(script_vector, "%%GetFrameDetails(%d, %d)[5]", break_id, i);
+ SNPrintF(script_vector, "%%GetFrameDetails(%d, %d)[5]", break_id, i);
v8::Local<v8::Value> result = CompileRun(script);
CHECK_EQ(expected_line_number[i],
i::Script::GetLineNumber(source_script, result->Int32Value()));
}
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
v8::V8::TerminateExecution(CcTest::isolate());
}
@@ -7533,7 +7203,7 @@ TEST(DebugBreakInline) {
"g(false); \n"
"%OptimizeFunctionOnNextCall(g); \n"
"g(true);";
- v8::Debug::SetDebugEventListener2(DebugBreakInlineListener);
+ v8::Debug::SetDebugEventListener(DebugBreakInlineListener);
inline_script =
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source));
inline_script->Run();
@@ -7567,7 +7237,7 @@ TEST(Regress131642) {
// on the stack.
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener2(DebugEventStepNext);
+ v8::Debug::SetDebugEventListener(DebugEventStepNext);
// We step through the first script. It exits through an exception. We run
// this inside a new frame to record a different FP than the second script
@@ -7579,7 +7249,7 @@ TEST(Regress131642) {
const char* script_2 = "[0].forEach(function() { });";
CompileRun(script_2);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
}
@@ -7596,15 +7266,15 @@ TEST(DebuggerCreatesContextIffActive) {
v8::HandleScope scope(env->GetIsolate());
CHECK_EQ(1, CountNativeContexts());
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CompileRun("debugger;");
CHECK_EQ(1, CountNativeContexts());
- v8::Debug::SetDebugEventListener2(NopListener);
+ v8::Debug::SetDebugEventListener(NopListener);
CompileRun("debugger;");
CHECK_EQ(2, CountNativeContexts());
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
}
@@ -7612,7 +7282,7 @@ TEST(LiveEditEnabled) {
v8::internal::FLAG_allow_natives_syntax = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetLiveEditEnabled(true, env->GetIsolate());
+ v8::Debug::SetLiveEditEnabled(env->GetIsolate(), true);
CompileRun("%LiveEditCompareStrings('', '')");
}
@@ -7621,7 +7291,7 @@ TEST(LiveEditDisabled) {
v8::internal::FLAG_allow_natives_syntax = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetLiveEditEnabled(false, env->GetIsolate());
+ v8::Debug::SetLiveEditEnabled(env->GetIsolate(), false);
CompileRun("%LiveEditCompareStrings('', '')");
}
@@ -7634,7 +7304,7 @@ TEST(PrecompiledFunction) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener2(DebugBreakInlineListener);
+ v8::Debug::SetDebugEventListener(DebugBreakInlineListener);
v8::Local<v8::Function> break_here =
CompileFunction(&env, "function break_here(){}", "break_here");
@@ -7651,12 +7321,12 @@ TEST(PrecompiledFunction) {
"}; \n"
"a = b = c = 2; \n"
"bar(); \n";
- v8::Local<v8::Value> result = PreCompileCompileRun(source);
+ v8::Local<v8::Value> result = ParserCacheCompileRun(source);
CHECK(result->IsString());
v8::String::Utf8Value utf8(result);
CHECK_EQ("bar", *utf8);
- v8::Debug::SetDebugEventListener2(NULL);
+ v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
}
@@ -7675,7 +7345,7 @@ static void AddDebugBreak(const v8::FunctionCallbackInfo<v8::Value>& args) {
TEST(DebugBreakStackTrace) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener2(DebugBreakStackTraceListener);
+ v8::Debug::SetDebugEventListener(DebugBreakStackTraceListener);
v8::Handle<v8::FunctionTemplate> add_debug_break_template =
v8::FunctionTemplate::New(env->GetIsolate(), AddDebugBreak);
v8::Handle<v8::Function> add_debug_break =
@@ -7690,3 +7360,48 @@ TEST(DebugBreakStackTrace) {
" }"
"})()");
}
+
+
+v8::base::Semaphore terminate_requested_semaphore(0);
+v8::base::Semaphore terminate_fired_semaphore(0);
+bool terminate_already_fired = false;
+
+
+static void DebugBreakTriggerTerminate(
+ const v8::Debug::EventDetails& event_details) {
+ if (event_details.GetEvent() != v8::Break || terminate_already_fired) return;
+ terminate_requested_semaphore.Signal();
+ // Wait for at most 2 seconds for the terminate request.
+ CHECK(terminate_fired_semaphore.WaitFor(v8::base::TimeDelta::FromSeconds(2)));
+ terminate_already_fired = true;
+}
+
+
+class TerminationThread : public v8::base::Thread {
+ public:
+ explicit TerminationThread(v8::Isolate* isolate)
+ : Thread(Options("terminator")), isolate_(isolate) {}
+
+ virtual void Run() {
+ terminate_requested_semaphore.Wait();
+ v8::V8::TerminateExecution(isolate_);
+ terminate_fired_semaphore.Signal();
+ }
+
+ private:
+ v8::Isolate* isolate_;
+};
+
+
+TEST(DebugBreakOffThreadTerminate) {
+ DebugLocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Debug::SetDebugEventListener(DebugBreakTriggerTerminate);
+ TerminationThread terminator(isolate);
+ terminator.Start();
+ v8::TryCatch try_catch;
+ v8::Debug::DebugBreak(isolate);
+ CompileRun("while (true);");
+ CHECK(try_catch.HasTerminated());
+}
diff --git a/deps/v8/test/cctest/test-declarative-accessors.cc b/deps/v8/test/cctest/test-declarative-accessors.cc
index f2169a9fb..8d93245eb 100644
--- a/deps/v8/test/cctest/test-declarative-accessors.cc
+++ b/deps/v8/test/cctest/test-declarative-accessors.cc
@@ -27,9 +27,9 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "cctest.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -37,7 +37,7 @@ using namespace v8::internal;
class HandleArray : public Malloced {
public:
static const unsigned kArraySize = 200;
- explicit HandleArray() {}
+ HandleArray() {}
~HandleArray() { Reset(); }
void Reset() {
for (unsigned i = 0; i < kArraySize; i++) {
diff --git a/deps/v8/test/cctest/test-decls.cc b/deps/v8/test/cctest/test-decls.cc
index d6738a31a..34f0b6964 100644
--- a/deps/v8/test/cctest/test-decls.cc
+++ b/deps/v8/test/cctest/test-decls.cc
@@ -27,10 +27,10 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "heap.h"
-#include "cctest.h"
+#include "src/heap/heap.h"
+#include "test/cctest/cctest.h"
using namespace v8;
@@ -236,17 +236,14 @@ TEST(Unknown) {
{ DeclarationContext context;
context.Check("var x; x",
1, // access
- 1, // declaration
- 2, // declaration + initialization
- EXPECT_RESULT, Undefined(CcTest::isolate()));
+ 0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
}
{ DeclarationContext context;
context.Check("var x = 0; x",
1, // access
- 2, // declaration + initialization
- 2, // declaration + initialization
- EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
+ 1, // initialization
+ 0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
}
{ DeclarationContext context;
@@ -260,78 +257,19 @@ TEST(Unknown) {
{ DeclarationContext context;
context.Check("const x; x",
1, // access
- 2, // declaration + initialization
- 1, // declaration
- EXPECT_RESULT, Undefined(CcTest::isolate()));
+ 0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
}
{ DeclarationContext context;
- // SB 0 - BUG 1213579
context.Check("const x = 0; x",
1, // access
- 2, // declaration + initialization
- 1, // declaration
- EXPECT_RESULT, Undefined(CcTest::isolate()));
- }
-}
-
-
-
-class PresentPropertyContext: public DeclarationContext {
- protected:
- virtual v8::Handle<Integer> Query(Local<String> key) {
- return Integer::New(isolate(), v8::None);
- }
-};
-
-
-
-TEST(Present) {
- HandleScope scope(CcTest::isolate());
-
- { PresentPropertyContext context;
- context.Check("var x; x",
- 1, // access
0,
- 2, // declaration + initialization
- EXPECT_EXCEPTION); // x is not defined!
- }
-
- { PresentPropertyContext context;
- context.Check("var x = 0; x",
- 1, // access
- 1, // initialization
- 2, // declaration + initialization
- EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
- }
-
- { PresentPropertyContext context;
- context.Check("function x() { }; x",
- 1, // access
0,
- 0,
- EXPECT_RESULT);
- }
-
- { PresentPropertyContext context;
- context.Check("const x; x",
- 1, // access
- 1, // initialization
- 1, // (re-)declaration
- EXPECT_RESULT, Undefined(CcTest::isolate()));
- }
-
- { PresentPropertyContext context;
- context.Check("const x = 0; x",
- 1, // access
- 1, // initialization
- 1, // (re-)declaration
EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
}
}
-
class AbsentPropertyContext: public DeclarationContext {
protected:
virtual v8::Handle<Integer> Query(Local<String> key) {
@@ -348,17 +286,14 @@ TEST(Absent) {
{ AbsentPropertyContext context;
context.Check("var x; x",
1, // access
- 1, // declaration
- 2, // declaration + initialization
- EXPECT_RESULT, Undefined(isolate));
+ 0, 0, EXPECT_RESULT, Undefined(isolate));
}
{ AbsentPropertyContext context;
context.Check("var x = 0; x",
1, // access
- 2, // declaration + initialization
- 2, // declaration + initialization
- EXPECT_RESULT, Number::New(isolate, 0));
+ 1, // initialization
+ 0, EXPECT_RESULT, Number::New(isolate, 0));
}
{ AbsentPropertyContext context;
@@ -372,25 +307,19 @@ TEST(Absent) {
{ AbsentPropertyContext context;
context.Check("const x; x",
1, // access
- 2, // declaration + initialization
- 1, // declaration
- EXPECT_RESULT, Undefined(isolate));
+ 0, 0, EXPECT_RESULT, Undefined(isolate));
}
{ AbsentPropertyContext context;
context.Check("const x = 0; x",
1, // access
- 2, // declaration + initialization
- 1, // declaration
- EXPECT_RESULT, Undefined(isolate)); // SB 0 - BUG 1213579
+ 0, 0, EXPECT_RESULT, Number::New(isolate, 0));
}
{ AbsentPropertyContext context;
context.Check("if (false) { var x = 0 }; x",
1, // access
- 1, // declaration
- 1, // declaration + initialization
- EXPECT_RESULT, Undefined(isolate));
+ 0, 0, EXPECT_RESULT, Undefined(isolate));
}
}
@@ -439,17 +368,14 @@ TEST(Appearing) {
{ AppearingPropertyContext context;
context.Check("var x; x",
1, // access
- 1, // declaration
- 2, // declaration + initialization
- EXPECT_RESULT, Undefined(CcTest::isolate()));
+ 0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
}
{ AppearingPropertyContext context;
context.Check("var x = 0; x",
1, // access
- 2, // declaration + initialization
- 2, // declaration + initialization
- EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
+ 1, // initialization
+ 0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
}
{ AppearingPropertyContext context;
@@ -463,78 +389,13 @@ TEST(Appearing) {
{ AppearingPropertyContext context;
context.Check("const x; x",
1, // access
- 2, // declaration + initialization
- 1, // declaration
- EXPECT_RESULT, Undefined(CcTest::isolate()));
+ 0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
}
{ AppearingPropertyContext context;
context.Check("const x = 0; x",
1, // access
- 2, // declaration + initialization
- 1, // declaration
- EXPECT_RESULT, Undefined(CcTest::isolate()));
- // Result is undefined because declaration succeeded but
- // initialization to 0 failed (due to context behavior).
- }
-}
-
-
-
-class ReappearingPropertyContext: public DeclarationContext {
- public:
- enum State {
- DECLARE,
- DONT_DECLARE,
- INITIALIZE,
- UNKNOWN
- };
-
- ReappearingPropertyContext() : state_(DECLARE) { }
-
- protected:
- virtual v8::Handle<Integer> Query(Local<String> key) {
- switch (state_) {
- case DECLARE:
- // Force the first declaration by returning that
- // the property is absent.
- state_ = DONT_DECLARE;
- return Handle<Integer>();
- case DONT_DECLARE:
- // Ignore the second declaration by returning
- // that the property is already there.
- state_ = INITIALIZE;
- return Integer::New(isolate(), v8::None);
- case INITIALIZE:
- // Force an initialization by returning that
- // the property is absent. This will make sure
- // that the setter is called and it will not
- // lead to redeclaration conflicts (yet).
- state_ = UNKNOWN;
- return Handle<Integer>();
- default:
- CHECK(state_ == UNKNOWN);
- break;
- }
- // Do the lookup in the object.
- return Handle<Integer>();
- }
-
- private:
- State state_;
-};
-
-
-TEST(Reappearing) {
- v8::V8::Initialize();
- HandleScope scope(CcTest::isolate());
-
- { ReappearingPropertyContext context;
- context.Check("const x; var x = 0",
- 0,
- 3, // const declaration+initialization, var initialization
- 3, // 2 x declaration + var initialization
- EXPECT_RESULT, Undefined(CcTest::isolate()));
+ 0, 0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
}
}
@@ -562,11 +423,8 @@ TEST(ExistsInPrototype) {
// Sanity check to make sure that the holder of the interceptor
// really is the prototype object.
{ ExistsInPrototypeContext context;
- context.Check("this.x = 87; this.x",
- 0,
- 0,
- 0,
- EXPECT_RESULT, Number::New(CcTest::isolate(), 87));
+ context.Check("this.x = 87; this.x", 0, 0, 1, EXPECT_RESULT,
+ Number::New(CcTest::isolate(), 87));
}
{ ExistsInPrototypeContext context;
@@ -669,19 +527,13 @@ TEST(ExistsInHiddenPrototype) {
HandleScope scope(CcTest::isolate());
{ ExistsInHiddenPrototypeContext context;
- context.Check("var x; x",
- 1, // access
- 0,
- 2, // declaration + initialization
- EXPECT_EXCEPTION); // x is not defined!
+ context.Check("var x; x", 0, 0, 0, EXPECT_RESULT,
+ Undefined(CcTest::isolate()));
}
{ ExistsInHiddenPrototypeContext context;
- context.Check("var x = 0; x",
- 1, // access
- 1, // initialization
- 2, // declaration + initialization
- EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
+ context.Check("var x = 0; x", 0, 0, 0, EXPECT_RESULT,
+ Number::New(CcTest::isolate(), 0));
}
{ ExistsInHiddenPrototypeContext context;
@@ -694,20 +546,14 @@ TEST(ExistsInHiddenPrototype) {
// TODO(mstarzinger): The semantics of global const is vague.
{ ExistsInHiddenPrototypeContext context;
- context.Check("const x; x",
- 0,
- 0,
- 1, // (re-)declaration
- EXPECT_RESULT, Undefined(CcTest::isolate()));
+ context.Check("const x; x", 0, 0, 0, EXPECT_RESULT,
+ Undefined(CcTest::isolate()));
}
// TODO(mstarzinger): The semantics of global const is vague.
{ ExistsInHiddenPrototypeContext context;
- context.Check("const x = 0; x",
- 0,
- 0,
- 1, // (re-)declaration
- EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
+ context.Check("const x = 0; x", 0, 0, 0, EXPECT_RESULT,
+ Number::New(CcTest::isolate(), 0));
}
}
@@ -768,10 +614,8 @@ TEST(CrossScriptReferences) {
EXPECT_RESULT, Number::New(isolate, 1));
context.Check("var x = 2; x",
EXPECT_RESULT, Number::New(isolate, 2));
- context.Check("const x = 3; x",
- EXPECT_RESULT, Number::New(isolate, 3));
- context.Check("const x = 4; x",
- EXPECT_RESULT, Number::New(isolate, 4));
+ context.Check("const x = 3; x", EXPECT_EXCEPTION);
+ context.Check("const x = 4; x", EXPECT_EXCEPTION);
context.Check("x = 5; x",
EXPECT_RESULT, Number::New(isolate, 5));
context.Check("var x = 6; x",
@@ -787,8 +631,7 @@ TEST(CrossScriptReferences) {
EXPECT_RESULT, Number::New(isolate, 1));
context.Check("var x = 2; x", // assignment ignored
EXPECT_RESULT, Number::New(isolate, 1));
- context.Check("const x = 3; x",
- EXPECT_RESULT, Number::New(isolate, 1));
+ context.Check("const x = 3; x", EXPECT_EXCEPTION);
context.Check("x = 4; x", // assignment ignored
EXPECT_RESULT, Number::New(isolate, 1));
context.Check("var x = 5; x", // assignment ignored
diff --git a/deps/v8/test/cctest/test-deoptimization.cc b/deps/v8/test/cctest/test-deoptimization.cc
index dbbb3edb0..3127acc6a 100644
--- a/deps/v8/test/cctest/test-deoptimization.cc
+++ b/deps/v8/test/cctest/test-deoptimization.cc
@@ -27,23 +27,23 @@
#include <stdlib.h>
-#include "v8.h"
-
-#include "api.h"
-#include "cctest.h"
-#include "compilation-cache.h"
-#include "debug.h"
-#include "deoptimizer.h"
-#include "isolate.h"
-#include "platform.h"
-#include "stub-cache.h"
-
+#include "src/v8.h"
+
+#include "src/api.h"
+#include "src/base/platform/platform.h"
+#include "src/compilation-cache.h"
+#include "src/debug.h"
+#include "src/deoptimizer.h"
+#include "src/isolate.h"
+#include "src/stub-cache.h"
+#include "test/cctest/cctest.h"
+
+using ::v8::base::OS;
using ::v8::internal::Deoptimizer;
using ::v8::internal::EmbeddedVector;
using ::v8::internal::Handle;
using ::v8::internal::Isolate;
using ::v8::internal::JSFunction;
-using ::v8::internal::OS;
using ::v8::internal::Object;
// Size of temp buffer for formatting small strings.
@@ -113,6 +113,8 @@ static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
TEST(DeoptimizeSimple) {
+ i::FLAG_turbo_deoptimization = true;
+
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -151,6 +153,8 @@ TEST(DeoptimizeSimple) {
TEST(DeoptimizeSimpleWithArguments) {
+ i::FLAG_turbo_deoptimization = true;
+
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -190,6 +194,8 @@ TEST(DeoptimizeSimpleWithArguments) {
TEST(DeoptimizeSimpleNested) {
+ i::FLAG_turbo_deoptimization = true;
+
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -215,6 +221,7 @@ TEST(DeoptimizeSimpleNested) {
TEST(DeoptimizeRecursive) {
+ i::FLAG_turbo_deoptimization = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -242,6 +249,7 @@ TEST(DeoptimizeRecursive) {
TEST(DeoptimizeMultiple) {
+ i::FLAG_turbo_deoptimization = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -270,6 +278,7 @@ TEST(DeoptimizeMultiple) {
TEST(DeoptimizeConstructor) {
+ i::FLAG_turbo_deoptimization = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -308,6 +317,7 @@ TEST(DeoptimizeConstructor) {
TEST(DeoptimizeConstructorMultiple) {
+ i::FLAG_turbo_deoptimization = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -337,6 +347,7 @@ TEST(DeoptimizeConstructorMultiple) {
TEST(DeoptimizeBinaryOperationADDString) {
+ i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
AllowNativesSyntaxNoInlining options;
LocalContext env;
@@ -397,9 +408,9 @@ static void CompileConstructorWithDeoptimizingValueOf() {
static void TestDeoptimizeBinaryOpHelper(LocalContext* env,
const char* binary_op) {
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> f_source_buffer;
- OS::SNPrintF(f_source_buffer,
- "function f(x, y) { return x %s y; };",
- binary_op);
+ SNPrintF(f_source_buffer,
+ "function f(x, y) { return x %s y; };",
+ binary_op);
char* f_source = f_source_buffer.start();
AllowNativesSyntaxNoInlining options;
@@ -428,6 +439,7 @@ static void TestDeoptimizeBinaryOpHelper(LocalContext* env,
TEST(DeoptimizeBinaryOperationADD) {
+ i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -441,6 +453,7 @@ TEST(DeoptimizeBinaryOperationADD) {
TEST(DeoptimizeBinaryOperationSUB) {
+ i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -454,6 +467,7 @@ TEST(DeoptimizeBinaryOperationSUB) {
TEST(DeoptimizeBinaryOperationMUL) {
+ i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -467,6 +481,7 @@ TEST(DeoptimizeBinaryOperationMUL) {
TEST(DeoptimizeBinaryOperationDIV) {
+ i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -480,6 +495,7 @@ TEST(DeoptimizeBinaryOperationDIV) {
TEST(DeoptimizeBinaryOperationMOD) {
+ i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -493,6 +509,7 @@ TEST(DeoptimizeBinaryOperationMOD) {
TEST(DeoptimizeCompare) {
+ i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -537,6 +554,7 @@ TEST(DeoptimizeCompare) {
TEST(DeoptimizeLoadICStoreIC) {
+ i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -617,6 +635,7 @@ TEST(DeoptimizeLoadICStoreIC) {
TEST(DeoptimizeLoadICStoreICNested) {
+ i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
diff --git a/deps/v8/test/cctest/test-dictionary.cc b/deps/v8/test/cctest/test-dictionary.cc
index aa1bc8623..9a1914237 100644
--- a/deps/v8/test/cctest/test-dictionary.cc
+++ b/deps/v8/test/cctest/test-dictionary.cc
@@ -25,16 +25,16 @@
// (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 "src/v8.h"
+#include "test/cctest/cctest.h"
-#include "api.h"
-#include "debug.h"
-#include "execution.h"
-#include "factory.h"
-#include "macro-assembler.h"
-#include "objects.h"
-#include "global-handles.h"
-#include "cctest.h"
+#include "src/api.h"
+#include "src/debug.h"
+#include "src/execution.h"
+#include "src/factory.h"
+#include "src/global-handles.h"
+#include "src/macro-assembler.h"
+#include "src/objects.h"
using namespace v8::internal;
@@ -51,6 +51,7 @@ static void TestHashMap(Handle<HashMap> table) {
table = HashMap::Put(table, a, b);
CHECK_EQ(table->NumberOfElements(), 1);
CHECK_EQ(table->Lookup(a), *b);
+ // When the key does not exist in the map, Lookup returns the hole.
CHECK_EQ(table->Lookup(b), CcTest::heap()->the_hole_value());
// Keys still have to be valid after objects were moved.
@@ -64,8 +65,10 @@ static void TestHashMap(Handle<HashMap> table) {
CHECK_EQ(table->NumberOfElements(), 1);
CHECK_NE(table->Lookup(a), *b);
- // Keys mapped to the hole should be removed permanently.
- table = HashMap::Put(table, a, factory->the_hole_value());
+ // Keys that have been removed are mapped to the hole.
+ bool was_present = false;
+ table = HashMap::Remove(table, a, &was_present);
+ CHECK(was_present);
CHECK_EQ(table->NumberOfElements(), 0);
CHECK_EQ(table->Lookup(a), CcTest::heap()->the_hole_value());
@@ -187,7 +190,9 @@ static void TestHashSetCausesGC(Handle<HashSet> table) {
CHECK(gc_count == isolate->heap()->gc_count());
// Calling Remove() will not cause GC in this case.
- table = HashSet::Remove(table, key);
+ bool was_present = false;
+ table = HashSet::Remove(table, key, &was_present);
+ CHECK(!was_present);
CHECK(gc_count == isolate->heap()->gc_count());
// Calling Add() should cause GC.
diff --git a/deps/v8/test/cctest/test-disasm-arm.cc b/deps/v8/test/cctest/test-disasm-arm.cc
index 24453bc88..c1f6ce269 100644
--- a/deps/v8/test/cctest/test-disasm-arm.cc
+++ b/deps/v8/test/cctest/test-disasm-arm.cc
@@ -28,14 +28,14 @@
#include <stdlib.h>
-#include "v8.h"
-
-#include "debug.h"
-#include "disasm.h"
-#include "disassembler.h"
-#include "macro-assembler.h"
-#include "serialize.h"
-#include "cctest.h"
+#include "src/v8.h"
+
+#include "src/debug.h"
+#include "src/disasm.h"
+#include "src/disassembler.h"
+#include "src/macro-assembler.h"
+#include "src/serialize.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-disasm-arm64.cc b/deps/v8/test/cctest/test-disasm-arm64.cc
index 23f7b6daf..fb01347c6 100644
--- a/deps/v8/test/cctest/test-disasm-arm64.cc
+++ b/deps/v8/test/cctest/test-disasm-arm64.cc
@@ -27,16 +27,17 @@
#include <stdio.h>
#include <cstring>
-#include "cctest.h"
-#include "v8.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
-#include "macro-assembler.h"
-#include "arm64/assembler-arm64.h"
-#include "arm64/macro-assembler-arm64.h"
-#include "arm64/decoder-arm64-inl.h"
-#include "arm64/disasm-arm64.h"
-#include "arm64/utils-arm64.h"
+#include "src/macro-assembler.h"
+
+#include "src/arm64/assembler-arm64.h"
+#include "src/arm64/decoder-arm64-inl.h"
+#include "src/arm64/disasm-arm64.h"
+#include "src/arm64/macro-assembler-arm64.h"
+#include "src/arm64/utils-arm64.h"
using namespace v8::internal;
@@ -1601,7 +1602,7 @@ TEST_(system_nop) {
TEST_(debug) {
SET_UP();
- ASSERT(kImmExceptionIsDebug == 0xdeb0);
+ DCHECK(kImmExceptionIsDebug == 0xdeb0);
// All debug codes should produce the same instruction, and the debug code
// can be any uint32_t.
diff --git a/deps/v8/test/cctest/test-disasm-ia32.cc b/deps/v8/test/cctest/test-disasm-ia32.cc
index 6972aeaba..8436df7c5 100644
--- a/deps/v8/test/cctest/test-disasm-ia32.cc
+++ b/deps/v8/test/cctest/test-disasm-ia32.cc
@@ -27,15 +27,15 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "debug.h"
-#include "disasm.h"
-#include "disassembler.h"
-#include "macro-assembler.h"
-#include "serialize.h"
-#include "stub-cache.h"
-#include "cctest.h"
+#include "src/debug.h"
+#include "src/disasm.h"
+#include "src/disassembler.h"
+#include "src/macro-assembler.h"
+#include "src/serialize.h"
+#include "src/stub-cache.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -168,6 +168,11 @@ TEST(DisasmIa320) {
__ nop();
__ idiv(edx);
+ __ idiv(Operand(edx, ecx, times_1, 1));
+ __ idiv(Operand(esp, 12));
+ __ div(edx);
+ __ div(Operand(edx, ecx, times_1, 1));
+ __ div(Operand(esp, 12));
__ mul(edx);
__ neg(edx);
__ not_(edx);
@@ -175,7 +180,9 @@ TEST(DisasmIa320) {
__ imul(edx, Operand(ebx, ecx, times_4, 10000));
__ imul(edx, ecx, 12);
+ __ imul(edx, Operand(edx, eax, times_2, 42), 8);
__ imul(edx, ecx, 1000);
+ __ imul(edx, Operand(ebx, ecx, times_4, 1), 9000);
__ inc(edx);
__ inc(Operand(ebx, ecx, times_4, 10000));
@@ -197,15 +204,24 @@ TEST(DisasmIa320) {
__ sar(edx, 1);
__ sar(edx, 6);
__ sar_cl(edx);
+ __ sar(Operand(ebx, ecx, times_4, 10000), 1);
+ __ sar(Operand(ebx, ecx, times_4, 10000), 6);
+ __ sar_cl(Operand(ebx, ecx, times_4, 10000));
__ sbb(edx, Operand(ebx, ecx, times_4, 10000));
__ shld(edx, Operand(ebx, ecx, times_4, 10000));
__ shl(edx, 1);
__ shl(edx, 6);
__ shl_cl(edx);
+ __ shl(Operand(ebx, ecx, times_4, 10000), 1);
+ __ shl(Operand(ebx, ecx, times_4, 10000), 6);
+ __ shl_cl(Operand(ebx, ecx, times_4, 10000));
__ shrd(edx, Operand(ebx, ecx, times_4, 10000));
__ shr(edx, 1);
__ shr(edx, 7);
__ shr_cl(edx);
+ __ shr(Operand(ebx, ecx, times_4, 10000), 1);
+ __ shr(Operand(ebx, ecx, times_4, 10000), 6);
+ __ shr_cl(Operand(ebx, ecx, times_4, 10000));
// Immediates
@@ -275,7 +291,7 @@ TEST(DisasmIa320) {
__ jmp(&L1);
__ jmp(Operand(ebx, ecx, times_4, 10000));
ExternalReference after_break_target =
- ExternalReference(Debug_Address::AfterBreakTarget(), isolate);
+ ExternalReference::debug_after_break_target_address(isolate);
__ jmp(Operand::StaticVariable(after_break_target));
__ jmp(ic, RelocInfo::CODE_TARGET);
__ nop();
@@ -364,86 +380,76 @@ TEST(DisasmIa320) {
// SSE instruction
{
- if (CpuFeatures::IsSupported(SSE2)) {
- CpuFeatureScope fscope(&assm, SSE2);
- // Move operation
- __ movaps(xmm0, xmm1);
- __ shufps(xmm0, xmm0, 0x0);
-
- // logic operation
- __ andps(xmm0, xmm1);
- __ andps(xmm0, Operand(ebx, ecx, times_4, 10000));
- __ orps(xmm0, xmm1);
- __ orps(xmm0, Operand(ebx, ecx, times_4, 10000));
- __ xorps(xmm0, xmm1);
- __ xorps(xmm0, Operand(ebx, ecx, times_4, 10000));
-
- // Arithmetic operation
- __ addps(xmm1, xmm0);
- __ addps(xmm1, Operand(ebx, ecx, times_4, 10000));
- __ subps(xmm1, xmm0);
- __ subps(xmm1, Operand(ebx, ecx, times_4, 10000));
- __ mulps(xmm1, xmm0);
- __ mulps(xmm1, Operand(ebx, ecx, times_4, 10000));
- __ divps(xmm1, xmm0);
- __ divps(xmm1, Operand(ebx, ecx, times_4, 10000));
- }
+ // Move operation
+ __ movaps(xmm0, xmm1);
+ __ shufps(xmm0, xmm0, 0x0);
+
+ // logic operation
+ __ andps(xmm0, xmm1);
+ __ andps(xmm0, Operand(ebx, ecx, times_4, 10000));
+ __ orps(xmm0, xmm1);
+ __ orps(xmm0, Operand(ebx, ecx, times_4, 10000));
+ __ xorps(xmm0, xmm1);
+ __ xorps(xmm0, Operand(ebx, ecx, times_4, 10000));
+
+ // Arithmetic operation
+ __ addps(xmm1, xmm0);
+ __ addps(xmm1, Operand(ebx, ecx, times_4, 10000));
+ __ subps(xmm1, xmm0);
+ __ subps(xmm1, Operand(ebx, ecx, times_4, 10000));
+ __ mulps(xmm1, xmm0);
+ __ mulps(xmm1, Operand(ebx, ecx, times_4, 10000));
+ __ divps(xmm1, xmm0);
+ __ divps(xmm1, Operand(ebx, ecx, times_4, 10000));
}
{
- if (CpuFeatures::IsSupported(SSE2)) {
- CpuFeatureScope fscope(&assm, SSE2);
- __ cvttss2si(edx, Operand(ebx, ecx, times_4, 10000));
- __ cvtsi2sd(xmm1, Operand(ebx, ecx, times_4, 10000));
- __ movsd(xmm1, Operand(ebx, ecx, times_4, 10000));
- __ movsd(Operand(ebx, ecx, times_4, 10000), xmm1);
- // 128 bit move instructions.
- __ movdqa(xmm0, Operand(ebx, ecx, times_4, 10000));
- __ movdqa(Operand(ebx, ecx, times_4, 10000), xmm0);
- __ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000));
- __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0);
-
- __ addsd(xmm1, xmm0);
- __ mulsd(xmm1, xmm0);
- __ subsd(xmm1, xmm0);
- __ divsd(xmm1, xmm0);
- __ ucomisd(xmm0, xmm1);
- __ cmpltsd(xmm0, xmm1);
-
- __ andpd(xmm0, xmm1);
- __ psllq(xmm0, 17);
- __ psllq(xmm0, xmm1);
- __ psrlq(xmm0, 17);
- __ psrlq(xmm0, xmm1);
- __ por(xmm0, xmm1);
- }
+ __ cvttss2si(edx, Operand(ebx, ecx, times_4, 10000));
+ __ cvtsi2sd(xmm1, Operand(ebx, ecx, times_4, 10000));
+ __ movsd(xmm1, Operand(ebx, ecx, times_4, 10000));
+ __ movsd(Operand(ebx, ecx, times_4, 10000), xmm1);
+ // 128 bit move instructions.
+ __ movdqa(xmm0, Operand(ebx, ecx, times_4, 10000));
+ __ movdqa(Operand(ebx, ecx, times_4, 10000), xmm0);
+ __ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000));
+ __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0);
+
+ __ addsd(xmm1, xmm0);
+ __ mulsd(xmm1, xmm0);
+ __ subsd(xmm1, xmm0);
+ __ divsd(xmm1, xmm0);
+ __ ucomisd(xmm0, xmm1);
+ __ cmpltsd(xmm0, xmm1);
+
+ __ andpd(xmm0, xmm1);
+ __ psllq(xmm0, 17);
+ __ psllq(xmm0, xmm1);
+ __ psrlq(xmm0, 17);
+ __ psrlq(xmm0, xmm1);
+ __ por(xmm0, xmm1);
}
// cmov.
{
- if (CpuFeatures::IsSupported(CMOV)) {
- CpuFeatureScope use_cmov(&assm, CMOV);
- __ cmov(overflow, eax, Operand(eax, 0));
- __ cmov(no_overflow, eax, Operand(eax, 1));
- __ cmov(below, eax, Operand(eax, 2));
- __ cmov(above_equal, eax, Operand(eax, 3));
- __ cmov(equal, eax, Operand(ebx, 0));
- __ cmov(not_equal, eax, Operand(ebx, 1));
- __ cmov(below_equal, eax, Operand(ebx, 2));
- __ cmov(above, eax, Operand(ebx, 3));
- __ cmov(sign, eax, Operand(ecx, 0));
- __ cmov(not_sign, eax, Operand(ecx, 1));
- __ cmov(parity_even, eax, Operand(ecx, 2));
- __ cmov(parity_odd, eax, Operand(ecx, 3));
- __ cmov(less, eax, Operand(edx, 0));
- __ cmov(greater_equal, eax, Operand(edx, 1));
- __ cmov(less_equal, eax, Operand(edx, 2));
- __ cmov(greater, eax, Operand(edx, 3));
- }
+ __ cmov(overflow, eax, Operand(eax, 0));
+ __ cmov(no_overflow, eax, Operand(eax, 1));
+ __ cmov(below, eax, Operand(eax, 2));
+ __ cmov(above_equal, eax, Operand(eax, 3));
+ __ cmov(equal, eax, Operand(ebx, 0));
+ __ cmov(not_equal, eax, Operand(ebx, 1));
+ __ cmov(below_equal, eax, Operand(ebx, 2));
+ __ cmov(above, eax, Operand(ebx, 3));
+ __ cmov(sign, eax, Operand(ecx, 0));
+ __ cmov(not_sign, eax, Operand(ecx, 1));
+ __ cmov(parity_even, eax, Operand(ecx, 2));
+ __ cmov(parity_odd, eax, Operand(ecx, 3));
+ __ cmov(less, eax, Operand(edx, 0));
+ __ cmov(greater_equal, eax, Operand(edx, 1));
+ __ cmov(less_equal, eax, Operand(edx, 2));
+ __ cmov(greater, eax, Operand(edx, 3));
}
{
- if (CpuFeatures::IsSupported(SSE2) &&
- CpuFeatures::IsSupported(SSE4_1)) {
+ if (CpuFeatures::IsSupported(SSE4_1)) {
CpuFeatureScope scope(&assm, SSE4_1);
__ pextrd(eax, xmm0, 1);
__ pinsrd(xmm1, eax, 0);
@@ -451,6 +457,14 @@ TEST(DisasmIa320) {
}
}
+ // xchg.
+ {
+ __ xchg(eax, eax);
+ __ xchg(eax, ebx);
+ __ xchg(ebx, ebx);
+ __ xchg(ebx, Operand(esp, 12));
+ }
+
// Nop instructions
for (int i = 0; i < 16; i++) {
__ Nop(i);
@@ -464,7 +478,8 @@ TEST(DisasmIa320) {
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
USE(code);
#ifdef OBJECT_PRINT
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
byte* begin = code->instruction_start();
byte* end = begin + code->instruction_size();
disasm::Disassembler::Disassemble(stdout, begin, end);
diff --git a/deps/v8/test/cctest/test-disasm-mips.cc b/deps/v8/test/cctest/test-disasm-mips.cc
index 725b3a567..cfd861e24 100644
--- a/deps/v8/test/cctest/test-disasm-mips.cc
+++ b/deps/v8/test/cctest/test-disasm-mips.cc
@@ -28,14 +28,14 @@
#include <stdlib.h>
-#include "v8.h"
-
-#include "debug.h"
-#include "disasm.h"
-#include "disassembler.h"
-#include "macro-assembler.h"
-#include "serialize.h"
-#include "cctest.h"
+#include "src/v8.h"
+
+#include "src/debug.h"
+#include "src/disasm.h"
+#include "src/disassembler.h"
+#include "src/macro-assembler.h"
+#include "src/serialize.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-disasm-mips64.cc b/deps/v8/test/cctest/test-disasm-mips64.cc
new file mode 100644
index 000000000..d682d3348
--- /dev/null
+++ b/deps/v8/test/cctest/test-disasm-mips64.cc
@@ -0,0 +1,674 @@
+// 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 "src/v8.h"
+
+#include "src/debug.h"
+#include "src/disasm.h"
+#include "src/disassembler.h"
+#include "src/macro-assembler.h"
+#include "src/serialize.h"
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+
+
+bool DisassembleAndCompare(byte* pc, const char* compare_string) {
+ disasm::NameConverter converter;
+ disasm::Disassembler disasm(converter);
+ EmbeddedVector<char, 128> disasm_buffer;
+
+ disasm.InstructionDecode(disasm_buffer, pc);
+
+ if (strcmp(compare_string, disasm_buffer.start()) != 0) {
+ fprintf(stderr,
+ "expected: \n"
+ "%s\n"
+ "disassembled: \n"
+ "%s\n\n",
+ compare_string, disasm_buffer.start());
+ return false;
+ }
+ return true;
+}
+
+
+// Set up V8 to a state where we can at least run the assembler and
+// disassembler. Declare the variables and allocate the data structures used
+// in the rest of the macros.
+#define SET_UP() \
+ CcTest::InitializeVM(); \
+ Isolate* isolate = CcTest::i_isolate(); \
+ HandleScope scope(isolate); \
+ byte *buffer = reinterpret_cast<byte*>(malloc(4*1024)); \
+ Assembler assm(isolate, buffer, 4*1024); \
+ bool failure = false;
+
+
+// This macro assembles one instruction using the preallocated assembler and
+// disassembles the generated instruction, comparing the output to the expected
+// value. If the comparison fails an error message is printed, but the test
+// continues to run until the end.
+#define COMPARE(asm_, compare_string) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, compare_string)) failure = true; \
+ }
+
+
+// Verify that all invocations of the COMPARE macro passed successfully.
+// Exit with a failure if at least one of the tests failed.
+#define VERIFY_RUN() \
+if (failure) { \
+ V8_Fatal(__FILE__, __LINE__, "MIPS Disassembler tests failed.\n"); \
+ }
+
+
+TEST(Type0) {
+ SET_UP();
+
+ COMPARE(addu(a0, a1, a2),
+ "00a62021 addu a0, a1, a2");
+ COMPARE(daddu(a0, a1, a2),
+ "00a6202d daddu a0, a1, a2");
+ COMPARE(addu(a6, a7, t0),
+ "016c5021 addu a6, a7, t0");
+ COMPARE(daddu(a6, a7, t0),
+ "016c502d daddu a6, a7, t0");
+ COMPARE(addu(v0, v1, s0),
+ "00701021 addu v0, v1, s0");
+ COMPARE(daddu(v0, v1, s0),
+ "0070102d daddu v0, v1, s0");
+
+ COMPARE(subu(a0, a1, a2),
+ "00a62023 subu a0, a1, a2");
+ COMPARE(dsubu(a0, a1, a2),
+ "00a6202f dsubu a0, a1, a2");
+ COMPARE(subu(a6, a7, t0),
+ "016c5023 subu a6, a7, t0");
+ COMPARE(dsubu(a6, a7, t0),
+ "016c502f dsubu a6, a7, t0");
+ COMPARE(subu(v0, v1, s0),
+ "00701023 subu v0, v1, s0");
+ COMPARE(dsubu(v0, v1, s0),
+ "0070102f dsubu v0, v1, s0");
+
+ if (kArchVariant != kMips64r6) {
+ COMPARE(mult(a0, a1),
+ "00850018 mult a0, a1");
+ COMPARE(dmult(a0, a1),
+ "0085001c dmult a0, a1");
+ COMPARE(mult(a6, a7),
+ "014b0018 mult a6, a7");
+ COMPARE(dmult(a6, a7),
+ "014b001c dmult a6, a7");
+ COMPARE(mult(v0, v1),
+ "00430018 mult v0, v1");
+ COMPARE(dmult(v0, v1),
+ "0043001c dmult v0, v1");
+
+ COMPARE(multu(a0, a1),
+ "00850019 multu a0, a1");
+ COMPARE(dmultu(a0, a1),
+ "0085001d dmultu a0, a1");
+ COMPARE(multu(a6, a7),
+ "014b0019 multu a6, a7");
+ COMPARE(dmultu(a6, a7),
+ "014b001d dmultu a6, a7");
+ COMPARE(multu(v0, v1),
+ "00430019 multu v0, v1");
+ COMPARE(dmultu(v0, v1),
+ "0043001d dmultu v0, v1");
+
+ COMPARE(div(a0, a1),
+ "0085001a div a0, a1");
+ COMPARE(div(a6, a7),
+ "014b001a div a6, a7");
+ COMPARE(div(v0, v1),
+ "0043001a div v0, v1");
+ COMPARE(ddiv(a0, a1),
+ "0085001e ddiv a0, a1");
+ COMPARE(ddiv(a6, a7),
+ "014b001e ddiv a6, a7");
+ COMPARE(ddiv(v0, v1),
+ "0043001e ddiv v0, v1");
+
+ COMPARE(divu(a0, a1),
+ "0085001b divu a0, a1");
+ COMPARE(divu(a6, a7),
+ "014b001b divu a6, a7");
+ COMPARE(divu(v0, v1),
+ "0043001b divu v0, v1");
+ COMPARE(ddivu(a0, a1),
+ "0085001f ddivu a0, a1");
+ COMPARE(ddivu(a6, a7),
+ "014b001f ddivu a6, a7");
+ COMPARE(ddivu(v0, v1),
+ "0043001f ddivu v0, v1");
+ COMPARE(mul(a0, a1, a2),
+ "70a62002 mul a0, a1, a2");
+ COMPARE(mul(a6, a7, t0),
+ "716c5002 mul a6, a7, t0");
+ COMPARE(mul(v0, v1, s0),
+ "70701002 mul v0, v1, s0");
+ } else { // MIPS64r6.
+ COMPARE(mul(a0, a1, a2),
+ "00a62098 mul a0, a1, a2");
+ COMPARE(muh(a0, a1, a2),
+ "00a620d8 muh a0, a1, a2");
+ COMPARE(dmul(a0, a1, a2),
+ "00a6209c dmul a0, a1, a2");
+ COMPARE(dmuh(a0, a1, a2),
+ "00a620dc dmuh a0, a1, a2");
+ COMPARE(mul(a5, a6, a7),
+ "014b4898 mul a5, a6, a7");
+ COMPARE(muh(a5, a6, a7),
+ "014b48d8 muh a5, a6, a7");
+ COMPARE(dmul(a5, a6, a7),
+ "014b489c dmul a5, a6, a7");
+ COMPARE(dmuh(a5, a6, a7),
+ "014b48dc dmuh a5, a6, a7");
+ COMPARE(mul(v0, v1, a0),
+ "00641098 mul v0, v1, a0");
+ COMPARE(muh(v0, v1, a0),
+ "006410d8 muh v0, v1, a0");
+ COMPARE(dmul(v0, v1, a0),
+ "0064109c dmul v0, v1, a0");
+ COMPARE(dmuh(v0, v1, a0),
+ "006410dc dmuh v0, v1, a0");
+
+ COMPARE(mulu(a0, a1, a2),
+ "00a62099 mulu a0, a1, a2");
+ COMPARE(muhu(a0, a1, a2),
+ "00a620d9 muhu a0, a1, a2");
+ COMPARE(dmulu(a0, a1, a2),
+ "00a6209d dmulu a0, a1, a2");
+ COMPARE(dmuhu(a0, a1, a2),
+ "00a620dd dmuhu a0, a1, a2");
+ COMPARE(mulu(a5, a6, a7),
+ "014b4899 mulu a5, a6, a7");
+ COMPARE(muhu(a5, a6, a7),
+ "014b48d9 muhu a5, a6, a7");
+ COMPARE(dmulu(a5, a6, a7),
+ "014b489d dmulu a5, a6, a7");
+ COMPARE(dmuhu(a5, a6, a7),
+ "014b48dd dmuhu a5, a6, a7");
+ COMPARE(mulu(v0, v1, a0),
+ "00641099 mulu v0, v1, a0");
+ COMPARE(muhu(v0, v1, a0),
+ "006410d9 muhu v0, v1, a0");
+ COMPARE(dmulu(v0, v1, a0),
+ "0064109d dmulu v0, v1, a0");
+ COMPARE(dmuhu(v0, v1, a0),
+ "006410dd dmuhu v0, v1, a0");
+
+ COMPARE(div(a0, a1, a2),
+ "00a6209a div a0, a1, a2");
+ COMPARE(mod(a0, a1, a2),
+ "00a620da mod a0, a1, a2");
+ COMPARE(ddiv(a0, a1, a2),
+ "00a6209e ddiv a0, a1, a2");
+ COMPARE(dmod(a0, a1, a2),
+ "00a620de dmod a0, a1, a2");
+ COMPARE(div(a5, a6, a7),
+ "014b489a div a5, a6, a7");
+ COMPARE(mod(a5, a6, a7),
+ "014b48da mod a5, a6, a7");
+ COMPARE(ddiv(a5, a6, a7),
+ "014b489e ddiv a5, a6, a7");
+ COMPARE(dmod(a5, a6, a7),
+ "014b48de dmod a5, a6, a7");
+ COMPARE(div(v0, v1, a0),
+ "0064109a div v0, v1, a0");
+ COMPARE(mod(v0, v1, a0),
+ "006410da mod v0, v1, a0");
+ COMPARE(ddiv(v0, v1, a0),
+ "0064109e ddiv v0, v1, a0");
+ COMPARE(dmod(v0, v1, a0),
+ "006410de dmod v0, v1, a0");
+
+ COMPARE(divu(a0, a1, a2),
+ "00a6209b divu a0, a1, a2");
+ COMPARE(modu(a0, a1, a2),
+ "00a620db modu a0, a1, a2");
+ COMPARE(ddivu(a0, a1, a2),
+ "00a6209f ddivu a0, a1, a2");
+ COMPARE(dmodu(a0, a1, a2),
+ "00a620df dmodu a0, a1, a2");
+ COMPARE(divu(a5, a6, a7),
+ "014b489b divu a5, a6, a7");
+ COMPARE(modu(a5, a6, a7),
+ "014b48db modu a5, a6, a7");
+ COMPARE(ddivu(a5, a6, a7),
+ "014b489f ddivu a5, a6, a7");
+ COMPARE(dmodu(a5, a6, a7),
+ "014b48df dmodu a5, a6, a7");
+ COMPARE(divu(v0, v1, a0),
+ "0064109b divu v0, v1, a0");
+ COMPARE(modu(v0, v1, a0),
+ "006410db modu v0, v1, a0");
+ COMPARE(ddivu(v0, v1, a0),
+ "0064109f ddivu v0, v1, a0");
+ COMPARE(dmodu(v0, v1, a0),
+ "006410df dmodu v0, v1, a0");
+
+ COMPARE(bovc(a0, a0, static_cast<int16_t>(0)),
+ "20840000 bovc a0, a0, 0");
+ COMPARE(bovc(a1, a0, static_cast<int16_t>(0)),
+ "20a40000 bovc a1, a0, 0");
+ COMPARE(bovc(a1, a0, 32767),
+ "20a47fff bovc a1, a0, 32767");
+ COMPARE(bovc(a1, a0, -32768),
+ "20a48000 bovc a1, a0, -32768");
+
+ COMPARE(bnvc(a0, a0, static_cast<int16_t>(0)),
+ "60840000 bnvc a0, a0, 0");
+ COMPARE(bnvc(a1, a0, static_cast<int16_t>(0)),
+ "60a40000 bnvc a1, a0, 0");
+ COMPARE(bnvc(a1, a0, 32767),
+ "60a47fff bnvc a1, a0, 32767");
+ COMPARE(bnvc(a1, a0, -32768),
+ "60a48000 bnvc a1, a0, -32768");
+
+ COMPARE(beqzc(a0, 0),
+ "d8800000 beqzc a0, 0x0");
+ COMPARE(beqzc(a0, 0xfffff), // 0x0fffff == 1048575.
+ "d88fffff beqzc a0, 0xfffff");
+ COMPARE(beqzc(a0, 0x100000), // 0x100000 == -1048576.
+ "d8900000 beqzc a0, 0x100000");
+
+ COMPARE(bnezc(a0, 0),
+ "f8800000 bnezc a0, 0x0");
+ COMPARE(bnezc(a0, 0xfffff), // 0x0fffff == 1048575.
+ "f88fffff bnezc a0, 0xfffff");
+ COMPARE(bnezc(a0, 0x100000), // 0x100000 == -1048576.
+ "f8900000 bnezc a0, 0x100000");
+ }
+
+ COMPARE(addiu(a0, a1, 0x0),
+ "24a40000 addiu a0, a1, 0");
+ COMPARE(addiu(s0, s1, 32767),
+ "26307fff addiu s0, s1, 32767");
+ COMPARE(addiu(a6, a7, -32768),
+ "256a8000 addiu a6, a7, -32768");
+ COMPARE(addiu(v0, v1, -1),
+ "2462ffff addiu v0, v1, -1");
+ COMPARE(daddiu(a0, a1, 0x0),
+ "64a40000 daddiu a0, a1, 0");
+ COMPARE(daddiu(s0, s1, 32767),
+ "66307fff daddiu s0, s1, 32767");
+ COMPARE(daddiu(a6, a7, -32768),
+ "656a8000 daddiu a6, a7, -32768");
+ COMPARE(daddiu(v0, v1, -1),
+ "6462ffff daddiu v0, v1, -1");
+
+ COMPARE(and_(a0, a1, a2),
+ "00a62024 and a0, a1, a2");
+ COMPARE(and_(s0, s1, s2),
+ "02328024 and s0, s1, s2");
+ COMPARE(and_(a6, a7, t0),
+ "016c5024 and a6, a7, t0");
+ COMPARE(and_(v0, v1, a2),
+ "00661024 and v0, v1, a2");
+
+ COMPARE(or_(a0, a1, a2),
+ "00a62025 or a0, a1, a2");
+ COMPARE(or_(s0, s1, s2),
+ "02328025 or s0, s1, s2");
+ COMPARE(or_(a6, a7, t0),
+ "016c5025 or a6, a7, t0");
+ COMPARE(or_(v0, v1, a2),
+ "00661025 or v0, v1, a2");
+
+ COMPARE(xor_(a0, a1, a2),
+ "00a62026 xor a0, a1, a2");
+ COMPARE(xor_(s0, s1, s2),
+ "02328026 xor s0, s1, s2");
+ COMPARE(xor_(a6, a7, t0),
+ "016c5026 xor a6, a7, t0");
+ COMPARE(xor_(v0, v1, a2),
+ "00661026 xor v0, v1, a2");
+
+ COMPARE(nor(a0, a1, a2),
+ "00a62027 nor a0, a1, a2");
+ COMPARE(nor(s0, s1, s2),
+ "02328027 nor s0, s1, s2");
+ COMPARE(nor(a6, a7, t0),
+ "016c5027 nor a6, a7, t0");
+ COMPARE(nor(v0, v1, a2),
+ "00661027 nor v0, v1, a2");
+
+ COMPARE(andi(a0, a1, 0x1),
+ "30a40001 andi a0, a1, 0x1");
+ COMPARE(andi(v0, v1, 0xffff),
+ "3062ffff andi v0, v1, 0xffff");
+
+ COMPARE(ori(a0, a1, 0x1),
+ "34a40001 ori a0, a1, 0x1");
+ COMPARE(ori(v0, v1, 0xffff),
+ "3462ffff ori v0, v1, 0xffff");
+
+ COMPARE(xori(a0, a1, 0x1),
+ "38a40001 xori a0, a1, 0x1");
+ COMPARE(xori(v0, v1, 0xffff),
+ "3862ffff xori v0, v1, 0xffff");
+
+ COMPARE(lui(a0, 0x1),
+ "3c040001 lui a0, 0x1");
+ COMPARE(lui(v0, 0xffff),
+ "3c02ffff lui v0, 0xffff");
+
+ COMPARE(sll(a0, a1, 0),
+ "00052000 sll a0, a1, 0");
+ COMPARE(sll(s0, s1, 8),
+ "00118200 sll s0, s1, 8");
+ COMPARE(sll(a6, a7, 24),
+ "000b5600 sll a6, a7, 24");
+ COMPARE(sll(v0, v1, 31),
+ "000317c0 sll v0, v1, 31");
+ COMPARE(dsll(a0, a1, 0),
+ "00052038 dsll a0, a1, 0");
+ COMPARE(dsll(s0, s1, 8),
+ "00118238 dsll s0, s1, 8");
+ COMPARE(dsll(a6, a7, 24),
+ "000b5638 dsll a6, a7, 24");
+ COMPARE(dsll(v0, v1, 31),
+ "000317f8 dsll v0, v1, 31");
+
+ COMPARE(sllv(a0, a1, a2),
+ "00c52004 sllv a0, a1, a2");
+ COMPARE(sllv(s0, s1, s2),
+ "02518004 sllv s0, s1, s2");
+ COMPARE(sllv(a6, a7, t0),
+ "018b5004 sllv a6, a7, t0");
+ COMPARE(sllv(v0, v1, fp),
+ "03c31004 sllv v0, v1, fp");
+ COMPARE(dsllv(a0, a1, a2),
+ "00c52014 dsllv a0, a1, a2");
+ COMPARE(dsllv(s0, s1, s2),
+ "02518014 dsllv s0, s1, s2");
+ COMPARE(dsllv(a6, a7, t0),
+ "018b5014 dsllv a6, a7, t0");
+ COMPARE(dsllv(v0, v1, fp),
+ "03c31014 dsllv v0, v1, fp");
+
+ COMPARE(srl(a0, a1, 0),
+ "00052002 srl a0, a1, 0");
+ COMPARE(srl(s0, s1, 8),
+ "00118202 srl s0, s1, 8");
+ COMPARE(srl(a6, a7, 24),
+ "000b5602 srl a6, a7, 24");
+ COMPARE(srl(v0, v1, 31),
+ "000317c2 srl v0, v1, 31");
+ COMPARE(dsrl(a0, a1, 0),
+ "0005203a dsrl a0, a1, 0");
+ COMPARE(dsrl(s0, s1, 8),
+ "0011823a dsrl s0, s1, 8");
+ COMPARE(dsrl(a6, a7, 24),
+ "000b563a dsrl a6, a7, 24");
+ COMPARE(dsrl(v0, v1, 31),
+ "000317fa dsrl v0, v1, 31");
+
+ COMPARE(srlv(a0, a1, a2),
+ "00c52006 srlv a0, a1, a2");
+ COMPARE(srlv(s0, s1, s2),
+ "02518006 srlv s0, s1, s2");
+ COMPARE(srlv(a6, a7, t0),
+ "018b5006 srlv a6, a7, t0");
+ COMPARE(srlv(v0, v1, fp),
+ "03c31006 srlv v0, v1, fp");
+ COMPARE(dsrlv(a0, a1, a2),
+ "00c52016 dsrlv a0, a1, a2");
+ COMPARE(dsrlv(s0, s1, s2),
+ "02518016 dsrlv s0, s1, s2");
+ COMPARE(dsrlv(a6, a7, t0),
+ "018b5016 dsrlv a6, a7, t0");
+ COMPARE(dsrlv(v0, v1, fp),
+ "03c31016 dsrlv v0, v1, fp");
+
+ COMPARE(sra(a0, a1, 0),
+ "00052003 sra a0, a1, 0");
+ COMPARE(sra(s0, s1, 8),
+ "00118203 sra s0, s1, 8");
+ COMPARE(sra(a6, a7, 24),
+ "000b5603 sra a6, a7, 24");
+ COMPARE(sra(v0, v1, 31),
+ "000317c3 sra v0, v1, 31");
+ COMPARE(dsra(a0, a1, 0),
+ "0005203b dsra a0, a1, 0");
+ COMPARE(dsra(s0, s1, 8),
+ "0011823b dsra s0, s1, 8");
+ COMPARE(dsra(a6, a7, 24),
+ "000b563b dsra a6, a7, 24");
+ COMPARE(dsra(v0, v1, 31),
+ "000317fb dsra v0, v1, 31");
+
+ COMPARE(srav(a0, a1, a2),
+ "00c52007 srav a0, a1, a2");
+ COMPARE(srav(s0, s1, s2),
+ "02518007 srav s0, s1, s2");
+ COMPARE(srav(a6, a7, t0),
+ "018b5007 srav a6, a7, t0");
+ COMPARE(srav(v0, v1, fp),
+ "03c31007 srav v0, v1, fp");
+ COMPARE(dsrav(a0, a1, a2),
+ "00c52017 dsrav a0, a1, a2");
+ COMPARE(dsrav(s0, s1, s2),
+ "02518017 dsrav s0, s1, s2");
+ COMPARE(dsrav(a6, a7, t0),
+ "018b5017 dsrav a6, a7, t0");
+ COMPARE(dsrav(v0, v1, fp),
+ "03c31017 dsrav v0, v1, fp");
+
+ if (kArchVariant == kMips64r2) {
+ COMPARE(rotr(a0, a1, 0),
+ "00252002 rotr a0, a1, 0");
+ COMPARE(rotr(s0, s1, 8),
+ "00318202 rotr s0, s1, 8");
+ COMPARE(rotr(a6, a7, 24),
+ "002b5602 rotr a6, a7, 24");
+ COMPARE(rotr(v0, v1, 31),
+ "002317c2 rotr v0, v1, 31");
+ COMPARE(drotr(a0, a1, 0),
+ "0025203a drotr a0, a1, 0");
+ COMPARE(drotr(s0, s1, 8),
+ "0031823a drotr s0, s1, 8");
+ COMPARE(drotr(a6, a7, 24),
+ "002b563a drotr a6, a7, 24");
+ COMPARE(drotr(v0, v1, 31),
+ "002317fa drotr v0, v1, 31");
+
+ COMPARE(rotrv(a0, a1, a2),
+ "00c52046 rotrv a0, a1, a2");
+ COMPARE(rotrv(s0, s1, s2),
+ "02518046 rotrv s0, s1, s2");
+ COMPARE(rotrv(a6, a7, t0),
+ "018b5046 rotrv a6, a7, t0");
+ COMPARE(rotrv(v0, v1, fp),
+ "03c31046 rotrv v0, v1, fp");
+ COMPARE(drotrv(a0, a1, a2),
+ "00c52056 drotrv a0, a1, a2");
+ COMPARE(drotrv(s0, s1, s2),
+ "02518056 drotrv s0, s1, s2");
+ COMPARE(drotrv(a6, a7, t0),
+ "018b5056 drotrv a6, a7, t0");
+ COMPARE(drotrv(v0, v1, fp),
+ "03c31056 drotrv v0, v1, fp");
+ }
+
+ COMPARE(break_(0),
+ "0000000d break, code: 0x00000 (0)");
+ COMPARE(break_(261120),
+ "00ff000d break, code: 0x3fc00 (261120)");
+ COMPARE(break_(1047552),
+ "03ff000d break, code: 0xffc00 (1047552)");
+
+ COMPARE(tge(a0, a1, 0),
+ "00850030 tge a0, a1, code: 0x000");
+ COMPARE(tge(s0, s1, 1023),
+ "0211fff0 tge s0, s1, code: 0x3ff");
+ COMPARE(tgeu(a0, a1, 0),
+ "00850031 tgeu a0, a1, code: 0x000");
+ COMPARE(tgeu(s0, s1, 1023),
+ "0211fff1 tgeu s0, s1, code: 0x3ff");
+ COMPARE(tlt(a0, a1, 0),
+ "00850032 tlt a0, a1, code: 0x000");
+ COMPARE(tlt(s0, s1, 1023),
+ "0211fff2 tlt s0, s1, code: 0x3ff");
+ COMPARE(tltu(a0, a1, 0),
+ "00850033 tltu a0, a1, code: 0x000");
+ COMPARE(tltu(s0, s1, 1023),
+ "0211fff3 tltu s0, s1, code: 0x3ff");
+ COMPARE(teq(a0, a1, 0),
+ "00850034 teq a0, a1, code: 0x000");
+ COMPARE(teq(s0, s1, 1023),
+ "0211fff4 teq s0, s1, code: 0x3ff");
+ COMPARE(tne(a0, a1, 0),
+ "00850036 tne a0, a1, code: 0x000");
+ COMPARE(tne(s0, s1, 1023),
+ "0211fff6 tne s0, s1, code: 0x3ff");
+
+ COMPARE(mfhi(a0),
+ "00002010 mfhi a0");
+ COMPARE(mfhi(s2),
+ "00009010 mfhi s2");
+ COMPARE(mfhi(t0),
+ "00006010 mfhi t0");
+ COMPARE(mfhi(v1),
+ "00001810 mfhi v1");
+ COMPARE(mflo(a0),
+ "00002012 mflo a0");
+ COMPARE(mflo(s2),
+ "00009012 mflo s2");
+ COMPARE(mflo(t0),
+ "00006012 mflo t0");
+ COMPARE(mflo(v1),
+ "00001812 mflo v1");
+
+ COMPARE(slt(a0, a1, a2),
+ "00a6202a slt a0, a1, a2");
+ COMPARE(slt(s0, s1, s2),
+ "0232802a slt s0, s1, s2");
+ COMPARE(slt(a6, a7, t0),
+ "016c502a slt a6, a7, t0");
+ COMPARE(slt(v0, v1, a2),
+ "0066102a slt v0, v1, a2");
+ COMPARE(sltu(a0, a1, a2),
+ "00a6202b sltu a0, a1, a2");
+ COMPARE(sltu(s0, s1, s2),
+ "0232802b sltu s0, s1, s2");
+ COMPARE(sltu(a6, a7, t0),
+ "016c502b sltu a6, a7, t0");
+ COMPARE(sltu(v0, v1, a2),
+ "0066102b sltu v0, v1, a2");
+
+ COMPARE(slti(a0, a1, 0),
+ "28a40000 slti a0, a1, 0");
+ COMPARE(slti(s0, s1, 32767),
+ "2a307fff slti s0, s1, 32767");
+ COMPARE(slti(a6, a7, -32768),
+ "296a8000 slti a6, a7, -32768");
+ COMPARE(slti(v0, v1, -1),
+ "2862ffff slti v0, v1, -1");
+ COMPARE(sltiu(a0, a1, 0),
+ "2ca40000 sltiu a0, a1, 0");
+ COMPARE(sltiu(s0, s1, 32767),
+ "2e307fff sltiu s0, s1, 32767");
+ COMPARE(sltiu(a6, a7, -32768),
+ "2d6a8000 sltiu a6, a7, -32768");
+ COMPARE(sltiu(v0, v1, -1),
+ "2c62ffff sltiu v0, v1, -1");
+ COMPARE(movz(a0, a1, a2),
+ "00a6200a movz a0, a1, a2");
+ COMPARE(movz(s0, s1, s2),
+ "0232800a movz s0, s1, s2");
+ COMPARE(movz(a6, a7, t0),
+ "016c500a movz a6, a7, t0");
+ COMPARE(movz(v0, v1, a2),
+ "0066100a movz v0, v1, a2");
+ COMPARE(movn(a0, a1, a2),
+ "00a6200b movn a0, a1, a2");
+ COMPARE(movn(s0, s1, s2),
+ "0232800b movn s0, s1, s2");
+ COMPARE(movn(a6, a7, t0),
+ "016c500b movn a6, a7, t0");
+ COMPARE(movn(v0, v1, a2),
+ "0066100b movn v0, v1, a2");
+
+ COMPARE(movt(a0, a1, 1),
+ "00a52001 movt a0, a1, 1");
+ COMPARE(movt(s0, s1, 2),
+ "02298001 movt s0, s1, 2");
+ COMPARE(movt(a6, a7, 3),
+ "016d5001 movt a6, a7, 3");
+ COMPARE(movt(v0, v1, 7),
+ "007d1001 movt v0, v1, 7");
+ COMPARE(movf(a0, a1, 0),
+ "00a02001 movf a0, a1, 0");
+ COMPARE(movf(s0, s1, 4),
+ "02308001 movf s0, s1, 4");
+ COMPARE(movf(a6, a7, 5),
+ "01745001 movf a6, a7, 5");
+ COMPARE(movf(v0, v1, 6),
+ "00781001 movf v0, v1, 6");
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(clz(a0, a1),
+ "00a02050 clz a0, a1");
+ COMPARE(clz(s6, s7),
+ "02e0b050 clz s6, s7");
+ COMPARE(clz(v0, v1),
+ "00601050 clz v0, v1");
+ } else {
+ COMPARE(clz(a0, a1),
+ "70a42020 clz a0, a1");
+ COMPARE(clz(s6, s7),
+ "72f6b020 clz s6, s7");
+ COMPARE(clz(v0, v1),
+ "70621020 clz v0, v1");
+ }
+
+ COMPARE(ins_(a0, a1, 31, 1),
+ "7ca4ffc4 ins a0, a1, 31, 1");
+ COMPARE(ins_(s6, s7, 30, 2),
+ "7ef6ff84 ins s6, s7, 30, 2");
+ COMPARE(ins_(v0, v1, 0, 32),
+ "7c62f804 ins v0, v1, 0, 32");
+ COMPARE(ext_(a0, a1, 31, 1),
+ "7ca407c0 ext a0, a1, 31, 1");
+ COMPARE(ext_(s6, s7, 30, 2),
+ "7ef60f80 ext s6, s7, 30, 2");
+ COMPARE(ext_(v0, v1, 0, 32),
+ "7c62f800 ext v0, v1, 0, 32");
+
+ VERIFY_RUN();
+}
diff --git a/deps/v8/test/cctest/test-disasm-x64.cc b/deps/v8/test/cctest/test-disasm-x64.cc
index 3b1f8af82..4778b04bb 100644
--- a/deps/v8/test/cctest/test-disasm-x64.cc
+++ b/deps/v8/test/cctest/test-disasm-x64.cc
@@ -27,15 +27,15 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "debug.h"
-#include "disasm.h"
-#include "disassembler.h"
-#include "macro-assembler.h"
-#include "serialize.h"
-#include "stub-cache.h"
-#include "cctest.h"
+#include "src/debug.h"
+#include "src/disasm.h"
+#include "src/disassembler.h"
+#include "src/macro-assembler.h"
+#include "src/serialize.h"
+#include "src/stub-cache.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -261,7 +261,7 @@ TEST(DisasmX64) {
// TODO(mstarzinger): The following is protected.
// __ jmp(Operand(rbx, rcx, times_4, 10000));
ExternalReference after_break_target =
- ExternalReference(Debug_Address::AfterBreakTarget(), isolate);
+ ExternalReference::debug_after_break_target_address(isolate);
USE(after_break_target);
__ jmp(ic, RelocInfo::CODE_TARGET);
__ nop();
@@ -420,6 +420,14 @@ TEST(DisasmX64) {
}
}
+ // xchg.
+ {
+ __ xchgq(rax, rax);
+ __ xchgq(rax, rbx);
+ __ xchgq(rbx, rbx);
+ __ xchgq(rbx, Operand(rsp, 12));
+ }
+
// Nop instructions
for (int i = 0; i < 16; i++) {
__ Nop(i);
@@ -433,7 +441,8 @@ TEST(DisasmX64) {
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
USE(code);
#ifdef OBJECT_PRINT
- code->Print();
+ OFStream os(stdout);
+ code->Print(os);
byte* begin = code->instruction_start();
byte* end = begin + code->instruction_size();
disasm::Disassembler::Disassemble(stdout, begin, end);
diff --git a/deps/v8/test/cctest/test-disasm-x87.cc b/deps/v8/test/cctest/test-disasm-x87.cc
new file mode 100644
index 000000000..1515cc793
--- /dev/null
+++ b/deps/v8/test/cctest/test-disasm-x87.cc
@@ -0,0 +1,410 @@
+// 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 <stdlib.h>
+
+#include "src/v8.h"
+
+#include "src/debug.h"
+#include "src/disasm.h"
+#include "src/disassembler.h"
+#include "src/macro-assembler.h"
+#include "src/serialize.h"
+#include "src/stub-cache.h"
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+
+
+#define __ assm.
+
+
+static void DummyStaticFunction(Object* result) {
+}
+
+
+TEST(DisasmIa320) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ v8::internal::byte buffer[2048];
+ Assembler assm(isolate, buffer, sizeof buffer);
+ DummyStaticFunction(NULL); // just bloody use it (DELETE; debugging)
+
+ // Short immediate instructions
+ __ adc(eax, 12345678);
+ __ add(eax, Immediate(12345678));
+ __ or_(eax, 12345678);
+ __ sub(eax, Immediate(12345678));
+ __ xor_(eax, 12345678);
+ __ and_(eax, 12345678);
+ Handle<FixedArray> foo = isolate->factory()->NewFixedArray(10, TENURED);
+ __ cmp(eax, foo);
+
+ // ---- This one caused crash
+ __ mov(ebx, Operand(esp, ecx, times_2, 0)); // [esp+ecx*4]
+
+ // ---- All instructions that I can think of
+ __ add(edx, ebx);
+ __ add(edx, Operand(12, RelocInfo::NONE32));
+ __ add(edx, Operand(ebx, 0));
+ __ add(edx, Operand(ebx, 16));
+ __ add(edx, Operand(ebx, 1999));
+ __ add(edx, Operand(ebx, -4));
+ __ add(edx, Operand(ebx, -1999));
+ __ add(edx, Operand(esp, 0));
+ __ add(edx, Operand(esp, 16));
+ __ add(edx, Operand(esp, 1999));
+ __ add(edx, Operand(esp, -4));
+ __ add(edx, Operand(esp, -1999));
+ __ nop();
+ __ add(esi, Operand(ecx, times_4, 0));
+ __ add(esi, Operand(ecx, times_4, 24));
+ __ add(esi, Operand(ecx, times_4, -4));
+ __ add(esi, Operand(ecx, times_4, -1999));
+ __ nop();
+ __ add(edi, Operand(ebp, ecx, times_4, 0));
+ __ add(edi, Operand(ebp, ecx, times_4, 12));
+ __ add(edi, Operand(ebp, ecx, times_4, -8));
+ __ add(edi, Operand(ebp, ecx, times_4, -3999));
+ __ add(Operand(ebp, ecx, times_4, 12), Immediate(12));
+
+ __ nop();
+ __ add(ebx, Immediate(12));
+ __ nop();
+ __ adc(ecx, 12);
+ __ adc(ecx, 1000);
+ __ nop();
+ __ and_(edx, 3);
+ __ and_(edx, Operand(esp, 4));
+ __ cmp(edx, 3);
+ __ cmp(edx, Operand(esp, 4));
+ __ cmp(Operand(ebp, ecx, times_4, 0), Immediate(1000));
+ Handle<FixedArray> foo2 = isolate->factory()->NewFixedArray(10, TENURED);
+ __ cmp(ebx, foo2);
+ __ cmpb(ebx, Operand(ebp, ecx, times_2, 0));
+ __ cmpb(Operand(ebp, ecx, times_2, 0), ebx);
+ __ or_(edx, 3);
+ __ xor_(edx, 3);
+ __ nop();
+ __ cpuid();
+ __ movsx_b(edx, ecx);
+ __ movsx_w(edx, ecx);
+ __ movzx_b(edx, ecx);
+ __ movzx_w(edx, ecx);
+
+ __ nop();
+ __ imul(edx, ecx);
+ __ shld(edx, ecx);
+ __ shrd(edx, ecx);
+ __ bts(edx, ecx);
+ __ bts(Operand(ebx, ecx, times_4, 0), ecx);
+ __ nop();
+ __ pushad();
+ __ popad();
+ __ pushfd();
+ __ popfd();
+ __ push(Immediate(12));
+ __ push(Immediate(23456));
+ __ push(ecx);
+ __ push(esi);
+ __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
+ __ push(Operand(ebx, ecx, times_4, 0));
+ __ push(Operand(ebx, ecx, times_4, 0));
+ __ push(Operand(ebx, ecx, times_4, 10000));
+ __ pop(edx);
+ __ pop(eax);
+ __ pop(Operand(ebx, ecx, times_4, 0));
+ __ nop();
+
+ __ add(edx, Operand(esp, 16));
+ __ add(edx, ecx);
+ __ mov_b(edx, ecx);
+ __ mov_b(ecx, 6);
+ __ mov_b(Operand(ebx, ecx, times_4, 10000), 6);
+ __ mov_b(Operand(esp, 16), edx);
+ __ mov_w(edx, Operand(esp, 16));
+ __ mov_w(Operand(esp, 16), edx);
+ __ nop();
+ __ movsx_w(edx, Operand(esp, 12));
+ __ movsx_b(edx, Operand(esp, 12));
+ __ movzx_w(edx, Operand(esp, 12));
+ __ movzx_b(edx, Operand(esp, 12));
+ __ nop();
+ __ mov(edx, 1234567);
+ __ mov(edx, Operand(esp, 12));
+ __ mov(Operand(ebx, ecx, times_4, 10000), Immediate(12345));
+ __ mov(Operand(ebx, ecx, times_4, 10000), edx);
+ __ nop();
+ __ dec_b(edx);
+ __ dec_b(Operand(eax, 10));
+ __ dec_b(Operand(ebx, ecx, times_4, 10000));
+ __ dec(edx);
+ __ cdq();
+
+ __ nop();
+ __ idiv(edx);
+ __ idiv(Operand(edx, ecx, times_1, 1));
+ __ idiv(Operand(esp, 12));
+ __ div(edx);
+ __ div(Operand(edx, ecx, times_1, 1));
+ __ div(Operand(esp, 12));
+ __ mul(edx);
+ __ neg(edx);
+ __ not_(edx);
+ __ test(Operand(ebx, ecx, times_4, 10000), Immediate(123456));
+
+ __ imul(edx, Operand(ebx, ecx, times_4, 10000));
+ __ imul(edx, ecx, 12);
+ __ imul(edx, Operand(edx, eax, times_2, 42), 8);
+ __ imul(edx, ecx, 1000);
+ __ imul(edx, Operand(ebx, ecx, times_4, 1), 9000);
+
+ __ inc(edx);
+ __ inc(Operand(ebx, ecx, times_4, 10000));
+ __ push(Operand(ebx, ecx, times_4, 10000));
+ __ pop(Operand(ebx, ecx, times_4, 10000));
+ __ call(Operand(ebx, ecx, times_4, 10000));
+ __ jmp(Operand(ebx, ecx, times_4, 10000));
+
+ __ lea(edx, Operand(ebx, ecx, times_4, 10000));
+ __ or_(edx, 12345);
+ __ or_(edx, Operand(ebx, ecx, times_4, 10000));
+
+ __ nop();
+
+ __ rcl(edx, 1);
+ __ rcl(edx, 7);
+ __ rcr(edx, 1);
+ __ rcr(edx, 7);
+ __ sar(edx, 1);
+ __ sar(edx, 6);
+ __ sar_cl(edx);
+ __ sar(Operand(ebx, ecx, times_4, 10000), 1);
+ __ sar(Operand(ebx, ecx, times_4, 10000), 6);
+ __ sar_cl(Operand(ebx, ecx, times_4, 10000));
+ __ sbb(edx, Operand(ebx, ecx, times_4, 10000));
+ __ shld(edx, Operand(ebx, ecx, times_4, 10000));
+ __ shl(edx, 1);
+ __ shl(edx, 6);
+ __ shl_cl(edx);
+ __ shl(Operand(ebx, ecx, times_4, 10000), 1);
+ __ shl(Operand(ebx, ecx, times_4, 10000), 6);
+ __ shl_cl(Operand(ebx, ecx, times_4, 10000));
+ __ shrd(edx, Operand(ebx, ecx, times_4, 10000));
+ __ shr(edx, 1);
+ __ shr(edx, 7);
+ __ shr_cl(edx);
+ __ shr(Operand(ebx, ecx, times_4, 10000), 1);
+ __ shr(Operand(ebx, ecx, times_4, 10000), 6);
+ __ shr_cl(Operand(ebx, ecx, times_4, 10000));
+
+
+ // Immediates
+
+ __ adc(edx, 12345);
+
+ __ add(ebx, Immediate(12));
+ __ add(Operand(edx, ecx, times_4, 10000), Immediate(12));
+
+ __ and_(ebx, 12345);
+
+ __ cmp(ebx, 12345);
+ __ cmp(ebx, Immediate(12));
+ __ cmp(Operand(edx, ecx, times_4, 10000), Immediate(12));
+ __ cmpb(eax, 100);
+
+ __ or_(ebx, 12345);
+
+ __ sub(ebx, Immediate(12));
+ __ sub(Operand(edx, ecx, times_4, 10000), Immediate(12));
+
+ __ xor_(ebx, 12345);
+
+ __ imul(edx, ecx, 12);
+ __ imul(edx, ecx, 1000);
+
+ __ cld();
+ __ rep_movs();
+ __ rep_stos();
+ __ stos();
+
+ __ sub(edx, Operand(ebx, ecx, times_4, 10000));
+ __ sub(edx, ebx);
+
+ __ test(edx, Immediate(12345));
+ __ test(edx, Operand(ebx, ecx, times_8, 10000));
+ __ test(Operand(esi, edi, times_1, -20000000), Immediate(300000000));
+ __ test_b(edx, Operand(ecx, ebx, times_2, 1000));
+ __ test_b(Operand(eax, -20), 0x9A);
+ __ nop();
+
+ __ xor_(edx, 12345);
+ __ xor_(edx, Operand(ebx, ecx, times_8, 10000));
+ __ bts(Operand(ebx, ecx, times_8, 10000), edx);
+ __ hlt();
+ __ int3();
+ __ ret(0);
+ __ ret(8);
+
+ // Calls
+
+ Label L1, L2;
+ __ bind(&L1);
+ __ nop();
+ __ call(&L1);
+ __ call(&L2);
+ __ nop();
+ __ bind(&L2);
+ __ call(Operand(ebx, ecx, times_4, 10000));
+ __ nop();
+ Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL));
+ __ call(ic, RelocInfo::CODE_TARGET);
+ __ nop();
+ __ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY);
+ __ nop();
+
+ __ jmp(&L1);
+ __ jmp(Operand(ebx, ecx, times_4, 10000));
+ ExternalReference after_break_target =
+ ExternalReference::debug_after_break_target_address(isolate);
+ __ jmp(Operand::StaticVariable(after_break_target));
+ __ jmp(ic, RelocInfo::CODE_TARGET);
+ __ nop();
+
+
+ Label Ljcc;
+ __ nop();
+ // long jumps
+ __ j(overflow, &Ljcc);
+ __ j(no_overflow, &Ljcc);
+ __ j(below, &Ljcc);
+ __ j(above_equal, &Ljcc);
+ __ j(equal, &Ljcc);
+ __ j(not_equal, &Ljcc);
+ __ j(below_equal, &Ljcc);
+ __ j(above, &Ljcc);
+ __ j(sign, &Ljcc);
+ __ j(not_sign, &Ljcc);
+ __ j(parity_even, &Ljcc);
+ __ j(parity_odd, &Ljcc);
+ __ j(less, &Ljcc);
+ __ j(greater_equal, &Ljcc);
+ __ j(less_equal, &Ljcc);
+ __ j(greater, &Ljcc);
+ __ nop();
+ __ bind(&Ljcc);
+ // short jumps
+ __ j(overflow, &Ljcc);
+ __ j(no_overflow, &Ljcc);
+ __ j(below, &Ljcc);
+ __ j(above_equal, &Ljcc);
+ __ j(equal, &Ljcc);
+ __ j(not_equal, &Ljcc);
+ __ j(below_equal, &Ljcc);
+ __ j(above, &Ljcc);
+ __ j(sign, &Ljcc);
+ __ j(not_sign, &Ljcc);
+ __ j(parity_even, &Ljcc);
+ __ j(parity_odd, &Ljcc);
+ __ j(less, &Ljcc);
+ __ j(greater_equal, &Ljcc);
+ __ j(less_equal, &Ljcc);
+ __ j(greater, &Ljcc);
+
+ // 0xD9 instructions
+ __ nop();
+
+ __ fld(1);
+ __ fld1();
+ __ fldz();
+ __ fldpi();
+ __ fabs();
+ __ fchs();
+ __ fprem();
+ __ fprem1();
+ __ fincstp();
+ __ ftst();
+ __ fxch(3);
+ __ fld_s(Operand(ebx, ecx, times_4, 10000));
+ __ fstp_s(Operand(ebx, ecx, times_4, 10000));
+ __ ffree(3);
+ __ fld_d(Operand(ebx, ecx, times_4, 10000));
+ __ fstp_d(Operand(ebx, ecx, times_4, 10000));
+ __ nop();
+
+ __ fild_s(Operand(ebx, ecx, times_4, 10000));
+ __ fistp_s(Operand(ebx, ecx, times_4, 10000));
+ __ fild_d(Operand(ebx, ecx, times_4, 10000));
+ __ fistp_d(Operand(ebx, ecx, times_4, 10000));
+ __ fnstsw_ax();
+ __ nop();
+ __ fadd(3);
+ __ fsub(3);
+ __ fmul(3);
+ __ fdiv(3);
+
+ __ faddp(3);
+ __ fsubp(3);
+ __ fmulp(3);
+ __ fdivp(3);
+ __ fcompp();
+ __ fwait();
+ __ frndint();
+ __ fninit();
+ __ nop();
+
+ // xchg.
+ {
+ __ xchg(eax, eax);
+ __ xchg(eax, ebx);
+ __ xchg(ebx, ebx);
+ __ xchg(ebx, Operand(esp, 12));
+ }
+
+ // Nop instructions
+ for (int i = 0; i < 16; i++) {
+ __ Nop(i);
+ }
+
+ __ ret(0);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ USE(code);
+#ifdef OBJECT_PRINT
+ OFStream os(stdout);
+ code->Print(os);
+ byte* begin = code->instruction_start();
+ byte* end = begin + code->instruction_size();
+ disasm::Disassembler::Disassemble(stdout, begin, end);
+#endif
+}
+
+#undef __
diff --git a/deps/v8/test/cctest/test-diy-fp.cc b/deps/v8/test/cctest/test-diy-fp.cc
index 145e317ff..255118e96 100644
--- a/deps/v8/test/cctest/test-diy-fp.cc
+++ b/deps/v8/test/cctest/test-diy-fp.cc
@@ -27,11 +27,11 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "platform.h"
-#include "cctest.h"
-#include "diy-fp.h"
+#include "src/base/platform/platform.h"
+#include "src/diy-fp.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-double.cc b/deps/v8/test/cctest/test-double.cc
index 2c9f0c21b..16dcb3710 100644
--- a/deps/v8/test/cctest/test-double.cc
+++ b/deps/v8/test/cctest/test-double.cc
@@ -27,12 +27,12 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "platform.h"
-#include "cctest.h"
-#include "diy-fp.h"
-#include "double.h"
+#include "src/base/platform/platform.h"
+#include "src/diy-fp.h"
+#include "src/double.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -105,7 +105,7 @@ TEST(IsDenormal) {
TEST(IsSpecial) {
CHECK(Double(V8_INFINITY).IsSpecial());
CHECK(Double(-V8_INFINITY).IsSpecial());
- CHECK(Double(OS::nan_value()).IsSpecial());
+ CHECK(Double(v8::base::OS::nan_value()).IsSpecial());
uint64_t bits = V8_2PART_UINT64_C(0xFFF12345, 00000000);
CHECK(Double(bits).IsSpecial());
// Denormals are not special:
@@ -128,7 +128,7 @@ TEST(IsSpecial) {
TEST(IsInfinite) {
CHECK(Double(V8_INFINITY).IsInfinite());
CHECK(Double(-V8_INFINITY).IsInfinite());
- CHECK(!Double(OS::nan_value()).IsInfinite());
+ CHECK(!Double(v8::base::OS::nan_value()).IsInfinite());
CHECK(!Double(0.0).IsInfinite());
CHECK(!Double(-0.0).IsInfinite());
CHECK(!Double(1.0).IsInfinite());
diff --git a/deps/v8/test/cctest/test-dtoa.cc b/deps/v8/test/cctest/test-dtoa.cc
index 66c2aafc6..3f396a5d1 100644
--- a/deps/v8/test/cctest/test-dtoa.cc
+++ b/deps/v8/test/cctest/test-dtoa.cc
@@ -27,16 +27,16 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "dtoa.h"
+#include "src/dtoa.h"
-#include "cctest.h"
-#include "double.h"
-#include "gay-fixed.h"
-#include "gay-precision.h"
-#include "gay-shortest.h"
-#include "platform.h"
+#include "src/base/platform/platform.h"
+#include "src/double.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/gay-fixed.h"
+#include "test/cctest/gay-precision.h"
+#include "test/cctest/gay-shortest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-fast-dtoa.cc b/deps/v8/test/cctest/test-fast-dtoa.cc
index 46f975799..52198a45f 100644
--- a/deps/v8/test/cctest/test-fast-dtoa.cc
+++ b/deps/v8/test/cctest/test-fast-dtoa.cc
@@ -27,15 +27,15 @@
#include <stdlib.h>
-#include "v8.h"
-
-#include "platform.h"
-#include "cctest.h"
-#include "diy-fp.h"
-#include "double.h"
-#include "fast-dtoa.h"
-#include "gay-precision.h"
-#include "gay-shortest.h"
+#include "src/v8.h"
+
+#include "src/base/platform/platform.h"
+#include "src/diy-fp.h"
+#include "src/double.h"
+#include "src/fast-dtoa.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/gay-precision.h"
+#include "test/cctest/gay-shortest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-fixed-dtoa.cc b/deps/v8/test/cctest/test-fixed-dtoa.cc
index 21926f197..de40d09f1 100644
--- a/deps/v8/test/cctest/test-fixed-dtoa.cc
+++ b/deps/v8/test/cctest/test-fixed-dtoa.cc
@@ -27,13 +27,13 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "platform.h"
-#include "cctest.h"
-#include "double.h"
-#include "fixed-dtoa.h"
-#include "gay-fixed.h"
+#include "src/base/platform/platform.h"
+#include "src/double.h"
+#include "src/fixed-dtoa.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/gay-fixed.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-flags.cc b/deps/v8/test/cctest/test-flags.cc
index a1d2405ad..862b73adb 100644
--- a/deps/v8/test/cctest/test-flags.cc
+++ b/deps/v8/test/cctest/test-flags.cc
@@ -27,8 +27,8 @@
#include <stdlib.h>
-#include "v8.h"
-#include "cctest.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-func-name-inference.cc b/deps/v8/test/cctest/test-func-name-inference.cc
index f452b3ed3..bc503b58c 100644
--- a/deps/v8/test/cctest/test-func-name-inference.cc
+++ b/deps/v8/test/cctest/test-func-name-inference.cc
@@ -26,12 +26,12 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "v8.h"
+#include "src/v8.h"
-#include "api.h"
-#include "debug.h"
-#include "runtime.h"
-#include "cctest.h"
+#include "src/api.h"
+#include "src/debug.h"
+#include "src/runtime.h"
+#include "test/cctest/cctest.h"
using ::v8::internal::CStrVector;
diff --git a/deps/v8/test/cctest/test-fuzz-arm64.cc b/deps/v8/test/cctest/test-fuzz-arm64.cc
index 0ceb60f7b..ada609fe7 100644
--- a/deps/v8/test/cctest/test-fuzz-arm64.cc
+++ b/deps/v8/test/cctest/test-fuzz-arm64.cc
@@ -23,11 +23,11 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h>
-#include "cctest.h"
+#include "test/cctest/cctest.h"
-#include "arm64/decoder-arm64.h"
-#include "arm64/decoder-arm64-inl.h"
-#include "arm64/disasm-arm64.h"
+#include "src/arm64/decoder-arm64.h"
+#include "src/arm64/decoder-arm64-inl.h"
+#include "src/arm64/disasm-arm64.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-gc-tracer.cc b/deps/v8/test/cctest/test-gc-tracer.cc
new file mode 100644
index 000000000..190644dec
--- /dev/null
+++ b/deps/v8/test/cctest/test-gc-tracer.cc
@@ -0,0 +1,125 @@
+// 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.
+
+#include <stdlib.h>
+#include <utility>
+
+#include "src/v8.h"
+
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+
+TEST(RingBufferPartialFill) {
+ const int max_size = 6;
+ typedef RingBuffer<int, max_size>::const_iterator Iter;
+ RingBuffer<int, max_size> ring_buffer;
+ CHECK(ring_buffer.empty());
+ CHECK_EQ(static_cast<int>(ring_buffer.size()), 0);
+ CHECK(ring_buffer.begin() == ring_buffer.end());
+
+ // Fill ring_buffer partially: [0, 1, 2]
+ for (int i = 0; i < max_size / 2; i++) ring_buffer.push_back(i);
+
+ CHECK(!ring_buffer.empty());
+ CHECK(static_cast<int>(ring_buffer.size()) == max_size / 2);
+ CHECK(ring_buffer.begin() != ring_buffer.end());
+
+ // Test forward itartion
+ int i = 0;
+ for (Iter iter = ring_buffer.begin(); iter != ring_buffer.end(); ++iter) {
+ CHECK(*iter == i);
+ ++i;
+ }
+ CHECK_EQ(i, 3); // one past last element.
+
+ // Test backward iteration
+ i = 2;
+ Iter iter = ring_buffer.back();
+ while (true) {
+ CHECK(*iter == i);
+ if (iter == ring_buffer.begin()) break;
+ --iter;
+ --i;
+ }
+ CHECK_EQ(i, 0);
+}
+
+
+TEST(RingBufferWrapAround) {
+ const int max_size = 6;
+ typedef RingBuffer<int, max_size>::const_iterator Iter;
+ RingBuffer<int, max_size> ring_buffer;
+
+ // Fill ring_buffer (wrap around): [9, 10, 11, 12, 13, 14]
+ for (int i = 0; i < 2 * max_size + 3; i++) ring_buffer.push_back(i);
+
+ CHECK(!ring_buffer.empty());
+ CHECK(static_cast<int>(ring_buffer.size()) == max_size);
+ CHECK(ring_buffer.begin() != ring_buffer.end());
+
+ // Test forward iteration
+ int i = 9;
+ for (Iter iter = ring_buffer.begin(); iter != ring_buffer.end(); ++iter) {
+ CHECK(*iter == i);
+ ++i;
+ }
+ CHECK_EQ(i, 15); // one past last element.
+
+ // Test backward iteration
+ i = 14;
+ Iter iter = ring_buffer.back();
+ while (true) {
+ CHECK(*iter == i);
+ if (iter == ring_buffer.begin()) break;
+ --iter;
+ --i;
+ }
+ CHECK_EQ(i, 9);
+}
+
+
+TEST(RingBufferPushFront) {
+ const int max_size = 6;
+ typedef RingBuffer<int, max_size>::const_iterator Iter;
+ RingBuffer<int, max_size> ring_buffer;
+
+ // Fill ring_buffer (wrap around): [14, 13, 12, 11, 10, 9]
+ for (int i = 0; i < 2 * max_size + 3; i++) ring_buffer.push_front(i);
+
+ CHECK(!ring_buffer.empty());
+ CHECK(static_cast<int>(ring_buffer.size()) == max_size);
+ CHECK(ring_buffer.begin() != ring_buffer.end());
+
+ // Test forward iteration
+ int i = 14;
+ for (Iter iter = ring_buffer.begin(); iter != ring_buffer.end(); ++iter) {
+ CHECK(*iter == i);
+ --i;
+ }
+ CHECK_EQ(i, 8); // one past last element.
+}
diff --git a/deps/v8/test/cctest/test-global-handles.cc b/deps/v8/test/cctest/test-global-handles.cc
index 1ab90ec5e..ee295d699 100644
--- a/deps/v8/test/cctest/test-global-handles.cc
+++ b/deps/v8/test/cctest/test-global-handles.cc
@@ -25,9 +25,9 @@
// (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 "global-handles.h"
+#include "src/global-handles.h"
-#include "cctest.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
using v8::UniqueId;
@@ -56,7 +56,7 @@ class TestRetainedObjectInfo : public v8::RetainedObjectInfo {
bool has_been_disposed() { return has_been_disposed_; }
virtual void Dispose() {
- ASSERT(!has_been_disposed_);
+ DCHECK(!has_been_disposed_);
has_been_disposed_ = true;
}
@@ -121,16 +121,16 @@ TEST(IterateObjectGroupsOldApi) {
global_handles->IterateObjectGroups(&visitor, &CanSkipCallback);
// CanSkipCallback was called for all objects.
- ASSERT(can_skip_called_objects.length() == 4);
- ASSERT(can_skip_called_objects.Contains(*g1s1.location()));
- ASSERT(can_skip_called_objects.Contains(*g1s2.location()));
- ASSERT(can_skip_called_objects.Contains(*g2s1.location()));
- ASSERT(can_skip_called_objects.Contains(*g2s2.location()));
+ DCHECK(can_skip_called_objects.length() == 4);
+ DCHECK(can_skip_called_objects.Contains(*g1s1.location()));
+ DCHECK(can_skip_called_objects.Contains(*g1s2.location()));
+ DCHECK(can_skip_called_objects.Contains(*g2s1.location()));
+ DCHECK(can_skip_called_objects.Contains(*g2s2.location()));
// Nothing was visited.
- ASSERT(visitor.visited.length() == 0);
- ASSERT(!info1.has_been_disposed());
- ASSERT(!info2.has_been_disposed());
+ DCHECK(visitor.visited.length() == 0);
+ DCHECK(!info1.has_been_disposed());
+ DCHECK(!info2.has_been_disposed());
}
// Iterate again, now only skip the second object group.
@@ -145,18 +145,18 @@ TEST(IterateObjectGroupsOldApi) {
global_handles->IterateObjectGroups(&visitor, &CanSkipCallback);
// CanSkipCallback was called for all objects.
- ASSERT(can_skip_called_objects.length() == 3 ||
+ DCHECK(can_skip_called_objects.length() == 3 ||
can_skip_called_objects.length() == 4);
- ASSERT(can_skip_called_objects.Contains(*g1s2.location()));
- ASSERT(can_skip_called_objects.Contains(*g2s1.location()));
- ASSERT(can_skip_called_objects.Contains(*g2s2.location()));
+ DCHECK(can_skip_called_objects.Contains(*g1s2.location()));
+ DCHECK(can_skip_called_objects.Contains(*g2s1.location()));
+ DCHECK(can_skip_called_objects.Contains(*g2s2.location()));
// The first group was visited.
- ASSERT(visitor.visited.length() == 2);
- ASSERT(visitor.visited.Contains(*g1s1.location()));
- ASSERT(visitor.visited.Contains(*g1s2.location()));
- ASSERT(info1.has_been_disposed());
- ASSERT(!info2.has_been_disposed());
+ DCHECK(visitor.visited.length() == 2);
+ DCHECK(visitor.visited.Contains(*g1s1.location()));
+ DCHECK(visitor.visited.Contains(*g1s2.location()));
+ DCHECK(info1.has_been_disposed());
+ DCHECK(!info2.has_been_disposed());
}
// Iterate again, don't skip anything.
@@ -166,15 +166,15 @@ TEST(IterateObjectGroupsOldApi) {
global_handles->IterateObjectGroups(&visitor, &CanSkipCallback);
// CanSkipCallback was called for all objects.
- ASSERT(can_skip_called_objects.length() == 1);
- ASSERT(can_skip_called_objects.Contains(*g2s1.location()) ||
+ DCHECK(can_skip_called_objects.length() == 1);
+ DCHECK(can_skip_called_objects.Contains(*g2s1.location()) ||
can_skip_called_objects.Contains(*g2s2.location()));
// The second group was visited.
- ASSERT(visitor.visited.length() == 2);
- ASSERT(visitor.visited.Contains(*g2s1.location()));
- ASSERT(visitor.visited.Contains(*g2s2.location()));
- ASSERT(info2.has_been_disposed());
+ DCHECK(visitor.visited.length() == 2);
+ DCHECK(visitor.visited.Contains(*g2s1.location()));
+ DCHECK(visitor.visited.Contains(*g2s2.location()));
+ DCHECK(info2.has_been_disposed());
}
}
@@ -216,16 +216,16 @@ TEST(IterateObjectGroups) {
global_handles->IterateObjectGroups(&visitor, &CanSkipCallback);
// CanSkipCallback was called for all objects.
- ASSERT(can_skip_called_objects.length() == 4);
- ASSERT(can_skip_called_objects.Contains(*g1s1.location()));
- ASSERT(can_skip_called_objects.Contains(*g1s2.location()));
- ASSERT(can_skip_called_objects.Contains(*g2s1.location()));
- ASSERT(can_skip_called_objects.Contains(*g2s2.location()));
+ DCHECK(can_skip_called_objects.length() == 4);
+ DCHECK(can_skip_called_objects.Contains(*g1s1.location()));
+ DCHECK(can_skip_called_objects.Contains(*g1s2.location()));
+ DCHECK(can_skip_called_objects.Contains(*g2s1.location()));
+ DCHECK(can_skip_called_objects.Contains(*g2s2.location()));
// Nothing was visited.
- ASSERT(visitor.visited.length() == 0);
- ASSERT(!info1.has_been_disposed());
- ASSERT(!info2.has_been_disposed());
+ DCHECK(visitor.visited.length() == 0);
+ DCHECK(!info1.has_been_disposed());
+ DCHECK(!info2.has_been_disposed());
}
// Iterate again, now only skip the second object group.
@@ -240,18 +240,18 @@ TEST(IterateObjectGroups) {
global_handles->IterateObjectGroups(&visitor, &CanSkipCallback);
// CanSkipCallback was called for all objects.
- ASSERT(can_skip_called_objects.length() == 3 ||
+ DCHECK(can_skip_called_objects.length() == 3 ||
can_skip_called_objects.length() == 4);
- ASSERT(can_skip_called_objects.Contains(*g1s2.location()));
- ASSERT(can_skip_called_objects.Contains(*g2s1.location()));
- ASSERT(can_skip_called_objects.Contains(*g2s2.location()));
+ DCHECK(can_skip_called_objects.Contains(*g1s2.location()));
+ DCHECK(can_skip_called_objects.Contains(*g2s1.location()));
+ DCHECK(can_skip_called_objects.Contains(*g2s2.location()));
// The first group was visited.
- ASSERT(visitor.visited.length() == 2);
- ASSERT(visitor.visited.Contains(*g1s1.location()));
- ASSERT(visitor.visited.Contains(*g1s2.location()));
- ASSERT(info1.has_been_disposed());
- ASSERT(!info2.has_been_disposed());
+ DCHECK(visitor.visited.length() == 2);
+ DCHECK(visitor.visited.Contains(*g1s1.location()));
+ DCHECK(visitor.visited.Contains(*g1s2.location()));
+ DCHECK(info1.has_been_disposed());
+ DCHECK(!info2.has_been_disposed());
}
// Iterate again, don't skip anything.
@@ -261,15 +261,15 @@ TEST(IterateObjectGroups) {
global_handles->IterateObjectGroups(&visitor, &CanSkipCallback);
// CanSkipCallback was called for all objects.
- ASSERT(can_skip_called_objects.length() == 1);
- ASSERT(can_skip_called_objects.Contains(*g2s1.location()) ||
+ DCHECK(can_skip_called_objects.length() == 1);
+ DCHECK(can_skip_called_objects.Contains(*g2s1.location()) ||
can_skip_called_objects.Contains(*g2s2.location()));
// The second group was visited.
- ASSERT(visitor.visited.length() == 2);
- ASSERT(visitor.visited.Contains(*g2s1.location()));
- ASSERT(visitor.visited.Contains(*g2s2.location()));
- ASSERT(info2.has_been_disposed());
+ DCHECK(visitor.visited.length() == 2);
+ DCHECK(visitor.visited.Contains(*g2s1.location()));
+ DCHECK(visitor.visited.Contains(*g2s2.location()));
+ DCHECK(info2.has_been_disposed());
}
}
@@ -306,16 +306,16 @@ TEST(ImplicitReferences) {
List<ImplicitRefGroup*>* implicit_refs =
global_handles->implicit_ref_groups();
USE(implicit_refs);
- ASSERT(implicit_refs->length() == 2);
- ASSERT(implicit_refs->at(0)->parent ==
+ DCHECK(implicit_refs->length() == 2);
+ DCHECK(implicit_refs->at(0)->parent ==
reinterpret_cast<HeapObject**>(g1s1.location()));
- ASSERT(implicit_refs->at(0)->length == 2);
- ASSERT(implicit_refs->at(0)->children[0] == g1c1.location());
- ASSERT(implicit_refs->at(0)->children[1] == g1c2.location());
- ASSERT(implicit_refs->at(1)->parent ==
+ DCHECK(implicit_refs->at(0)->length == 2);
+ DCHECK(implicit_refs->at(0)->children[0] == g1c1.location());
+ DCHECK(implicit_refs->at(0)->children[1] == g1c2.location());
+ DCHECK(implicit_refs->at(1)->parent ==
reinterpret_cast<HeapObject**>(g2s1.location()));
- ASSERT(implicit_refs->at(1)->length == 1);
- ASSERT(implicit_refs->at(1)->children[0] == g2c1.location());
+ DCHECK(implicit_refs->at(1)->length == 1);
+ DCHECK(implicit_refs->at(1)->children[0] == g2c1.location());
global_handles->RemoveObjectGroups();
global_handles->RemoveImplicitRefGroups();
}
diff --git a/deps/v8/test/cctest/test-global-object.cc b/deps/v8/test/cctest/test-global-object.cc
index bbec9df77..0e2c9408c 100644
--- a/deps/v8/test/cctest/test-global-object.cc
+++ b/deps/v8/test/cctest/test-global-object.cc
@@ -25,9 +25,9 @@
// (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 "src/v8.h"
-#include "cctest.h"
+#include "test/cctest/cctest.h"
using namespace v8;
diff --git a/deps/v8/test/cctest/test-hashing.cc b/deps/v8/test/cctest/test-hashing.cc
index 9a7d61ddd..9857f9d88 100644
--- a/deps/v8/test/cctest/test-hashing.cc
+++ b/deps/v8/test/cctest/test-hashing.cc
@@ -27,16 +27,16 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "factory.h"
-#include "macro-assembler.h"
-#include "cctest.h"
-#include "code-stubs.h"
-#include "objects.h"
+#include "src/code-stubs.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "src/objects.h"
+#include "test/cctest/cctest.h"
#ifdef USE_SIMULATOR
-#include "simulator.h"
+#include "src/simulator.h"
#endif
using namespace v8::internal;
@@ -50,8 +50,8 @@ typedef uint32_t (*HASH_FUNCTION)();
void generate(MacroAssembler* masm, i::Vector<const uint8_t> string) {
// GenerateHashInit takes the first character as an argument so it can't
// handle the zero length string.
- ASSERT(string.length() > 0);
-#if V8_TARGET_ARCH_IA32
+ DCHECK(string.length() > 0);
+#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
__ push(ebx);
__ push(ecx);
__ mov(eax, Immediate(0));
@@ -114,11 +114,11 @@ void generate(MacroAssembler* masm, i::Vector<const uint8_t> string) {
__ Pop(xzr, root);
__ Ret();
__ SetStackPointer(old_stack_pointer);
-#elif V8_TARGET_ARCH_MIPS
+#elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
__ push(kRootRegister);
__ InitializeRootRegister();
- __ li(v0, Operand(0));
+ __ mov(v0, zero_reg);
__ li(t1, Operand(string.at(0)));
StringHelper::GenerateHashInit(masm, v0, t1);
for (int i = 1; i < string.length(); i++) {
@@ -136,7 +136,7 @@ void generate(MacroAssembler* masm, i::Vector<const uint8_t> string) {
void generate(MacroAssembler* masm, uint32_t key) {
-#if V8_TARGET_ARCH_IA32
+#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
__ push(ebx);
__ mov(eax, Immediate(key));
__ GetNumberHash(eax, ebx);
@@ -170,7 +170,7 @@ void generate(MacroAssembler* masm, uint32_t key) {
__ Pop(xzr, root);
__ Ret();
__ SetStackPointer(old_stack_pointer);
-#elif V8_TARGET_ARCH_MIPS
+#elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
__ push(kRootRegister);
__ InitializeRootRegister();
__ li(v0, Operand(key));
diff --git a/deps/v8/test/cctest/test-hashmap.cc b/deps/v8/test/cctest/test-hashmap.cc
index 70213c9aa..1e94bed59 100644
--- a/deps/v8/test/cctest/test-hashmap.cc
+++ b/deps/v8/test/cctest/test-hashmap.cc
@@ -27,9 +27,10 @@
#include <stdlib.h>
-#include "v8.h"
-#include "hashmap.h"
-#include "cctest.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/hashmap.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc
index eeafc7093..e456323ba 100644
--- a/deps/v8/test/cctest/test-heap-profiler.cc
+++ b/deps/v8/test/cctest/test-heap-profiler.cc
@@ -29,16 +29,16 @@
#include <ctype.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "allocation-tracker.h"
-#include "cctest.h"
-#include "hashmap.h"
-#include "heap-profiler.h"
-#include "snapshot.h"
-#include "debug.h"
-#include "utils-inl.h"
-#include "../include/v8-profiler.h"
+#include "include/v8-profiler.h"
+#include "src/allocation-tracker.h"
+#include "src/debug.h"
+#include "src/hashmap.h"
+#include "src/heap-profiler.h"
+#include "src/snapshot.h"
+#include "src/utils-inl.h"
+#include "test/cctest/cctest.h"
using i::AllocationTraceNode;
using i::AllocationTraceTree;
@@ -471,6 +471,174 @@ TEST(HeapSnapshotConsString) {
}
+TEST(HeapSnapshotSymbol) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
+
+ CompileRun("a = Symbol('mySymbol');\n");
+ const v8::HeapSnapshot* snapshot =
+ heap_profiler->TakeHeapSnapshot(v8_str("Symbol"));
+ CHECK(ValidateSnapshot(snapshot));
+ const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+ const v8::HeapGraphNode* a =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "a");
+ CHECK_NE(NULL, a);
+ CHECK_EQ(a->GetType(), v8::HeapGraphNode::kSymbol);
+ CHECK_EQ(v8_str("symbol"), a->GetName());
+ const v8::HeapGraphNode* name =
+ GetProperty(a, v8::HeapGraphEdge::kInternal, "name");
+ CHECK_NE(NULL, name);
+ CHECK_EQ(v8_str("mySymbol"), name->GetName());
+}
+
+
+TEST(HeapSnapshotWeakCollection) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
+
+ CompileRun(
+ "k = {}; v = {}; s = 'str';\n"
+ "ws = new WeakSet(); ws.add(k); ws.add(v); ws[s] = s;\n"
+ "wm = new WeakMap(); wm.set(k, v); wm[s] = s;\n");
+ const v8::HeapSnapshot* snapshot =
+ heap_profiler->TakeHeapSnapshot(v8_str("WeakCollections"));
+ CHECK(ValidateSnapshot(snapshot));
+ const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+ const v8::HeapGraphNode* k =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "k");
+ CHECK_NE(NULL, k);
+ const v8::HeapGraphNode* v =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "v");
+ CHECK_NE(NULL, v);
+ const v8::HeapGraphNode* s =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "s");
+ CHECK_NE(NULL, s);
+
+ const v8::HeapGraphNode* ws =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "ws");
+ CHECK_NE(NULL, ws);
+ CHECK_EQ(v8::HeapGraphNode::kObject, ws->GetType());
+ CHECK_EQ(v8_str("WeakSet"), ws->GetName());
+
+ const v8::HeapGraphNode* ws_table =
+ GetProperty(ws, v8::HeapGraphEdge::kInternal, "table");
+ CHECK_EQ(v8::HeapGraphNode::kArray, ws_table->GetType());
+ CHECK_GT(ws_table->GetChildrenCount(), 0);
+ int weak_entries = 0;
+ for (int i = 0, count = ws_table->GetChildrenCount(); i < count; ++i) {
+ const v8::HeapGraphEdge* prop = ws_table->GetChild(i);
+ if (prop->GetType() != v8::HeapGraphEdge::kWeak) continue;
+ if (k->GetId() == prop->GetToNode()->GetId()) {
+ ++weak_entries;
+ }
+ }
+ CHECK_EQ(1, weak_entries);
+ const v8::HeapGraphNode* ws_s =
+ GetProperty(ws, v8::HeapGraphEdge::kProperty, "str");
+ CHECK_NE(NULL, ws_s);
+ CHECK_EQ(static_cast<int>(s->GetId()), static_cast<int>(ws_s->GetId()));
+
+ const v8::HeapGraphNode* wm =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "wm");
+ CHECK_NE(NULL, wm);
+ CHECK_EQ(v8::HeapGraphNode::kObject, wm->GetType());
+ CHECK_EQ(v8_str("WeakMap"), wm->GetName());
+
+ const v8::HeapGraphNode* wm_table =
+ GetProperty(wm, v8::HeapGraphEdge::kInternal, "table");
+ CHECK_EQ(v8::HeapGraphNode::kArray, wm_table->GetType());
+ CHECK_GT(wm_table->GetChildrenCount(), 0);
+ weak_entries = 0;
+ for (int i = 0, count = wm_table->GetChildrenCount(); i < count; ++i) {
+ const v8::HeapGraphEdge* prop = wm_table->GetChild(i);
+ if (prop->GetType() != v8::HeapGraphEdge::kWeak) continue;
+ const v8::SnapshotObjectId to_node_id = prop->GetToNode()->GetId();
+ if (to_node_id == k->GetId() || to_node_id == v->GetId()) {
+ ++weak_entries;
+ }
+ }
+ CHECK_EQ(2, weak_entries);
+ const v8::HeapGraphNode* wm_s =
+ GetProperty(wm, v8::HeapGraphEdge::kProperty, "str");
+ CHECK_NE(NULL, wm_s);
+ CHECK_EQ(static_cast<int>(s->GetId()), static_cast<int>(wm_s->GetId()));
+}
+
+
+TEST(HeapSnapshotCollection) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
+
+ CompileRun(
+ "k = {}; v = {}; s = 'str';\n"
+ "set = new Set(); set.add(k); set.add(v); set[s] = s;\n"
+ "map = new Map(); map.set(k, v); map[s] = s;\n");
+ const v8::HeapSnapshot* snapshot =
+ heap_profiler->TakeHeapSnapshot(v8_str("Collections"));
+ CHECK(ValidateSnapshot(snapshot));
+ const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+ const v8::HeapGraphNode* k =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "k");
+ CHECK_NE(NULL, k);
+ const v8::HeapGraphNode* v =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "v");
+ CHECK_NE(NULL, v);
+ const v8::HeapGraphNode* s =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "s");
+ CHECK_NE(NULL, s);
+
+ const v8::HeapGraphNode* set =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "set");
+ CHECK_NE(NULL, set);
+ CHECK_EQ(v8::HeapGraphNode::kObject, set->GetType());
+ CHECK_EQ(v8_str("Set"), set->GetName());
+
+ const v8::HeapGraphNode* set_table =
+ GetProperty(set, v8::HeapGraphEdge::kInternal, "table");
+ CHECK_EQ(v8::HeapGraphNode::kArray, set_table->GetType());
+ CHECK_GT(set_table->GetChildrenCount(), 0);
+ int entries = 0;
+ for (int i = 0, count = set_table->GetChildrenCount(); i < count; ++i) {
+ const v8::HeapGraphEdge* prop = set_table->GetChild(i);
+ const v8::SnapshotObjectId to_node_id = prop->GetToNode()->GetId();
+ if (to_node_id == k->GetId() || to_node_id == v->GetId()) {
+ ++entries;
+ }
+ }
+ CHECK_EQ(2, entries);
+ const v8::HeapGraphNode* set_s =
+ GetProperty(set, v8::HeapGraphEdge::kProperty, "str");
+ CHECK_NE(NULL, set_s);
+ CHECK_EQ(static_cast<int>(s->GetId()), static_cast<int>(set_s->GetId()));
+
+ const v8::HeapGraphNode* map =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "map");
+ CHECK_NE(NULL, map);
+ CHECK_EQ(v8::HeapGraphNode::kObject, map->GetType());
+ CHECK_EQ(v8_str("Map"), map->GetName());
+
+ const v8::HeapGraphNode* map_table =
+ GetProperty(map, v8::HeapGraphEdge::kInternal, "table");
+ CHECK_EQ(v8::HeapGraphNode::kArray, map_table->GetType());
+ CHECK_GT(map_table->GetChildrenCount(), 0);
+ entries = 0;
+ for (int i = 0, count = map_table->GetChildrenCount(); i < count; ++i) {
+ const v8::HeapGraphEdge* prop = map_table->GetChild(i);
+ const v8::SnapshotObjectId to_node_id = prop->GetToNode()->GetId();
+ if (to_node_id == k->GetId() || to_node_id == v->GetId()) {
+ ++entries;
+ }
+ }
+ CHECK_EQ(2, entries);
+ const v8::HeapGraphNode* map_s =
+ GetProperty(map, v8::HeapGraphEdge::kProperty, "str");
+ CHECK_NE(NULL, map_s);
+ CHECK_EQ(static_cast<int>(s->GetId()), static_cast<int>(map_s->GetId()));
+}
+
TEST(HeapSnapshotInternalReferences) {
v8::Isolate* isolate = CcTest::isolate();
@@ -690,11 +858,11 @@ class TestJSONStream : public v8::OutputStream {
if (abort_countdown_ == 0) return kAbort;
CHECK_GT(chars_written, 0);
i::Vector<char> chunk = buffer_.AddBlock(chars_written, '\0');
- i::OS::MemCopy(chunk.start(), buffer, chars_written);
+ i::MemCopy(chunk.start(), buffer, chars_written);
return kContinue;
}
virtual WriteResult WriteUint32Chunk(uint32_t* buffer, int chars_written) {
- ASSERT(false);
+ DCHECK(false);
return kAbort;
}
void WriteTo(i::Vector<char> dest) { buffer_.WriteTo(dest); }
@@ -863,13 +1031,13 @@ class TestStatsStream : public v8::OutputStream {
virtual ~TestStatsStream() {}
virtual void EndOfStream() { ++eos_signaled_; }
virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) {
- ASSERT(false);
+ DCHECK(false);
return kAbort;
}
virtual WriteResult WriteHeapStatsChunk(v8::HeapStatsUpdate* buffer,
int updates_written) {
++intervals_count_;
- ASSERT(updates_written);
+ DCHECK(updates_written);
updates_written_ += updates_written;
entries_count_ = 0;
if (first_interval_index_ == -1 && updates_written != 0)
@@ -1554,9 +1722,9 @@ TEST(GlobalObjectFields) {
const v8::HeapGraphNode* global_context =
GetProperty(global, v8::HeapGraphEdge::kInternal, "global_context");
CHECK_NE(NULL, global_context);
- const v8::HeapGraphNode* global_receiver =
- GetProperty(global, v8::HeapGraphEdge::kInternal, "global_receiver");
- CHECK_NE(NULL, global_receiver);
+ const v8::HeapGraphNode* global_proxy =
+ GetProperty(global, v8::HeapGraphEdge::kInternal, "global_proxy");
+ CHECK_NE(NULL, global_proxy);
}
@@ -1601,7 +1769,7 @@ TEST(GetHeapValueForNode) {
v8::HandleScope scope(env->GetIsolate());
v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
- CompileRun("a = { s_prop: \'value\', n_prop: 0.1 };");
+ CompileRun("a = { s_prop: \'value\', n_prop: \'value2\' };");
const v8::HeapSnapshot* snapshot =
heap_profiler->TakeHeapSnapshot(v8_str("value"));
CHECK(ValidateSnapshot(snapshot));
@@ -1622,10 +1790,9 @@ TEST(GetHeapValueForNode) {
CHECK(js_s_prop == heap_profiler->FindObjectById(s_prop->GetId()));
const v8::HeapGraphNode* n_prop =
GetProperty(obj, v8::HeapGraphEdge::kProperty, "n_prop");
- v8::Local<v8::Number> js_n_prop =
- js_obj->Get(v8_str("n_prop")).As<v8::Number>();
- CHECK(js_n_prop->NumberValue() ==
- heap_profiler->FindObjectById(n_prop->GetId())->NumberValue());
+ v8::Local<v8::String> js_n_prop =
+ js_obj->Get(v8_str("n_prop")).As<v8::String>();
+ CHECK(js_n_prop == heap_profiler->FindObjectById(n_prop->GetId()));
}
@@ -1888,7 +2055,7 @@ TEST(NoDebugObjectInSnapshot) {
v8::HandleScope scope(env->GetIsolate());
v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
- CcTest::i_isolate()->debug()->Load();
+ CHECK(CcTest::i_isolate()->debug()->Load());
CompileRun("foo = {};");
const v8::HeapSnapshot* snapshot =
heap_profiler->TakeHeapSnapshot(v8_str("snapshot"));
@@ -2017,7 +2184,7 @@ TEST(ManyLocalsInSharedContext) {
// ... well check just every 15th because otherwise it's too slow in debug.
for (int i = 0; i < num_objects - 1; i += 15) {
i::EmbeddedVector<char, 100> var_name;
- i::OS::SNPrintF(var_name, "f_%d", i);
+ i::SNPrintF(var_name, "f_%d", i);
const v8::HeapGraphNode* f_object = GetProperty(
context_object, v8::HeapGraphEdge::kContextVariable, var_name.start());
CHECK_NE(NULL, f_object);
@@ -2112,7 +2279,7 @@ static const v8::HeapGraphNode* GetNodeByPath(const v8::HeapSnapshot* snapshot,
v8::String::Utf8Value edge_name(edge->GetName());
v8::String::Utf8Value node_name(to_node->GetName());
i::EmbeddedVector<char, 100> name;
- i::OS::SNPrintF(name, "%s::%s", *edge_name, *node_name);
+ i::SNPrintF(name, "%s::%s", *edge_name, *node_name);
if (strstr(name.start(), path[current_depth])) {
node = to_node;
break;
@@ -2239,7 +2406,7 @@ TEST(ArrayGrowLeftTrim) {
"for (var i = 0; i < 3; ++i)\n"
" a.shift();\n");
- const char* names[] = { "(anonymous function)" };
+ const char* names[] = {""};
AllocationTracker* tracker =
reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker();
CHECK_NE(NULL, tracker);
@@ -2274,8 +2441,7 @@ TEST(TrackHeapAllocations) {
// Print for better diagnostics in case of failure.
tracker->trace_tree()->Print(tracker);
- const char* names[] =
- { "(anonymous function)", "start", "f_0_0", "f_0_1", "f_0_2" };
+ const char* names[] = {"", "start", "f_0_0", "f_0_1", "f_0_2"};
AllocationTraceNode* node =
FindNode(tracker, Vector<const char*>(names, ARRAY_SIZE(names)));
CHECK_NE(NULL, node);
@@ -2310,7 +2476,7 @@ TEST(TrackBumpPointerAllocations) {
LocalContext env;
v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
- const char* names[] = { "(anonymous function)", "start", "f_0", "f_1" };
+ const char* names[] = {"", "start", "f_0", "f_1"};
// First check that normally all allocations are recorded.
{
heap_profiler->StartTrackingHeapObjects(true);
@@ -2444,7 +2610,7 @@ TEST(ArrayBufferSharedBackingStore) {
CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength()));
void* data = ab_contents.Data();
- ASSERT(data != NULL);
+ DCHECK(data != NULL);
v8::Local<v8::ArrayBuffer> ab2 =
v8::ArrayBuffer::New(isolate, data, ab_contents.ByteLength());
CHECK(ab2->IsExternal());
diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc
index 3cc61ed5f..ab000dc6a 100644
--- a/deps/v8/test/cctest/test-heap.cc
+++ b/deps/v8/test/cctest/test-heap.cc
@@ -28,37 +28,18 @@
#include <stdlib.h>
#include <utility>
-#include "v8.h"
+#include "src/v8.h"
-#include "compilation-cache.h"
-#include "execution.h"
-#include "factory.h"
-#include "macro-assembler.h"
-#include "global-handles.h"
-#include "stub-cache.h"
-#include "cctest.h"
+#include "src/compilation-cache.h"
+#include "src/execution.h"
+#include "src/factory.h"
+#include "src/global-handles.h"
+#include "src/macro-assembler.h"
+#include "src/stub-cache.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
-// Go through all incremental marking steps in one swoop.
-static void SimulateIncrementalMarking() {
- MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
- IncrementalMarking* marking = CcTest::heap()->incremental_marking();
- if (collector->IsConcurrentSweepingInProgress()) {
- collector->WaitUntilSweepingCompleted();
- }
- CHECK(marking->IsMarking() || marking->IsStopped());
- if (marking->IsStopped()) {
- marking->Start();
- }
- CHECK(marking->IsMarking());
- while (!marking->IsComplete()) {
- marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
- }
- CHECK(marking->IsComplete());
-}
-
-
static void CheckMap(Map* map, int type, int instance_size) {
CHECK(map->IsHeapObject());
#ifdef DEBUG
@@ -179,7 +160,8 @@ TEST(HeapObjects) {
CHECK(value->IsNumber());
CHECK_EQ(Smi::kMaxValue, Handle<Smi>::cast(value)->value());
-#if !defined(V8_TARGET_ARCH_X64) && !defined(V8_TARGET_ARCH_ARM64)
+#if !defined(V8_TARGET_ARCH_X64) && !defined(V8_TARGET_ARCH_ARM64) && \
+ !defined(V8_TARGET_ARCH_MIPS64)
// TODO(lrn): We need a NumberFromIntptr function in order to test this.
value = factory->NewNumberFromInt(Smi::kMinValue - 1);
CHECK(value->IsHeapNumber());
@@ -209,7 +191,9 @@ TEST(HeapObjects) {
Handle<String> object_string = Handle<String>::cast(factory->Object_string());
Handle<GlobalObject> global(CcTest::i_isolate()->context()->global_object());
- CHECK(JSReceiver::HasLocalProperty(global, object_string));
+ v8::Maybe<bool> maybe = JSReceiver::HasOwnProperty(global, object_string);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
// Check ToString for oddballs
CheckOddball(isolate, heap->true_value(), "true");
@@ -260,18 +244,12 @@ TEST(GarbageCollection) {
{
HandleScope inner_scope(isolate);
// Allocate a function and keep it in global object's property.
- Handle<JSFunction> function = factory->NewFunctionWithPrototype(
- name, factory->undefined_value());
- Handle<Map> initial_map =
- factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
- function->set_initial_map(*initial_map);
- JSReceiver::SetProperty(global, name, function, NONE, SLOPPY).Check();
+ Handle<JSFunction> function = factory->NewFunction(name);
+ JSReceiver::SetProperty(global, name, function, SLOPPY).Check();
// Allocate an object. Unrooted after leaving the scope.
Handle<JSObject> obj = factory->NewJSObject(function);
- JSReceiver::SetProperty(
- obj, prop_name, twenty_three, NONE, SLOPPY).Check();
- JSReceiver::SetProperty(
- obj, prop_namex, twenty_four, NONE, SLOPPY).Check();
+ JSReceiver::SetProperty(obj, prop_name, twenty_three, SLOPPY).Check();
+ JSReceiver::SetProperty(obj, prop_namex, twenty_four, SLOPPY).Check();
CHECK_EQ(Smi::FromInt(23),
*Object::GetProperty(obj, prop_name).ToHandleChecked());
@@ -282,7 +260,9 @@ TEST(GarbageCollection) {
heap->CollectGarbage(NEW_SPACE);
// Function should be alive.
- CHECK(JSReceiver::HasLocalProperty(global, name));
+ v8::Maybe<bool> maybe = JSReceiver::HasOwnProperty(global, name);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
// Check function is retained.
Handle<Object> func_value =
Object::GetProperty(global, name).ToHandleChecked();
@@ -293,15 +273,16 @@ TEST(GarbageCollection) {
HandleScope inner_scope(isolate);
// Allocate another object, make it reachable from global.
Handle<JSObject> obj = factory->NewJSObject(function);
- JSReceiver::SetProperty(global, obj_name, obj, NONE, SLOPPY).Check();
- JSReceiver::SetProperty(
- obj, prop_name, twenty_three, NONE, SLOPPY).Check();
+ JSReceiver::SetProperty(global, obj_name, obj, SLOPPY).Check();
+ JSReceiver::SetProperty(obj, prop_name, twenty_three, SLOPPY).Check();
}
// After gc, it should survive.
heap->CollectGarbage(NEW_SPACE);
- CHECK(JSReceiver::HasLocalProperty(global, obj_name));
+ maybe = JSReceiver::HasOwnProperty(global, obj_name);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
Handle<Object> obj =
Object::GetProperty(global, obj_name).ToHandleChecked();
CHECK(obj->IsJSObject());
@@ -623,23 +604,18 @@ TEST(FunctionAllocation) {
v8::HandleScope sc(CcTest::isolate());
Handle<String> name = factory->InternalizeUtf8String("theFunction");
- Handle<JSFunction> function = factory->NewFunctionWithPrototype(
- name, factory->undefined_value());
- Handle<Map> initial_map =
- factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
- function->set_initial_map(*initial_map);
+ Handle<JSFunction> function = factory->NewFunction(name);
Handle<Smi> twenty_three(Smi::FromInt(23), isolate);
Handle<Smi> twenty_four(Smi::FromInt(24), isolate);
Handle<String> prop_name = factory->InternalizeUtf8String("theSlot");
Handle<JSObject> obj = factory->NewJSObject(function);
- JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, SLOPPY).Check();
+ JSReceiver::SetProperty(obj, prop_name, twenty_three, SLOPPY).Check();
CHECK_EQ(Smi::FromInt(23),
*Object::GetProperty(obj, prop_name).ToHandleChecked());
// Check that we can add properties to function objects.
- JSReceiver::SetProperty(
- function, prop_name, twenty_four, NONE, SLOPPY).Check();
+ JSReceiver::SetProperty(function, prop_name, twenty_four, SLOPPY).Check();
CHECK_EQ(Smi::FromInt(24),
*Object::GetProperty(function, prop_name).ToHandleChecked());
}
@@ -663,55 +639,85 @@ TEST(ObjectProperties) {
Handle<Smi> two(Smi::FromInt(2), isolate);
// check for empty
- CHECK(!JSReceiver::HasLocalProperty(obj, first));
+ v8::Maybe<bool> maybe = JSReceiver::HasOwnProperty(obj, first);
+ CHECK(maybe.has_value);
+ CHECK(!maybe.value);
// add first
- JSReceiver::SetProperty(obj, first, one, NONE, SLOPPY).Check();
- CHECK(JSReceiver::HasLocalProperty(obj, first));
+ JSReceiver::SetProperty(obj, first, one, SLOPPY).Check();
+ maybe = JSReceiver::HasOwnProperty(obj, first);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
// delete first
JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION).Check();
- CHECK(!JSReceiver::HasLocalProperty(obj, first));
+ maybe = JSReceiver::HasOwnProperty(obj, first);
+ CHECK(maybe.has_value);
+ CHECK(!maybe.value);
// add first and then second
- JSReceiver::SetProperty(obj, first, one, NONE, SLOPPY).Check();
- JSReceiver::SetProperty(obj, second, two, NONE, SLOPPY).Check();
- CHECK(JSReceiver::HasLocalProperty(obj, first));
- CHECK(JSReceiver::HasLocalProperty(obj, second));
+ JSReceiver::SetProperty(obj, first, one, SLOPPY).Check();
+ JSReceiver::SetProperty(obj, second, two, SLOPPY).Check();
+ maybe = JSReceiver::HasOwnProperty(obj, first);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
+ maybe = JSReceiver::HasOwnProperty(obj, second);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
// delete first and then second
JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION).Check();
- CHECK(JSReceiver::HasLocalProperty(obj, second));
+ maybe = JSReceiver::HasOwnProperty(obj, second);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION).Check();
- CHECK(!JSReceiver::HasLocalProperty(obj, first));
- CHECK(!JSReceiver::HasLocalProperty(obj, second));
+ maybe = JSReceiver::HasOwnProperty(obj, first);
+ CHECK(maybe.has_value);
+ CHECK(!maybe.value);
+ maybe = JSReceiver::HasOwnProperty(obj, second);
+ CHECK(maybe.has_value);
+ CHECK(!maybe.value);
// add first and then second
- JSReceiver::SetProperty(obj, first, one, NONE, SLOPPY).Check();
- JSReceiver::SetProperty(obj, second, two, NONE, SLOPPY).Check();
- CHECK(JSReceiver::HasLocalProperty(obj, first));
- CHECK(JSReceiver::HasLocalProperty(obj, second));
+ JSReceiver::SetProperty(obj, first, one, SLOPPY).Check();
+ JSReceiver::SetProperty(obj, second, two, SLOPPY).Check();
+ maybe = JSReceiver::HasOwnProperty(obj, first);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
+ maybe = JSReceiver::HasOwnProperty(obj, second);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
// delete second and then first
JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION).Check();
- CHECK(JSReceiver::HasLocalProperty(obj, first));
+ maybe = JSReceiver::HasOwnProperty(obj, first);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION).Check();
- CHECK(!JSReceiver::HasLocalProperty(obj, first));
- CHECK(!JSReceiver::HasLocalProperty(obj, second));
+ maybe = JSReceiver::HasOwnProperty(obj, first);
+ CHECK(maybe.has_value);
+ CHECK(!maybe.value);
+ maybe = JSReceiver::HasOwnProperty(obj, second);
+ CHECK(maybe.has_value);
+ CHECK(!maybe.value);
// check string and internalized string match
const char* string1 = "fisk";
Handle<String> s1 = factory->NewStringFromAsciiChecked(string1);
- JSReceiver::SetProperty(obj, s1, one, NONE, SLOPPY).Check();
+ JSReceiver::SetProperty(obj, s1, one, SLOPPY).Check();
Handle<String> s1_string = factory->InternalizeUtf8String(string1);
- CHECK(JSReceiver::HasLocalProperty(obj, s1_string));
+ maybe = JSReceiver::HasOwnProperty(obj, s1_string);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
// check internalized string and string match
const char* string2 = "fugl";
Handle<String> s2_string = factory->InternalizeUtf8String(string2);
- JSReceiver::SetProperty(obj, s2_string, one, NONE, SLOPPY).Check();
+ JSReceiver::SetProperty(obj, s2_string, one, SLOPPY).Check();
Handle<String> s2 = factory->NewStringFromAsciiChecked(string2);
- CHECK(JSReceiver::HasLocalProperty(obj, s2));
+ maybe = JSReceiver::HasOwnProperty(obj, s2);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
}
@@ -722,18 +728,15 @@ TEST(JSObjectMaps) {
v8::HandleScope sc(CcTest::isolate());
Handle<String> name = factory->InternalizeUtf8String("theFunction");
- Handle<JSFunction> function = factory->NewFunctionWithPrototype(
- name, factory->undefined_value());
- Handle<Map> initial_map =
- factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
- function->set_initial_map(*initial_map);
+ Handle<JSFunction> function = factory->NewFunction(name);
Handle<String> prop_name = factory->InternalizeUtf8String("theSlot");
Handle<JSObject> obj = factory->NewJSObject(function);
+ Handle<Map> initial_map(function->initial_map());
// Set a propery
Handle<Smi> twenty_three(Smi::FromInt(23), isolate);
- JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, SLOPPY).Check();
+ JSReceiver::SetProperty(obj, prop_name, twenty_three, SLOPPY).Check();
CHECK_EQ(Smi::FromInt(23),
*Object::GetProperty(obj, prop_name).ToHandleChecked());
@@ -811,8 +814,8 @@ TEST(JSObjectCopy) {
Handle<Smi> one(Smi::FromInt(1), isolate);
Handle<Smi> two(Smi::FromInt(2), isolate);
- JSReceiver::SetProperty(obj, first, one, NONE, SLOPPY).Check();
- JSReceiver::SetProperty(obj, second, two, NONE, SLOPPY).Check();
+ JSReceiver::SetProperty(obj, first, one, SLOPPY).Check();
+ JSReceiver::SetProperty(obj, second, two, SLOPPY).Check();
JSReceiver::SetElement(obj, 0, first, NONE, SLOPPY).Check();
JSReceiver::SetElement(obj, 1, second, NONE, SLOPPY).Check();
@@ -837,8 +840,8 @@ TEST(JSObjectCopy) {
CHECK_EQ(*value1, *value2);
// Flip the values.
- JSReceiver::SetProperty(clone, first, two, NONE, SLOPPY).Check();
- JSReceiver::SetProperty(clone, second, one, NONE, SLOPPY).Check();
+ JSReceiver::SetProperty(clone, first, two, SLOPPY).Check();
+ JSReceiver::SetProperty(clone, second, one, SLOPPY).Check();
JSReceiver::SetElement(clone, 0, second, NONE, SLOPPY).Check();
JSReceiver::SetElement(clone, 1, first, NONE, SLOPPY).Check();
@@ -901,7 +904,6 @@ TEST(StringAllocation) {
static int ObjectsFoundInHeap(Heap* heap, Handle<Object> objs[], int size) {
// Count the number of objects found in the heap.
int found_count = 0;
- heap->EnsureHeapIsIterable();
HeapIterator iterator(heap);
for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
for (int i = 0; i < size; i++) {
@@ -1030,7 +1032,9 @@ TEST(Regression39128) {
CHECK_EQ(0, FixedArray::cast(jsobject->elements())->length());
CHECK_EQ(0, jsobject->properties()->length());
// Create a reference to object in new space in jsobject.
- jsobject->FastPropertyAtPut(-1, array);
+ FieldIndex index = FieldIndex::ForInObjectOffset(
+ JSObject::kHeaderSize - kPointerSize);
+ jsobject->FastPropertyAtPut(index, array);
CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr));
@@ -1200,7 +1204,7 @@ TEST(TestCodeFlushingIncremental) {
// Simulate several GCs that use incremental marking.
const int kAgingThreshold = 6;
for (int i = 0; i < kAgingThreshold; i++) {
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
}
CHECK(!function->shared()->is_compiled() || function->IsOptimized());
@@ -1214,7 +1218,7 @@ TEST(TestCodeFlushingIncremental) {
// Simulate several GCs that use incremental marking but make sure
// the loop breaks once the function is enqueued as a candidate.
for (int i = 0; i < kAgingThreshold; i++) {
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
if (!function->next_function_link()->IsUndefined()) break;
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
}
@@ -1290,7 +1294,7 @@ TEST(TestCodeFlushingIncrementalScavenge) {
// Simulate incremental marking so that the functions are enqueued as
// code flushing candidates. Then kill one of the functions. Finally
// perform a scavenge while incremental marking is still running.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
*function2.location() = NULL;
CcTest::heap()->CollectGarbage(NEW_SPACE, "test scavenge while marking");
@@ -1344,7 +1348,7 @@ TEST(TestCodeFlushingIncrementalAbort) {
// Simulate incremental marking so that the function is enqueued as
// code flushing candidate.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
// Enable the debugger and add a breakpoint while incremental marking
// is running so that incremental marking aborts and code flushing is
@@ -1604,8 +1608,8 @@ TEST(TestSizeOfObjects) {
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
- if (collector->IsConcurrentSweepingInProgress()) {
- collector->WaitUntilSweepingCompleted();
+ if (collector->sweeping_in_progress()) {
+ collector->EnsureSweepingCompleted();
}
int initial_size = static_cast<int>(CcTest::heap()->SizeOfObjects());
@@ -1631,8 +1635,8 @@ TEST(TestSizeOfObjects) {
CHECK_EQ(initial_size, static_cast<int>(CcTest::heap()->SizeOfObjects()));
// Waiting for sweeper threads should not change heap size.
- if (collector->IsConcurrentSweepingInProgress()) {
- collector->WaitUntilSweepingCompleted();
+ if (collector->sweeping_in_progress()) {
+ collector->EnsureSweepingCompleted();
}
CHECK_EQ(initial_size, static_cast<int>(CcTest::heap()->SizeOfObjects()));
}
@@ -1640,9 +1644,8 @@ TEST(TestSizeOfObjects) {
TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
CcTest::InitializeVM();
- CcTest::heap()->EnsureHeapIsIterable();
- intptr_t size_of_objects_1 = CcTest::heap()->SizeOfObjects();
HeapIterator iterator(CcTest::heap());
+ intptr_t size_of_objects_1 = CcTest::heap()->SizeOfObjects();
intptr_t size_of_objects_2 = 0;
for (HeapObject* obj = iterator.next();
obj != NULL;
@@ -1811,7 +1814,7 @@ TEST(LeakNativeContextViaMap) {
ctx2->Exit();
v8::Local<v8::Context>::New(isolate, ctx1)->Exit();
ctx1p.Reset();
- v8::V8::ContextDisposedNotification();
+ isolate->ContextDisposedNotification();
}
CcTest::heap()->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
@@ -1857,7 +1860,7 @@ TEST(LeakNativeContextViaFunction) {
ctx2->Exit();
ctx1->Exit();
ctx1p.Reset();
- v8::V8::ContextDisposedNotification();
+ isolate->ContextDisposedNotification();
}
CcTest::heap()->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
@@ -1901,7 +1904,7 @@ TEST(LeakNativeContextViaMapKeyed) {
ctx2->Exit();
ctx1->Exit();
ctx1p.Reset();
- v8::V8::ContextDisposedNotification();
+ isolate->ContextDisposedNotification();
}
CcTest::heap()->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
@@ -1949,7 +1952,7 @@ TEST(LeakNativeContextViaMapProto) {
ctx2->Exit();
ctx1->Exit();
ctx1p.Reset();
- v8::V8::ContextDisposedNotification();
+ isolate->ContextDisposedNotification();
}
CcTest::heap()->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
@@ -2110,8 +2113,8 @@ TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) {
// The following two calls will increment CcTest::heap()->global_ic_age().
const int kLongIdlePauseInMs = 1000;
- v8::V8::ContextDisposedNotification();
- v8::V8::IdleNotification(kLongIdlePauseInMs);
+ CcTest::isolate()->ContextDisposedNotification();
+ CcTest::isolate()->IdleNotification(kLongIdlePauseInMs);
while (!marking->IsStopped() && !marking->IsComplete()) {
marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
@@ -2166,8 +2169,8 @@ TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) {
// The following two calls will increment CcTest::heap()->global_ic_age().
// Since incremental marking is off, IdleNotification will do full GC.
const int kLongIdlePauseInMs = 1000;
- v8::V8::ContextDisposedNotification();
- v8::V8::IdleNotification(kLongIdlePauseInMs);
+ CcTest::isolate()->ContextDisposedNotification();
+ CcTest::isolate()->IdleNotification(kLongIdlePauseInMs);
CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age());
CHECK_EQ(0, f->shared()->opt_count());
@@ -2207,100 +2210,70 @@ TEST(OptimizedAllocationAlwaysInNewSpace) {
TEST(OptimizedPretenuringAllocationFolding) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_max_new_space_size = 2;
- i::FLAG_allocation_site_pretenuring = false;
+ i::FLAG_expose_gc = true;
CcTest::InitializeVM();
if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
- CcTest::heap()->SetNewSpaceHighPromotionModeActive(true);
- v8::Local<v8::Value> res = CompileRun(
- "function DataObject() {"
- " this.a = 1.1;"
- " this.b = [{}];"
- " this.c = 1.2;"
- " this.d = [{}];"
- " this.e = 1.3;"
- " this.f = [{}];"
- "}"
- "var number_elements = 20000;"
+ // Grow new space unitl maximum capacity reached.
+ while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) {
+ CcTest::heap()->new_space()->Grow();
+ }
+
+ i::ScopedVector<char> source(1024);
+ i::SNPrintF(
+ source,
+ "var number_elements = %d;"
"var elements = new Array();"
"function f() {"
" for (var i = 0; i < number_elements; i++) {"
- " elements[i] = new DataObject();"
+ " elements[i] = [[{}], [1.1]];"
" }"
" return elements[number_elements-1]"
"};"
- "f(); f(); f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
-
- Handle<JSObject> o =
- v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
-
- CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(0)));
- CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(1)));
- CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(2)));
- CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(3)));
- CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(4)));
- CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(5)));
-}
+ "f(); gc();"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ AllocationSite::kPretenureMinimumCreated);
+ v8::Local<v8::Value> res = CompileRun(source.start());
-TEST(OptimizedPretenuringAllocationFoldingBlocks) {
- i::FLAG_allow_natives_syntax = true;
- i::FLAG_max_new_space_size = 2;
- i::FLAG_allocation_site_pretenuring = false;
- CcTest::InitializeVM();
- if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
- if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
- v8::HandleScope scope(CcTest::isolate());
- CcTest::heap()->SetNewSpaceHighPromotionModeActive(true);
-
- v8::Local<v8::Value> res = CompileRun(
- "var number_elements = 30000;"
- "var elements = new Array(number_elements);"
- "function DataObject() {"
- " this.a = [{}];"
- " this.b = [{}];"
- " this.c = 1.1;"
- " this.d = 1.2;"
- " this.e = [{}];"
- " this.f = 1.3;"
- "}"
- "function f() {"
- " for (var i = 0; i < number_elements; i++) {"
- " elements[i] = new DataObject();"
- " }"
- " return elements[number_elements - 1];"
- "};"
- "f(); f(); f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
+ v8::Local<v8::Value> int_array = v8::Object::Cast(*res)->Get(v8_str("0"));
+ Handle<JSObject> int_array_handle =
+ v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array));
+ v8::Local<v8::Value> double_array = v8::Object::Cast(*res)->Get(v8_str("1"));
+ Handle<JSObject> double_array_handle =
+ v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array));
Handle<JSObject> o =
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
-
- CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(0)));
- CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(1)));
- CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(2)));
- CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(3)));
- CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(4)));
- CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(5)));
+ CHECK(CcTest::heap()->InOldPointerSpace(*o));
+ CHECK(CcTest::heap()->InOldPointerSpace(*int_array_handle));
+ CHECK(CcTest::heap()->InOldPointerSpace(int_array_handle->elements()));
+ CHECK(CcTest::heap()->InOldPointerSpace(*double_array_handle));
+ CHECK(CcTest::heap()->InOldDataSpace(double_array_handle->elements()));
}
TEST(OptimizedPretenuringObjectArrayLiterals) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_max_new_space_size = 2;
+ i::FLAG_expose_gc = true;
CcTest::InitializeVM();
if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Value> res = CompileRun(
- "var number_elements = 20000;"
+ // Grow new space unitl maximum capacity reached.
+ while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) {
+ CcTest::heap()->new_space()->Grow();
+ }
+
+ i::ScopedVector<char> source(1024);
+ i::SNPrintF(
+ source,
+ "var number_elements = %d;"
"var elements = new Array(number_elements);"
"function f() {"
" for (var i = 0; i < number_elements; i++) {"
@@ -2308,9 +2281,13 @@ TEST(OptimizedPretenuringObjectArrayLiterals) {
" }"
" return elements[number_elements - 1];"
"};"
- "f(); f(); f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
+ "f(); gc();"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ AllocationSite::kPretenureMinimumCreated);
+
+ v8::Local<v8::Value> res = CompileRun(source.start());
Handle<JSObject> o =
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
@@ -2322,14 +2299,22 @@ TEST(OptimizedPretenuringObjectArrayLiterals) {
TEST(OptimizedPretenuringMixedInObjectProperties) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_max_new_space_size = 2;
+ i::FLAG_expose_gc = true;
CcTest::InitializeVM();
if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Value> res = CompileRun(
- "var number_elements = 20000;"
+ // Grow new space unitl maximum capacity reached.
+ while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) {
+ CcTest::heap()->new_space()->Grow();
+ }
+
+
+ i::ScopedVector<char> source(1024);
+ i::SNPrintF(
+ source,
+ "var number_elements = %d;"
"var elements = new Array(number_elements);"
"function f() {"
" for (var i = 0; i < number_elements; i++) {"
@@ -2337,34 +2322,49 @@ TEST(OptimizedPretenuringMixedInObjectProperties) {
" }"
" return elements[number_elements - 1];"
"};"
- "f(); f(); f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
+ "f(); gc();"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ AllocationSite::kPretenureMinimumCreated);
+
+ v8::Local<v8::Value> res = CompileRun(source.start());
Handle<JSObject> o =
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
CHECK(CcTest::heap()->InOldPointerSpace(*o));
- CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(0)));
- CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(1)));
+ FieldIndex idx1 = FieldIndex::ForPropertyIndex(o->map(), 0);
+ FieldIndex idx2 = FieldIndex::ForPropertyIndex(o->map(), 1);
+ CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(idx1)));
+ CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(idx2)));
- JSObject* inner_object = reinterpret_cast<JSObject*>(o->RawFastPropertyAt(0));
+ JSObject* inner_object =
+ reinterpret_cast<JSObject*>(o->RawFastPropertyAt(idx1));
CHECK(CcTest::heap()->InOldPointerSpace(inner_object));
- CHECK(CcTest::heap()->InOldDataSpace(inner_object->RawFastPropertyAt(0)));
- CHECK(CcTest::heap()->InOldPointerSpace(inner_object->RawFastPropertyAt(1)));
+ CHECK(CcTest::heap()->InOldDataSpace(inner_object->RawFastPropertyAt(idx1)));
+ CHECK(CcTest::heap()->InOldPointerSpace(
+ inner_object->RawFastPropertyAt(idx2)));
}
TEST(OptimizedPretenuringDoubleArrayProperties) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_max_new_space_size = 2;
+ i::FLAG_expose_gc = true;
CcTest::InitializeVM();
if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Value> res = CompileRun(
- "var number_elements = 30000;"
+ // Grow new space unitl maximum capacity reached.
+ while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) {
+ CcTest::heap()->new_space()->Grow();
+ }
+
+ i::ScopedVector<char> source(1024);
+ i::SNPrintF(
+ source,
+ "var number_elements = %d;"
"var elements = new Array(number_elements);"
"function f() {"
" for (var i = 0; i < number_elements; i++) {"
@@ -2372,9 +2372,13 @@ TEST(OptimizedPretenuringDoubleArrayProperties) {
" }"
" return elements[i - 1];"
"};"
- "f(); f(); f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
+ "f(); gc();"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ AllocationSite::kPretenureMinimumCreated);
+
+ v8::Local<v8::Value> res = CompileRun(source.start());
Handle<JSObject> o =
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
@@ -2386,14 +2390,21 @@ TEST(OptimizedPretenuringDoubleArrayProperties) {
TEST(OptimizedPretenuringdoubleArrayLiterals) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_max_new_space_size = 2;
+ i::FLAG_expose_gc = true;
CcTest::InitializeVM();
if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Value> res = CompileRun(
- "var number_elements = 30000;"
+ // Grow new space unitl maximum capacity reached.
+ while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) {
+ CcTest::heap()->new_space()->Grow();
+ }
+
+ i::ScopedVector<char> source(1024);
+ i::SNPrintF(
+ source,
+ "var number_elements = %d;"
"var elements = new Array(number_elements);"
"function f() {"
" for (var i = 0; i < number_elements; i++) {"
@@ -2401,9 +2412,13 @@ TEST(OptimizedPretenuringdoubleArrayLiterals) {
" }"
" return elements[number_elements - 1];"
"};"
- "f(); f(); f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
+ "f(); gc();"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ AllocationSite::kPretenureMinimumCreated);
+
+ v8::Local<v8::Value> res = CompileRun(source.start());
Handle<JSObject> o =
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
@@ -2415,14 +2430,21 @@ TEST(OptimizedPretenuringdoubleArrayLiterals) {
TEST(OptimizedPretenuringNestedMixedArrayLiterals) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_max_new_space_size = 2;
+ i::FLAG_expose_gc = true;
CcTest::InitializeVM();
if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Value> res = CompileRun(
- "var number_elements = 20000;"
+ // Grow new space unitl maximum capacity reached.
+ while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) {
+ CcTest::heap()->new_space()->Grow();
+ }
+
+ i::ScopedVector<char> source(1024);
+ i::SNPrintF(
+ source,
+ "var number_elements = 100;"
"var elements = new Array(number_elements);"
"function f() {"
" for (var i = 0; i < number_elements; i++) {"
@@ -2430,10 +2452,13 @@ TEST(OptimizedPretenuringNestedMixedArrayLiterals) {
" }"
" return elements[number_elements - 1];"
"};"
- "f(); f(); f();"
- "%OptimizeFunctionOnNextCall(f);"
+ "f(); gc();"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
"f();");
+ v8::Local<v8::Value> res = CompileRun(source.start());
+
v8::Local<v8::Value> int_array = v8::Object::Cast(*res)->Get(v8_str("0"));
Handle<JSObject> int_array_handle =
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array));
@@ -2453,14 +2478,21 @@ TEST(OptimizedPretenuringNestedMixedArrayLiterals) {
TEST(OptimizedPretenuringNestedObjectLiterals) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_max_new_space_size = 2;
+ i::FLAG_expose_gc = true;
CcTest::InitializeVM();
if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Value> res = CompileRun(
- "var number_elements = 20000;"
+ // Grow new space unitl maximum capacity reached.
+ while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) {
+ CcTest::heap()->new_space()->Grow();
+ }
+
+ i::ScopedVector<char> source(1024);
+ i::SNPrintF(
+ source,
+ "var number_elements = %d;"
"var elements = new Array(number_elements);"
"function f() {"
" for (var i = 0; i < number_elements; i++) {"
@@ -2468,9 +2500,13 @@ TEST(OptimizedPretenuringNestedObjectLiterals) {
" }"
" return elements[number_elements - 1];"
"};"
- "f(); f(); f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
+ "f(); gc();"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ AllocationSite::kPretenureMinimumCreated);
+
+ v8::Local<v8::Value> res = CompileRun(source.start());
v8::Local<v8::Value> int_array_1 = v8::Object::Cast(*res)->Get(v8_str("0"));
Handle<JSObject> int_array_handle_1 =
@@ -2491,14 +2527,21 @@ TEST(OptimizedPretenuringNestedObjectLiterals) {
TEST(OptimizedPretenuringNestedDoubleLiterals) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_max_new_space_size = 2;
+ i::FLAG_expose_gc = true;
CcTest::InitializeVM();
if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Value> res = CompileRun(
- "var number_elements = 20000;"
+ // Grow new space unitl maximum capacity reached.
+ while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) {
+ CcTest::heap()->new_space()->Grow();
+ }
+
+ i::ScopedVector<char> source(1024);
+ i::SNPrintF(
+ source,
+ "var number_elements = %d;"
"var elements = new Array(number_elements);"
"function f() {"
" for (var i = 0; i < number_elements; i++) {"
@@ -2506,9 +2549,13 @@ TEST(OptimizedPretenuringNestedDoubleLiterals) {
" }"
" return elements[number_elements - 1];"
"};"
- "f(); f(); f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
+ "f(); gc();"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ AllocationSite::kPretenureMinimumCreated);
+
+ v8::Local<v8::Value> res = CompileRun(source.start());
v8::Local<v8::Value> double_array_1 =
v8::Object::Cast(*res)->Get(v8_str("0"));
@@ -2532,19 +2579,29 @@ TEST(OptimizedPretenuringNestedDoubleLiterals) {
// Make sure pretenuring feedback is gathered for constructed objects as well
// as for literals.
TEST(OptimizedPretenuringConstructorCalls) {
- if (!FLAG_allocation_site_pretenuring || !i::FLAG_pretenuring_call_new) {
+ if (!i::FLAG_pretenuring_call_new) {
// FLAG_pretenuring_call_new needs to be synced with the snapshot.
return;
}
i::FLAG_allow_natives_syntax = true;
- i::FLAG_max_new_space_size = 2;
+ i::FLAG_expose_gc = true;
CcTest::InitializeVM();
if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Value> res = CompileRun(
- "var number_elements = 20000;"
+ // Grow new space unitl maximum capacity reached.
+ while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) {
+ CcTest::heap()->new_space()->Grow();
+ }
+
+ i::ScopedVector<char> source(1024);
+ // Call new is doing slack tracking for the first
+ // JSFunction::kGenerousAllocationCount allocations, and we can't find
+ // mementos during that time.
+ i::SNPrintF(
+ source,
+ "var number_elements = %d;"
"var elements = new Array(number_elements);"
"function foo() {"
" this.a = 3;"
@@ -2556,9 +2613,14 @@ TEST(OptimizedPretenuringConstructorCalls) {
" }"
" return elements[number_elements - 1];"
"};"
- "f(); f(); f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
+ "f(); gc();"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ AllocationSite::kPretenureMinimumCreated +
+ JSFunction::kGenerousAllocationCount);
+
+ v8::Local<v8::Value> res = CompileRun(source.start());
Handle<JSObject> o =
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
@@ -2567,57 +2629,77 @@ TEST(OptimizedPretenuringConstructorCalls) {
}
-// Test regular array literals allocation.
-TEST(OptimizedAllocationArrayLiterals) {
+TEST(OptimizedPretenuringCallNew) {
+ if (!i::FLAG_pretenuring_call_new) {
+ // FLAG_pretenuring_call_new needs to be synced with the snapshot.
+ return;
+ }
i::FLAG_allow_natives_syntax = true;
+ i::FLAG_expose_gc = true;
CcTest::InitializeVM();
if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Value> res = CompileRun(
+ // Grow new space unitl maximum capacity reached.
+ while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) {
+ CcTest::heap()->new_space()->Grow();
+ }
+
+ i::ScopedVector<char> source(1024);
+ // Call new is doing slack tracking for the first
+ // JSFunction::kGenerousAllocationCount allocations, and we can't find
+ // mementos during that time.
+ i::SNPrintF(
+ source,
+ "var number_elements = %d;"
+ "var elements = new Array(number_elements);"
+ "function g() { this.a = 0; }"
"function f() {"
- " var numbers = new Array(1, 2, 3);"
- " numbers[0] = 3.14;"
- " return numbers;"
+ " for (var i = 0; i < number_elements; i++) {"
+ " elements[i] = new g();"
+ " }"
+ " return elements[number_elements - 1];"
"};"
- "f(); f(); f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
- CHECK_EQ(static_cast<int>(3.14),
- v8::Object::Cast(*res)->Get(v8_str("0"))->Int32Value());
+ "f(); gc();"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ AllocationSite::kPretenureMinimumCreated +
+ JSFunction::kGenerousAllocationCount);
+
+ v8::Local<v8::Value> res = CompileRun(source.start());
Handle<JSObject> o =
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
-
- CHECK(CcTest::heap()->InNewSpace(o->elements()));
+ CHECK(CcTest::heap()->InOldPointerSpace(*o));
}
-// Test global pretenuring call new.
-TEST(OptimizedPretenuringCallNew) {
+// Test regular array literals allocation.
+TEST(OptimizedAllocationArrayLiterals) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_allocation_site_pretenuring = false;
- i::FLAG_pretenuring_call_new = true;
CcTest::InitializeVM();
if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
- CcTest::heap()->SetNewSpaceHighPromotionModeActive(true);
- AlwaysAllocateScope always_allocate(CcTest::i_isolate());
v8::Local<v8::Value> res = CompileRun(
- "function g() { this.a = 0; }"
"function f() {"
- " return new g();"
+ " var numbers = new Array(1, 2, 3);"
+ " numbers[0] = 3.14;"
+ " return numbers;"
"};"
"f(); f(); f();"
"%OptimizeFunctionOnNextCall(f);"
"f();");
+ CHECK_EQ(static_cast<int>(3.14),
+ v8::Object::Cast(*res)->Get(v8_str("0"))->Int32Value());
Handle<JSObject> o =
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
- CHECK(CcTest::heap()->InOldPointerSpace(*o));
+
+ CHECK(CcTest::heap()->InNewSpace(o->elements()));
}
@@ -2641,7 +2723,7 @@ TEST(Regress1465) {
AlwaysAllocateScope always_allocate(CcTest::i_isolate());
for (int i = 0; i < transitions_count; i++) {
EmbeddedVector<char, 64> buffer;
- OS::SNPrintF(buffer, "var o = new F; o.prop%d = %d;", i, i);
+ SNPrintF(buffer, "var o = new F; o.prop%d = %d;", i, i);
CompileRun(buffer.start());
}
CompileRun("var root = new F;");
@@ -2657,7 +2739,7 @@ TEST(Regress1465) {
CompileRun("%DebugPrint(root);");
CHECK_EQ(transitions_count, transitions_before);
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
// Count number of live transitions after marking. Note that one transition
@@ -2673,7 +2755,7 @@ static void AddTransitions(int transitions_count) {
AlwaysAllocateScope always_allocate(CcTest::i_isolate());
for (int i = 0; i < transitions_count; i++) {
EmbeddedVector<char, 64> buffer;
- OS::SNPrintF(buffer, "var o = new F; o.prop%d = %d;", i, i);
+ SNPrintF(buffer, "var o = new F; o.prop%d = %d;", i, i);
CompileRun(buffer.start());
}
}
@@ -2695,8 +2777,7 @@ static void AddPropertyTo(
i::FLAG_gc_interval = gc_count;
i::FLAG_gc_global = true;
CcTest::heap()->set_allocation_timeout(gc_count);
- JSReceiver::SetProperty(
- object, prop_name, twenty_three, NONE, SLOPPY).Check();
+ JSReceiver::SetProperty(object, prop_name, twenty_three, SLOPPY).Check();
}
@@ -2799,7 +2880,7 @@ TEST(TransitionArraySimpleToFull) {
CompileRun("o = new F;"
"root = new F");
root = GetByName("root");
- ASSERT(root->map()->transitions()->IsSimpleTransition());
+ DCHECK(root->map()->transitions()->IsSimpleTransition());
AddPropertyTo(2, root, "happy");
// Count number of live transitions after marking. Note that one transition
@@ -2823,7 +2904,7 @@ TEST(Regress2143a) {
"root.foo = 0;"
"root = new Object;");
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
// Compile a StoreIC that performs the prepared map transition. This
// will restart incremental marking and should make sure the root is
@@ -2864,7 +2945,7 @@ TEST(Regress2143b) {
"root.foo = 0;"
"root = new Object;");
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
// Compile an optimized LStoreNamedField that performs the prepared
// map transition. This will restart incremental marking and should
@@ -2920,7 +3001,8 @@ TEST(ReleaseOverReservedPages) {
// Triggering one GC will cause a lot of garbage to be discovered but
// even spread across all allocated pages.
- heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered for preparation");
+ heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask,
+ "triggered for preparation");
CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages());
// Triggering subsequent GCs should cause at least half of the pages
@@ -2986,8 +3068,9 @@ TEST(PrintSharedFunctionInfo) {
*v8::Handle<v8::Function>::Cast(
CcTest::global()->Get(v8_str("g"))));
- DisallowHeapAllocation no_allocation;
- g->shared()->PrintLn();
+ OFStream os(stdout);
+ g->shared()->Print(os);
+ os << endl;
}
#endif // OBJECT_PRINT
@@ -3018,9 +3101,9 @@ TEST(Regress2211) {
CHECK(value->Equals(obj->GetHiddenValue(v8_str("key string"))));
// Check size.
- DescriptorArray* descriptors = internal_obj->map()->instance_descriptors();
+ FieldIndex index = FieldIndex::ForDescriptor(internal_obj->map(), 0);
ObjectHashTable* hashtable = ObjectHashTable::cast(
- internal_obj->RawFastPropertyAt(descriptors->GetFieldIndex(0)));
+ internal_obj->RawFastPropertyAt(index));
// HashTable header (5) and 4 initial entries (8).
CHECK_LE(hashtable->SizeFor(hashtable->length()), 13 * kPointerSize);
}
@@ -3058,18 +3141,22 @@ TEST(IncrementalMarkingClearsTypeFeedbackInfo) {
Handle<FixedArray> feedback_vector(f->shared()->feedback_vector());
- CHECK_EQ(2, feedback_vector->length());
- CHECK(feedback_vector->get(0)->IsJSFunction());
- CHECK(feedback_vector->get(1)->IsJSFunction());
+ int expected_length = FLAG_vector_ics ? 4 : 2;
+ CHECK_EQ(expected_length, feedback_vector->length());
+ for (int i = 0; i < expected_length; i++) {
+ if ((i % 2) == 1) {
+ CHECK(feedback_vector->get(i)->IsJSFunction());
+ }
+ }
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
- CHECK_EQ(2, feedback_vector->length());
- CHECK_EQ(feedback_vector->get(0),
- *TypeFeedbackInfo::UninitializedSentinel(CcTest::i_isolate()));
- CHECK_EQ(feedback_vector->get(1),
- *TypeFeedbackInfo::UninitializedSentinel(CcTest::i_isolate()));
+ CHECK_EQ(expected_length, feedback_vector->length());
+ for (int i = 0; i < expected_length; i++) {
+ CHECK_EQ(feedback_vector->get(i),
+ *TypeFeedbackInfo::UninitializedSentinel(CcTest::i_isolate()));
+ }
}
@@ -3105,7 +3192,7 @@ TEST(IncrementalMarkingPreservesMonomorphicIC) {
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
CHECK(ic_before->ic_state() == MONOMORPHIC);
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
@@ -3138,8 +3225,8 @@ TEST(IncrementalMarkingClearsMonomorphicIC) {
CHECK(ic_before->ic_state() == MONOMORPHIC);
// Fire context dispose notification.
- v8::V8::ContextDisposedNotification();
- SimulateIncrementalMarking();
+ CcTest::isolate()->ContextDisposedNotification();
+ SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
@@ -3179,8 +3266,8 @@ TEST(IncrementalMarkingClearsPolymorphicIC) {
CHECK(ic_before->ic_state() == POLYMORPHIC);
// Fire context dispose notification.
- v8::V8::ContextDisposedNotification();
- SimulateIncrementalMarking();
+ CcTest::isolate()->ContextDisposedNotification();
+ SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
@@ -3341,7 +3428,7 @@ TEST(Regress159140) {
// Simulate incremental marking so that the functions are enqueued as
// code flushing candidates. Then optimize one function. Finally
// finish the GC to complete code flushing.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
CompileRun("%OptimizeFunctionOnNextCall(g); g(3);");
heap->CollectAllGarbage(Heap::kNoGCFlags);
@@ -3388,7 +3475,7 @@ TEST(Regress165495) {
// Simulate incremental marking so that unoptimized code is flushed
// even though it still is cached in the optimized code map.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
heap->CollectAllGarbage(Heap::kNoGCFlags);
// Make a new closure that will get code installed from the code map.
@@ -3456,7 +3543,7 @@ TEST(Regress169209) {
}
// Simulate incremental marking and collect code flushing candidates.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
CHECK(shared1->code()->gc_metadata() != NULL);
// Optimize function and make sure the unoptimized code is replaced.
@@ -3602,7 +3689,7 @@ TEST(Regress168801) {
// Simulate incremental marking so that unoptimized function is enqueued as a
// candidate for code flushing. The shared function info however will not be
// explicitly enqueued.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
// Now optimize the function so that it is taken off the candidate list.
{
@@ -3659,7 +3746,7 @@ TEST(Regress173458) {
// Simulate incremental marking so that unoptimized function is enqueued as a
// candidate for code flushing. The shared function info however will not be
// explicitly enqueued.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
// Now enable the debugger which in turn will disable code flushing.
CHECK(isolate->debug()->Load());
@@ -3688,7 +3775,7 @@ TEST(DeferredHandles) {
}
// An entire block of handles has been filled.
// Next handle would require a new block.
- ASSERT(data->next == data->limit);
+ DCHECK(data->next == data->limit);
DeferredHandleScope deferred(isolate);
DummyVisitor visitor;
@@ -3709,7 +3796,7 @@ TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) {
if (marking->IsStopped()) marking->Start();
// This big step should be sufficient to mark the whole array.
marking->Step(100 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
- ASSERT(marking->IsComplete());
+ DCHECK(marking->IsComplete());
}
@@ -3736,10 +3823,6 @@ TEST(DisableInlineAllocation) {
CcTest::heap()->DisableInlineAllocation();
CompileRun("run()");
- // Run test with inline allocation disabled and pretenuring.
- CcTest::heap()->SetNewSpaceHighPromotionModeActive(true);
- CompileRun("run()");
-
// Run test with inline allocation re-enabled.
CcTest::heap()->EnableInlineAllocation();
CompileRun("run()");
@@ -3803,7 +3886,7 @@ TEST(EnsureAllocationSiteDependentCodesProcessed) {
// Now make sure that a gc should get rid of the function, even though we
// still have the allocation site alive.
for (int i = 0; i < 4; i++) {
- heap->CollectAllGarbage(false);
+ heap->CollectAllGarbage(Heap::kNoGCFlags);
}
// The site still exists because of our global handle, but the code is no
@@ -3853,7 +3936,7 @@ TEST(CellsInOptimizedCodeAreWeak) {
heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
}
- ASSERT(code->marked_for_deoptimization());
+ DCHECK(code->marked_for_deoptimization());
}
@@ -3894,7 +3977,7 @@ TEST(ObjectsInOptimizedCodeAreWeak) {
heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
}
- ASSERT(code->marked_for_deoptimization());
+ DCHECK(code->marked_for_deoptimization());
}
@@ -3911,37 +3994,41 @@ TEST(NoWeakHashTableLeakWithIncrementalMarking) {
if (!isolate->use_crankshaft()) return;
HandleScope outer_scope(heap->isolate());
for (int i = 0; i < 3; i++) {
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
{
LocalContext context;
HandleScope scope(heap->isolate());
EmbeddedVector<char, 256> source;
- OS::SNPrintF(source,
- "function bar%d() {"
- " return foo%d(1);"
- "};"
- "function foo%d(x) { with (x) { return 1 + x; } };"
- "bar%d();"
- "bar%d();"
- "bar%d();"
- "%OptimizeFunctionOnNextCall(bar%d);"
- "bar%d();", i, i, i, i, i, i, i, i);
+ SNPrintF(source,
+ "function bar%d() {"
+ " return foo%d(1);"
+ "};"
+ "function foo%d(x) { with (x) { return 1 + x; } };"
+ "bar%d();"
+ "bar%d();"
+ "bar%d();"
+ "%%OptimizeFunctionOnNextCall(bar%d);"
+ "bar%d();", i, i, i, i, i, i, i, i);
CompileRun(source.start());
}
heap->CollectAllGarbage(i::Heap::kNoGCFlags);
}
- WeakHashTable* table = WeakHashTable::cast(heap->weak_object_to_code_table());
- CHECK_EQ(0, table->NumberOfElements());
+ int elements = 0;
+ if (heap->weak_object_to_code_table()->IsHashTable()) {
+ WeakHashTable* t = WeakHashTable::cast(heap->weak_object_to_code_table());
+ elements = t->NumberOfElements();
+ }
+ CHECK_EQ(0, elements);
}
static Handle<JSFunction> OptimizeDummyFunction(const char* name) {
EmbeddedVector<char, 256> source;
- OS::SNPrintF(source,
- "function %s() { return 0; }"
- "%s(); %s();"
- "%%OptimizeFunctionOnNextCall(%s);"
- "%s();", name, name, name, name, name);
+ SNPrintF(source,
+ "function %s() { return 0; }"
+ "%s(); %s();"
+ "%%OptimizeFunctionOnNextCall(%s);"
+ "%s();", name, name, name, name, name);
CompileRun(source.start());
Handle<JSFunction> fun =
v8::Utils::OpenHandle(
@@ -3993,7 +4080,8 @@ static Handle<Code> DummyOptimizedCode(Isolate* isolate) {
i::byte buffer[i::Assembler::kMinimalBufferSize];
MacroAssembler masm(isolate, buffer, sizeof(buffer));
CodeDesc desc;
- masm.Prologue(BUILD_FUNCTION_FRAME);
+ masm.Push(isolate->factory()->undefined_value());
+ masm.Drop(1);
masm.GetCode(&desc);
Handle<Object> undefined(isolate->heap()->undefined_value(), isolate);
Handle<Code> code = isolate->factory()->NewCode(
@@ -4221,7 +4309,7 @@ TEST(Regress357137) {
global->Set(v8::String::NewFromUtf8(isolate, "interrupt"),
v8::FunctionTemplate::New(isolate, RequestInterrupt));
v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global);
- ASSERT(!context.IsEmpty());
+ DCHECK(!context.IsEmpty());
v8::Context::Scope cscope(context);
v8::Local<v8::Value> result = CompileRun(
@@ -4246,6 +4334,7 @@ TEST(ArrayShiftSweeping) {
"var tmp = new Array(100000);"
"array[0] = 10;"
"gc();"
+ "gc();"
"array.shift();"
"array;");
@@ -4254,6 +4343,145 @@ TEST(ArrayShiftSweeping) {
CHECK(heap->InOldPointerSpace(o->elements()));
CHECK(heap->InOldPointerSpace(*o));
Page* page = Page::FromAddress(o->elements()->address());
- CHECK(page->WasSwept() ||
+ CHECK(page->parallel_sweeping() <= MemoryChunk::SWEEPING_FINALIZE ||
Marking::IsBlack(Marking::MarkBitFrom(o->elements())));
}
+
+
+TEST(PromotionQueue) {
+ i::FLAG_expose_gc = true;
+ i::FLAG_max_semi_space_size = 2;
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ NewSpace* new_space = heap->new_space();
+
+ // In this test we will try to overwrite the promotion queue which is at the
+ // end of to-space. To actually make that possible, we need at least two
+ // semi-space pages and take advantage of fragementation.
+ // (1) Grow semi-space to two pages.
+ // (2) Create a few small long living objects and call the scavenger to
+ // move them to the other semi-space.
+ // (3) Create a huge object, i.e., remainder of first semi-space page and
+ // create another huge object which should be of maximum allocatable memory
+ // size of the second semi-space page.
+ // (4) Call the scavenger again.
+ // What will happen is: the scavenger will promote the objects created in (2)
+ // and will create promotion queue entries at the end of the second
+ // semi-space page during the next scavenge when it promotes the objects to
+ // the old generation. The first allocation of (3) will fill up the first
+ // semi-space page. The second allocation in (3) will not fit into the first
+ // semi-space page, but it will overwrite the promotion queue which are in
+ // the second semi-space page. If the right guards are in place, the promotion
+ // queue will be evacuated in that case.
+
+ // Grow the semi-space to two pages to make semi-space copy overwrite the
+ // promotion queue, which will be at the end of the second page.
+ intptr_t old_capacity = new_space->Capacity();
+ new_space->Grow();
+ CHECK(new_space->IsAtMaximumCapacity());
+ CHECK(2 * old_capacity == new_space->Capacity());
+
+ // Call the scavenger two times to get an empty new space
+ heap->CollectGarbage(NEW_SPACE);
+ heap->CollectGarbage(NEW_SPACE);
+
+ // First create a few objects which will survive a scavenge, and will get
+ // promoted to the old generation later on. These objects will create
+ // promotion queue entries at the end of the second semi-space page.
+ const int number_handles = 12;
+ Handle<FixedArray> handles[number_handles];
+ for (int i = 0; i < number_handles; i++) {
+ handles[i] = isolate->factory()->NewFixedArray(1, NOT_TENURED);
+ }
+ heap->CollectGarbage(NEW_SPACE);
+
+ // Create the first huge object which will exactly fit the first semi-space
+ // page.
+ int new_linear_size = static_cast<int>(
+ *heap->new_space()->allocation_limit_address() -
+ *heap->new_space()->allocation_top_address());
+ int length = new_linear_size / kPointerSize - FixedArray::kHeaderSize;
+ Handle<FixedArray> first =
+ isolate->factory()->NewFixedArray(length, NOT_TENURED);
+ CHECK(heap->InNewSpace(*first));
+
+ // Create the second huge object of maximum allocatable second semi-space
+ // page size.
+ new_linear_size = static_cast<int>(
+ *heap->new_space()->allocation_limit_address() -
+ *heap->new_space()->allocation_top_address());
+ length = Page::kMaxRegularHeapObjectSize / kPointerSize -
+ FixedArray::kHeaderSize;
+ Handle<FixedArray> second =
+ isolate->factory()->NewFixedArray(length, NOT_TENURED);
+ CHECK(heap->InNewSpace(*second));
+
+ // This scavenge will corrupt memory if the promotion queue is not evacuated.
+ heap->CollectGarbage(NEW_SPACE);
+}
+
+
+TEST(Regress388880) {
+ i::FLAG_expose_gc = true;
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Factory* factory = isolate->factory();
+ Heap* heap = isolate->heap();
+
+ Handle<Map> map1 = Map::Create(isolate->object_function(), 1);
+ Handle<Map> map2 =
+ Map::CopyWithField(map1, factory->NewStringFromStaticAscii("foo"),
+ HeapType::Any(isolate), NONE, Representation::Tagged(),
+ OMIT_TRANSITION).ToHandleChecked();
+
+ int desired_offset = Page::kPageSize - map1->instance_size();
+
+ // Allocate fixed array in old pointer space so, that object allocated
+ // afterwards would end at the end of the page.
+ {
+ SimulateFullSpace(heap->old_pointer_space());
+ int padding_size = desired_offset - Page::kObjectStartOffset;
+ int padding_array_length =
+ (padding_size - FixedArray::kHeaderSize) / kPointerSize;
+
+ Handle<FixedArray> temp2 =
+ factory->NewFixedArray(padding_array_length, TENURED);
+ Page* page = Page::FromAddress(temp2->address());
+ CHECK_EQ(Page::kObjectStartOffset, page->Offset(temp2->address()));
+ }
+
+ Handle<JSObject> o = factory->NewJSObjectFromMap(map1, TENURED, false);
+ o->set_properties(*factory->empty_fixed_array());
+
+ // Ensure that the object allocated where we need it.
+ Page* page = Page::FromAddress(o->address());
+ CHECK_EQ(desired_offset, page->Offset(o->address()));
+
+ // Now we have an object right at the end of the page.
+
+ // Enable incremental marking to trigger actions in Heap::AdjustLiveBytes()
+ // that would cause crash.
+ IncrementalMarking* marking = CcTest::heap()->incremental_marking();
+ marking->Abort();
+ marking->Start();
+ CHECK(marking->IsMarking());
+
+ // Now everything is set up for crashing in JSObject::MigrateFastToFast()
+ // when it calls heap->AdjustLiveBytes(...).
+ JSObject::MigrateToMap(o, map2);
+}
+
+
+#ifdef DEBUG
+TEST(PathTracer) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+
+ v8::Local<v8::Value> result = CompileRun("'abc'");
+ Handle<Object> o = v8::Utils::OpenHandle(*result);
+ CcTest::i_isolate()->heap()->TracePathToObject(*o);
+}
+#endif // DEBUG
diff --git a/deps/v8/test/cctest/test-hydrogen-types.cc b/deps/v8/test/cctest/test-hydrogen-types.cc
new file mode 100644
index 000000000..0ac53bde0
--- /dev/null
+++ b/deps/v8/test/cctest/test-hydrogen-types.cc
@@ -0,0 +1,168 @@
+// 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 "src/hydrogen-types.h"
+
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+
+
+static const HType kTypes[] = {
+ #define DECLARE_TYPE(Name, mask) HType::Name(),
+ HTYPE_LIST(DECLARE_TYPE)
+ #undef DECLARE_TYPE
+};
+
+static const int kNumberOfTypes = sizeof(kTypes) / sizeof(kTypes[0]);
+
+
+TEST(HTypeDistinct) {
+ for (int i = 0; i < kNumberOfTypes; ++i) {
+ for (int j = 0; j < kNumberOfTypes; ++j) {
+ CHECK(i == j || !kTypes[i].Equals(kTypes[j]));
+ }
+ }
+}
+
+
+TEST(HTypeReflexivity) {
+ // Reflexivity of =
+ for (int i = 0; i < kNumberOfTypes; ++i) {
+ CHECK(kTypes[i].Equals(kTypes[i]));
+ }
+
+ // Reflexivity of <
+ for (int i = 0; i < kNumberOfTypes; ++i) {
+ CHECK(kTypes[i].IsSubtypeOf(kTypes[i]));
+ }
+}
+
+
+TEST(HTypeTransitivity) {
+ // Transitivity of =
+ for (int i = 0; i < kNumberOfTypes; ++i) {
+ for (int j = 0; j < kNumberOfTypes; ++j) {
+ for (int k = 0; k < kNumberOfTypes; ++k) {
+ HType ti = kTypes[i];
+ HType tj = kTypes[j];
+ HType tk = kTypes[k];
+ CHECK(!ti.Equals(tj) || !tj.Equals(tk) || ti.Equals(tk));
+ }
+ }
+ }
+
+ // Transitivity of <
+ for (int i = 0; i < kNumberOfTypes; ++i) {
+ for (int j = 0; j < kNumberOfTypes; ++j) {
+ for (int k = 0; k < kNumberOfTypes; ++k) {
+ HType ti = kTypes[i];
+ HType tj = kTypes[j];
+ HType tk = kTypes[k];
+ CHECK(!ti.IsSubtypeOf(tj) || !tj.IsSubtypeOf(tk) || ti.IsSubtypeOf(tk));
+ }
+ }
+ }
+}
+
+
+TEST(HTypeCombine) {
+ // T < T /\ T' and T' < T /\ T' for all T,T'
+ for (int i = 0; i < kNumberOfTypes; ++i) {
+ for (int j = 0; j < kNumberOfTypes; ++j) {
+ HType ti = kTypes[i];
+ HType tj = kTypes[j];
+ CHECK(ti.IsSubtypeOf(ti.Combine(tj)));
+ CHECK(tj.IsSubtypeOf(ti.Combine(tj)));
+ }
+ }
+}
+
+
+TEST(HTypeAny) {
+ // T < Any for all T
+ for (int i = 0; i < kNumberOfTypes; ++i) {
+ HType ti = kTypes[i];
+ CHECK(ti.IsAny());
+ }
+
+ // Any < T implies T = Any for all T
+ for (int i = 0; i < kNumberOfTypes; ++i) {
+ HType ti = kTypes[i];
+ CHECK(!HType::Any().IsSubtypeOf(ti) || HType::Any().Equals(ti));
+ }
+}
+
+
+TEST(HTypeTagged) {
+ // T < Tagged for all T \ {Any}
+ for (int i = 0; i < kNumberOfTypes; ++i) {
+ HType ti = kTypes[i];
+ CHECK(ti.IsTagged() || HType::Any().Equals(ti));
+ }
+
+ // Tagged < T implies T = Tagged or T = Any
+ for (int i = 0; i < kNumberOfTypes; ++i) {
+ HType ti = kTypes[i];
+ CHECK(!HType::Tagged().IsSubtypeOf(ti) ||
+ HType::Tagged().Equals(ti) ||
+ HType::Any().Equals(ti));
+ }
+}
+
+
+TEST(HTypeSmi) {
+ // T < Smi implies T = None or T = Smi for all T
+ for (int i = 0; i < kNumberOfTypes; ++i) {
+ HType ti = kTypes[i];
+ CHECK(!ti.IsSmi() ||
+ ti.Equals(HType::Smi()) ||
+ ti.Equals(HType::None()));
+ }
+}
+
+
+TEST(HTypeHeapObject) {
+ CHECK(!HType::TaggedPrimitive().IsHeapObject());
+ CHECK(!HType::TaggedNumber().IsHeapObject());
+ CHECK(!HType::Smi().IsHeapObject());
+ CHECK(HType::HeapObject().IsHeapObject());
+ CHECK(HType::HeapPrimitive().IsHeapObject());
+ CHECK(HType::Null().IsHeapObject());
+ CHECK(HType::HeapNumber().IsHeapObject());
+ CHECK(HType::String().IsHeapObject());
+ CHECK(HType::Boolean().IsHeapObject());
+ CHECK(HType::Undefined().IsHeapObject());
+ CHECK(HType::JSObject().IsHeapObject());
+ CHECK(HType::JSArray().IsHeapObject());
+}
+
+
+TEST(HTypePrimitive) {
+ CHECK(HType::TaggedNumber().IsTaggedPrimitive());
+ CHECK(HType::Smi().IsTaggedPrimitive());
+ CHECK(!HType::HeapObject().IsTaggedPrimitive());
+ CHECK(HType::HeapPrimitive().IsTaggedPrimitive());
+ CHECK(HType::Null().IsHeapPrimitive());
+ CHECK(HType::HeapNumber().IsHeapPrimitive());
+ CHECK(HType::String().IsHeapPrimitive());
+ CHECK(HType::Boolean().IsHeapPrimitive());
+ CHECK(HType::Undefined().IsHeapPrimitive());
+ CHECK(!HType::JSObject().IsTaggedPrimitive());
+ CHECK(!HType::JSArray().IsTaggedPrimitive());
+}
+
+
+TEST(HTypeJSObject) {
+ CHECK(HType::JSArray().IsJSObject());
+}
+
+
+TEST(HTypeNone) {
+ // None < T for all T
+ for (int i = 0; i < kNumberOfTypes; ++i) {
+ HType ti = kTypes[i];
+ CHECK(HType::None().IsSubtypeOf(ti));
+ }
+}
diff --git a/deps/v8/test/cctest/test-javascript-arm64.cc b/deps/v8/test/cctest/test-javascript-arm64.cc
index bd7a2b285..5e4503478 100644
--- a/deps/v8/test/cctest/test-javascript-arm64.cc
+++ b/deps/v8/test/cctest/test-javascript-arm64.cc
@@ -27,18 +27,18 @@
#include <limits.h>
-#include "v8.h"
-
-#include "api.h"
-#include "isolate.h"
-#include "compilation-cache.h"
-#include "execution.h"
-#include "snapshot.h"
-#include "platform.h"
-#include "utils.h"
-#include "cctest.h"
-#include "parser.h"
-#include "unicode-inl.h"
+#include "src/v8.h"
+
+#include "src/api.h"
+#include "src/base/platform/platform.h"
+#include "src/compilation-cache.h"
+#include "src/execution.h"
+#include "src/isolate.h"
+#include "src/parser.h"
+#include "src/snapshot.h"
+#include "src/unicode-inl.h"
+#include "src/utils.h"
+#include "test/cctest/cctest.h"
using ::v8::Context;
using ::v8::Extension;
diff --git a/deps/v8/test/cctest/test-js-arm64-variables.cc b/deps/v8/test/cctest/test-js-arm64-variables.cc
index df3f4a829..7f2771094 100644
--- a/deps/v8/test/cctest/test-js-arm64-variables.cc
+++ b/deps/v8/test/cctest/test-js-arm64-variables.cc
@@ -29,18 +29,18 @@
#include <limits.h>
-#include "v8.h"
-
-#include "api.h"
-#include "isolate.h"
-#include "compilation-cache.h"
-#include "execution.h"
-#include "snapshot.h"
-#include "platform.h"
-#include "utils.h"
-#include "cctest.h"
-#include "parser.h"
-#include "unicode-inl.h"
+#include "src/v8.h"
+
+#include "src/api.h"
+#include "src/base/platform/platform.h"
+#include "src/compilation-cache.h"
+#include "src/execution.h"
+#include "src/isolate.h"
+#include "src/parser.h"
+#include "src/snapshot.h"
+#include "src/unicode-inl.h"
+#include "src/utils.h"
+#include "test/cctest/cctest.h"
using ::v8::Context;
using ::v8::Extension;
diff --git a/deps/v8/test/cctest/test-libplatform-default-platform.cc b/deps/v8/test/cctest/test-libplatform-default-platform.cc
new file mode 100644
index 000000000..dac6db2a0
--- /dev/null
+++ b/deps/v8/test/cctest/test-libplatform-default-platform.cc
@@ -0,0 +1,30 @@
+// 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 "src/v8.h"
+
+#include "src/libplatform/default-platform.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-libplatform.h"
+
+using namespace v8::internal;
+using namespace v8::platform;
+
+
+TEST(DefaultPlatformMessagePump) {
+ TaskCounter task_counter;
+
+ DefaultPlatform platform;
+
+ TestTask* task = new TestTask(&task_counter, true);
+
+ CHECK(!platform.PumpMessageLoop(CcTest::isolate()));
+
+ platform.CallOnForegroundThread(CcTest::isolate(), task);
+
+ CHECK_EQ(1, task_counter.GetCount());
+ CHECK(platform.PumpMessageLoop(CcTest::isolate()));
+ CHECK_EQ(0, task_counter.GetCount());
+ CHECK(!platform.PumpMessageLoop(CcTest::isolate()));
+}
diff --git a/deps/v8/test/cctest/test-libplatform-task-queue.cc b/deps/v8/test/cctest/test-libplatform-task-queue.cc
index 476551576..630686b45 100644
--- a/deps/v8/test/cctest/test-libplatform-task-queue.cc
+++ b/deps/v8/test/cctest/test-libplatform-task-queue.cc
@@ -25,13 +25,14 @@
// (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 "src/v8.h"
-#include "cctest.h"
-#include "libplatform/task-queue.h"
-#include "test-libplatform.h"
+#include "src/libplatform/task-queue.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-libplatform.h"
using namespace v8::internal;
+using namespace v8::platform;
TEST(TaskQueueBasic) {
diff --git a/deps/v8/test/cctest/test-libplatform-worker-thread.cc b/deps/v8/test/cctest/test-libplatform-worker-thread.cc
index 090d6e1a1..ba6b51fd0 100644
--- a/deps/v8/test/cctest/test-libplatform-worker-thread.cc
+++ b/deps/v8/test/cctest/test-libplatform-worker-thread.cc
@@ -25,14 +25,15 @@
// (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 "src/v8.h"
-#include "cctest.h"
-#include "libplatform/task-queue.h"
-#include "libplatform/worker-thread.h"
-#include "test-libplatform.h"
+#include "src/libplatform/task-queue.h"
+#include "src/libplatform/worker-thread.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-libplatform.h"
using namespace v8::internal;
+using namespace v8::platform;
TEST(WorkerThread) {
@@ -54,7 +55,7 @@ TEST(WorkerThread) {
queue.Append(task3);
queue.Append(task4);
- // TaskQueue ASSERTs that it is empty in its destructor.
+ // TaskQueue DCHECKs that it is empty in its destructor.
queue.Terminate();
delete thread1;
diff --git a/deps/v8/test/cctest/test-libplatform.h b/deps/v8/test/cctest/test-libplatform.h
index e32770eed..67147f33e 100644
--- a/deps/v8/test/cctest/test-libplatform.h
+++ b/deps/v8/test/cctest/test-libplatform.h
@@ -28,11 +28,12 @@
#ifndef TEST_LIBPLATFORM_H_
#define TEST_LIBPLATFORM_H_
-#include "v8.h"
+#include "src/v8.h"
-#include "cctest.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
+using namespace v8::platform;
class TaskCounter {
public:
@@ -40,22 +41,22 @@ class TaskCounter {
~TaskCounter() { CHECK_EQ(0, counter_); }
int GetCount() const {
- LockGuard<Mutex> guard(&lock_);
+ v8::base::LockGuard<v8::base::Mutex> guard(&lock_);
return counter_;
}
void Inc() {
- LockGuard<Mutex> guard(&lock_);
+ v8::base::LockGuard<v8::base::Mutex> guard(&lock_);
++counter_;
}
void Dec() {
- LockGuard<Mutex> guard(&lock_);
+ v8::base::LockGuard<v8::base::Mutex> guard(&lock_);
--counter_;
}
private:
- mutable Mutex lock_;
+ mutable v8::base::Mutex lock_;
int counter_;
DISALLOW_COPY_AND_ASSIGN(TaskCounter);
@@ -93,10 +94,12 @@ class TestTask : public v8::Task {
};
-class TestWorkerThread : public Thread {
+class TestWorkerThread : public v8::base::Thread {
public:
explicit TestWorkerThread(v8::Task* task)
- : Thread("libplatform TestWorkerThread"), semaphore_(0), task_(task) {}
+ : Thread(Options("libplatform TestWorkerThread")),
+ semaphore_(0),
+ task_(task) {}
virtual ~TestWorkerThread() {}
void Signal() { semaphore_.Signal(); }
@@ -111,7 +114,7 @@ class TestWorkerThread : public Thread {
}
private:
- Semaphore semaphore_;
+ v8::base::Semaphore semaphore_;
v8::Task* task_;
DISALLOW_COPY_AND_ASSIGN(TestWorkerThread);
diff --git a/deps/v8/test/cctest/test-list.cc b/deps/v8/test/cctest/test-list.cc
index a29972b58..20c13f6e6 100644
--- a/deps/v8/test/cctest/test-list.cc
+++ b/deps/v8/test/cctest/test-list.cc
@@ -27,8 +27,8 @@
#include <stdlib.h>
#include <string.h>
-#include "v8.h"
-#include "cctest.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-liveedit.cc b/deps/v8/test/cctest/test-liveedit.cc
index 1c64108c8..f5c22743b 100644
--- a/deps/v8/test/cctest/test-liveedit.cc
+++ b/deps/v8/test/cctest/test-liveedit.cc
@@ -27,10 +27,10 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "liveedit.h"
-#include "cctest.h"
+#include "src/liveedit.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -117,12 +117,12 @@ void CompareStringsOneWay(const char* s1, const char* s2,
int similar_part_length = diff_pos1 - pos1;
int diff_pos2 = pos2 + similar_part_length;
- ASSERT_EQ(diff_pos2, chunk->pos2);
+ DCHECK_EQ(diff_pos2, chunk->pos2);
for (int j = 0; j < similar_part_length; j++) {
- ASSERT(pos1 + j < len1);
- ASSERT(pos2 + j < len2);
- ASSERT_EQ(s1[pos1 + j], s2[pos2 + j]);
+ DCHECK(pos1 + j < len1);
+ DCHECK(pos2 + j < len2);
+ DCHECK_EQ(s1[pos1 + j], s2[pos2 + j]);
}
diff_parameter += chunk->len1 + chunk->len2;
pos1 = diff_pos1 + chunk->len1;
@@ -131,17 +131,17 @@ void CompareStringsOneWay(const char* s1, const char* s2,
{
// After last chunk.
int similar_part_length = len1 - pos1;
- ASSERT_EQ(similar_part_length, len2 - pos2);
+ DCHECK_EQ(similar_part_length, len2 - pos2);
USE(len2);
for (int j = 0; j < similar_part_length; j++) {
- ASSERT(pos1 + j < len1);
- ASSERT(pos2 + j < len2);
- ASSERT_EQ(s1[pos1 + j], s2[pos2 + j]);
+ DCHECK(pos1 + j < len1);
+ DCHECK(pos2 + j < len2);
+ DCHECK_EQ(s1[pos1 + j], s2[pos2 + j]);
}
}
if (expected_diff_parameter != -1) {
- ASSERT_EQ(expected_diff_parameter, diff_parameter);
+ DCHECK_EQ(expected_diff_parameter, diff_parameter);
}
}
diff --git a/deps/v8/test/cctest/test-lockers.cc b/deps/v8/test/cctest/test-lockers.cc
index 12b35a5c4..ed315cea3 100644
--- a/deps/v8/test/cctest/test-lockers.cc
+++ b/deps/v8/test/cctest/test-lockers.cc
@@ -27,19 +27,19 @@
#include <limits.h>
-#include "v8.h"
-
-#include "api.h"
-#include "isolate.h"
-#include "compilation-cache.h"
-#include "execution.h"
-#include "smart-pointers.h"
-#include "snapshot.h"
-#include "platform.h"
-#include "utils.h"
-#include "cctest.h"
-#include "parser.h"
-#include "unicode-inl.h"
+#include "src/v8.h"
+
+#include "src/api.h"
+#include "src/base/platform/platform.h"
+#include "src/compilation-cache.h"
+#include "src/execution.h"
+#include "src/isolate.h"
+#include "src/parser.h"
+#include "src/smart-pointers.h"
+#include "src/snapshot.h"
+#include "src/unicode-inl.h"
+#include "src/utils.h"
+#include "test/cctest/cctest.h"
using ::v8::Context;
using ::v8::Extension;
@@ -56,10 +56,10 @@ using ::v8::V8;
// Migrating an isolate
-class KangarooThread : public v8::internal::Thread {
+class KangarooThread : public v8::base::Thread {
public:
KangarooThread(v8::Isolate* isolate, v8::Handle<v8::Context> context)
- : Thread("KangarooThread"),
+ : Thread(Options("KangarooThread")),
isolate_(isolate),
context_(isolate, context) {}
@@ -146,12 +146,11 @@ class JoinableThread {
virtual void Run() = 0;
private:
- class ThreadWithSemaphore : public i::Thread {
+ class ThreadWithSemaphore : public v8::base::Thread {
public:
explicit ThreadWithSemaphore(JoinableThread* joinable_thread)
- : Thread(joinable_thread->name_),
- joinable_thread_(joinable_thread) {
- }
+ : Thread(Options(joinable_thread->name_)),
+ joinable_thread_(joinable_thread) {}
virtual void Run() {
joinable_thread_->Run();
@@ -163,7 +162,7 @@ class JoinableThread {
};
const char* name_;
- i::Semaphore semaphore_;
+ v8::base::Semaphore semaphore_;
ThreadWithSemaphore thread_;
friend class ThreadWithSemaphore;
@@ -223,9 +222,7 @@ TEST(IsolateLockingStress) {
class IsolateNonlockingThread : public JoinableThread {
public:
- explicit IsolateNonlockingThread()
- : JoinableThread("IsolateNonlockingThread") {
- }
+ IsolateNonlockingThread() : JoinableThread("IsolateNonlockingThread") {}
virtual void Run() {
v8::Isolate* isolate = v8::Isolate::New();
@@ -247,6 +244,8 @@ class IsolateNonlockingThread : public JoinableThread {
TEST(MultithreadedParallelIsolates) {
#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
const int kNThreads = 10;
+#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
+ const int kNThreads = 4;
#else
const int kNThreads = 50;
#endif
@@ -713,6 +712,8 @@ class IsolateGenesisThread : public JoinableThread {
TEST(ExtensionsRegistration) {
#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
const int kNThreads = 10;
+#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
+ const int kNThreads = 4;
#else
const int kNThreads = 40;
#endif
diff --git a/deps/v8/test/cctest/test-log-stack-tracer.cc b/deps/v8/test/cctest/test-log-stack-tracer.cc
index 5b6858e55..334a20105 100644
--- a/deps/v8/test/cctest/test-log-stack-tracer.cc
+++ b/deps/v8/test/cctest/test-log-stack-tracer.cc
@@ -29,17 +29,17 @@
#include <stdlib.h>
-#include "v8.h"
-
-#include "api.h"
-#include "cctest.h"
-#include "codegen.h"
-#include "disassembler.h"
-#include "isolate.h"
-#include "log.h"
-#include "sampler.h"
-#include "trace-extension.h"
-#include "vm-state-inl.h"
+#include "src/v8.h"
+
+#include "src/api.h"
+#include "src/codegen.h"
+#include "src/disassembler.h"
+#include "src/isolate.h"
+#include "src/log.h"
+#include "src/sampler.h"
+#include "src/vm-state-inl.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/trace-extension.h"
using v8::Function;
using v8::Local;
@@ -119,12 +119,12 @@ static void CreateTraceCallerFunction(v8::Local<v8::Context> context,
const char* func_name,
const char* trace_func_name) {
i::EmbeddedVector<char, 256> trace_call_buf;
- i::OS::SNPrintF(trace_call_buf,
- "function %s() {"
- " fp = new FPGrabber();"
- " %s(fp.low_bits, fp.high_bits);"
- "}",
- func_name, trace_func_name);
+ i::SNPrintF(trace_call_buf,
+ "function %s() {"
+ " fp = new FPGrabber();"
+ " %s(fp.low_bits, fp.high_bits);"
+ "}",
+ func_name, trace_func_name);
// Create the FPGrabber function, which grabs the caller's frame pointer
// when called as a constructor.
@@ -172,7 +172,7 @@ TEST(CFromJSStackTrace) {
CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::Trace), sample.external_callback);
// Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace"
- int base = 0;
+ unsigned base = 0;
CHECK_GT(sample.frames_count, base + 1);
CHECK(IsAddressWithinFuncCode(
@@ -225,7 +225,7 @@ TEST(PureJSStackTrace) {
CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::JSTrace), sample.external_callback);
// Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace"
- int base = 0;
+ unsigned base = 0;
CHECK_GT(sample.frames_count, base + 1);
CHECK(IsAddressWithinFuncCode(context, "JSTrace", sample.stack[base + 0]));
CHECK(IsAddressWithinFuncCode(
diff --git a/deps/v8/test/cctest/test-log.cc b/deps/v8/test/cctest/test-log.cc
index e6ed75e64..d72e6f0e1 100644
--- a/deps/v8/test/cctest/test-log.cc
+++ b/deps/v8/test/cctest/test-log.cc
@@ -34,15 +34,16 @@
#include <cmath>
#endif // __linux__
-#include "v8.h"
-#include "log.h"
-#include "log-utils.h"
-#include "cpu-profiler.h"
-#include "natives.h"
-#include "utils.h"
-#include "v8threads.h"
-#include "cctest.h"
-#include "vm-state-inl.h"
+#include "src/v8.h"
+
+#include "src/cpu-profiler.h"
+#include "src/log.h"
+#include "src/log-utils.h"
+#include "src/natives.h"
+#include "src/utils.h"
+#include "src/v8threads.h"
+#include "src/vm-state-inl.h"
+#include "test/cctest/cctest.h"
using v8::internal::Address;
using v8::internal::EmbeddedVector;
@@ -112,7 +113,7 @@ class ScopedLoggerInitializer {
static const char* StrNStr(const char* s1, const char* s2, int n) {
if (s1[n] == '\0') return strstr(s1, s2);
i::ScopedVector<char> str(n + 1);
- i::OS::StrNCpy(str, s1, static_cast<size_t>(n));
+ i::StrNCpy(str, s1, static_cast<size_t>(n));
str[n] = '\0';
char* found = strstr(str.start(), s2);
return found != NULL ? s1 + (found - str.start()) : NULL;
@@ -358,9 +359,9 @@ TEST(LogCallbacks) {
CHECK(exists);
i::EmbeddedVector<char, 100> ref_data;
- i::OS::SNPrintF(ref_data,
- "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"method1\"\0",
- ObjMethod1);
+ i::SNPrintF(ref_data,
+ "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"method1\"",
+ reinterpret_cast<intptr_t>(ObjMethod1));
CHECK_NE(NULL, StrNStr(log.start(), ref_data.start(), log.length()));
log.Dispose();
@@ -402,23 +403,23 @@ TEST(LogAccessorCallbacks) {
CHECK(exists);
EmbeddedVector<char, 100> prop1_getter_record;
- i::OS::SNPrintF(prop1_getter_record,
- "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop1\"",
- Prop1Getter);
+ i::SNPrintF(prop1_getter_record,
+ "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop1\"",
+ reinterpret_cast<intptr_t>(Prop1Getter));
CHECK_NE(NULL,
StrNStr(log.start(), prop1_getter_record.start(), log.length()));
EmbeddedVector<char, 100> prop1_setter_record;
- i::OS::SNPrintF(prop1_setter_record,
- "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"set prop1\"",
- Prop1Setter);
+ i::SNPrintF(prop1_setter_record,
+ "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"set prop1\"",
+ reinterpret_cast<intptr_t>(Prop1Setter));
CHECK_NE(NULL,
StrNStr(log.start(), prop1_setter_record.start(), log.length()));
EmbeddedVector<char, 100> prop2_getter_record;
- i::OS::SNPrintF(prop2_getter_record,
- "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop2\"",
- Prop2Getter);
+ i::SNPrintF(prop2_getter_record,
+ "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop2\"",
+ reinterpret_cast<intptr_t>(Prop2Getter));
CHECK_NE(NULL,
StrNStr(log.start(), prop2_getter_record.start(), log.length()));
log.Dispose();
diff --git a/deps/v8/test/cctest/test-macro-assembler-arm.cc b/deps/v8/test/cctest/test-macro-assembler-arm.cc
index 8aed4c27b..2cfad0df8 100644
--- a/deps/v8/test/cctest/test-macro-assembler-arm.cc
+++ b/deps/v8/test/cctest/test-macro-assembler-arm.cc
@@ -27,11 +27,13 @@
#include <stdlib.h>
-#include "v8.h"
-#include "macro-assembler.h"
-#include "arm/macro-assembler-arm.h"
-#include "arm/simulator-arm.h"
-#include "cctest.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/macro-assembler.h"
+
+#include "src/arm/macro-assembler-arm.h"
+#include "src/arm/simulator-arm.h"
using namespace v8::internal;
@@ -66,10 +68,12 @@ TEST(CopyBytes) {
size_t act_size;
// Allocate two blocks to copy data between.
- byte* src_buffer = static_cast<byte*>(OS::Allocate(data_size, &act_size, 0));
+ byte* src_buffer =
+ static_cast<byte*>(v8::base::OS::Allocate(data_size, &act_size, 0));
CHECK(src_buffer);
CHECK(act_size >= static_cast<size_t>(data_size));
- byte* dest_buffer = static_cast<byte*>(OS::Allocate(data_size, &act_size, 0));
+ byte* dest_buffer =
+ static_cast<byte*>(v8::base::OS::Allocate(data_size, &act_size, 0));
CHECK(dest_buffer);
CHECK(act_size >= static_cast<size_t>(data_size));
@@ -137,9 +141,8 @@ TEST(LoadAndStoreWithRepresentation) {
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
diff --git a/deps/v8/test/cctest/test-macro-assembler-ia32.cc b/deps/v8/test/cctest/test-macro-assembler-ia32.cc
index 3ad52712c..4d3757991 100644
--- a/deps/v8/test/cctest/test-macro-assembler-ia32.cc
+++ b/deps/v8/test/cctest/test-macro-assembler-ia32.cc
@@ -27,13 +27,13 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
-#include "macro-assembler.h"
-#include "factory.h"
-#include "platform.h"
-#include "serialize.h"
-#include "cctest.h"
+#include "src/base/platform/platform.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "src/serialize.h"
using namespace v8::internal;
@@ -54,9 +54,8 @@ TEST(LoadAndStoreWithRepresentation) {
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -123,20 +122,17 @@ TEST(LoadAndStoreWithRepresentation) {
__ j(not_equal, &exit);
// Test 5.
- if (CpuFeatures::IsSupported(SSE2)) {
- CpuFeatureScope scope(masm, SSE2);
- __ mov(eax, Immediate(5)); // Test XMM move immediate.
- __ Move(xmm0, 0.0);
- __ Move(xmm1, 0.0);
- __ ucomisd(xmm0, xmm1);
- __ j(not_equal, &exit);
- __ Move(xmm2, 991.01);
- __ ucomisd(xmm0, xmm2);
- __ j(equal, &exit);
- __ Move(xmm0, 991.01);
- __ ucomisd(xmm0, xmm2);
- __ j(not_equal, &exit);
- }
+ __ mov(eax, Immediate(5)); // Test XMM move immediate.
+ __ Move(xmm0, 0.0);
+ __ Move(xmm1, 0.0);
+ __ ucomisd(xmm0, xmm1);
+ __ j(not_equal, &exit);
+ __ Move(xmm2, 991.01);
+ __ ucomisd(xmm0, xmm2);
+ __ j(equal, &exit);
+ __ Move(xmm0, 991.01);
+ __ ucomisd(xmm0, xmm2);
+ __ j(not_equal, &exit);
// Test 6.
__ mov(eax, Immediate(6));
diff --git a/deps/v8/test/cctest/test-macro-assembler-mips.cc b/deps/v8/test/cctest/test-macro-assembler-mips.cc
index a5045a8f0..33a461154 100644
--- a/deps/v8/test/cctest/test-macro-assembler-mips.cc
+++ b/deps/v8/test/cctest/test-macro-assembler-mips.cc
@@ -27,11 +27,12 @@
#include <stdlib.h>
-#include "v8.h"
-#include "macro-assembler.h"
-#include "mips/macro-assembler-mips.h"
-#include "mips/simulator-mips.h"
-#include "cctest.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/macro-assembler.h"
+#include "src/mips/macro-assembler-mips.h"
+#include "src/mips/simulator-mips.h"
using namespace v8::internal;
@@ -66,10 +67,12 @@ TEST(CopyBytes) {
size_t act_size;
// Allocate two blocks to copy data between.
- byte* src_buffer = static_cast<byte*>(OS::Allocate(data_size, &act_size, 0));
+ byte* src_buffer =
+ static_cast<byte*>(v8::base::OS::Allocate(data_size, &act_size, 0));
CHECK(src_buffer);
CHECK(act_size >= static_cast<size_t>(data_size));
- byte* dest_buffer = static_cast<byte*>(OS::Allocate(data_size, &act_size, 0));
+ byte* dest_buffer =
+ static_cast<byte*>(v8::base::OS::Allocate(data_size, &act_size, 0));
CHECK(dest_buffer);
CHECK(act_size >= static_cast<size_t>(data_size));
diff --git a/deps/v8/test/cctest/test-macro-assembler-mips64.cc b/deps/v8/test/cctest/test-macro-assembler-mips64.cc
new file mode 100644
index 000000000..eef658de6
--- /dev/null
+++ b/deps/v8/test/cctest/test-macro-assembler-mips64.cc
@@ -0,0 +1,217 @@
+// 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 <stdlib.h>
+
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/macro-assembler.h"
+#include "src/mips64/macro-assembler-mips64.h"
+#include "src/mips64/simulator-mips64.h"
+
+
+using namespace v8::internal;
+
+typedef void* (*F)(int64_t x, int64_t y, int p2, int p3, int p4);
+
+#define __ masm->
+
+
+static byte to_non_zero(int n) {
+ return static_cast<unsigned>(n) % 255 + 1;
+}
+
+
+static bool all_zeroes(const byte* beg, const byte* end) {
+ CHECK(beg);
+ CHECK(beg <= end);
+ while (beg < end) {
+ if (*beg++ != 0)
+ return false;
+ }
+ return true;
+}
+
+
+TEST(CopyBytes) {
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ HandleScope handles(isolate);
+
+ const int data_size = 1 * KB;
+ size_t act_size;
+
+ // Allocate two blocks to copy data between.
+ byte* src_buffer =
+ static_cast<byte*>(v8::base::OS::Allocate(data_size, &act_size, 0));
+ CHECK(src_buffer);
+ CHECK(act_size >= static_cast<size_t>(data_size));
+ byte* dest_buffer =
+ static_cast<byte*>(v8::base::OS::Allocate(data_size, &act_size, 0));
+ CHECK(dest_buffer);
+ CHECK(act_size >= static_cast<size_t>(data_size));
+
+ // Storage for a0 and a1.
+ byte* a0_;
+ byte* a1_;
+
+ MacroAssembler assembler(isolate, NULL, 0);
+ MacroAssembler* masm = &assembler;
+
+ // Code to be generated: The stuff in CopyBytes followed by a store of a0 and
+ // a1, respectively.
+ __ CopyBytes(a0, a1, a2, a3);
+ __ li(a2, Operand(reinterpret_cast<int64_t>(&a0_)));
+ __ li(a3, Operand(reinterpret_cast<int64_t>(&a1_)));
+ __ sd(a0, MemOperand(a2));
+ __ jr(ra);
+ __ sd(a1, MemOperand(a3));
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ ::F f = FUNCTION_CAST< ::F>(code->entry());
+
+ // Initialise source data with non-zero bytes.
+ for (int i = 0; i < data_size; i++) {
+ src_buffer[i] = to_non_zero(i);
+ }
+
+ const int fuzz = 11;
+
+ for (int size = 0; size < 600; size++) {
+ for (const byte* src = src_buffer; src < src_buffer + fuzz; src++) {
+ for (byte* dest = dest_buffer; dest < dest_buffer + fuzz; dest++) {
+ memset(dest_buffer, 0, data_size);
+ CHECK(dest + size < dest_buffer + data_size);
+ (void) CALL_GENERATED_CODE(f, reinterpret_cast<int64_t>(src),
+ reinterpret_cast<int64_t>(dest),
+ size, 0, 0);
+ // a0 and a1 should point at the first byte after the copied data.
+ CHECK_EQ(src + size, a0_);
+ CHECK_EQ(dest + size, a1_);
+ // Check that we haven't written outside the target area.
+ CHECK(all_zeroes(dest_buffer, dest));
+ CHECK(all_zeroes(dest + size, dest_buffer + data_size));
+ // Check the target area.
+ CHECK_EQ(0, memcmp(src, dest, size));
+ }
+ }
+ }
+
+ // Check that the source data hasn't been clobbered.
+ for (int i = 0; i < data_size; i++) {
+ CHECK(src_buffer[i] == to_non_zero(i));
+ }
+}
+
+
+TEST(LoadConstants) {
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ HandleScope handles(isolate);
+
+ int64_t refConstants[64];
+ int64_t result[64];
+
+ int64_t mask = 1;
+ for (int i = 0; i < 64; i++) {
+ refConstants[i] = ~(mask << i);
+ }
+
+ MacroAssembler assembler(isolate, NULL, 0);
+ MacroAssembler* masm = &assembler;
+
+ __ mov(a4, a0);
+ for (int i = 0; i < 64; i++) {
+ // Load constant.
+ __ li(a5, Operand(refConstants[i]));
+ __ sd(a5, MemOperand(a4));
+ __ Daddu(a4, a4, Operand(kPointerSize));
+ }
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ ::F f = FUNCTION_CAST< ::F>(code->entry());
+ (void) CALL_GENERATED_CODE(f, reinterpret_cast<int64_t>(result),
+ 0, 0, 0, 0);
+ // Check results.
+ for (int i = 0; i < 64; i++) {
+ CHECK(refConstants[i] == result[i]);
+ }
+}
+
+
+TEST(LoadAddress) {
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ HandleScope handles(isolate);
+
+ MacroAssembler assembler(isolate, NULL, 0);
+ MacroAssembler* masm = &assembler;
+ Label to_jump, skip;
+ __ mov(a4, a0);
+
+ __ Branch(&skip);
+ __ bind(&to_jump);
+ __ nop();
+ __ nop();
+ __ jr(ra);
+ __ nop();
+ __ bind(&skip);
+ __ li(a4, Operand(masm->jump_address(&to_jump)), ADDRESS_LOAD);
+ int check_size = masm->InstructionsGeneratedSince(&skip);
+ CHECK_EQ(check_size, 4);
+ __ jr(a4);
+ __ nop();
+ __ stop("invalid");
+ __ stop("invalid");
+ __ stop("invalid");
+ __ stop("invalid");
+ __ stop("invalid");
+
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ ::F f = FUNCTION_CAST< ::F>(code->entry());
+ (void) CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0);
+ // Check results.
+}
+
+#undef __
diff --git a/deps/v8/test/cctest/test-macro-assembler-x64.cc b/deps/v8/test/cctest/test-macro-assembler-x64.cc
index 609bc6995..2c0e91805 100644
--- a/deps/v8/test/cctest/test-macro-assembler-x64.cc
+++ b/deps/v8/test/cctest/test-macro-assembler-x64.cc
@@ -27,13 +27,13 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "macro-assembler.h"
-#include "factory.h"
-#include "platform.h"
-#include "serialize.h"
-#include "cctest.h"
+#include "src/base/platform/platform.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "src/serialize.h"
+#include "test/cctest/cctest.h"
namespace i = v8::internal;
using i::Address;
@@ -46,7 +46,6 @@ using i::Immediate;
using i::Isolate;
using i::Label;
using i::MacroAssembler;
-using i::OS;
using i::Operand;
using i::RelocInfo;
using i::Representation;
@@ -157,9 +156,8 @@ TEST(SmiMove) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -207,7 +205,7 @@ void TestSmiCompare(MacroAssembler* masm, Label* exit, int id, int x, int y) {
__ movl(rax, Immediate(id + 2));
__ j(less_equal, exit);
} else {
- ASSERT_EQ(x, y);
+ DCHECK_EQ(x, y);
__ movl(rax, Immediate(id + 3));
__ j(not_equal, exit);
}
@@ -224,7 +222,7 @@ void TestSmiCompare(MacroAssembler* masm, Label* exit, int id, int x, int y) {
__ movl(rax, Immediate(id + 9));
__ j(greater_equal, exit);
} else {
- ASSERT(y > x);
+ DCHECK(y > x);
__ movl(rax, Immediate(id + 10));
__ j(less_equal, exit);
}
@@ -244,10 +242,8 @@ TEST(SmiCompare) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 2, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -295,9 +291,8 @@ TEST(Integer32ToSmi) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -399,7 +394,7 @@ void TestI64PlusConstantToSmi(MacroAssembler* masm,
int64_t x,
int y) {
int64_t result = x + y;
- ASSERT(Smi::IsValid(result));
+ DCHECK(Smi::IsValid(result));
__ movl(rax, Immediate(id));
__ Move(r8, Smi::FromInt(static_cast<int>(result)));
__ movq(rcx, x);
@@ -423,9 +418,8 @@ TEST(Integer64PlusConstantToSmi) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -467,9 +461,8 @@ TEST(SmiCheck) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -714,10 +707,8 @@ TEST(SmiNeg) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -820,7 +811,7 @@ static void SmiAddOverflowTest(MacroAssembler* masm,
int id,
int x) {
// Adds a Smi to x so that the addition overflows.
- ASSERT(x != 0); // Can't overflow by adding a Smi.
+ DCHECK(x != 0); // Can't overflow by adding a Smi.
int y_max = (x > 0) ? (Smi::kMaxValue + 0) : (Smi::kMinValue - x - 1);
int y_min = (x > 0) ? (Smi::kMaxValue - x + 1) : (Smi::kMinValue + 0);
@@ -930,10 +921,8 @@ TEST(SmiAdd) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 3,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 3, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -1039,7 +1028,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm,
int id,
int x) {
// Subtracts a Smi from x so that the subtraction overflows.
- ASSERT(x != -1); // Can't overflow by subtracting a Smi.
+ DCHECK(x != -1); // Can't overflow by subtracting a Smi.
int y_max = (x < 0) ? (Smi::kMaxValue + 0) : (Smi::kMinValue + 0);
int y_min = (x < 0) ? (Smi::kMaxValue + x + 2) : (Smi::kMinValue + x);
@@ -1151,10 +1140,8 @@ TEST(SmiSub) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 4,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 4, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -1242,9 +1229,8 @@ TEST(SmiMul) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -1347,10 +1333,8 @@ TEST(SmiDiv) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 2, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -1457,10 +1441,8 @@ TEST(SmiMod) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 2, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -1515,7 +1497,7 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) {
for (int i = 0; i < 8; i++) {
__ Move(rcx, Smi::FromInt(x));
SmiIndex index = masm->SmiToIndex(rdx, rcx, i);
- ASSERT(index.reg.is(rcx) || index.reg.is(rdx));
+ DCHECK(index.reg.is(rcx) || index.reg.is(rdx));
__ shlq(index.reg, Immediate(index.scale));
__ Set(r8, static_cast<intptr_t>(x) << i);
__ cmpq(index.reg, r8);
@@ -1523,7 +1505,7 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) {
__ incq(rax);
__ Move(rcx, Smi::FromInt(x));
index = masm->SmiToIndex(rcx, rcx, i);
- ASSERT(index.reg.is(rcx));
+ DCHECK(index.reg.is(rcx));
__ shlq(rcx, Immediate(index.scale));
__ Set(r8, static_cast<intptr_t>(x) << i);
__ cmpq(rcx, r8);
@@ -1532,7 +1514,7 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) {
__ Move(rcx, Smi::FromInt(x));
index = masm->SmiToNegativeIndex(rdx, rcx, i);
- ASSERT(index.reg.is(rcx) || index.reg.is(rdx));
+ DCHECK(index.reg.is(rcx) || index.reg.is(rdx));
__ shlq(index.reg, Immediate(index.scale));
__ Set(r8, static_cast<intptr_t>(-x) << i);
__ cmpq(index.reg, r8);
@@ -1540,7 +1522,7 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) {
__ incq(rax);
__ Move(rcx, Smi::FromInt(x));
index = masm->SmiToNegativeIndex(rcx, rcx, i);
- ASSERT(index.reg.is(rcx));
+ DCHECK(index.reg.is(rcx));
__ shlq(rcx, Immediate(index.scale));
__ Set(r8, static_cast<intptr_t>(-x) << i);
__ cmpq(rcx, r8);
@@ -1554,10 +1536,8 @@ TEST(SmiIndex) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 5,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 5, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -1623,10 +1603,8 @@ TEST(SmiSelectNonSmi) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 2, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -1702,10 +1680,8 @@ TEST(SmiAnd) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 2, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -1783,10 +1759,8 @@ TEST(SmiOr) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 2, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -1866,10 +1840,8 @@ TEST(SmiXor) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 2, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -1933,10 +1905,8 @@ TEST(SmiNot) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -2029,10 +1999,8 @@ TEST(SmiShiftLeft) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 7,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 7, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -2135,10 +2103,8 @@ TEST(SmiShiftLogicalRight) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 5,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 5, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -2204,10 +2170,8 @@ TEST(SmiShiftArithmeticRight) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 3,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 3, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -2239,7 +2203,7 @@ TEST(SmiShiftArithmeticRight) {
void TestPositiveSmiPowerUp(MacroAssembler* masm, Label* exit, int id, int x) {
- ASSERT(x >= 0);
+ DCHECK(x >= 0);
int powers[] = { 0, 1, 2, 3, 8, 16, 24, 31 };
int power_count = 8;
__ movl(rax, Immediate(id));
@@ -2268,10 +2232,8 @@ TEST(PositiveSmiTimesPowerOfTwoToInteger64) {
i::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 4,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 4, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -2311,10 +2273,8 @@ TEST(OperandOffset) {
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize * 2, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
@@ -2665,9 +2625,8 @@ TEST(LoadAndStoreWithRepresentation) {
// Allocate an executable page of memory.
size_t actual_size;
- byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
- &actual_size,
- true));
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
diff --git a/deps/v8/test/cctest/test-macro-assembler-x87.cc b/deps/v8/test/cctest/test-macro-assembler-x87.cc
new file mode 100644
index 000000000..9aa40c0b1
--- /dev/null
+++ b/deps/v8/test/cctest/test-macro-assembler-x87.cc
@@ -0,0 +1,150 @@
+// 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 <stdlib.h>
+
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/base/platform/platform.h"
+#include "src/factory.h"
+#include "src/macro-assembler.h"
+#include "src/serialize.h"
+
+using namespace v8::internal;
+
+#if __GNUC__
+#define STDCALL __attribute__((stdcall))
+#else
+#define STDCALL __stdcall
+#endif
+
+typedef int STDCALL F0Type();
+typedef F0Type* F0;
+
+#define __ masm->
+
+
+TEST(LoadAndStoreWithRepresentation) {
+ v8::internal::V8::Initialize(NULL);
+
+ // Allocate an executable page of memory.
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
+ CHECK(buffer);
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope handles(isolate);
+ MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size));
+ MacroAssembler* masm = &assembler; // Create a pointer for the __ macro.
+ __ push(ebx);
+ __ push(edx);
+ __ sub(esp, Immediate(1 * kPointerSize));
+ Label exit;
+
+ // Test 1.
+ __ mov(eax, Immediate(1)); // Test number.
+ __ mov(Operand(esp, 0 * kPointerSize), Immediate(0));
+ __ mov(ebx, Immediate(-1));
+ __ Store(ebx, Operand(esp, 0 * kPointerSize), Representation::UInteger8());
+ __ mov(ebx, Operand(esp, 0 * kPointerSize));
+ __ mov(edx, Immediate(255));
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+ __ Load(ebx, Operand(esp, 0 * kPointerSize), Representation::UInteger8());
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+
+
+ // Test 2.
+ __ mov(eax, Immediate(2)); // Test number.
+ __ mov(Operand(esp, 0 * kPointerSize), Immediate(0));
+ __ mov(ebx, Immediate(-1));
+ __ Store(ebx, Operand(esp, 0 * kPointerSize), Representation::Integer8());
+ __ mov(ebx, Operand(esp, 0 * kPointerSize));
+ __ mov(edx, Immediate(255));
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+ __ Load(ebx, Operand(esp, 0 * kPointerSize), Representation::Integer8());
+ __ mov(edx, Immediate(-1));
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+
+ // Test 3.
+ __ mov(eax, Immediate(3)); // Test number.
+ __ mov(Operand(esp, 0 * kPointerSize), Immediate(0));
+ __ mov(ebx, Immediate(-1));
+ __ Store(ebx, Operand(esp, 0 * kPointerSize), Representation::Integer16());
+ __ mov(ebx, Operand(esp, 0 * kPointerSize));
+ __ mov(edx, Immediate(65535));
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+ __ Load(edx, Operand(esp, 0 * kPointerSize), Representation::Integer16());
+ __ mov(ebx, Immediate(-1));
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+
+ // Test 4.
+ __ mov(eax, Immediate(4)); // Test number.
+ __ mov(Operand(esp, 0 * kPointerSize), Immediate(0));
+ __ mov(ebx, Immediate(-1));
+ __ Store(ebx, Operand(esp, 0 * kPointerSize), Representation::UInteger16());
+ __ mov(ebx, Operand(esp, 0 * kPointerSize));
+ __ mov(edx, Immediate(65535));
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+ __ Load(edx, Operand(esp, 0 * kPointerSize), Representation::UInteger16());
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+
+ // Test 5.
+ __ mov(eax, Immediate(5));
+ __ Move(edx, Immediate(0)); // Test Move()
+ __ cmp(edx, Immediate(0));
+ __ j(not_equal, &exit);
+ __ Move(ecx, Immediate(-1));
+ __ cmp(ecx, Immediate(-1));
+ __ j(not_equal, &exit);
+ __ Move(ebx, Immediate(0x77));
+ __ cmp(ebx, Immediate(0x77));
+ __ j(not_equal, &exit);
+
+ __ xor_(eax, eax); // Success.
+ __ bind(&exit);
+ __ add(esp, Immediate(1 * kPointerSize));
+ __ pop(edx);
+ __ pop(ebx);
+ __ ret(0);
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ // Call the function from C++.
+ int result = FUNCTION_CAST<F0>(buffer)();
+ CHECK_EQ(0, result);
+}
+
+#undef __
diff --git a/deps/v8/test/cctest/test-mark-compact.cc b/deps/v8/test/cctest/test-mark-compact.cc
index 5f13bd25a..1d4b0d8e7 100644
--- a/deps/v8/test/cctest/test-mark-compact.cc
+++ b/deps/v8/test/cctest/test-mark-compact.cc
@@ -28,21 +28,21 @@
#include <stdlib.h>
#ifdef __linux__
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <errno.h>
#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <unistd.h>
-#include <errno.h>
#endif
#include <utility>
-#include "v8.h"
+#include "src/v8.h"
-#include "full-codegen.h"
-#include "global-handles.h"
-#include "snapshot.h"
-#include "cctest.h"
+#include "src/full-codegen.h"
+#include "src/global-handles.h"
+#include "src/snapshot.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -77,7 +77,7 @@ TEST(MarkingDeque) {
TEST(Promotion) {
CcTest::InitializeVM();
TestHeap* heap = CcTest::test_heap();
- heap->ConfigureHeap(2*256*KB, 1*MB, 1*MB, 0);
+ heap->ConfigureHeap(1, 1, 1, 0);
v8::HandleScope sc(CcTest::isolate());
@@ -92,7 +92,8 @@ TEST(Promotion) {
CHECK(heap->InSpace(*array, NEW_SPACE));
// Call mark compact GC, so array becomes an old object.
- heap->CollectGarbage(OLD_POINTER_SPACE);
+ heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+ heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
// Array now sits in the old space
CHECK(heap->InSpace(*array, OLD_POINTER_SPACE));
@@ -102,7 +103,7 @@ TEST(Promotion) {
TEST(NoPromotion) {
CcTest::InitializeVM();
TestHeap* heap = CcTest::test_heap();
- heap->ConfigureHeap(2*256*KB, 1*MB, 1*MB, 0);
+ heap->ConfigureHeap(1, 1, 1, 0);
v8::HandleScope sc(CcTest::isolate());
@@ -156,12 +157,8 @@ TEST(MarkCompactCollector) {
{ HandleScope scope(isolate);
// allocate a garbage
Handle<String> func_name = factory->InternalizeUtf8String("theFunction");
- Handle<JSFunction> function = factory->NewFunctionWithPrototype(
- func_name, factory->undefined_value());
- Handle<Map> initial_map = factory->NewMap(
- JS_OBJECT_TYPE, JSObject::kHeaderSize);
- function->set_initial_map(*initial_map);
- JSReceiver::SetProperty(global, func_name, function, NONE, SLOPPY).Check();
+ Handle<JSFunction> function = factory->NewFunction(func_name);
+ JSReceiver::SetProperty(global, func_name, function, SLOPPY).Check();
factory->NewJSObject(function);
}
@@ -170,7 +167,9 @@ TEST(MarkCompactCollector) {
{ HandleScope scope(isolate);
Handle<String> func_name = factory->InternalizeUtf8String("theFunction");
- CHECK(JSReceiver::HasLocalProperty(global, func_name));
+ v8::Maybe<bool> maybe = JSReceiver::HasOwnProperty(global, func_name);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
Handle<Object> func_value =
Object::GetProperty(global, func_name).ToHandleChecked();
CHECK(func_value->IsJSFunction());
@@ -178,17 +177,19 @@ TEST(MarkCompactCollector) {
Handle<JSObject> obj = factory->NewJSObject(function);
Handle<String> obj_name = factory->InternalizeUtf8String("theObject");
- JSReceiver::SetProperty(global, obj_name, obj, NONE, SLOPPY).Check();
+ JSReceiver::SetProperty(global, obj_name, obj, SLOPPY).Check();
Handle<String> prop_name = factory->InternalizeUtf8String("theSlot");
Handle<Smi> twenty_three(Smi::FromInt(23), isolate);
- JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, SLOPPY).Check();
+ JSReceiver::SetProperty(obj, prop_name, twenty_three, SLOPPY).Check();
}
heap->CollectGarbage(OLD_POINTER_SPACE, "trigger 5");
{ HandleScope scope(isolate);
Handle<String> obj_name = factory->InternalizeUtf8String("theObject");
- CHECK(JSReceiver::HasLocalProperty(global, obj_name));
+ v8::Maybe<bool> maybe = JSReceiver::HasOwnProperty(global, obj_name);
+ CHECK(maybe.has_value);
+ CHECK(maybe.value);
Handle<Object> object =
Object::GetProperty(global, obj_name).ToHandleChecked();
CHECK(object->IsJSObject());
@@ -240,7 +241,7 @@ static void WeakPointerCallback(
std::pair<v8::Persistent<v8::Value>*, int>* p =
reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>(
data.GetParameter());
- ASSERT_EQ(1234, p->second);
+ DCHECK_EQ(1234, p->second);
NumberOfWeakCalls++;
p->first->Reset();
}
@@ -365,7 +366,7 @@ class TestRetainedObjectInfo : public v8::RetainedObjectInfo {
bool has_been_disposed() { return has_been_disposed_; }
virtual void Dispose() {
- ASSERT(!has_been_disposed_);
+ DCHECK(!has_been_disposed_);
has_been_disposed_ = true;
}
@@ -393,7 +394,7 @@ TEST(EmptyObjectGroups) {
TestRetainedObjectInfo info;
global_handles->AddObjectGroup(NULL, 0, &info);
- ASSERT(info.has_been_disposed());
+ DCHECK(info.has_been_disposed());
global_handles->AddImplicitReferences(
Handle<HeapObject>::cast(object).location(), NULL, 0);
diff --git a/deps/v8/test/cctest/test-mementos.cc b/deps/v8/test/cctest/test-mementos.cc
index a377b4a4c..4c85151b8 100644
--- a/deps/v8/test/cctest/test-mementos.cc
+++ b/deps/v8/test/cctest/test-mementos.cc
@@ -25,7 +25,7 @@
// (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 "cctest.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -89,10 +89,7 @@ TEST(PretenuringCallNew) {
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
- // We need to create several instances to get past the slack-tracking
- // phase, where mementos aren't emitted.
int call_count = 10;
- CHECK_GE(call_count, SharedFunctionInfo::kGenerousAllocationCount);
i::ScopedVector<char> test_buf(1024);
const char* program =
"function f() {"
@@ -105,7 +102,7 @@ TEST(PretenuringCallNew) {
" a = new f();"
"}"
"a;";
- i::OS::SNPrintF(test_buf, program, call_count);
+ i::SNPrintF(test_buf, program, call_count);
v8::Local<v8::Value> res = CompileRun(test_buf.start());
Handle<JSObject> o =
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
@@ -117,8 +114,8 @@ TEST(PretenuringCallNew) {
CHECK_EQ(memento->map(), heap->allocation_memento_map());
// Furthermore, how many mementos did we create? The count should match
- // call_count - SharedFunctionInfo::kGenerousAllocationCount.
+ // call_count. Note, that mementos are allocated during the inobject slack
+ // tracking phase.
AllocationSite* site = memento->GetAllocationSite();
- CHECK_EQ(call_count - SharedFunctionInfo::kGenerousAllocationCount,
- site->pretenure_create_count()->value());
+ CHECK_EQ(call_count, site->pretenure_create_count()->value());
}
diff --git a/deps/v8/test/cctest/test-microtask-delivery.cc b/deps/v8/test/cctest/test-microtask-delivery.cc
index e6f38b79b..082bc1a3e 100644
--- a/deps/v8/test/cctest/test-microtask-delivery.cc
+++ b/deps/v8/test/cctest/test-microtask-delivery.cc
@@ -25,9 +25,9 @@
// (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 "src/v8.h"
-#include "cctest.h"
+#include "test/cctest/cctest.h"
using namespace v8;
namespace i = v8::internal;
diff --git a/deps/v8/test/cctest/test-mutex.cc b/deps/v8/test/cctest/test-mutex.cc
deleted file mode 100644
index cdc829f15..000000000
--- a/deps/v8/test/cctest/test-mutex.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// 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 <cstdlib>
-
-#include "v8.h"
-
-#include "cctest.h"
-#include "platform/mutex.h"
-
-using namespace ::v8::internal;
-
-
-TEST(LockGuardMutex) {
- Mutex mutex;
- { LockGuard<Mutex> lock_guard(&mutex);
- }
- { LockGuard<Mutex> lock_guard(&mutex);
- }
-}
-
-
-TEST(LockGuardRecursiveMutex) {
- RecursiveMutex recursive_mutex;
- { LockGuard<RecursiveMutex> lock_guard(&recursive_mutex);
- }
- { LockGuard<RecursiveMutex> lock_guard1(&recursive_mutex);
- LockGuard<RecursiveMutex> lock_guard2(&recursive_mutex);
- }
-}
-
-
-TEST(LockGuardLazyMutex) {
- LazyMutex lazy_mutex = LAZY_MUTEX_INITIALIZER;
- { LockGuard<Mutex> lock_guard(lazy_mutex.Pointer());
- }
- { LockGuard<Mutex> lock_guard(lazy_mutex.Pointer());
- }
-}
-
-
-TEST(LockGuardLazyRecursiveMutex) {
- LazyRecursiveMutex lazy_recursive_mutex = LAZY_RECURSIVE_MUTEX_INITIALIZER;
- { LockGuard<RecursiveMutex> lock_guard(lazy_recursive_mutex.Pointer());
- }
- { LockGuard<RecursiveMutex> lock_guard1(lazy_recursive_mutex.Pointer());
- LockGuard<RecursiveMutex> lock_guard2(lazy_recursive_mutex.Pointer());
- }
-}
-
-
-TEST(MultipleMutexes) {
- Mutex mutex1;
- Mutex mutex2;
- Mutex mutex3;
- // Order 1
- mutex1.Lock();
- mutex2.Lock();
- mutex3.Lock();
- mutex1.Unlock();
- mutex2.Unlock();
- mutex3.Unlock();
- // Order 2
- mutex1.Lock();
- mutex2.Lock();
- mutex3.Lock();
- mutex3.Unlock();
- mutex2.Unlock();
- mutex1.Unlock();
-}
-
-
-TEST(MultipleRecursiveMutexes) {
- RecursiveMutex recursive_mutex1;
- RecursiveMutex recursive_mutex2;
- // Order 1
- recursive_mutex1.Lock();
- recursive_mutex2.Lock();
- CHECK(recursive_mutex1.TryLock());
- CHECK(recursive_mutex2.TryLock());
- recursive_mutex1.Unlock();
- recursive_mutex1.Unlock();
- recursive_mutex2.Unlock();
- recursive_mutex2.Unlock();
- // Order 2
- recursive_mutex1.Lock();
- CHECK(recursive_mutex1.TryLock());
- recursive_mutex2.Lock();
- CHECK(recursive_mutex2.TryLock());
- recursive_mutex2.Unlock();
- recursive_mutex1.Unlock();
- recursive_mutex2.Unlock();
- recursive_mutex1.Unlock();
-}
diff --git a/deps/v8/test/cctest/test-object-observe.cc b/deps/v8/test/cctest/test-object-observe.cc
index a7b346fc6..679569e27 100644
--- a/deps/v8/test/cctest/test-object-observe.cc
+++ b/deps/v8/test/cctest/test-object-observe.cc
@@ -25,9 +25,9 @@
// (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 "src/v8.h"
-#include "cctest.h"
+#include "test/cctest/cctest.h"
using namespace v8;
namespace i = v8::internal;
@@ -275,8 +275,8 @@ TEST(APITestBasicMutation) {
// Setting an indexed element via the property setting method
obj->Set(Number::New(v8_isolate, 1), Number::New(v8_isolate, 5));
// Setting with a non-String, non-uint32 key
- obj->Set(Number::New(v8_isolate, 1.1),
- Number::New(v8_isolate, 6), DontDelete);
+ obj->ForceSet(Number::New(v8_isolate, 1.1), Number::New(v8_isolate, 6),
+ DontDelete);
obj->Delete(String::NewFromUtf8(v8_isolate, "foo"));
obj->Delete(1);
obj->ForceDelete(Number::New(v8_isolate, 1.1));
@@ -616,7 +616,6 @@ TEST(GetNotifierFromSameOrigin) {
static int GetGlobalObjectsCount() {
- CcTest::heap()->EnsureHeapIsIterable();
int count = 0;
i::HeapIterator it(CcTest::heap());
for (i::HeapObject* object = it.next(); object != NULL; object = it.next())
@@ -659,7 +658,7 @@ TEST(DontLeakContextOnObserve) {
"Object.unobserve(obj, observer);");
}
- v8::V8::ContextDisposedNotification();
+ CcTest::isolate()->ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(1);
}
@@ -680,7 +679,7 @@ TEST(DontLeakContextOnGetNotifier) {
CompileRun("Object.getNotifier(obj);");
}
- v8::V8::ContextDisposedNotification();
+ CcTest::isolate()->ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(1);
}
@@ -707,6 +706,6 @@ TEST(DontLeakContextOnNotifierPerformChange) {
"notifier, 'foo', function(){})");
}
- v8::V8::ContextDisposedNotification();
+ CcTest::isolate()->ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(1);
}
diff --git a/deps/v8/test/cctest/test-ordered-hash-table.cc b/deps/v8/test/cctest/test-ordered-hash-table.cc
index 48a457f5e..bb1e0145b 100644
--- a/deps/v8/test/cctest/test-ordered-hash-table.cc
+++ b/deps/v8/test/cctest/test-ordered-hash-table.cc
@@ -27,34 +27,17 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "cctest.h"
-#include "factory.h"
+#include "src/factory.h"
+#include "test/cctest/cctest.h"
namespace {
using namespace v8::internal;
-void CheckIterResultObject(Isolate* isolate,
- Handle<JSObject> result,
- Handle<Object> value,
- bool done) {
- Handle<Object> value_object =
- Object::GetProperty(isolate, result, "value").ToHandleChecked();
- Handle<Object> done_object =
- Object::GetProperty(isolate, result, "done").ToHandleChecked();
-
- CHECK_EQ(*value_object, *value);
- CHECK(done_object->IsBoolean());
- CHECK_EQ(done_object->BooleanValue(), done);
-}
-
-
TEST(Set) {
- i::FLAG_harmony_collections = true;
-
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
@@ -64,21 +47,22 @@ TEST(Set) {
CHECK_EQ(0, ordered_set->NumberOfElements());
CHECK_EQ(0, ordered_set->NumberOfDeletedElements());
- Handle<JSSetIterator> value_iterator =
- JSSetIterator::Create(ordered_set, JSSetIterator::kKindValues);
- Handle<JSSetIterator> value_iterator_2 =
- JSSetIterator::Create(ordered_set, JSSetIterator::kKindValues);
-
Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
Handle<JSObject> obj = factory->NewJSObjectFromMap(map);
CHECK(!ordered_set->Contains(obj));
ordered_set = OrderedHashSet::Add(ordered_set, obj);
CHECK_EQ(1, ordered_set->NumberOfElements());
CHECK(ordered_set->Contains(obj));
- ordered_set = OrderedHashSet::Remove(ordered_set, obj);
+ bool was_present = false;
+ ordered_set = OrderedHashSet::Remove(ordered_set, obj, &was_present);
+ CHECK(was_present);
CHECK_EQ(0, ordered_set->NumberOfElements());
CHECK(!ordered_set->Contains(obj));
+ // Removing a not-present object should set was_present to false.
+ ordered_set = OrderedHashSet::Remove(ordered_set, obj, &was_present);
+ CHECK(!was_present);
+
// Test for collisions/chaining
Handle<JSObject> obj1 = factory->NewJSObjectFromMap(map);
ordered_set = OrderedHashSet::Add(ordered_set, obj1);
@@ -91,18 +75,6 @@ TEST(Set) {
CHECK(ordered_set->Contains(obj2));
CHECK(ordered_set->Contains(obj3));
- // Test iteration
- CheckIterResultObject(
- isolate, JSSetIterator::Next(value_iterator), obj1, false);
- CheckIterResultObject(
- isolate, JSSetIterator::Next(value_iterator), obj2, false);
- CheckIterResultObject(
- isolate, JSSetIterator::Next(value_iterator), obj3, false);
- CheckIterResultObject(isolate,
- JSSetIterator::Next(value_iterator),
- factory->undefined_value(),
- true);
-
// Test growth
ordered_set = OrderedHashSet::Add(ordered_set, obj);
Handle<JSObject> obj4 = factory->NewJSObjectFromMap(map);
@@ -116,35 +88,21 @@ TEST(Set) {
CHECK_EQ(0, ordered_set->NumberOfDeletedElements());
CHECK_EQ(4, ordered_set->NumberOfBuckets());
- // Test iteration after growth
- CheckIterResultObject(
- isolate, JSSetIterator::Next(value_iterator_2), obj1, false);
- CheckIterResultObject(
- isolate, JSSetIterator::Next(value_iterator_2), obj2, false);
- CheckIterResultObject(
- isolate, JSSetIterator::Next(value_iterator_2), obj3, false);
- CheckIterResultObject(
- isolate, JSSetIterator::Next(value_iterator_2), obj, false);
- CheckIterResultObject(
- isolate, JSSetIterator::Next(value_iterator_2), obj4, false);
- CheckIterResultObject(isolate,
- JSSetIterator::Next(value_iterator_2),
- factory->undefined_value(),
- true);
-
// Test shrinking
- ordered_set = OrderedHashSet::Remove(ordered_set, obj);
- ordered_set = OrderedHashSet::Remove(ordered_set, obj1);
- ordered_set = OrderedHashSet::Remove(ordered_set, obj2);
- ordered_set = OrderedHashSet::Remove(ordered_set, obj3);
+ ordered_set = OrderedHashSet::Remove(ordered_set, obj, &was_present);
+ CHECK(was_present);
+ ordered_set = OrderedHashSet::Remove(ordered_set, obj1, &was_present);
+ CHECK(was_present);
+ ordered_set = OrderedHashSet::Remove(ordered_set, obj2, &was_present);
+ CHECK(was_present);
+ ordered_set = OrderedHashSet::Remove(ordered_set, obj3, &was_present);
+ CHECK(was_present);
CHECK_EQ(1, ordered_set->NumberOfElements());
CHECK_EQ(2, ordered_set->NumberOfBuckets());
}
TEST(Map) {
- i::FLAG_harmony_collections = true;
-
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
@@ -154,11 +112,6 @@ TEST(Map) {
CHECK_EQ(0, ordered_map->NumberOfElements());
CHECK_EQ(0, ordered_map->NumberOfDeletedElements());
- Handle<JSMapIterator> value_iterator =
- JSMapIterator::Create(ordered_map, JSMapIterator::kKindValues);
- Handle<JSMapIterator> key_iterator =
- JSMapIterator::Create(ordered_map, JSMapIterator::kKindKeys);
-
Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
Handle<JSObject> obj = factory->NewJSObjectFromMap(map);
Handle<JSObject> val = factory->NewJSObjectFromMap(map);
@@ -166,8 +119,9 @@ TEST(Map) {
ordered_map = OrderedHashMap::Put(ordered_map, obj, val);
CHECK_EQ(1, ordered_map->NumberOfElements());
CHECK(ordered_map->Lookup(obj)->SameValue(*val));
- ordered_map = OrderedHashMap::Put(
- ordered_map, obj, factory->the_hole_value());
+ bool was_present = false;
+ ordered_map = OrderedHashMap::Remove(ordered_map, obj, &was_present);
+ CHECK(was_present);
CHECK_EQ(0, ordered_map->NumberOfElements());
CHECK(ordered_map->Lookup(obj)->IsTheHole());
@@ -186,18 +140,6 @@ TEST(Map) {
CHECK(ordered_map->Lookup(obj2)->SameValue(*val2));
CHECK(ordered_map->Lookup(obj3)->SameValue(*val3));
- // Test iteration
- CheckIterResultObject(
- isolate, JSMapIterator::Next(value_iterator), val1, false);
- CheckIterResultObject(
- isolate, JSMapIterator::Next(value_iterator), val2, false);
- CheckIterResultObject(
- isolate, JSMapIterator::Next(value_iterator), val3, false);
- CheckIterResultObject(isolate,
- JSMapIterator::Next(value_iterator),
- factory->undefined_value(),
- true);
-
// Test growth
ordered_map = OrderedHashMap::Put(ordered_map, obj, val);
Handle<JSObject> obj4 = factory->NewJSObjectFromMap(map);
@@ -211,31 +153,15 @@ TEST(Map) {
CHECK_EQ(5, ordered_map->NumberOfElements());
CHECK_EQ(4, ordered_map->NumberOfBuckets());
- // Test iteration after growth
- CheckIterResultObject(
- isolate, JSMapIterator::Next(key_iterator), obj1, false);
- CheckIterResultObject(
- isolate, JSMapIterator::Next(key_iterator), obj2, false);
- CheckIterResultObject(
- isolate, JSMapIterator::Next(key_iterator), obj3, false);
- CheckIterResultObject(
- isolate, JSMapIterator::Next(key_iterator), obj, false);
- CheckIterResultObject(
- isolate, JSMapIterator::Next(key_iterator), obj4, false);
- CheckIterResultObject(isolate,
- JSMapIterator::Next(key_iterator),
- factory->undefined_value(),
- true);
-
// Test shrinking
- ordered_map = OrderedHashMap::Put(
- ordered_map, obj, factory->the_hole_value());
- ordered_map = OrderedHashMap::Put(
- ordered_map, obj1, factory->the_hole_value());
- ordered_map = OrderedHashMap::Put(
- ordered_map, obj2, factory->the_hole_value());
- ordered_map = OrderedHashMap::Put(
- ordered_map, obj3, factory->the_hole_value());
+ ordered_map = OrderedHashMap::Remove(ordered_map, obj, &was_present);
+ CHECK(was_present);
+ ordered_map = OrderedHashMap::Remove(ordered_map, obj1, &was_present);
+ CHECK(was_present);
+ ordered_map = OrderedHashMap::Remove(ordered_map, obj2, &was_present);
+ CHECK(was_present);
+ ordered_map = OrderedHashMap::Remove(ordered_map, obj3, &was_present);
+ CHECK(was_present);
CHECK_EQ(1, ordered_map->NumberOfElements());
CHECK_EQ(2, ordered_map->NumberOfBuckets());
}
diff --git a/deps/v8/test/cctest/test-ostreams.cc b/deps/v8/test/cctest/test-ostreams.cc
new file mode 100644
index 000000000..c83f96d46
--- /dev/null
+++ b/deps/v8/test/cctest/test-ostreams.cc
@@ -0,0 +1,148 @@
+// 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.h>
+#include <limits>
+
+#include "include/v8stdint.h"
+#include "src/ostreams.h"
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+
+
+TEST(OStringStreamConstructor) {
+ OStringStream oss;
+ const size_t expected_size = 0;
+ CHECK(expected_size == oss.size());
+ CHECK_GT(oss.capacity(), 0);
+ CHECK_NE(NULL, oss.data());
+ CHECK_EQ("", oss.c_str());
+}
+
+
+#define TEST_STRING \
+ "Ash nazg durbatuluk, " \
+ "ash nazg gimbatul, " \
+ "ash nazg thrakatuluk, " \
+ "agh burzum-ishi krimpatul."
+
+TEST(OStringStreamGrow) {
+ OStringStream oss;
+ const int repeat = 30;
+ size_t len = strlen(TEST_STRING);
+ for (int i = 0; i < repeat; ++i) {
+ oss.write(TEST_STRING, len);
+ }
+ const char* expected =
+ TEST_STRING TEST_STRING TEST_STRING TEST_STRING TEST_STRING
+ TEST_STRING TEST_STRING TEST_STRING TEST_STRING TEST_STRING
+ TEST_STRING TEST_STRING TEST_STRING TEST_STRING TEST_STRING
+ TEST_STRING TEST_STRING TEST_STRING TEST_STRING TEST_STRING
+ TEST_STRING TEST_STRING TEST_STRING TEST_STRING TEST_STRING
+ TEST_STRING TEST_STRING TEST_STRING TEST_STRING TEST_STRING;
+ const size_t expected_len = len * repeat;
+ CHECK(expected_len == oss.size());
+ CHECK_GT(oss.capacity(), 0);
+ CHECK_EQ(0, strncmp(expected, oss.data(), expected_len));
+ CHECK_EQ(expected, oss.c_str());
+}
+
+
+template <class T>
+static void check(const char* expected, T value) {
+ OStringStream oss;
+ oss << value << " " << hex << value;
+ CHECK_EQ(expected, oss.c_str());
+}
+
+
+TEST(NumericFormatting) {
+ check<bool>("0 0", false);
+ check<bool>("1 1", true);
+
+ check<int16_t>("-12345 cfc7", -12345);
+ check<int16_t>("-32768 8000", std::numeric_limits<int16_t>::min());
+ check<int16_t>("32767 7fff", std::numeric_limits<int16_t>::max());
+
+ check<uint16_t>("34567 8707", 34567);
+ check<uint16_t>("0 0", std::numeric_limits<uint16_t>::min());
+ check<uint16_t>("65535 ffff", std::numeric_limits<uint16_t>::max());
+
+ check<int32_t>("-1234567 ffed2979", -1234567);
+ check<int32_t>("-2147483648 80000000", std::numeric_limits<int32_t>::min());
+ check<int32_t>("2147483647 7fffffff", std::numeric_limits<int32_t>::max());
+
+ check<uint32_t>("3456789 34bf15", 3456789);
+ check<uint32_t>("0 0", std::numeric_limits<uint32_t>::min());
+ check<uint32_t>("4294967295 ffffffff", std::numeric_limits<uint32_t>::max());
+
+ check<int64_t>("-1234567 ffffffffffed2979", -1234567);
+ check<int64_t>("-9223372036854775808 8000000000000000",
+ std::numeric_limits<int64_t>::min());
+ check<int64_t>("9223372036854775807 7fffffffffffffff",
+ std::numeric_limits<int64_t>::max());
+
+ check<uint64_t>("3456789 34bf15", 3456789);
+ check<uint64_t>("0 0", std::numeric_limits<uint64_t>::min());
+ check<uint64_t>("18446744073709551615 ffffffffffffffff",
+ std::numeric_limits<uint64_t>::max());
+
+ check<float>("0 0", 0.0f);
+ check<float>("123 123", 123.0f);
+ check<float>("-0.5 -0.5", -0.5f);
+ check<float>("1.25 1.25", 1.25f);
+ check<float>("0.0625 0.0625", 6.25e-2f);
+
+ check<double>("0 0", 0.0);
+ check<double>("123 123", 123.0);
+ check<double>("-0.5 -0.5", -0.5);
+ check<double>("1.25 1.25", 1.25);
+ check<double>("0.0625 0.0625", 6.25e-2);
+}
+
+
+TEST(CharacterOutput) {
+ check<char>("a a", 'a');
+ check<signed char>("B B", 'B');
+ check<unsigned char>("9 9", '9');
+ check<const char*>("bye bye", "bye");
+
+ OStringStream os;
+ os.put('H').write("ello", 4);
+ CHECK_EQ("Hello", os.c_str());
+}
+
+
+TEST(Manipulators) {
+ OStringStream os;
+ os << 123 << hex << 123 << endl << 123 << dec << 123 << 123;
+ CHECK_EQ("1237b\n7b123123", os.c_str());
+}
+
+
+class MiscStuff {
+ public:
+ MiscStuff(int i, double d, const char* s) : i_(i), d_(d), s_(s) { }
+
+ private:
+ friend OStream& operator<<(OStream& os, const MiscStuff& m);
+
+ int i_;
+ double d_;
+ const char* s_;
+};
+
+
+OStream& operator<<(OStream& os, const MiscStuff& m) {
+ return os << "{i:" << m.i_ << ", d:" << m.d_ << ", s:'" << m.s_ << "'}";
+}
+
+
+TEST(CustomOutput) {
+ OStringStream os;
+ MiscStuff m(123, 4.5, "Hurz!");
+ os << m;
+ CHECK_EQ("{i:123, d:4.5, s:'Hurz!'}", os.c_str());
+}
diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc
index 58734d054..9cb5d69e6 100644
--- a/deps/v8/test/cctest/test-parsing.cc
+++ b/deps/v8/test/cctest/test-parsing.cc
@@ -25,22 +25,25 @@
// (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 <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include "v8.h"
+#include "src/v8.h"
+
+#include "src/ast-value-factory.h"
+#include "src/compiler.h"
+#include "src/execution.h"
+#include "src/isolate.h"
+#include "src/objects.h"
+#include "src/parser.h"
+#include "src/preparser.h"
+#include "src/rewriter.h"
+#include "src/scanner-character-streams.h"
+#include "src/token.h"
+#include "src/utils.h"
-#include "cctest.h"
-#include "compiler.h"
-#include "execution.h"
-#include "isolate.h"
-#include "objects.h"
-#include "parser.h"
-#include "preparser.h"
-#include "scanner-character-streams.h"
-#include "token.h"
-#include "utils.h"
+#include "test/cctest/cctest.h"
TEST(ScanKeywords) {
struct KeywordToken {
@@ -84,7 +87,7 @@ TEST(ScanKeywords) {
// Adding characters will make keyword matching fail.
static const char chars_to_append[] = { 'z', '0', '_' };
for (int j = 0; j < static_cast<int>(ARRAY_SIZE(chars_to_append)); ++j) {
- i::OS::MemMove(buffer, keyword, length);
+ i::MemMove(buffer, keyword, length);
buffer[length] = chars_to_append[j];
i::Utf8ToUtf16CharacterStream stream(buffer, length + 1);
i::Scanner scanner(&unicode_cache);
@@ -94,7 +97,7 @@ TEST(ScanKeywords) {
}
// Replacing characters will make keyword matching fail.
{
- i::OS::MemMove(buffer, keyword, length);
+ i::MemMove(buffer, keyword, length);
buffer[length - 1] = '_';
i::Utf8ToUtf16CharacterStream stream(buffer, length);
i::Scanner scanner(&unicode_cache);
@@ -141,9 +144,8 @@ TEST(ScanHTMLEndComments) {
};
// Parser/Scanner needs a stack limit.
- int marker;
- CcTest::i_isolate()->stack_guard()->SetStackLimit(
- reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
+ 128 * 1024);
uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
for (int i = 0; tests[i]; i++) {
const i::byte* source =
@@ -156,8 +158,7 @@ TEST(ScanHTMLEndComments) {
preparser.set_allow_lazy(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
- i::ScriptData data(log.ExtractData());
- CHECK(!data.has_error());
+ CHECK(!log.HasError());
}
for (int i = 0; fail_tests[i]; i++) {
@@ -172,8 +173,7 @@ TEST(ScanHTMLEndComments) {
i::PreParser::PreParseResult result = preparser.PreParseProgram();
// Even in the case of a syntax error, kPreParseSuccess is returned.
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
- i::ScriptData data(log.ExtractData());
- CHECK(data.has_error());
+ CHECK(log.HasError());
}
}
@@ -197,9 +197,8 @@ TEST(UsingCachedData) {
v8::HandleScope handles(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
- int marker;
- CcTest::i_isolate()->stack_guard()->SetStackLimit(
- reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
+ 128 * 1024);
// Source containing functions that might be lazily compiled and all types
// of symbols (string, propertyName, regexp).
@@ -213,23 +212,28 @@ TEST(UsingCachedData) {
"var v = /RegExp Literal/;"
"var w = /RegExp Literal\\u0020With Escape/gin;"
"var y = { get getter() { return 42; }, "
- " set setter(v) { this.value = v; }};";
+ " set setter(v) { this.value = v; }};"
+ "var f = a => function (b) { return a + b; };"
+ "var g = a => b => a + b;";
int source_length = i::StrLength(source);
// ScriptResource will be deleted when the corresponding String is GCd.
v8::ScriptCompiler::Source script_source(v8::String::NewExternal(
isolate, new ScriptResource(source, source_length)));
+ i::FLAG_harmony_arrow_functions = true;
i::FLAG_min_preparse_length = 0;
v8::ScriptCompiler::Compile(isolate, &script_source,
- v8::ScriptCompiler::kProduceDataToCache);
+ v8::ScriptCompiler::kProduceParserCache);
CHECK(script_source.GetCachedData());
// Compile the script again, using the cached data.
bool lazy_flag = i::FLAG_lazy;
i::FLAG_lazy = true;
- v8::ScriptCompiler::Compile(isolate, &script_source);
+ v8::ScriptCompiler::Compile(isolate, &script_source,
+ v8::ScriptCompiler::kConsumeParserCache);
i::FLAG_lazy = false;
- v8::ScriptCompiler::CompileUnbound(isolate, &script_source);
+ v8::ScriptCompiler::CompileUnbound(isolate, &script_source,
+ v8::ScriptCompiler::kConsumeParserCache);
i::FLAG_lazy = lazy_flag;
}
@@ -240,49 +244,55 @@ TEST(PreparseFunctionDataIsUsed) {
// Make preparsing work for short scripts.
i::FLAG_min_preparse_length = 0;
+ i::FLAG_harmony_arrow_functions = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handles(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
- int marker;
- CcTest::i_isolate()->stack_guard()->SetStackLimit(
- reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
+ 128 * 1024);
- const char* good_code =
- "function this_is_lazy() { var a; } function foo() { return 25; } foo();";
+ const char* good_code[] = {
+ "function this_is_lazy() { var a; } function foo() { return 25; } foo();",
+ "var this_is_lazy = () => { var a; }; var foo = () => 25; foo();",
+ };
// Insert a syntax error inside the lazy function.
- const char* bad_code =
- "function this_is_lazy() { if ( } function foo() { return 25; } foo();";
-
- v8::ScriptCompiler::Source good_source(v8_str(good_code));
- v8::ScriptCompiler::Compile(isolate, &good_source,
- v8::ScriptCompiler::kProduceDataToCache);
-
- const v8::ScriptCompiler::CachedData* cached_data =
- good_source.GetCachedData();
- CHECK(cached_data->data != NULL);
- CHECK_GT(cached_data->length, 0);
-
- // Now compile the erroneous code with the good preparse data. If the preparse
- // data is used, the lazy function is skipped and it should compile fine.
- v8::ScriptCompiler::Source bad_source(
- v8_str(bad_code), new v8::ScriptCompiler::CachedData(
- cached_data->data, cached_data->length));
- v8::Local<v8::Value> result =
- v8::ScriptCompiler::Compile(isolate, &bad_source)->Run();
- CHECK(result->IsInt32());
- CHECK_EQ(25, result->Int32Value());
+ const char* bad_code[] = {
+ "function this_is_lazy() { if ( } function foo() { return 25; } foo();",
+ "var this_is_lazy = () => { if ( }; var foo = () => 25; foo();",
+ };
+
+ for (unsigned i = 0; i < ARRAY_SIZE(good_code); i++) {
+ v8::ScriptCompiler::Source good_source(v8_str(good_code[i]));
+ v8::ScriptCompiler::Compile(isolate, &good_source,
+ v8::ScriptCompiler::kProduceDataToCache);
+
+ const v8::ScriptCompiler::CachedData* cached_data =
+ good_source.GetCachedData();
+ CHECK(cached_data->data != NULL);
+ CHECK_GT(cached_data->length, 0);
+
+ // Now compile the erroneous code with the good preparse data. If the
+ // preparse data is used, the lazy function is skipped and it should
+ // compile fine.
+ v8::ScriptCompiler::Source bad_source(
+ v8_str(bad_code[i]), new v8::ScriptCompiler::CachedData(
+ cached_data->data, cached_data->length));
+ v8::Local<v8::Value> result =
+ v8::ScriptCompiler::Compile(isolate, &bad_source)->Run();
+ CHECK(result->IsInt32());
+ CHECK_EQ(25, result->Int32Value());
+ }
}
TEST(StandAlonePreParser) {
v8::V8::Initialize();
- int marker;
- CcTest::i_isolate()->stack_guard()->SetStackLimit(
- reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
+ 128 * 1024);
const char* programs[] = {
"{label: 42}",
@@ -290,6 +300,7 @@ TEST(StandAlonePreParser) {
"function foo(x, y) { return x + y; }",
"%ArgleBargle(glop);",
"var x = new new Function('this.x = 42');",
+ "var f = (x, y) => x + y;",
NULL
};
@@ -306,10 +317,10 @@ TEST(StandAlonePreParser) {
i::PreParser preparser(&scanner, &log, stack_limit);
preparser.set_allow_lazy(true);
preparser.set_allow_natives_syntax(true);
+ preparser.set_allow_arrow_functions(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
- i::ScriptData data(log.ExtractData());
- CHECK(!data.has_error());
+ CHECK(!log.HasError());
}
}
@@ -317,9 +328,8 @@ TEST(StandAlonePreParser) {
TEST(StandAlonePreParserNoNatives) {
v8::V8::Initialize();
- int marker;
- CcTest::i_isolate()->stack_guard()->SetStackLimit(
- reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
+ 128 * 1024);
const char* programs[] = {
"%ArgleBargle(glop);",
@@ -342,9 +352,7 @@ TEST(StandAlonePreParserNoNatives) {
preparser.set_allow_lazy(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
- i::ScriptData data(log.ExtractData());
- // Data contains syntax error.
- CHECK(data.has_error());
+ CHECK(log.HasError());
}
}
@@ -356,13 +364,12 @@ TEST(PreparsingObjectLiterals) {
v8::HandleScope handles(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
- int marker;
- CcTest::i_isolate()->stack_guard()->SetStackLimit(
- reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
+ 128 * 1024);
{
const char* source = "var myo = {if: \"foo\"}; myo.if;";
- v8::Local<v8::Value> result = PreCompileCompileRun(source);
+ v8::Local<v8::Value> result = ParserCacheCompileRun(source);
CHECK(result->IsString());
v8::String::Utf8Value utf8(result);
CHECK_EQ("foo", *utf8);
@@ -370,7 +377,7 @@ TEST(PreparsingObjectLiterals) {
{
const char* source = "var myo = {\"bar\": \"foo\"}; myo[\"bar\"];";
- v8::Local<v8::Value> result = PreCompileCompileRun(source);
+ v8::Local<v8::Value> result = ParserCacheCompileRun(source);
CHECK(result->IsString());
v8::String::Utf8Value utf8(result);
CHECK_EQ("foo", *utf8);
@@ -378,7 +385,7 @@ TEST(PreparsingObjectLiterals) {
{
const char* source = "var myo = {1: \"foo\"}; myo[1];";
- v8::Local<v8::Value> result = PreCompileCompileRun(source);
+ v8::Local<v8::Value> result = ParserCacheCompileRun(source);
CHECK(result->IsString());
v8::String::Utf8Value utf8(result);
CHECK_EQ("foo", *utf8);
@@ -390,9 +397,7 @@ TEST(RegressChromium62639) {
v8::V8::Initialize();
i::Isolate* isolate = CcTest::i_isolate();
- int marker;
- isolate->stack_guard()->SetStackLimit(
- reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ isolate->stack_guard()->SetStackLimit(GetCurrentStackPosition() - 128 * 1024);
const char* program = "var x = 'something';\n"
"escape: function() {}";
@@ -413,8 +418,7 @@ TEST(RegressChromium62639) {
i::PreParser::PreParseResult result = preparser.PreParseProgram();
// Even in the case of a syntax error, kPreParseSuccess is returned.
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
- i::ScriptData data(log.ExtractData());
- CHECK(data.has_error());
+ CHECK(log.HasError());
}
@@ -427,9 +431,7 @@ TEST(Regress928) {
// as with-content, which made it assume that a function inside
// the block could be lazily compiled, and an extra, unexpected,
// entry was added to the data.
- int marker;
- isolate->stack_guard()->SetStackLimit(
- reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ isolate->stack_guard()->SetStackLimit(GetCurrentStackPosition() - 128 * 1024);
const char* program =
"try { } catch (e) { var foo = function () { /* first */ } }"
@@ -446,15 +448,15 @@ TEST(Regress928) {
preparser.set_allow_lazy(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
- i::ScriptData data(log.ExtractData());
- CHECK(!data.has_error());
- data.Initialize();
+ i::ScriptData* sd = log.GetScriptData();
+ i::ParseData pd(sd);
+ pd.Initialize();
int first_function =
static_cast<int>(strstr(program, "function") - program);
int first_lbrace = first_function + i::StrLength("function () ");
CHECK_EQ('{', program[first_lbrace]);
- i::FunctionEntry entry1 = data.GetFunctionEntry(first_lbrace);
+ i::FunctionEntry entry1 = pd.GetFunctionEntry(first_lbrace);
CHECK(!entry1.is_valid());
int second_function =
@@ -462,18 +464,18 @@ TEST(Regress928) {
int second_lbrace =
second_function + i::StrLength("function () ");
CHECK_EQ('{', program[second_lbrace]);
- i::FunctionEntry entry2 = data.GetFunctionEntry(second_lbrace);
+ i::FunctionEntry entry2 = pd.GetFunctionEntry(second_lbrace);
CHECK(entry2.is_valid());
CHECK_EQ('}', program[entry2.end_pos() - 1]);
+ delete sd;
}
TEST(PreParseOverflow) {
v8::V8::Initialize();
- int marker;
- CcTest::i_isolate()->stack_guard()->SetStackLimit(
- reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
+ 128 * 1024);
size_t kProgramSize = 1024 * 1024;
i::SmartArrayPointer<char> program(i::NewArray<char>(kProgramSize + 1));
@@ -491,6 +493,7 @@ TEST(PreParseOverflow) {
i::PreParser preparser(&scanner, &log, stack_limit);
preparser.set_allow_lazy(true);
+ preparser.set_allow_arrow_functions(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
}
@@ -669,7 +672,7 @@ TEST(Utf8CharacterStream) {
i,
unibrow::Utf16::kNoPreviousCharacter);
}
- ASSERT(cursor == kAllUtf8CharsSizeU);
+ DCHECK(cursor == kAllUtf8CharsSizeU);
i::Utf8ToUtf16CharacterStream stream(reinterpret_cast<const i::byte*>(buffer),
kAllUtf8CharsSizeU);
@@ -758,8 +761,8 @@ TEST(StreamScanner) {
i::Token::EOS,
i::Token::ILLEGAL
};
- ASSERT_EQ('{', str2[19]);
- ASSERT_EQ('}', str2[37]);
+ DCHECK_EQ('{', str2[19]);
+ DCHECK_EQ('}', str2[37]);
TestStreamScanner(&stream2, expectations2, 20, 37);
const char* str3 = "{}}}}";
@@ -796,8 +799,12 @@ void TestScanRegExp(const char* re_source, const char* expected) {
CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV);
CHECK(scanner.ScanRegExpPattern(start == i::Token::ASSIGN_DIV));
scanner.Next(); // Current token is now the regexp literal.
+ i::Zone zone(CcTest::i_isolate());
+ i::AstValueFactory ast_value_factory(&zone,
+ CcTest::i_isolate()->heap()->HashSeed());
+ ast_value_factory.Internalize(CcTest::i_isolate());
i::Handle<i::String> val =
- scanner.AllocateInternalizedString(CcTest::i_isolate());
+ scanner.CurrentSymbol(&ast_value_factory)->string();
i::DisallowHeapAllocation no_alloc;
i::String::FlatContent content = val->GetFlatContent();
CHECK(content.IsAscii());
@@ -964,7 +971,13 @@ TEST(ScopePositions) {
" infunction;\n"
" }", "\n"
" more;", i::FUNCTION_SCOPE, i::SLOPPY },
- { " (function fun", "(a,b) { infunction; }", ")();",
+ // TODO(aperez): Change to use i::ARROW_SCOPE when implemented
+ { " start;\n", "(a,b) => a + b", "; more;",
+ i::FUNCTION_SCOPE, i::SLOPPY },
+ { " start;\n", "(a,b) => { return a+b; }", "\nmore;",
+ i::FUNCTION_SCOPE, i::SLOPPY },
+ { " start;\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
i::FUNCTION_SCOPE, i::SLOPPY },
{ " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;",
i::BLOCK_SCOPE, i::STRICT },
@@ -1091,9 +1104,7 @@ TEST(ScopePositions) {
v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
v8::Context::Scope context_scope(context);
- int marker;
- isolate->stack_guard()->SetStackLimit(
- reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ isolate->stack_guard()->SetStackLimit(GetCurrentStackPosition() - 128 * 1024);
for (int i = 0; source_data[i].outer_prefix; i++) {
int kPrefixLen = Utf8LengthHelper(source_data[i].outer_prefix);
@@ -1105,10 +1116,10 @@ TEST(ScopePositions) {
int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen;
int kProgramByteSize = kPrefixByteLen + kInnerByteLen + kSuffixByteLen;
i::ScopedVector<char> program(kProgramByteSize + 1);
- i::OS::SNPrintF(program, "%s%s%s",
- source_data[i].outer_prefix,
- source_data[i].inner_source,
- source_data[i].outer_suffix);
+ i::SNPrintF(program, "%s%s%s",
+ source_data[i].outer_prefix,
+ source_data[i].inner_source,
+ source_data[i].outer_suffix);
// Parse program source.
i::Handle<i::String> source = factory->NewStringFromUtf8(
@@ -1119,6 +1130,7 @@ TEST(ScopePositions) {
i::Parser parser(&info);
parser.set_allow_lazy(true);
parser.set_allow_harmony_scoping(true);
+ parser.set_allow_arrow_functions(true);
info.MarkAsGlobal();
info.SetStrictMode(source_data[i].strict_mode);
parser.Parse();
@@ -1141,20 +1153,41 @@ TEST(ScopePositions) {
}
-i::Handle<i::String> FormatMessage(i::ScriptData* data) {
+const char* ReadString(unsigned* start) {
+ int length = start[0];
+ char* result = i::NewArray<char>(length + 1);
+ for (int i = 0; i < length; i++) {
+ result[i] = start[i + 1];
+ }
+ result[length] = '\0';
+ return result;
+}
+
+
+i::Handle<i::String> FormatMessage(i::Vector<unsigned> data) {
i::Isolate* isolate = CcTest::i_isolate();
i::Factory* factory = isolate->factory();
- const char* message = data->BuildMessage();
+ const char* message =
+ ReadString(&data[i::PreparseDataConstants::kMessageTextPos]);
i::Handle<i::String> format = v8::Utils::OpenHandle(
*v8::String::NewFromUtf8(CcTest::isolate(), message));
- i::Vector<const char*> args = data->BuildArgs();
- i::Handle<i::JSArray> args_array = factory->NewJSArray(args.length());
- for (int i = 0; i < args.length(); i++) {
- i::JSArray::SetElement(
- args_array, i, v8::Utils::OpenHandle(*v8::String::NewFromUtf8(
- CcTest::isolate(), args[i])),
- NONE, i::SLOPPY).Check();
+ int arg_count = data[i::PreparseDataConstants::kMessageArgCountPos];
+ const char* arg = NULL;
+ i::Handle<i::JSArray> args_array;
+ if (arg_count == 1) {
+ // Position after text found by skipping past length field and
+ // length field content words.
+ int pos = i::PreparseDataConstants::kMessageTextPos + 1 +
+ data[i::PreparseDataConstants::kMessageTextPos];
+ arg = ReadString(&data[pos]);
+ args_array = factory->NewJSArray(1);
+ i::JSArray::SetElement(args_array, 0, v8::Utils::OpenHandle(*v8_str(arg)),
+ NONE, i::SLOPPY).Check();
+ } else {
+ CHECK_EQ(0, arg_count);
+ args_array = factory->NewJSArray(0);
}
+
i::Handle<i::JSObject> builtins(isolate->js_builtins_object());
i::Handle<i::Object> format_fun = i::Object::GetProperty(
isolate, builtins, "FormatMessage").ToHandleChecked();
@@ -1162,11 +1195,9 @@ i::Handle<i::String> FormatMessage(i::ScriptData* data) {
i::Handle<i::Object> result = i::Execution::Call(
isolate, format_fun, builtins, 2, arg_handles).ToHandleChecked();
CHECK(result->IsString());
- for (int i = 0; i < args.length(); i++) {
- i::DeleteArray(args[i]);
- }
- i::DeleteArray(args.start());
i::DeleteArray(message);
+ i::DeleteArray(arg);
+ data.Dispose();
return i::Handle<i::String>::cast(result);
}
@@ -1177,8 +1208,8 @@ enum ParserFlag {
kAllowHarmonyScoping,
kAllowModules,
kAllowGenerators,
- kAllowForOf,
- kAllowHarmonyNumericLiterals
+ kAllowHarmonyNumericLiterals,
+ kAllowArrowFunctions
};
@@ -1196,9 +1227,9 @@ void SetParserFlags(i::ParserBase<Traits>* parser,
parser->set_allow_harmony_scoping(flags.Contains(kAllowHarmonyScoping));
parser->set_allow_modules(flags.Contains(kAllowModules));
parser->set_allow_generators(flags.Contains(kAllowGenerators));
- parser->set_allow_for_of(flags.Contains(kAllowForOf));
parser->set_allow_harmony_numeric_literals(
flags.Contains(kAllowHarmonyNumericLiterals));
+ parser->set_allow_arrow_functions(flags.Contains(kAllowArrowFunctions));
}
@@ -1221,7 +1252,8 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
}
- i::ScriptData data(log.ExtractData());
+
+ bool preparse_error = log.HasError();
// Parse the data
i::FunctionLiteral* function;
@@ -1246,7 +1278,7 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
isolate, exception_handle, "message").ToHandleChecked());
if (result == kSuccess) {
- i::OS::Print(
+ v8::base::OS::Print(
"Parser failed on:\n"
"\t%s\n"
"with error:\n"
@@ -1256,8 +1288,8 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
CHECK(false);
}
- if (!data.has_error()) {
- i::OS::Print(
+ if (!preparse_error) {
+ v8::base::OS::Print(
"Parser failed on:\n"
"\t%s\n"
"with error:\n"
@@ -1267,9 +1299,10 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
CHECK(false);
}
// Check that preparser and parser produce the same error.
- i::Handle<i::String> preparser_message = FormatMessage(&data);
+ i::Handle<i::String> preparser_message =
+ FormatMessage(log.ErrorMessageData());
if (!i::String::Equals(message_string, preparser_message)) {
- i::OS::Print(
+ v8::base::OS::Print(
"Expected parser and preparser to produce the same error on:\n"
"\t%s\n"
"However, found the following error messages\n"
@@ -1280,17 +1313,18 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
preparser_message->ToCString().get());
CHECK(false);
}
- } else if (data.has_error()) {
- i::OS::Print(
+ } else if (preparse_error) {
+ v8::base::OS::Print(
"Preparser failed on:\n"
"\t%s\n"
"with error:\n"
"\t%s\n"
"However, the parser succeeded",
- source->ToCString().get(), FormatMessage(&data)->ToCString().get());
+ source->ToCString().get(),
+ FormatMessage(log.ErrorMessageData())->ToCString().get());
CHECK(false);
} else if (result == kError) {
- i::OS::Print(
+ v8::base::OS::Print(
"Expected error on:\n"
"\t%s\n"
"However, parser and preparser succeeded",
@@ -1301,15 +1335,22 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
void TestParserSync(const char* source,
- const ParserFlag* flag_list,
- size_t flag_list_length,
- ParserSyncTestResult result = kSuccessOrError) {
+ const ParserFlag* varying_flags,
+ size_t varying_flags_length,
+ ParserSyncTestResult result = kSuccessOrError,
+ const ParserFlag* always_true_flags = NULL,
+ size_t always_true_flags_length = 0) {
i::Handle<i::String> str =
CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source);
- for (int bits = 0; bits < (1 << flag_list_length); bits++) {
+ for (int bits = 0; bits < (1 << varying_flags_length); bits++) {
i::EnumSet<ParserFlag> flags;
- for (size_t flag_index = 0; flag_index < flag_list_length; flag_index++) {
- if ((bits & (1 << flag_index)) != 0) flags.Add(flag_list[flag_index]);
+ for (size_t flag_index = 0; flag_index < varying_flags_length;
+ ++flag_index) {
+ if ((bits & (1 << flag_index)) != 0) flags.Add(varying_flags[flag_index]);
+ }
+ for (size_t flag_index = 0; flag_index < always_true_flags_length;
+ ++flag_index) {
+ flags.Add(always_true_flags[flag_index]);
}
TestParserSyncWithFlags(str, flags, result);
}
@@ -1390,14 +1431,12 @@ TEST(ParserSync) {
v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
v8::Context::Scope context_scope(context);
- int marker;
- CcTest::i_isolate()->stack_guard()->SetStackLimit(
- reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
+ 128 * 1024);
- static const ParserFlag flags1[] = {
- kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
- kAllowForOf
- };
+ static const ParserFlag flags1[] = {kAllowLazy, kAllowHarmonyScoping,
+ kAllowModules, kAllowGenerators,
+ kAllowArrowFunctions};
for (int i = 0; context_data[i][0] != NULL; ++i) {
for (int j = 0; statement_data[j] != NULL; ++j) {
for (int k = 0; termination_data[k] != NULL; ++k) {
@@ -1410,7 +1449,7 @@ TEST(ParserSync) {
// Plug the source code pieces together.
i::ScopedVector<char> program(kProgramSize + 1);
- int length = i::OS::SNPrintF(program,
+ int length = i::SNPrintF(program,
"label: for (;;) { %s%s%s%s }",
context_data[i][0],
statement_data[j],
@@ -1461,22 +1500,42 @@ void RunParserSyncTest(const char* context_data[][2],
const char* statement_data[],
ParserSyncTestResult result,
const ParserFlag* flags = NULL,
- int flags_len = 0) {
+ int flags_len = 0,
+ const ParserFlag* always_true_flags = NULL,
+ int always_true_flags_len = 0) {
v8::HandleScope handles(CcTest::isolate());
v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
v8::Context::Scope context_scope(context);
- int marker;
- CcTest::i_isolate()->stack_guard()->SetStackLimit(
- reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
+ 128 * 1024);
static const ParserFlag default_flags[] = {
- kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
- kAllowForOf, kAllowNativesSyntax
- };
- if (!flags) {
+ kAllowLazy, kAllowHarmonyScoping, kAllowModules,
+ kAllowGenerators, kAllowNativesSyntax, kAllowArrowFunctions};
+ ParserFlag* generated_flags = NULL;
+ if (flags == NULL) {
flags = default_flags;
flags_len = ARRAY_SIZE(default_flags);
+ if (always_true_flags != NULL) {
+ // Remove always_true_flags from default_flags.
+ CHECK(always_true_flags_len < flags_len);
+ generated_flags = new ParserFlag[flags_len - always_true_flags_len];
+ int flag_index = 0;
+ for (int i = 0; i < flags_len; ++i) {
+ bool use_flag = true;
+ for (int j = 0; j < always_true_flags_len; ++j) {
+ if (flags[i] == always_true_flags[j]) {
+ use_flag = false;
+ break;
+ }
+ }
+ if (use_flag) generated_flags[flag_index++] = flags[i];
+ }
+ CHECK(flag_index == flags_len - always_true_flags_len);
+ flags_len = flag_index;
+ flags = generated_flags;
+ }
}
for (int i = 0; context_data[i][0] != NULL; ++i) {
for (int j = 0; statement_data[j] != NULL; ++j) {
@@ -1487,18 +1546,21 @@ void RunParserSyncTest(const char* context_data[][2],
// Plug the source code pieces together.
i::ScopedVector<char> program(kProgramSize + 1);
- int length = i::OS::SNPrintF(program,
- "%s%s%s",
- context_data[i][0],
- statement_data[j],
- context_data[i][1]);
+ int length = i::SNPrintF(program,
+ "%s%s%s",
+ context_data[i][0],
+ statement_data[j],
+ context_data[i][1]);
CHECK(length == kProgramSize);
TestParserSync(program.start(),
flags,
flags_len,
- result);
+ result,
+ always_true_flags,
+ always_true_flags_len);
}
}
+ delete[] generated_flags;
}
@@ -1526,6 +1588,10 @@ TEST(ErrorsEvalAndArguments) {
"function foo(arguments) { }",
"function foo(bar, eval) { }",
"function foo(bar, arguments) { }",
+ "(eval) => { }",
+ "(arguments) => { }",
+ "(foo, eval) => { }",
+ "(foo, arguments) => { }",
"eval = 1;",
"arguments = 1;",
"var foo = eval = 1;",
@@ -1582,6 +1648,7 @@ TEST(NoErrorsEvalAndArgumentsStrict) {
const char* context_data[][2] = {
{ "\"use strict\";", "" },
{ "function test_func() { \"use strict\";", "}" },
+ { "() => { \"use strict\"; ", "}" },
{ NULL, NULL }
};
@@ -1597,7 +1664,9 @@ TEST(NoErrorsEvalAndArgumentsStrict) {
NULL
};
- RunParserSyncTest(context_data, statement_data, kSuccess);
+ static const ParserFlag always_flags[] = {kAllowArrowFunctions};
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+ always_flags, ARRAY_SIZE(always_flags));
}
@@ -1609,6 +1678,7 @@ TEST(ErrorsFutureStrictReservedWords) {
const char* context_data[][2] = {
{ "\"use strict\";", "" },
{ "function test_func() {\"use strict\"; ", "}"},
+ { "() => { \"use strict\"; ", "}" },
{ NULL, NULL }
};
@@ -1623,10 +1693,13 @@ TEST(ErrorsFutureStrictReservedWords) {
"var foo = interface = 1;",
"++interface;",
"interface++;",
+ "var yield = 13;",
NULL
};
- RunParserSyncTest(context_data, statement_data, kError);
+ static const ParserFlag always_flags[] = {kAllowArrowFunctions};
+ RunParserSyncTest(context_data, statement_data, kError, NULL, 0, always_flags,
+ ARRAY_SIZE(always_flags));
}
@@ -1634,6 +1707,7 @@ TEST(NoErrorsFutureStrictReservedWords) {
const char* context_data[][2] = {
{ "", "" },
{ "function test_func() {", "}"},
+ { "() => {", "}" },
{ NULL, NULL }
};
@@ -1648,10 +1722,13 @@ TEST(NoErrorsFutureStrictReservedWords) {
"var foo = interface = 1;",
"++interface;",
"interface++;",
+ "var yield = 13;",
NULL
};
- RunParserSyncTest(context_data, statement_data, kSuccess);
+ static const ParserFlag always_flags[] = {kAllowArrowFunctions};
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+ always_flags, ARRAY_SIZE(always_flags));
}
@@ -1664,6 +1741,8 @@ TEST(ErrorsReservedWords) {
{ "\"use strict\";", "" },
{ "var eval; function test_func() {", "}"},
{ "var eval; function test_func() {\"use strict\"; ", "}"},
+ { "var eval; () => {", "}"},
+ { "var eval; () => {\"use strict\"; ", "}"},
{ NULL, NULL }
};
@@ -1674,6 +1753,8 @@ TEST(ErrorsReservedWords) {
"function super() { }",
"function foo(super) { }",
"function foo(bar, super) { }",
+ "(super) => { }",
+ "(bar, super) => { }",
"super = 1;",
"var foo = super = 1;",
"++super;",
@@ -1686,12 +1767,47 @@ TEST(ErrorsReservedWords) {
}
-TEST(NoErrorsYieldSloppy) {
+TEST(NoErrorsLetSloppyAllModes) {
+ // In sloppy mode, it's okay to use "let" as identifier.
+ const char* context_data[][2] = {
+ { "", "" },
+ { "function f() {", "}" },
+ { "(function f() {", "})" },
+ { NULL, NULL }
+ };
+
+ const char* statement_data[] = {
+ "var let;",
+ "var foo, let;",
+ "try { } catch (let) { }",
+ "function let() { }",
+ "(function let() { })",
+ "function foo(let) { }",
+ "function foo(bar, let) { }",
+ "let = 1;",
+ "var foo = let = 1;",
+ "let * 2;",
+ "++let;",
+ "let++;",
+ "let: 34",
+ "function let(let) { let: let(let + let(0)); }",
+ "({ let: 1 })",
+ "({ get let() { 1 } })",
+ "let(100)",
+ NULL
+ };
+
+ RunParserSyncTest(context_data, statement_data, kSuccess);
+}
+
+
+TEST(NoErrorsYieldSloppyAllModes) {
// In sloppy mode, it's okay to use "yield" as identifier, *except* inside a
- // generator (see next test).
+ // generator (see other test).
const char* context_data[][2] = {
{ "", "" },
- { "function is_not_gen() {", "}" },
+ { "function not_gen() {", "}" },
+ { "(function not_gen() {", "})" },
{ NULL, NULL }
};
@@ -1700,12 +1816,20 @@ TEST(NoErrorsYieldSloppy) {
"var foo, yield;",
"try { } catch (yield) { }",
"function yield() { }",
+ "(function yield() { })",
"function foo(yield) { }",
"function foo(bar, yield) { }",
"yield = 1;",
"var foo = yield = 1;",
+ "yield * 2;",
"++yield;",
"yield++;",
+ "yield: 34",
+ "function yield(yield) { yield: yield (yield + yield(0)); }",
+ "({ yield: 1 })",
+ "({ get yield() { 1 } })",
+ "yield(100)",
+ "yield[100]",
NULL
};
@@ -1713,9 +1837,15 @@ TEST(NoErrorsYieldSloppy) {
}
-TEST(ErrorsYieldSloppyGenerator) {
+TEST(NoErrorsYieldSloppyGeneratorsEnabled) {
+ // In sloppy mode, it's okay to use "yield" as identifier, *except* inside a
+ // generator (see next test).
const char* context_data[][2] = {
- { "function * is_gen() {", "}" },
+ { "", "" },
+ { "function not_gen() {", "}" },
+ { "function * gen() { function not_gen() {", "} }" },
+ { "(function not_gen() {", "})" },
+ { "(function * gen() { (function not_gen() {", "}) })" },
{ NULL, NULL }
};
@@ -1724,28 +1854,41 @@ TEST(ErrorsYieldSloppyGenerator) {
"var foo, yield;",
"try { } catch (yield) { }",
"function yield() { }",
- // BUG: These should not be allowed, but they are (if kAllowGenerators is
- // set)
- // "function foo(yield) { }",
- // "function foo(bar, yield) { }",
+ "(function yield() { })",
+ "function foo(yield) { }",
+ "function foo(bar, yield) { }",
+ "function * yield() { }",
+ "(function * yield() { })",
"yield = 1;",
"var foo = yield = 1;",
+ "yield * 2;",
"++yield;",
"yield++;",
+ "yield: 34",
+ "function yield(yield) { yield: yield (yield + yield(0)); }",
+ "({ yield: 1 })",
+ "({ get yield() { 1 } })",
+ "yield(100)",
+ "yield[100]",
NULL
};
- // If generators are not allowed, the error will be produced at the '*' token,
- // so this test works both with and without the kAllowGenerators flag.
- RunParserSyncTest(context_data, statement_data, kError);
+ // This test requires kAllowGenerators to succeed.
+ static const ParserFlag always_true_flags[] = { kAllowGenerators };
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+ always_true_flags, 1);
}
TEST(ErrorsYieldStrict) {
const char* context_data[][2] = {
{ "\"use strict\";", "" },
- { "\"use strict\"; function is_not_gen() {", "}" },
+ { "\"use strict\"; function not_gen() {", "}" },
{ "function test_func() {\"use strict\"; ", "}"},
+ { "\"use strict\"; function * gen() { function not_gen() {", "} }" },
+ { "\"use strict\"; (function not_gen() {", "})" },
+ { "\"use strict\"; (function * gen() { (function not_gen() {", "}) })" },
+ { "() => {\"use strict\"; ", "}" },
{ NULL, NULL }
};
@@ -1754,12 +1897,16 @@ TEST(ErrorsYieldStrict) {
"var foo, yield;",
"try { } catch (yield) { }",
"function yield() { }",
+ "(function yield() { })",
"function foo(yield) { }",
"function foo(bar, yield) { }",
+ "function * yield() { }",
+ "(function * yield() { })",
"yield = 1;",
"var foo = yield = 1;",
"++yield;",
"yield++;",
+ "yield: 34;",
NULL
};
@@ -1767,22 +1914,116 @@ TEST(ErrorsYieldStrict) {
}
-TEST(ErrorsYield) {
+TEST(NoErrorsGenerator) {
const char* context_data[][2] = {
- { "function * is_gen() {", "}" },
+ { "function * gen() {", "}" },
+ { "(function * gen() {", "})" },
+ { "(function * () {", "})" },
{ NULL, NULL }
};
const char* statement_data[] = {
- "yield 2;", // this is legal inside generator
- "yield * 2;", // this is legal inside generator
+ // A generator without a body is valid.
+ ""
+ // Valid yield expressions inside generators.
+ "yield 2;",
+ "yield * 2;",
+ "yield * \n 2;",
+ "yield yield 1;",
+ "yield * yield * 1;",
+ "yield 3 + (yield 4);",
+ "yield * 3 + (yield * 4);",
+ "(yield * 3) + (yield * 4);",
+ "yield 3; yield 4;",
+ "yield * 3; yield * 4;",
+ "(function (yield) { })",
+ "yield { yield: 12 }",
+ "yield /* comment */ { yield: 12 }",
+ "yield * \n { yield: 12 }",
+ "yield /* comment */ * \n { yield: 12 }",
+ // You can return in a generator.
+ "yield 1; return",
+ "yield * 1; return",
+ "yield 1; return 37",
+ "yield * 1; return 37",
+ "yield 1; return 37; yield 'dead';",
+ "yield * 1; return 37; yield * 'dead';",
+ // Yield is still a valid key in object literals.
+ "({ yield: 1 })",
+ "({ get yield() { } })",
+ // Yield without RHS.
+ "yield;",
+ "yield",
+ "yield\n",
+ "yield /* comment */"
+ "yield // comment\n"
+ "(yield)",
+ "[yield]",
+ "{yield}",
+ "yield, yield",
+ "yield; yield",
+ "(yield) ? yield : yield",
+ "(yield) \n ? yield : yield",
+ // If there is a newline before the next token, we don't look for RHS.
+ "yield\nfor (;;) {}",
+ NULL
+ };
+
+ // This test requires kAllowGenerators to succeed.
+ static const ParserFlag always_true_flags[] = {
+ kAllowGenerators
+ };
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+ always_true_flags, 1);
+}
+
+
+TEST(ErrorsYieldGenerator) {
+ const char* context_data[][2] = {
+ { "function * gen() {", "}" },
+ { "\"use strict\"; function * gen() {", "}" },
+ { NULL, NULL }
+ };
+
+ const char* statement_data[] = {
+ // Invalid yield expressions inside generators.
+ "var yield;",
+ "var foo, yield;",
+ "try { } catch (yield) { }",
+ "function yield() { }",
+ // The name of the NFE is let-bound in the generator, which does not permit
+ // yield to be an identifier.
+ "(function yield() { })",
+ "(function * yield() { })",
+ // Yield isn't valid as a formal parameter for generators.
+ "function * foo(yield) { }",
+ "(function * foo(yield) { })",
+ "yield = 1;",
+ "var foo = yield = 1;",
+ "++yield;",
+ "yield++;",
+ "yield *",
+ "(yield *)",
+ // Yield binds very loosely, so this parses as "yield (3 + yield 4)", which
+ // is invalid.
+ "yield 3 + yield 4;",
+ "yield: 34",
+ "yield ? 1 : 2",
+ // Parses as yield (/ yield): invalid.
+ "yield / yield",
+ "+ yield",
+ "+ yield 3",
+ // Invalid (no newline allowed between yield and *).
+ "yield\n*3",
+ // Invalid (we see a newline, so we parse {yield:42} as a statement, not an
+ // object literal, and yield is not a valid label).
+ "yield\n{yield: 42}",
+ "yield /* comment */\n {yield: 42}",
+ "yield //comment\n {yield: 42}",
NULL
};
- // Here we cannot assert that there is no error, since there will be without
- // the kAllowGenerators flag. However, we test that Parser and PreParser
- // produce the same errors.
- RunParserSyncTest(context_data, statement_data, kSuccessOrError);
+ RunParserSyncTest(context_data, statement_data, kError);
}
@@ -1790,16 +2031,18 @@ TEST(ErrorsNameOfStrictFunction) {
// Tests that illegal tokens as names of a strict function produce the correct
// errors.
const char* context_data[][2] = {
- { "", ""},
- { "\"use strict\";", ""},
+ { "function ", ""},
+ { "\"use strict\"; function", ""},
+ { "function * ", ""},
+ { "\"use strict\"; function * ", ""},
{ NULL, NULL }
};
const char* statement_data[] = {
- "function eval() {\"use strict\";}",
- "function arguments() {\"use strict\";}",
- "function interface() {\"use strict\";}",
- "function yield() {\"use strict\";}",
+ "eval() {\"use strict\";}",
+ "arguments() {\"use strict\";}",
+ "interface() {\"use strict\";}",
+ "yield() {\"use strict\";}",
// Future reserved words are always illegal
"function super() { }",
"function super() {\"use strict\";}",
@@ -1812,15 +2055,15 @@ TEST(ErrorsNameOfStrictFunction) {
TEST(NoErrorsNameOfStrictFunction) {
const char* context_data[][2] = {
- { "", ""},
+ { "function ", ""},
{ NULL, NULL }
};
const char* statement_data[] = {
- "function eval() { }",
- "function arguments() { }",
- "function interface() { }",
- "function yield() { }",
+ "eval() { }",
+ "arguments() { }",
+ "interface() { }",
+ "yield() { }",
NULL
};
@@ -1828,12 +2071,35 @@ TEST(NoErrorsNameOfStrictFunction) {
}
+TEST(NoErrorsNameOfStrictGenerator) {
+ const char* context_data[][2] = {
+ { "function * ", ""},
+ { NULL, NULL }
+ };
+
+ const char* statement_data[] = {
+ "eval() { }",
+ "arguments() { }",
+ "interface() { }",
+ "yield() { }",
+ NULL
+ };
+
+ // This test requires kAllowGenerators to succeed.
+ static const ParserFlag always_true_flags[] = {
+ kAllowGenerators
+ };
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+ always_true_flags, 1);
+}
+
TEST(ErrorsIllegalWordsAsLabelsSloppy) {
// Using future reserved words as labels is always an error.
const char* context_data[][2] = {
{ "", ""},
{ "function test_func() {", "}" },
+ { "() => {", "}" },
{ NULL, NULL }
};
@@ -1851,6 +2117,7 @@ TEST(ErrorsIllegalWordsAsLabelsStrict) {
const char* context_data[][2] = {
{ "\"use strict\";", "" },
{ "function test_func() {\"use strict\"; ", "}"},
+ { "() => {\"use strict\"; ", "}" },
{ NULL, NULL }
};
@@ -1870,8 +2137,10 @@ TEST(NoErrorsIllegalWordsAsLabels) {
const char* context_data[][2] = {
{ "", ""},
{ "function test_func() {", "}" },
+ { "() => {", "}" },
{ "\"use strict\";", "" },
{ "\"use strict\"; function test_func() {", "}" },
+ { "\"use strict\"; () => {", "}" },
{ NULL, NULL }
};
@@ -1882,7 +2151,9 @@ TEST(NoErrorsIllegalWordsAsLabels) {
NULL
};
- RunParserSyncTest(context_data, statement_data, kSuccess);
+ static const ParserFlag always_flags[] = {kAllowArrowFunctions};
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+ always_flags, ARRAY_SIZE(always_flags));
}
@@ -1891,6 +2162,7 @@ TEST(ErrorsParenthesizedLabels) {
const char* context_data[][2] = {
{ "", ""},
{ "function test_func() {", "}" },
+ { "() => {", "}" },
{ NULL, NULL }
};
@@ -1969,9 +2241,8 @@ TEST(DontRegressPreParserDataSizes) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handles(isolate);
- int marker;
- CcTest::i_isolate()->stack_guard()->SetStackLimit(
- reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
+ 128 * 1024);
struct TestCase {
const char* program;
@@ -1997,21 +2268,20 @@ TEST(DontRegressPreParserDataSizes) {
factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked();
i::Handle<i::Script> script = factory->NewScript(source);
i::CompilationInfoWithZone info(script);
- i::ScriptData* data = NULL;
- info.SetCachedData(&data, i::PRODUCE_CACHED_DATA);
+ i::ScriptData* sd = NULL;
+ info.SetCachedData(&sd, v8::ScriptCompiler::kProduceParserCache);
i::Parser::Parse(&info, true);
- CHECK(data);
- CHECK(!data->HasError());
+ i::ParseData pd(sd);
- if (data->function_count() != test_cases[i].functions) {
- i::OS::Print(
+ if (pd.FunctionCount() != test_cases[i].functions) {
+ v8::base::OS::Print(
"Expected preparse data for program:\n"
"\t%s\n"
"to contain %d functions, however, received %d functions.\n",
- program, test_cases[i].functions,
- data->function_count());
+ program, test_cases[i].functions, pd.FunctionCount());
CHECK(false);
}
+ delete sd;
}
}
@@ -2132,9 +2402,13 @@ TEST(Intrinsics) {
NULL
};
- // Parsing will fail or succeed depending on whether we allow natives syntax
- // or not.
- RunParserSyncTest(context_data, statement_data, kSuccessOrError);
+ // This test requires kAllowNativesSyntax to succeed.
+ static const ParserFlag always_true_flags[] = {
+ kAllowNativesSyntax
+ };
+
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+ always_true_flags, 1);
}
@@ -2199,10 +2473,12 @@ TEST(ErrorsNewExpression) {
TEST(StrictObjectLiteralChecking) {
const char* strict_context_data[][2] = {
{"\"use strict\"; var myobject = {", "};"},
+ {"\"use strict\"; var myobject = {", ",};"},
{ NULL, NULL }
};
const char* non_strict_context_data[][2] = {
{"var myobject = {", "};"},
+ {"var myobject = {", ",};"},
{ NULL, NULL }
};
@@ -2231,23 +2507,29 @@ TEST(ErrorsObjectLiteralChecking) {
};
const char* statement_data[] = {
+ ",",
"foo: 1, get foo() {}",
- "foo: 1, set foo() {}",
+ "foo: 1, set foo(v) {}",
"\"foo\": 1, get \"foo\"() {}",
- "\"foo\": 1, set \"foo\"() {}",
+ "\"foo\": 1, set \"foo\"(v) {}",
"1: 1, get 1() {}",
"1: 1, set 1() {}",
// It's counter-intuitive, but these collide too (even in classic
// mode). Note that we can have "foo" and foo as properties in classic mode,
// but we cannot have "foo" and get foo, or foo and get "foo".
"foo: 1, get \"foo\"() {}",
- "foo: 1, set \"foo\"() {}",
+ "foo: 1, set \"foo\"(v) {}",
"\"foo\": 1, get foo() {}",
- "\"foo\": 1, set foo() {}",
+ "\"foo\": 1, set foo(v) {}",
"1: 1, get \"1\"() {}",
"1: 1, set \"1\"() {}",
"\"1\": 1, get 1() {}"
- "\"1\": 1, set 1() {}"
+ "\"1\": 1, set 1(v) {}"
+ // Wrong number of parameters
+ "get bar(x) {}",
+ "get bar(x, y) {}",
+ "set bar() {}",
+ "set bar(x, y) {}",
// Parsing FunctionLiteral for getter or setter fails
"get foo( +",
"get foo() \"error\"",
@@ -2261,7 +2543,9 @@ TEST(ErrorsObjectLiteralChecking) {
TEST(NoErrorsObjectLiteralChecking) {
const char* context_data[][2] = {
{"var myobject = {", "};"},
+ {"var myobject = {", ",};"},
{"\"use strict\"; var myobject = {", "};"},
+ {"\"use strict\"; var myobject = {", ",};"},
{ NULL, NULL }
};
@@ -2271,25 +2555,22 @@ TEST(NoErrorsObjectLiteralChecking) {
"1: 1, 2: 2",
// Syntax: IdentifierName ':' AssignmentExpression
"foo: bar = 5 + baz",
- // Syntax: 'get' (IdentifierName | String | Number) FunctionLiteral
+ // Syntax: 'get' PropertyName '(' ')' '{' FunctionBody '}'
"get foo() {}",
"get \"foo\"() {}",
"get 1() {}",
- // Syntax: 'set' (IdentifierName | String | Number) FunctionLiteral
- "set foo() {}",
- "set \"foo\"() {}",
- "set 1() {}",
+ // Syntax: 'set' PropertyName '(' PropertySetParameterList ')'
+ // '{' FunctionBody '}'
+ "set foo(v) {}",
+ "set \"foo\"(v) {}",
+ "set 1(v) {}",
// Non-colliding getters and setters -> no errors
"foo: 1, get bar() {}",
- "foo: 1, set bar(b) {}",
+ "foo: 1, set bar(v) {}",
"\"foo\": 1, get \"bar\"() {}",
- "\"foo\": 1, set \"bar\"() {}",
+ "\"foo\": 1, set \"bar\"(v) {}",
"1: 1, get 2() {}",
- "1: 1, set 2() {}",
- // Weird number of parameters -> no errors
- "get bar() {}, set bar() {}",
- "get bar(x) {}, set bar(x) {}",
- "get bar(x, y) {}, set bar(x, y) {}",
+ "1: 1, set 2(v) {}",
// Keywords, future reserved and strict future reserved are also allowed as
// property names.
"if: 4",
@@ -2459,3 +2740,606 @@ TEST(InvalidLeftHandSide) {
RunParserSyncTest(postfix_context_data, good_statement_data, kSuccess);
RunParserSyncTest(postfix_context_data, bad_statement_data_common, kError);
}
+
+
+TEST(FuncNameInferrerBasic) {
+ // Tests that function names are inferred properly.
+ i::FLAG_allow_natives_syntax = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ LocalContext env;
+ CompileRun("var foo1 = function() {}; "
+ "var foo2 = function foo3() {}; "
+ "function not_ctor() { "
+ " var foo4 = function() {}; "
+ " return %FunctionGetInferredName(foo4); "
+ "} "
+ "function Ctor() { "
+ " var foo5 = function() {}; "
+ " return %FunctionGetInferredName(foo5); "
+ "} "
+ "var obj1 = { foo6: function() {} }; "
+ "var obj2 = { 'foo7': function() {} }; "
+ "var obj3 = {}; "
+ "obj3[1] = function() {}; "
+ "var obj4 = {}; "
+ "obj4[1] = function foo8() {}; "
+ "var obj5 = {}; "
+ "obj5['foo9'] = function() {}; "
+ "var obj6 = { obj7 : { foo10: function() {} } };");
+ ExpectString("%FunctionGetInferredName(foo1)", "foo1");
+ // foo2 is not unnamed -> its name is not inferred.
+ ExpectString("%FunctionGetInferredName(foo2)", "");
+ ExpectString("not_ctor()", "foo4");
+ ExpectString("Ctor()", "Ctor.foo5");
+ ExpectString("%FunctionGetInferredName(obj1.foo6)", "obj1.foo6");
+ ExpectString("%FunctionGetInferredName(obj2.foo7)", "obj2.foo7");
+ ExpectString("%FunctionGetInferredName(obj3[1])",
+ "obj3.(anonymous function)");
+ ExpectString("%FunctionGetInferredName(obj4[1])", "");
+ ExpectString("%FunctionGetInferredName(obj5['foo9'])", "obj5.foo9");
+ ExpectString("%FunctionGetInferredName(obj6.obj7.foo10)", "obj6.obj7.foo10");
+}
+
+
+TEST(FuncNameInferrerTwoByte) {
+ // Tests function name inferring in cases where some parts of the inferred
+ // function name are two-byte strings.
+ i::FLAG_allow_natives_syntax = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ LocalContext env;
+ uint16_t* two_byte_source = AsciiToTwoByteString(
+ "var obj1 = { oXj2 : { foo1: function() {} } }; "
+ "%FunctionGetInferredName(obj1.oXj2.foo1)");
+ uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
+ // Make it really non-ASCII (replace the Xs with a non-ASCII character).
+ two_byte_source[14] = two_byte_source[78] = two_byte_name[6] = 0x010d;
+ v8::Local<v8::String> source =
+ v8::String::NewFromTwoByte(isolate, two_byte_source);
+ v8::Local<v8::Value> result = CompileRun(source);
+ CHECK(result->IsString());
+ v8::Local<v8::String> expected_name =
+ v8::String::NewFromTwoByte(isolate, two_byte_name);
+ CHECK(result->Equals(expected_name));
+ i::DeleteArray(two_byte_source);
+ i::DeleteArray(two_byte_name);
+}
+
+
+TEST(FuncNameInferrerEscaped) {
+ // The same as FuncNameInferrerTwoByte, except that we express the two-byte
+ // character as a unicode escape.
+ i::FLAG_allow_natives_syntax = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ LocalContext env;
+ uint16_t* two_byte_source = AsciiToTwoByteString(
+ "var obj1 = { o\\u010dj2 : { foo1: function() {} } }; "
+ "%FunctionGetInferredName(obj1.o\\u010dj2.foo1)");
+ uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
+ // Fix to correspond to the non-ASCII name in two_byte_source.
+ two_byte_name[6] = 0x010d;
+ v8::Local<v8::String> source =
+ v8::String::NewFromTwoByte(isolate, two_byte_source);
+ v8::Local<v8::Value> result = CompileRun(source);
+ CHECK(result->IsString());
+ v8::Local<v8::String> expected_name =
+ v8::String::NewFromTwoByte(isolate, two_byte_name);
+ CHECK(result->Equals(expected_name));
+ i::DeleteArray(two_byte_source);
+ i::DeleteArray(two_byte_name);
+}
+
+
+TEST(RegressionLazyFunctionWithErrorWithArg) {
+ // The bug occurred when a lazy function had an error which requires a
+ // parameter (such as "unknown label" here). The error message was processed
+ // before the AstValueFactory containing the error message string was
+ // internalized.
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ LocalContext env;
+ i::FLAG_lazy = true;
+ i::FLAG_min_preparse_length = 0;
+ CompileRun("function this_is_lazy() {\n"
+ " break p;\n"
+ "}\n"
+ "this_is_lazy();\n");
+}
+
+
+TEST(SerializationOfMaybeAssignmentFlag) {
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::Factory* factory = isolate->factory();
+ i::HandleScope scope(isolate);
+ LocalContext env;
+
+ const char* src =
+ "function h() {"
+ " var result = [];"
+ " function f() {"
+ " result.push(2);"
+ " }"
+ " function assertResult(r) {"
+ " f();"
+ " result = [];"
+ " }"
+ " assertResult([2]);"
+ " assertResult([2]);"
+ " return f;"
+ "};"
+ "h();";
+
+ i::ScopedVector<char> program(Utf8LengthHelper(src) + 1);
+ i::SNPrintF(program, "%s", src);
+ i::Handle<i::String> source = factory->InternalizeUtf8String(program.start());
+ source->PrintOn(stdout);
+ printf("\n");
+ i::Zone zone(isolate);
+ v8::Local<v8::Value> v = CompileRun(src);
+ i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
+ i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
+ i::Context* context = f->context();
+ i::AstValueFactory avf(&zone, isolate->heap()->HashSeed());
+ avf.Internalize(isolate);
+ const i::AstRawString* name = avf.GetOneByteString("result");
+ i::Handle<i::String> str = name->string();
+ CHECK(str->IsInternalizedString());
+ i::Scope* global_scope =
+ new (&zone) i::Scope(NULL, i::GLOBAL_SCOPE, &avf, &zone);
+ global_scope->Initialize();
+ i::Scope* s = i::Scope::DeserializeScopeChain(context, global_scope, &zone);
+ DCHECK(s != global_scope);
+ DCHECK(name != NULL);
+
+ // Get result from h's function context (that is f's context)
+ i::Variable* var = s->Lookup(name);
+
+ CHECK(var != NULL);
+ // Maybe assigned should survive deserialization
+ CHECK(var->maybe_assigned() == i::kMaybeAssigned);
+ // TODO(sigurds) Figure out if is_used should survive context serialization.
+}
+
+
+TEST(IfArgumentsArrayAccessedThenParametersMaybeAssigned) {
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::Factory* factory = isolate->factory();
+ i::HandleScope scope(isolate);
+ LocalContext env;
+
+
+ const char* src =
+ "function f(x) {"
+ " var a = arguments;"
+ " function g(i) {"
+ " ++a[0];"
+ " };"
+ " return g;"
+ " }"
+ "f(0);";
+
+ i::ScopedVector<char> program(Utf8LengthHelper(src) + 1);
+ i::SNPrintF(program, "%s", src);
+ i::Handle<i::String> source = factory->InternalizeUtf8String(program.start());
+ source->PrintOn(stdout);
+ printf("\n");
+ i::Zone zone(isolate);
+ v8::Local<v8::Value> v = CompileRun(src);
+ i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
+ i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
+ i::Context* context = f->context();
+ i::AstValueFactory avf(&zone, isolate->heap()->HashSeed());
+ avf.Internalize(isolate);
+
+ i::Scope* global_scope =
+ new (&zone) i::Scope(NULL, i::GLOBAL_SCOPE, &avf, &zone);
+ global_scope->Initialize();
+ i::Scope* s = i::Scope::DeserializeScopeChain(context, global_scope, &zone);
+ DCHECK(s != global_scope);
+ const i::AstRawString* name_x = avf.GetOneByteString("x");
+
+ // Get result from f's function context (that is g's outer context)
+ i::Variable* var_x = s->Lookup(name_x);
+ CHECK(var_x != NULL);
+ CHECK(var_x->maybe_assigned() == i::kMaybeAssigned);
+}
+
+
+TEST(ExportsMaybeAssigned) {
+ i::FLAG_use_strict = true;
+ i::FLAG_harmony_scoping = true;
+ i::FLAG_harmony_modules = true;
+
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::Factory* factory = isolate->factory();
+ i::HandleScope scope(isolate);
+ LocalContext env;
+
+ const char* src =
+ "module A {"
+ " export var x = 1;"
+ " export function f() { return x };"
+ " export const y = 2;"
+ " module B {}"
+ " export module C {}"
+ "};"
+ "A.f";
+
+ i::ScopedVector<char> program(Utf8LengthHelper(src) + 1);
+ i::SNPrintF(program, "%s", src);
+ i::Handle<i::String> source = factory->InternalizeUtf8String(program.start());
+ source->PrintOn(stdout);
+ printf("\n");
+ i::Zone zone(isolate);
+ v8::Local<v8::Value> v = CompileRun(src);
+ i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
+ i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
+ i::Context* context = f->context();
+ i::AstValueFactory avf(&zone, isolate->heap()->HashSeed());
+ avf.Internalize(isolate);
+
+ i::Scope* global_scope =
+ new (&zone) i::Scope(NULL, i::GLOBAL_SCOPE, &avf, &zone);
+ global_scope->Initialize();
+ i::Scope* s = i::Scope::DeserializeScopeChain(context, global_scope, &zone);
+ DCHECK(s != global_scope);
+ const i::AstRawString* name_x = avf.GetOneByteString("x");
+ const i::AstRawString* name_f = avf.GetOneByteString("f");
+ const i::AstRawString* name_y = avf.GetOneByteString("y");
+ const i::AstRawString* name_B = avf.GetOneByteString("B");
+ const i::AstRawString* name_C = avf.GetOneByteString("C");
+
+ // Get result from h's function context (that is f's context)
+ i::Variable* var_x = s->Lookup(name_x);
+ CHECK(var_x != NULL);
+ CHECK(var_x->maybe_assigned() == i::kMaybeAssigned);
+ i::Variable* var_f = s->Lookup(name_f);
+ CHECK(var_f != NULL);
+ CHECK(var_f->maybe_assigned() == i::kMaybeAssigned);
+ i::Variable* var_y = s->Lookup(name_y);
+ CHECK(var_y != NULL);
+ CHECK(var_y->maybe_assigned() == i::kNotAssigned);
+ i::Variable* var_B = s->Lookup(name_B);
+ CHECK(var_B != NULL);
+ CHECK(var_B->maybe_assigned() == i::kNotAssigned);
+ i::Variable* var_C = s->Lookup(name_C);
+ CHECK(var_C != NULL);
+ CHECK(var_C->maybe_assigned() == i::kNotAssigned);
+}
+
+
+TEST(InnerAssignment) {
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::Factory* factory = isolate->factory();
+ i::HandleScope scope(isolate);
+ LocalContext env;
+
+ const char* prefix = "function f() {";
+ const char* midfix = " function g() {";
+ const char* suffix = "}}";
+ struct { const char* source; bool assigned; bool strict; } outers[] = {
+ // Actual assignments.
+ { "var x; var x = 5;", true, false },
+ { "var x; { var x = 5; }", true, false },
+ { "'use strict'; let x; x = 6;", true, true },
+ { "var x = 5; function x() {}", true, false },
+ // Actual non-assignments.
+ { "var x;", false, false },
+ { "var x = 5;", false, false },
+ { "'use strict'; let x;", false, true },
+ { "'use strict'; let x = 6;", false, true },
+ { "'use strict'; var x = 0; { let x = 6; }", false, true },
+ { "'use strict'; var x = 0; { let x; x = 6; }", false, true },
+ { "'use strict'; let x = 0; { let x = 6; }", false, true },
+ { "'use strict'; let x = 0; { let x; x = 6; }", false, true },
+ { "var x; try {} catch (x) { x = 5; }", false, false },
+ { "function x() {}", false, false },
+ // Eval approximation.
+ { "var x; eval('');", true, false },
+ { "eval(''); var x;", true, false },
+ { "'use strict'; let x; eval('');", true, true },
+ { "'use strict'; eval(''); let x;", true, true },
+ // Non-assignments not recognized, because the analysis is approximative.
+ { "var x; var x;", true, false },
+ { "var x = 5; var x;", true, false },
+ { "var x; { var x; }", true, false },
+ { "var x; function x() {}", true, false },
+ { "function x() {}; var x;", true, false },
+ { "var x; try {} catch (x) { var x = 5; }", true, false },
+ };
+ struct { const char* source; bool assigned; bool with; } inners[] = {
+ // Actual assignments.
+ { "x = 1;", true, false },
+ { "x++;", true, false },
+ { "++x;", true, false },
+ { "x--;", true, false },
+ { "--x;", true, false },
+ { "{ x = 1; }", true, false },
+ { "'use strict'; { let x; }; x = 0;", true, false },
+ { "'use strict'; { const x = 1; }; x = 0;", true, false },
+ { "'use strict'; { function x() {} }; x = 0;", true, false },
+ { "with ({}) { x = 1; }", true, true },
+ { "eval('');", true, false },
+ { "'use strict'; { let y; eval('') }", true, false },
+ { "function h() { x = 0; }", true, false },
+ { "(function() { x = 0; })", true, false },
+ { "(function() { x = 0; })", true, false },
+ { "with ({}) (function() { x = 0; })", true, true },
+ // Actual non-assignments.
+ { "", false, false },
+ { "x;", false, false },
+ { "var x;", false, false },
+ { "var x = 8;", false, false },
+ { "var x; x = 8;", false, false },
+ { "'use strict'; let x;", false, false },
+ { "'use strict'; let x = 8;", false, false },
+ { "'use strict'; let x; x = 8;", false, false },
+ { "'use strict'; const x = 8;", false, false },
+ { "function x() {}", false, false },
+ { "function x() { x = 0; }", false, false },
+ { "function h(x) { x = 0; }", false, false },
+ { "'use strict'; { let x; x = 0; }", false, false },
+ { "{ var x; }; x = 0;", false, false },
+ { "with ({}) {}", false, true },
+ { "var x; { with ({}) { x = 1; } }", false, true },
+ { "try {} catch(x) { x = 0; }", false, false },
+ { "try {} catch(x) { with ({}) { x = 1; } }", false, true },
+ // Eval approximation.
+ { "eval('');", true, false },
+ { "function h() { eval(''); }", true, false },
+ { "(function() { eval(''); })", true, false },
+ // Shadowing not recognized because of eval approximation.
+ { "var x; eval('');", true, false },
+ { "'use strict'; let x; eval('');", true, false },
+ { "try {} catch(x) { eval(''); }", true, false },
+ { "function x() { eval(''); }", true, false },
+ { "(function(x) { eval(''); })", true, false },
+ };
+
+ // Used to trigger lazy compilation of function
+ int comment_len = 2048;
+ i::ScopedVector<char> comment(comment_len + 1);
+ i::SNPrintF(comment, "/*%0*d*/", comment_len - 4, 0);
+ int prefix_len = Utf8LengthHelper(prefix);
+ int midfix_len = Utf8LengthHelper(midfix);
+ int suffix_len = Utf8LengthHelper(suffix);
+ for (unsigned i = 0; i < ARRAY_SIZE(outers); ++i) {
+ const char* outer = outers[i].source;
+ int outer_len = Utf8LengthHelper(outer);
+ for (unsigned j = 0; j < ARRAY_SIZE(inners); ++j) {
+ for (unsigned outer_lazy = 0; outer_lazy < 2; ++outer_lazy) {
+ for (unsigned inner_lazy = 0; inner_lazy < 2; ++inner_lazy) {
+ if (outers[i].strict && inners[j].with) continue;
+ const char* inner = inners[j].source;
+ int inner_len = Utf8LengthHelper(inner);
+
+ int outer_comment_len = outer_lazy ? comment_len : 0;
+ int inner_comment_len = inner_lazy ? comment_len : 0;
+ const char* outer_comment = outer_lazy ? comment.start() : "";
+ const char* inner_comment = inner_lazy ? comment.start() : "";
+ int len = prefix_len + outer_comment_len + outer_len + midfix_len +
+ inner_comment_len + inner_len + suffix_len;
+ i::ScopedVector<char> program(len + 1);
+
+ i::SNPrintF(program, "%s%s%s%s%s%s%s", prefix, outer_comment, outer,
+ midfix, inner_comment, inner, suffix);
+ i::Handle<i::String> source =
+ factory->InternalizeUtf8String(program.start());
+ source->PrintOn(stdout);
+ printf("\n");
+
+ i::Handle<i::Script> script = factory->NewScript(source);
+ i::CompilationInfoWithZone info(script);
+ i::Parser parser(&info);
+ parser.set_allow_harmony_scoping(true);
+ CHECK(parser.Parse());
+ CHECK(i::Rewriter::Rewrite(&info));
+ CHECK(i::Scope::Analyze(&info));
+ CHECK(info.function() != NULL);
+
+ i::Scope* scope = info.function()->scope();
+ CHECK_EQ(scope->inner_scopes()->length(), 1);
+ i::Scope* inner_scope = scope->inner_scopes()->at(0);
+ const i::AstRawString* var_name =
+ info.ast_value_factory()->GetOneByteString("x");
+ i::Variable* var = inner_scope->Lookup(var_name);
+ bool expected = outers[i].assigned || inners[j].assigned;
+ CHECK(var != NULL);
+ CHECK(var->is_used() || !expected);
+ CHECK((var->maybe_assigned() == i::kMaybeAssigned) == expected);
+ }
+ }
+ }
+ }
+}
+
+namespace {
+
+int* global_use_counts = NULL;
+
+void MockUseCounterCallback(v8::Isolate* isolate,
+ v8::Isolate::UseCounterFeature feature) {
+ ++global_use_counts[feature];
+}
+
+}
+
+
+TEST(UseAsmUseCount) {
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::HandleScope scope(isolate);
+ LocalContext env;
+ int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
+ global_use_counts = use_counts;
+ CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
+ CompileRun("\"use asm\";\n"
+ "var foo = 1;\n"
+ "\"use asm\";\n" // Only the first one counts.
+ "function bar() { \"use asm\"; var baz = 1; }");
+ CHECK_EQ(2, use_counts[v8::Isolate::kUseAsm]);
+}
+
+
+TEST(ErrorsArrowFunctions) {
+ // Tests that parser and preparser generate the same kind of errors
+ // on invalid arrow function syntax.
+ const char* context_data[][2] = {
+ {"", ";"},
+ {"v = ", ";"},
+ {"bar ? (", ") : baz;"},
+ {"bar ? baz : (", ");"},
+ {"bar[", "];"},
+ {"bar, ", ";"},
+ {"", ", bar;"},
+ {NULL, NULL}
+ };
+
+ const char* statement_data[] = {
+ "=> 0",
+ "=>",
+ "() =>",
+ "=> {}",
+ ") => {}",
+ ", => {}",
+ "(,) => {}",
+ "return => {}",
+ "() => {'value': 42}",
+
+ // Check that the early return introduced in ParsePrimaryExpression
+ // does not accept stray closing parentheses.
+ ")",
+ ") => 0",
+ "foo[()]",
+ "()",
+
+ // Parameter lists with extra parens should be recognized as errors.
+ "(()) => 0",
+ "((x)) => 0",
+ "((x, y)) => 0",
+ "(x, (y)) => 0",
+ "((x, y, z)) => 0",
+ "(x, (y, z)) => 0",
+ "((x, y), z) => 0",
+
+ // Parameter lists are always validated as strict, so those are errors.
+ "eval => {}",
+ "arguments => {}",
+ "yield => {}",
+ "interface => {}",
+ "(eval) => {}",
+ "(arguments) => {}",
+ "(yield) => {}",
+ "(interface) => {}",
+ "(eval, bar) => {}",
+ "(bar, eval) => {}",
+ "(bar, arguments) => {}",
+ "(bar, yield) => {}",
+ "(bar, interface) => {}",
+ // TODO(aperez): Detecting duplicates does not work in PreParser.
+ // "(bar, bar) => {}",
+
+ // The parameter list is parsed as an expression, but only
+ // a comma-separated list of identifier is valid.
+ "32 => {}",
+ "(32) => {}",
+ "(a, 32) => {}",
+ "if => {}",
+ "(if) => {}",
+ "(a, if) => {}",
+ "a + b => {}",
+ "(a + b) => {}",
+ "(a + b, c) => {}",
+ "(a, b - c) => {}",
+ "\"a\" => {}",
+ "(\"a\") => {}",
+ "(\"a\", b) => {}",
+ "(a, \"b\") => {}",
+ "-a => {}",
+ "(-a) => {}",
+ "(-a, b) => {}",
+ "(a, -b) => {}",
+ "{} => {}",
+ "({}) => {}",
+ "(a, {}) => {}",
+ "({}, a) => {}",
+ "a++ => {}",
+ "(a++) => {}",
+ "(a++, b) => {}",
+ "(a, b++) => {}",
+ "[] => {}",
+ "([]) => {}",
+ "(a, []) => {}",
+ "([], a) => {}",
+ "(a = b) => {}",
+ "(a = b, c) => {}",
+ "(a, b = c) => {}",
+ "(foo ? bar : baz) => {}",
+ "(a, foo ? bar : baz) => {}",
+ "(foo ? bar : baz, a) => {}",
+ NULL
+ };
+
+ // The test is quite slow, so run it with a reduced set of flags.
+ static const ParserFlag flags[] = {
+ kAllowLazy, kAllowHarmonyScoping, kAllowGenerators
+ };
+ static const ParserFlag always_flags[] = { kAllowArrowFunctions };
+ RunParserSyncTest(context_data, statement_data, kError, flags,
+ ARRAY_SIZE(flags), always_flags, ARRAY_SIZE(always_flags));
+}
+
+
+TEST(NoErrorsArrowFunctions) {
+ // Tests that parser and preparser accept valid arrow functions syntax.
+ const char* context_data[][2] = {
+ {"", ";"},
+ {"bar ? (", ") : baz;"},
+ {"bar ? baz : (", ");"},
+ {"bar, ", ";"},
+ {"", ", bar;"},
+ {NULL, NULL}
+ };
+
+ const char* statement_data[] = {
+ "() => {}",
+ "() => { return 42 }",
+ "x => { return x; }",
+ "(x) => { return x; }",
+ "(x, y) => { return x + y; }",
+ "(x, y, z) => { return x + y + z; }",
+ "(x, y) => { x.a = y; }",
+ "() => 42",
+ "x => x",
+ "x => x * x",
+ "(x) => x",
+ "(x) => x * x",
+ "(x, y) => x + y",
+ "(x, y, z) => x, y, z",
+ "(x, y) => x.a = y",
+ "() => ({'value': 42})",
+ "x => y => x + y",
+ "(x, y) => (u, v) => x*u + y*v",
+ "(x, y) => z => z * (x + y)",
+ "x => (y, z) => z * (x + y)",
+
+ // Those are comma-separated expressions, with arrow functions as items.
+ // They stress the code for validating arrow function parameter lists.
+ "a, b => 0",
+ "a, b, (c, d) => 0",
+ "(a, b, (c, d) => 0)",
+ "(a, b) => 0, (c, d) => 1",
+ "(a, b => {}, a => a + 1)",
+ "((a, b) => {}, (a => a + 1))",
+ "(a, (a, (b, c) => 0))",
+
+ // Arrow has more precedence, this is the same as: foo ? bar : (baz = {})
+ "foo ? bar : baz => {}",
+ NULL
+ };
+
+ static const ParserFlag always_flags[] = {kAllowArrowFunctions};
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+ always_flags, ARRAY_SIZE(always_flags));
+}
diff --git a/deps/v8/test/cctest/test-platform-linux.cc b/deps/v8/test/cctest/test-platform-linux.cc
index f289e9482..613638e78 100644
--- a/deps/v8/test/cctest/test-platform-linux.cc
+++ b/deps/v8/test/cctest/test-platform-linux.cc
@@ -31,16 +31,16 @@
#include <stdlib.h>
#include <unistd.h> // for usleep()
-#include "v8.h"
+#include "src/v8.h"
-#include "platform.h"
-#include "cctest.h"
+#include "src/base/platform/platform.h"
+#include "test/cctest/cctest.h"
using namespace ::v8::internal;
TEST(VirtualMemory) {
- VirtualMemory* vm = new VirtualMemory(1 * MB);
+ v8::base::VirtualMemory* vm = new v8::base::VirtualMemory(1 * MB);
CHECK(vm->IsReserved());
void* block_addr = vm->address();
size_t block_size = 4 * KB;
@@ -51,8 +51,3 @@ TEST(VirtualMemory) {
CHECK(vm->Uncommit(block_addr, block_size));
delete vm;
}
-
-
-TEST(GetCurrentProcessId) {
- CHECK_EQ(static_cast<int>(getpid()), OS::GetCurrentProcessId());
-}
diff --git a/deps/v8/test/cctest/test-platform-tls.cc b/deps/v8/test/cctest/test-platform-tls.cc
deleted file mode 100644
index 31501d9ef..000000000
--- a/deps/v8/test/cctest/test-platform-tls.cc
+++ /dev/null
@@ -1,93 +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.
-//
-// Tests of fast TLS support.
-
-#include "v8.h"
-
-#include "cctest.h"
-#include "checks.h"
-#include "platform.h"
-
-using v8::internal::Thread;
-
-static const int kValueCount = 128;
-
-static Thread::LocalStorageKey keys[kValueCount];
-
-static void* GetValue(int num) {
- return reinterpret_cast<void*>(static_cast<intptr_t>(num + 1));
-}
-
-
-static void DoTest() {
- for (int i = 0; i < kValueCount; i++) {
- CHECK(!Thread::HasThreadLocal(keys[i]));
- }
- for (int i = 0; i < kValueCount; i++) {
- Thread::SetThreadLocal(keys[i], GetValue(i));
- }
- for (int i = 0; i < kValueCount; i++) {
- CHECK(Thread::HasThreadLocal(keys[i]));
- }
- for (int i = 0; i < kValueCount; i++) {
- CHECK_EQ(GetValue(i), Thread::GetThreadLocal(keys[i]));
- CHECK_EQ(GetValue(i), Thread::GetExistingThreadLocal(keys[i]));
- }
- for (int i = 0; i < kValueCount; i++) {
- Thread::SetThreadLocal(keys[i], GetValue(kValueCount - i - 1));
- }
- for (int i = 0; i < kValueCount; i++) {
- CHECK(Thread::HasThreadLocal(keys[i]));
- }
- for (int i = 0; i < kValueCount; i++) {
- CHECK_EQ(GetValue(kValueCount - i - 1),
- Thread::GetThreadLocal(keys[i]));
- CHECK_EQ(GetValue(kValueCount - i - 1),
- Thread::GetExistingThreadLocal(keys[i]));
- }
-}
-
-class TestThread : public Thread {
- public:
- TestThread() : Thread("TestThread") {}
-
- virtual void Run() {
- DoTest();
- }
-};
-
-
-TEST(FastTLS) {
- for (int i = 0; i < kValueCount; i++) {
- keys[i] = Thread::CreateThreadLocalKey();
- }
- DoTest();
- TestThread thread;
- thread.Start();
- thread.Join();
-}
diff --git a/deps/v8/test/cctest/test-platform-win32.cc b/deps/v8/test/cctest/test-platform-win32.cc
index d7fdab11e..cecde7412 100644
--- a/deps/v8/test/cctest/test-platform-win32.cc
+++ b/deps/v8/test/cctest/test-platform-win32.cc
@@ -29,17 +29,17 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "platform.h"
-#include "cctest.h"
-#include "win32-headers.h"
+#include "src/base/platform/platform.h"
+#include "src/base/win32-headers.h"
+#include "test/cctest/cctest.h"
using namespace ::v8::internal;
TEST(VirtualMemory) {
- VirtualMemory* vm = new VirtualMemory(1 * MB);
+ v8::base::VirtualMemory* vm = new v8::base::VirtualMemory(1 * MB);
CHECK(vm->IsReserved());
void* block_addr = vm->address();
size_t block_size = 4 * KB;
@@ -50,9 +50,3 @@ TEST(VirtualMemory) {
CHECK(vm->Uncommit(block_addr, block_size));
delete vm;
}
-
-
-TEST(GetCurrentProcessId) {
- CHECK_EQ(static_cast<int>(::GetCurrentProcessId()),
- OS::GetCurrentProcessId());
-}
diff --git a/deps/v8/test/cctest/test-platform.cc b/deps/v8/test/cctest/test-platform.cc
index 6b28b1895..3beaccea8 100644
--- a/deps/v8/test/cctest/test-platform.cc
+++ b/deps/v8/test/cctest/test-platform.cc
@@ -27,8 +27,8 @@
#include <stdlib.h>
-#include "cctest.h"
-#include "platform.h"
+#include "src/base/platform/platform.h"
+#include "test/cctest/cctest.h"
using namespace ::v8::internal;
@@ -94,7 +94,7 @@ TEST(StackAlignment) {
v8::Local<v8::Function>::Cast(global_object->Get(v8_str("foo")));
v8::Local<v8::Value> result = foo->Call(global_object, 0, NULL);
- CHECK_EQ(0, result->Int32Value() % OS::ActivationFrameAlignment());
+ CHECK_EQ(0, result->Int32Value() % v8::base::OS::ActivationFrameAlignment());
}
#undef GET_STACK_POINTERS
diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc
index c3198b151..7578b35fb 100644
--- a/deps/v8/test/cctest/test-profile-generator.cc
+++ b/deps/v8/test/cctest/test-profile-generator.cc
@@ -27,12 +27,13 @@
//
// Tests of profiles generator and utilities.
-#include "v8.h"
-#include "profile-generator-inl.h"
-#include "profiler-extension.h"
-#include "cctest.h"
-#include "cpu-profiler.h"
-#include "../include/v8-profiler.h"
+#include "src/v8.h"
+
+#include "include/v8-profiler.h"
+#include "src/cpu-profiler.h"
+#include "src/profile-generator-inl.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/profiler-extension.h"
using i::CodeEntry;
using i::CodeMap;
@@ -571,14 +572,14 @@ TEST(RecordStackTraceAtStartProfiling) {
const_cast<ProfileNode*>(current)->Print(0);
// The tree should look like this:
// (root)
- // (anonymous function)
+ // ""
// a
// b
// c
// There can also be:
// startProfiling
// if the sampler managed to get a tick.
- current = PickChild(current, "(anonymous function)");
+ current = PickChild(current, "");
CHECK_NE(NULL, const_cast<ProfileNode*>(current));
current = PickChild(current, "a");
CHECK_NE(NULL, const_cast<ProfileNode*>(current));
@@ -601,7 +602,7 @@ TEST(Issue51919) {
CpuProfilesCollection::kMaxSimultaneousProfiles> titles;
for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) {
i::Vector<char> title = i::Vector<char>::New(16);
- i::OS::SNPrintF(title, "%d", i);
+ i::SNPrintF(title, "%d", i);
CHECK(collection.StartProfiling(title.start(), false));
titles[i] = title.start();
}
@@ -650,22 +651,22 @@ TEST(ProfileNodeScriptId) {
const_cast<v8::CpuProfileNode*>(current))->Print(0);
// The tree should look like this:
// (root)
- // (anonymous function)
+ // ""
// b
// a
// There can also be:
// startProfiling
// if the sampler managed to get a tick.
- current = PickChild(current, i::ProfileGenerator::kAnonymousFunctionName);
+ current = PickChild(current, "");
CHECK_NE(NULL, const_cast<v8::CpuProfileNode*>(current));
current = PickChild(current, "b");
CHECK_NE(NULL, const_cast<v8::CpuProfileNode*>(current));
- CHECK_EQ(script_b->GetId(), current->GetScriptId());
+ CHECK_EQ(script_b->GetUnboundScript()->GetId(), current->GetScriptId());
current = PickChild(current, "a");
CHECK_NE(NULL, const_cast<v8::CpuProfileNode*>(current));
- CHECK_EQ(script_a->GetId(), current->GetScriptId());
+ CHECK_EQ(script_a->GetUnboundScript()->GetId(), current->GetScriptId());
}
@@ -759,10 +760,10 @@ TEST(BailoutReason) {
const_cast<v8::CpuProfileNode*>(current))->Print(0);
// The tree should look like this:
// (root)
- // (anonymous function)
+ // ""
// kTryFinally
// kTryCatch
- current = PickChild(current, i::ProfileGenerator::kAnonymousFunctionName);
+ current = PickChild(current, "");
CHECK_NE(NULL, const_cast<v8::CpuProfileNode*>(current));
current = PickChild(current, "TryFinally");
diff --git a/deps/v8/test/cctest/test-random-number-generator.cc b/deps/v8/test/cctest/test-random-number-generator.cc
index 93f325700..a53205c9c 100644
--- a/deps/v8/test/cctest/test-random-number-generator.cc
+++ b/deps/v8/test/cctest/test-random-number-generator.cc
@@ -25,10 +25,11 @@
// (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 "src/v8.h"
+#include "test/cctest/cctest.h"
-#include "cctest.h"
-#include "utils/random-number-generator.h"
+#include "src/base/utils/random-number-generator.h"
+#include "src/isolate-inl.h"
using namespace v8::internal;
@@ -39,46 +40,13 @@ static const int kRandomSeeds[] = {
};
-TEST(NextIntWithMaxValue) {
- for (unsigned n = 0; n < ARRAY_SIZE(kRandomSeeds); ++n) {
- RandomNumberGenerator rng(kRandomSeeds[n]);
- for (int max = 1; max <= kMaxRuns; ++max) {
- int n = rng.NextInt(max);
- CHECK_LE(0, n);
- CHECK_LT(n, max);
- }
- }
-}
-
-
-TEST(NextBoolReturnsBooleanValue) {
- for (unsigned n = 0; n < ARRAY_SIZE(kRandomSeeds); ++n) {
- RandomNumberGenerator rng(kRandomSeeds[n]);
- for (int k = 0; k < kMaxRuns; ++k) {
- bool b = rng.NextBool();
- CHECK(b == false || b == true);
- }
- }
-}
-
-
-TEST(NextDoubleRange) {
- for (unsigned n = 0; n < ARRAY_SIZE(kRandomSeeds); ++n) {
- RandomNumberGenerator rng(kRandomSeeds[n]);
- for (int k = 0; k < kMaxRuns; ++k) {
- double d = rng.NextDouble();
- CHECK_LE(0.0, d);
- CHECK_LT(d, 1.0);
- }
- }
-}
-
-
TEST(RandomSeedFlagIsUsed) {
for (unsigned n = 0; n < ARRAY_SIZE(kRandomSeeds); ++n) {
FLAG_random_seed = kRandomSeeds[n];
- RandomNumberGenerator rng1;
- RandomNumberGenerator rng2(kRandomSeeds[n]);
+ v8::Isolate* i = v8::Isolate::New();
+ v8::base::RandomNumberGenerator& rng1 =
+ *reinterpret_cast<Isolate*>(i)->random_number_generator();
+ v8::base::RandomNumberGenerator rng2(kRandomSeeds[n]);
for (int k = 1; k <= kMaxRuns; ++k) {
int64_t i1, i2;
rng1.NextBytes(&i1, sizeof(i1));
@@ -88,5 +56,6 @@ TEST(RandomSeedFlagIsUsed) {
CHECK_EQ(rng2.NextInt(k), rng1.NextInt(k));
CHECK_EQ(rng2.NextDouble(), rng1.NextDouble());
}
+ i->Dispose();
}
}
diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc
index 10b227c8e..5c1764eac 100644
--- a/deps/v8/test/cctest/test-regexp.cc
+++ b/deps/v8/test/cctest/test-regexp.cc
@@ -28,48 +28,58 @@
#include <stdlib.h>
-#include "v8.h"
-
-#include "ast.h"
-#include "char-predicates-inl.h"
-#include "cctest.h"
-#include "jsregexp.h"
-#include "parser.h"
-#include "regexp-macro-assembler.h"
-#include "regexp-macro-assembler-irregexp.h"
-#include "string-stream.h"
-#include "zone-inl.h"
+#include "src/v8.h"
+
+#include "src/ast.h"
+#include "src/char-predicates-inl.h"
+#include "src/jsregexp.h"
+#include "src/ostreams.h"
+#include "src/parser.h"
+#include "src/regexp-macro-assembler.h"
+#include "src/regexp-macro-assembler-irregexp.h"
+#include "src/string-stream.h"
+#include "src/zone-inl.h"
#ifdef V8_INTERPRETED_REGEXP
-#include "interpreter-irregexp.h"
+#include "src/interpreter-irregexp.h"
#else // V8_INTERPRETED_REGEXP
-#include "macro-assembler.h"
-#include "code.h"
+#include "src/macro-assembler.h"
#if V8_TARGET_ARCH_ARM
-#include "arm/assembler-arm.h"
-#include "arm/macro-assembler-arm.h"
-#include "arm/regexp-macro-assembler-arm.h"
+#include "src/arm/assembler-arm.h" // NOLINT
+#include "src/arm/macro-assembler-arm.h"
+#include "src/arm/regexp-macro-assembler-arm.h"
#endif
#if V8_TARGET_ARCH_ARM64
-#include "arm64/assembler-arm64.h"
-#include "arm64/macro-assembler-arm64.h"
-#include "arm64/regexp-macro-assembler-arm64.h"
+#include "src/arm64/assembler-arm64.h"
+#include "src/arm64/macro-assembler-arm64.h"
+#include "src/arm64/regexp-macro-assembler-arm64.h"
#endif
#if V8_TARGET_ARCH_MIPS
-#include "mips/assembler-mips.h"
-#include "mips/macro-assembler-mips.h"
-#include "mips/regexp-macro-assembler-mips.h"
+#include "src/mips/assembler-mips.h"
+#include "src/mips/macro-assembler-mips.h"
+#include "src/mips/regexp-macro-assembler-mips.h"
+#endif
+#if V8_TARGET_ARCH_MIPS64
+#include "src/mips64/assembler-mips64.h"
+#include "src/mips64/macro-assembler-mips64.h"
+#include "src/mips64/regexp-macro-assembler-mips64.h"
#endif
#if V8_TARGET_ARCH_X64
-#include "x64/assembler-x64.h"
-#include "x64/macro-assembler-x64.h"
-#include "x64/regexp-macro-assembler-x64.h"
+#include "src/x64/assembler-x64.h"
+#include "src/x64/macro-assembler-x64.h"
+#include "src/x64/regexp-macro-assembler-x64.h"
#endif
#if V8_TARGET_ARCH_IA32
-#include "ia32/assembler-ia32.h"
-#include "ia32/macro-assembler-ia32.h"
-#include "ia32/regexp-macro-assembler-ia32.h"
+#include "src/ia32/assembler-ia32.h"
+#include "src/ia32/macro-assembler-ia32.h"
+#include "src/ia32/regexp-macro-assembler-ia32.h"
+#endif
+#if V8_TARGET_ARCH_X87
+#include "src/x87/assembler-x87.h"
+#include "src/x87/macro-assembler-x87.h"
+#include "src/x87/regexp-macro-assembler-x87.h"
#endif
#endif // V8_INTERPRETED_REGEXP
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -85,7 +95,7 @@ static bool CheckParse(const char* input) {
}
-static SmartArrayPointer<const char> Parse(const char* input) {
+static void CheckParseEq(const char* input, const char* expected) {
V8::Initialize(NULL);
v8::HandleScope scope(CcTest::isolate());
Zone zone(CcTest::i_isolate());
@@ -95,8 +105,9 @@ static SmartArrayPointer<const char> Parse(const char* input) {
&reader, false, &result, &zone));
CHECK(result.tree != NULL);
CHECK(result.error.is_null());
- SmartArrayPointer<const char> output = result.tree->ToString(&zone);
- return output;
+ OStringStream os;
+ result.tree->Print(os, &zone);
+ CHECK_EQ(expected, os.c_str());
}
@@ -137,7 +148,6 @@ static MinMaxPair CheckMinMaxMatch(const char* input) {
#define CHECK_PARSE_ERROR(input) CHECK(!CheckParse(input))
-#define CHECK_PARSE_EQ(input, expected) CHECK_EQ(expected, Parse(input).get())
#define CHECK_SIMPLE(input, simple) CHECK_EQ(simple, CheckSimple(input));
#define CHECK_MIN_MAX(input, min, max) \
{ MinMaxPair min_max = CheckMinMaxMatch(input); \
@@ -150,126 +160,129 @@ TEST(Parser) {
CHECK_PARSE_ERROR("?");
- CHECK_PARSE_EQ("abc", "'abc'");
- CHECK_PARSE_EQ("", "%");
- CHECK_PARSE_EQ("abc|def", "(| 'abc' 'def')");
- CHECK_PARSE_EQ("abc|def|ghi", "(| 'abc' 'def' 'ghi')");
- CHECK_PARSE_EQ("^xxx$", "(: @^i 'xxx' @$i)");
- CHECK_PARSE_EQ("ab\\b\\d\\bcd", "(: 'ab' @b [0-9] @b 'cd')");
- CHECK_PARSE_EQ("\\w|\\d", "(| [0-9 A-Z _ a-z] [0-9])");
- CHECK_PARSE_EQ("a*", "(# 0 - g 'a')");
- CHECK_PARSE_EQ("a*?", "(# 0 - n 'a')");
- CHECK_PARSE_EQ("abc+", "(: 'ab' (# 1 - g 'c'))");
- CHECK_PARSE_EQ("abc+?", "(: 'ab' (# 1 - n 'c'))");
- CHECK_PARSE_EQ("xyz?", "(: 'xy' (# 0 1 g 'z'))");
- CHECK_PARSE_EQ("xyz??", "(: 'xy' (# 0 1 n 'z'))");
- CHECK_PARSE_EQ("xyz{0,1}", "(: 'xy' (# 0 1 g 'z'))");
- CHECK_PARSE_EQ("xyz{0,1}?", "(: 'xy' (# 0 1 n 'z'))");
- CHECK_PARSE_EQ("xyz{93}", "(: 'xy' (# 93 93 g 'z'))");
- CHECK_PARSE_EQ("xyz{93}?", "(: 'xy' (# 93 93 n 'z'))");
- CHECK_PARSE_EQ("xyz{1,32}", "(: 'xy' (# 1 32 g 'z'))");
- CHECK_PARSE_EQ("xyz{1,32}?", "(: 'xy' (# 1 32 n 'z'))");
- CHECK_PARSE_EQ("xyz{1,}", "(: 'xy' (# 1 - g 'z'))");
- CHECK_PARSE_EQ("xyz{1,}?", "(: 'xy' (# 1 - n 'z'))");
- CHECK_PARSE_EQ("a\\fb\\nc\\rd\\te\\vf", "'a\\x0cb\\x0ac\\x0dd\\x09e\\x0bf'");
- CHECK_PARSE_EQ("a\\nb\\bc", "(: 'a\\x0ab' @b 'c')");
- CHECK_PARSE_EQ("(?:foo)", "'foo'");
- CHECK_PARSE_EQ("(?: foo )", "' foo '");
- CHECK_PARSE_EQ("(foo|bar|baz)", "(^ (| 'foo' 'bar' 'baz'))");
- CHECK_PARSE_EQ("foo|(bar|baz)|quux", "(| 'foo' (^ (| 'bar' 'baz')) 'quux')");
- CHECK_PARSE_EQ("foo(?=bar)baz", "(: 'foo' (-> + 'bar') 'baz')");
- CHECK_PARSE_EQ("foo(?!bar)baz", "(: 'foo' (-> - 'bar') 'baz')");
- CHECK_PARSE_EQ("()", "(^ %)");
- CHECK_PARSE_EQ("(?=)", "(-> + %)");
- CHECK_PARSE_EQ("[]", "^[\\x00-\\uffff]"); // Doesn't compile on windows
- CHECK_PARSE_EQ("[^]", "[\\x00-\\uffff]"); // \uffff isn't in codepage 1252
- CHECK_PARSE_EQ("[x]", "[x]");
- CHECK_PARSE_EQ("[xyz]", "[x y z]");
- CHECK_PARSE_EQ("[a-zA-Z0-9]", "[a-z A-Z 0-9]");
- CHECK_PARSE_EQ("[-123]", "[- 1 2 3]");
- CHECK_PARSE_EQ("[^123]", "^[1 2 3]");
- CHECK_PARSE_EQ("]", "']'");
- CHECK_PARSE_EQ("}", "'}'");
- CHECK_PARSE_EQ("[a-b-c]", "[a-b - c]");
- CHECK_PARSE_EQ("[\\d]", "[0-9]");
- CHECK_PARSE_EQ("[x\\dz]", "[x 0-9 z]");
- CHECK_PARSE_EQ("[\\d-z]", "[0-9 - z]");
- CHECK_PARSE_EQ("[\\d-\\d]", "[0-9 - 0-9]");
- CHECK_PARSE_EQ("[z-\\d]", "[z - 0-9]");
+ CheckParseEq("abc", "'abc'");
+ CheckParseEq("", "%");
+ CheckParseEq("abc|def", "(| 'abc' 'def')");
+ CheckParseEq("abc|def|ghi", "(| 'abc' 'def' 'ghi')");
+ CheckParseEq("^xxx$", "(: @^i 'xxx' @$i)");
+ CheckParseEq("ab\\b\\d\\bcd", "(: 'ab' @b [0-9] @b 'cd')");
+ CheckParseEq("\\w|\\d", "(| [0-9 A-Z _ a-z] [0-9])");
+ CheckParseEq("a*", "(# 0 - g 'a')");
+ CheckParseEq("a*?", "(# 0 - n 'a')");
+ CheckParseEq("abc+", "(: 'ab' (# 1 - g 'c'))");
+ CheckParseEq("abc+?", "(: 'ab' (# 1 - n 'c'))");
+ CheckParseEq("xyz?", "(: 'xy' (# 0 1 g 'z'))");
+ CheckParseEq("xyz??", "(: 'xy' (# 0 1 n 'z'))");
+ CheckParseEq("xyz{0,1}", "(: 'xy' (# 0 1 g 'z'))");
+ CheckParseEq("xyz{0,1}?", "(: 'xy' (# 0 1 n 'z'))");
+ CheckParseEq("xyz{93}", "(: 'xy' (# 93 93 g 'z'))");
+ CheckParseEq("xyz{93}?", "(: 'xy' (# 93 93 n 'z'))");
+ CheckParseEq("xyz{1,32}", "(: 'xy' (# 1 32 g 'z'))");
+ CheckParseEq("xyz{1,32}?", "(: 'xy' (# 1 32 n 'z'))");
+ CheckParseEq("xyz{1,}", "(: 'xy' (# 1 - g 'z'))");
+ CheckParseEq("xyz{1,}?", "(: 'xy' (# 1 - n 'z'))");
+ CheckParseEq("a\\fb\\nc\\rd\\te\\vf", "'a\\x0cb\\x0ac\\x0dd\\x09e\\x0bf'");
+ CheckParseEq("a\\nb\\bc", "(: 'a\\x0ab' @b 'c')");
+ CheckParseEq("(?:foo)", "'foo'");
+ CheckParseEq("(?: foo )", "' foo '");
+ CheckParseEq("(foo|bar|baz)", "(^ (| 'foo' 'bar' 'baz'))");
+ CheckParseEq("foo|(bar|baz)|quux", "(| 'foo' (^ (| 'bar' 'baz')) 'quux')");
+ CheckParseEq("foo(?=bar)baz", "(: 'foo' (-> + 'bar') 'baz')");
+ CheckParseEq("foo(?!bar)baz", "(: 'foo' (-> - 'bar') 'baz')");
+ CheckParseEq("()", "(^ %)");
+ CheckParseEq("(?=)", "(-> + %)");
+ CheckParseEq("[]", "^[\\x00-\\uffff]"); // Doesn't compile on windows
+ CheckParseEq("[^]", "[\\x00-\\uffff]"); // \uffff isn't in codepage 1252
+ CheckParseEq("[x]", "[x]");
+ CheckParseEq("[xyz]", "[x y z]");
+ CheckParseEq("[a-zA-Z0-9]", "[a-z A-Z 0-9]");
+ CheckParseEq("[-123]", "[- 1 2 3]");
+ CheckParseEq("[^123]", "^[1 2 3]");
+ CheckParseEq("]", "']'");
+ CheckParseEq("}", "'}'");
+ CheckParseEq("[a-b-c]", "[a-b - c]");
+ CheckParseEq("[\\d]", "[0-9]");
+ CheckParseEq("[x\\dz]", "[x 0-9 z]");
+ CheckParseEq("[\\d-z]", "[0-9 - z]");
+ CheckParseEq("[\\d-\\d]", "[0-9 - 0-9]");
+ CheckParseEq("[z-\\d]", "[z - 0-9]");
// Control character outside character class.
- CHECK_PARSE_EQ("\\cj\\cJ\\ci\\cI\\ck\\cK",
- "'\\x0a\\x0a\\x09\\x09\\x0b\\x0b'");
- CHECK_PARSE_EQ("\\c!", "'\\c!'");
- CHECK_PARSE_EQ("\\c_", "'\\c_'");
- CHECK_PARSE_EQ("\\c~", "'\\c~'");
- CHECK_PARSE_EQ("\\c1", "'\\c1'");
+ CheckParseEq("\\cj\\cJ\\ci\\cI\\ck\\cK", "'\\x0a\\x0a\\x09\\x09\\x0b\\x0b'");
+ CheckParseEq("\\c!", "'\\c!'");
+ CheckParseEq("\\c_", "'\\c_'");
+ CheckParseEq("\\c~", "'\\c~'");
+ CheckParseEq("\\c1", "'\\c1'");
// Control character inside character class.
- CHECK_PARSE_EQ("[\\c!]", "[\\ c !]");
- CHECK_PARSE_EQ("[\\c_]", "[\\x1f]");
- CHECK_PARSE_EQ("[\\c~]", "[\\ c ~]");
- CHECK_PARSE_EQ("[\\ca]", "[\\x01]");
- CHECK_PARSE_EQ("[\\cz]", "[\\x1a]");
- CHECK_PARSE_EQ("[\\cA]", "[\\x01]");
- CHECK_PARSE_EQ("[\\cZ]", "[\\x1a]");
- CHECK_PARSE_EQ("[\\c1]", "[\\x11]");
-
- CHECK_PARSE_EQ("[a\\]c]", "[a ] c]");
- CHECK_PARSE_EQ("\\[\\]\\{\\}\\(\\)\\%\\^\\#\\ ", "'[]{}()%^# '");
- CHECK_PARSE_EQ("[\\[\\]\\{\\}\\(\\)\\%\\^\\#\\ ]", "[[ ] { } ( ) % ^ # ]");
- CHECK_PARSE_EQ("\\0", "'\\x00'");
- CHECK_PARSE_EQ("\\8", "'8'");
- CHECK_PARSE_EQ("\\9", "'9'");
- CHECK_PARSE_EQ("\\11", "'\\x09'");
- CHECK_PARSE_EQ("\\11a", "'\\x09a'");
- CHECK_PARSE_EQ("\\011", "'\\x09'");
- CHECK_PARSE_EQ("\\00011", "'\\x0011'");
- CHECK_PARSE_EQ("\\118", "'\\x098'");
- CHECK_PARSE_EQ("\\111", "'I'");
- CHECK_PARSE_EQ("\\1111", "'I1'");
- CHECK_PARSE_EQ("(x)(x)(x)\\1", "(: (^ 'x') (^ 'x') (^ 'x') (<- 1))");
- CHECK_PARSE_EQ("(x)(x)(x)\\2", "(: (^ 'x') (^ 'x') (^ 'x') (<- 2))");
- CHECK_PARSE_EQ("(x)(x)(x)\\3", "(: (^ 'x') (^ 'x') (^ 'x') (<- 3))");
- CHECK_PARSE_EQ("(x)(x)(x)\\4", "(: (^ 'x') (^ 'x') (^ 'x') '\\x04')");
- CHECK_PARSE_EQ("(x)(x)(x)\\1*", "(: (^ 'x') (^ 'x') (^ 'x')"
- " (# 0 - g (<- 1)))");
- CHECK_PARSE_EQ("(x)(x)(x)\\2*", "(: (^ 'x') (^ 'x') (^ 'x')"
- " (# 0 - g (<- 2)))");
- CHECK_PARSE_EQ("(x)(x)(x)\\3*", "(: (^ 'x') (^ 'x') (^ 'x')"
- " (# 0 - g (<- 3)))");
- CHECK_PARSE_EQ("(x)(x)(x)\\4*", "(: (^ 'x') (^ 'x') (^ 'x')"
- " (# 0 - g '\\x04'))");
- CHECK_PARSE_EQ("(x)(x)(x)(x)(x)(x)(x)(x)(x)(x)\\10",
- "(: (^ 'x') (^ 'x') (^ 'x') (^ 'x') (^ 'x') (^ 'x')"
- " (^ 'x') (^ 'x') (^ 'x') (^ 'x') (<- 10))");
- CHECK_PARSE_EQ("(x)(x)(x)(x)(x)(x)(x)(x)(x)(x)\\11",
- "(: (^ 'x') (^ 'x') (^ 'x') (^ 'x') (^ 'x') (^ 'x')"
- " (^ 'x') (^ 'x') (^ 'x') (^ 'x') '\\x09')");
- CHECK_PARSE_EQ("(a)\\1", "(: (^ 'a') (<- 1))");
- CHECK_PARSE_EQ("(a\\1)", "(^ 'a')");
- CHECK_PARSE_EQ("(\\1a)", "(^ 'a')");
- CHECK_PARSE_EQ("(?=a)?a", "'a'");
- CHECK_PARSE_EQ("(?=a){0,10}a", "'a'");
- CHECK_PARSE_EQ("(?=a){1,10}a", "(: (-> + 'a') 'a')");
- CHECK_PARSE_EQ("(?=a){9,10}a", "(: (-> + 'a') 'a')");
- CHECK_PARSE_EQ("(?!a)?a", "'a'");
- CHECK_PARSE_EQ("\\1(a)", "(^ 'a')");
- CHECK_PARSE_EQ("(?!(a))\\1", "(: (-> - (^ 'a')) (<- 1))");
- CHECK_PARSE_EQ("(?!\\1(a\\1)\\1)\\1", "(: (-> - (: (^ 'a') (<- 1))) (<- 1))");
- CHECK_PARSE_EQ("[\\0]", "[\\x00]");
- CHECK_PARSE_EQ("[\\11]", "[\\x09]");
- CHECK_PARSE_EQ("[\\11a]", "[\\x09 a]");
- CHECK_PARSE_EQ("[\\011]", "[\\x09]");
- CHECK_PARSE_EQ("[\\00011]", "[\\x00 1 1]");
- CHECK_PARSE_EQ("[\\118]", "[\\x09 8]");
- CHECK_PARSE_EQ("[\\111]", "[I]");
- CHECK_PARSE_EQ("[\\1111]", "[I 1]");
- CHECK_PARSE_EQ("\\x34", "'\x34'");
- CHECK_PARSE_EQ("\\x60", "'\x60'");
- CHECK_PARSE_EQ("\\x3z", "'x3z'");
- CHECK_PARSE_EQ("\\c", "'\\c'");
- CHECK_PARSE_EQ("\\u0034", "'\x34'");
- CHECK_PARSE_EQ("\\u003z", "'u003z'");
- CHECK_PARSE_EQ("foo[z]*", "(: 'foo' (# 0 - g [z]))");
+ CheckParseEq("[\\c!]", "[\\ c !]");
+ CheckParseEq("[\\c_]", "[\\x1f]");
+ CheckParseEq("[\\c~]", "[\\ c ~]");
+ CheckParseEq("[\\ca]", "[\\x01]");
+ CheckParseEq("[\\cz]", "[\\x1a]");
+ CheckParseEq("[\\cA]", "[\\x01]");
+ CheckParseEq("[\\cZ]", "[\\x1a]");
+ CheckParseEq("[\\c1]", "[\\x11]");
+
+ CheckParseEq("[a\\]c]", "[a ] c]");
+ CheckParseEq("\\[\\]\\{\\}\\(\\)\\%\\^\\#\\ ", "'[]{}()%^# '");
+ CheckParseEq("[\\[\\]\\{\\}\\(\\)\\%\\^\\#\\ ]", "[[ ] { } ( ) % ^ # ]");
+ CheckParseEq("\\0", "'\\x00'");
+ CheckParseEq("\\8", "'8'");
+ CheckParseEq("\\9", "'9'");
+ CheckParseEq("\\11", "'\\x09'");
+ CheckParseEq("\\11a", "'\\x09a'");
+ CheckParseEq("\\011", "'\\x09'");
+ CheckParseEq("\\00011", "'\\x0011'");
+ CheckParseEq("\\118", "'\\x098'");
+ CheckParseEq("\\111", "'I'");
+ CheckParseEq("\\1111", "'I1'");
+ CheckParseEq("(x)(x)(x)\\1", "(: (^ 'x') (^ 'x') (^ 'x') (<- 1))");
+ CheckParseEq("(x)(x)(x)\\2", "(: (^ 'x') (^ 'x') (^ 'x') (<- 2))");
+ CheckParseEq("(x)(x)(x)\\3", "(: (^ 'x') (^ 'x') (^ 'x') (<- 3))");
+ CheckParseEq("(x)(x)(x)\\4", "(: (^ 'x') (^ 'x') (^ 'x') '\\x04')");
+ CheckParseEq("(x)(x)(x)\\1*",
+ "(: (^ 'x') (^ 'x') (^ 'x')"
+ " (# 0 - g (<- 1)))");
+ CheckParseEq("(x)(x)(x)\\2*",
+ "(: (^ 'x') (^ 'x') (^ 'x')"
+ " (# 0 - g (<- 2)))");
+ CheckParseEq("(x)(x)(x)\\3*",
+ "(: (^ 'x') (^ 'x') (^ 'x')"
+ " (# 0 - g (<- 3)))");
+ CheckParseEq("(x)(x)(x)\\4*",
+ "(: (^ 'x') (^ 'x') (^ 'x')"
+ " (# 0 - g '\\x04'))");
+ CheckParseEq("(x)(x)(x)(x)(x)(x)(x)(x)(x)(x)\\10",
+ "(: (^ 'x') (^ 'x') (^ 'x') (^ 'x') (^ 'x') (^ 'x')"
+ " (^ 'x') (^ 'x') (^ 'x') (^ 'x') (<- 10))");
+ CheckParseEq("(x)(x)(x)(x)(x)(x)(x)(x)(x)(x)\\11",
+ "(: (^ 'x') (^ 'x') (^ 'x') (^ 'x') (^ 'x') (^ 'x')"
+ " (^ 'x') (^ 'x') (^ 'x') (^ 'x') '\\x09')");
+ CheckParseEq("(a)\\1", "(: (^ 'a') (<- 1))");
+ CheckParseEq("(a\\1)", "(^ 'a')");
+ CheckParseEq("(\\1a)", "(^ 'a')");
+ CheckParseEq("(?=a)?a", "'a'");
+ CheckParseEq("(?=a){0,10}a", "'a'");
+ CheckParseEq("(?=a){1,10}a", "(: (-> + 'a') 'a')");
+ CheckParseEq("(?=a){9,10}a", "(: (-> + 'a') 'a')");
+ CheckParseEq("(?!a)?a", "'a'");
+ CheckParseEq("\\1(a)", "(^ 'a')");
+ CheckParseEq("(?!(a))\\1", "(: (-> - (^ 'a')) (<- 1))");
+ CheckParseEq("(?!\\1(a\\1)\\1)\\1", "(: (-> - (: (^ 'a') (<- 1))) (<- 1))");
+ CheckParseEq("[\\0]", "[\\x00]");
+ CheckParseEq("[\\11]", "[\\x09]");
+ CheckParseEq("[\\11a]", "[\\x09 a]");
+ CheckParseEq("[\\011]", "[\\x09]");
+ CheckParseEq("[\\00011]", "[\\x00 1 1]");
+ CheckParseEq("[\\118]", "[\\x09 8]");
+ CheckParseEq("[\\111]", "[I]");
+ CheckParseEq("[\\1111]", "[I 1]");
+ CheckParseEq("\\x34", "'\x34'");
+ CheckParseEq("\\x60", "'\x60'");
+ CheckParseEq("\\x3z", "'x3z'");
+ CheckParseEq("\\c", "'\\c'");
+ CheckParseEq("\\u0034", "'\x34'");
+ CheckParseEq("\\u003z", "'u003z'");
+ CheckParseEq("foo[z]*", "(: 'foo' (# 0 - g [z]))");
CHECK_SIMPLE("", false);
CHECK_SIMPLE("a", true);
@@ -317,22 +330,22 @@ TEST(Parser) {
CHECK_SIMPLE("(?!a)?a\\1", false);
CHECK_SIMPLE("(?:(?=a))a\\1", false);
- CHECK_PARSE_EQ("a{}", "'a{}'");
- CHECK_PARSE_EQ("a{,}", "'a{,}'");
- CHECK_PARSE_EQ("a{", "'a{'");
- CHECK_PARSE_EQ("a{z}", "'a{z}'");
- CHECK_PARSE_EQ("a{1z}", "'a{1z}'");
- CHECK_PARSE_EQ("a{12z}", "'a{12z}'");
- CHECK_PARSE_EQ("a{12,", "'a{12,'");
- CHECK_PARSE_EQ("a{12,3b", "'a{12,3b'");
- CHECK_PARSE_EQ("{}", "'{}'");
- CHECK_PARSE_EQ("{,}", "'{,}'");
- CHECK_PARSE_EQ("{", "'{'");
- CHECK_PARSE_EQ("{z}", "'{z}'");
- CHECK_PARSE_EQ("{1z}", "'{1z}'");
- CHECK_PARSE_EQ("{12z}", "'{12z}'");
- CHECK_PARSE_EQ("{12,", "'{12,'");
- CHECK_PARSE_EQ("{12,3b", "'{12,3b'");
+ CheckParseEq("a{}", "'a{}'");
+ CheckParseEq("a{,}", "'a{,}'");
+ CheckParseEq("a{", "'a{'");
+ CheckParseEq("a{z}", "'a{z}'");
+ CheckParseEq("a{1z}", "'a{1z}'");
+ CheckParseEq("a{12z}", "'a{12z}'");
+ CheckParseEq("a{12,", "'a{12,'");
+ CheckParseEq("a{12,3b", "'a{12,3b'");
+ CheckParseEq("{}", "'{}'");
+ CheckParseEq("{,}", "'{,}'");
+ CheckParseEq("{", "'{'");
+ CheckParseEq("{z}", "'{z}'");
+ CheckParseEq("{1z}", "'{1z}'");
+ CheckParseEq("{12z}", "'{12z}'");
+ CheckParseEq("{12,", "'{12,'");
+ CheckParseEq("{12,3b", "'{12,3b'");
CHECK_MIN_MAX("a", 1, 1);
CHECK_MIN_MAX("abc", 3, 3);
@@ -386,10 +399,10 @@ TEST(Parser) {
TEST(ParserRegression) {
- CHECK_PARSE_EQ("[A-Z$-][x]", "(! [A-Z $ -] [x])");
- CHECK_PARSE_EQ("a{3,4*}", "(: 'a{3,' (# 0 - g '4') '}')");
- CHECK_PARSE_EQ("{", "'{'");
- CHECK_PARSE_EQ("a|", "(| 'a' %)");
+ CheckParseEq("[A-Z$-][x]", "(! [A-Z $ -] [x])");
+ CheckParseEq("a{3,4*}", "(: 'a{3,' (# 0 - g '4') '}')");
+ CheckParseEq("{", "'{'");
+ CheckParseEq("a|", "(| 'a' %)");
}
static void ExpectError(const char* input,
@@ -429,13 +442,11 @@ TEST(Errors) {
// Check that we don't allow more than kMaxCapture captures
const int kMaxCaptures = 1 << 16; // Must match RegExpParser::kMaxCaptures.
const char* kTooManyCaptures = "Too many captures";
- HeapStringAllocator allocator;
- StringStream accumulator(&allocator);
+ OStringStream os;
for (int i = 0; i <= kMaxCaptures; i++) {
- accumulator.Add("()");
+ os << "()";
}
- SmartArrayPointer<const char> many_captures(accumulator.ToCString());
- ExpectError(many_captures.get(), kTooManyCaptures);
+ ExpectError(os.c_str(), kTooManyCaptures);
}
@@ -663,11 +674,11 @@ TEST(ParsePossessiveRepetition) {
// Enable possessive quantifier syntax.
FLAG_regexp_possessive_quantifier = true;
- CHECK_PARSE_EQ("a*+", "(# 0 - p 'a')");
- CHECK_PARSE_EQ("a++", "(# 1 - p 'a')");
- CHECK_PARSE_EQ("a?+", "(# 0 1 p 'a')");
- CHECK_PARSE_EQ("a{10,20}+", "(# 10 20 p 'a')");
- CHECK_PARSE_EQ("za{10,20}+b", "(: 'z' (# 10 20 p 'a') 'b')");
+ CheckParseEq("a*+", "(# 0 - p 'a')");
+ CheckParseEq("a++", "(# 1 - p 'a')");
+ CheckParseEq("a?+", "(# 0 1 p 'a')");
+ CheckParseEq("a{10,20}+", "(# 10 20 p 'a')");
+ CheckParseEq("za{10,20}+b", "(: 'z' (# 10 20 p 'a') 'b')");
// Disable possessive quantifier syntax.
FLAG_regexp_possessive_quantifier = false;
@@ -698,6 +709,10 @@ typedef RegExpMacroAssemblerARM ArchRegExpMacroAssembler;
typedef RegExpMacroAssemblerARM64 ArchRegExpMacroAssembler;
#elif V8_TARGET_ARCH_MIPS
typedef RegExpMacroAssemblerMIPS ArchRegExpMacroAssembler;
+#elif V8_TARGET_ARCH_MIPS64
+typedef RegExpMacroAssemblerMIPS ArchRegExpMacroAssembler;
+#elif V8_TARGET_ARCH_X87
+typedef RegExpMacroAssemblerX87 ArchRegExpMacroAssembler;
#endif
class ContextInitializer {
@@ -1668,26 +1683,26 @@ TEST(CanonicalizeCharacterSets) {
list->Add(CharacterRange(30, 40), &zone);
list->Add(CharacterRange(50, 60), &zone);
set.Canonicalize();
- ASSERT_EQ(3, list->length());
- ASSERT_EQ(10, list->at(0).from());
- ASSERT_EQ(20, list->at(0).to());
- ASSERT_EQ(30, list->at(1).from());
- ASSERT_EQ(40, list->at(1).to());
- ASSERT_EQ(50, list->at(2).from());
- ASSERT_EQ(60, list->at(2).to());
+ DCHECK_EQ(3, list->length());
+ DCHECK_EQ(10, list->at(0).from());
+ DCHECK_EQ(20, list->at(0).to());
+ DCHECK_EQ(30, list->at(1).from());
+ DCHECK_EQ(40, list->at(1).to());
+ DCHECK_EQ(50, list->at(2).from());
+ DCHECK_EQ(60, list->at(2).to());
list->Rewind(0);
list->Add(CharacterRange(10, 20), &zone);
list->Add(CharacterRange(50, 60), &zone);
list->Add(CharacterRange(30, 40), &zone);
set.Canonicalize();
- ASSERT_EQ(3, list->length());
- ASSERT_EQ(10, list->at(0).from());
- ASSERT_EQ(20, list->at(0).to());
- ASSERT_EQ(30, list->at(1).from());
- ASSERT_EQ(40, list->at(1).to());
- ASSERT_EQ(50, list->at(2).from());
- ASSERT_EQ(60, list->at(2).to());
+ DCHECK_EQ(3, list->length());
+ DCHECK_EQ(10, list->at(0).from());
+ DCHECK_EQ(20, list->at(0).to());
+ DCHECK_EQ(30, list->at(1).from());
+ DCHECK_EQ(40, list->at(1).to());
+ DCHECK_EQ(50, list->at(2).from());
+ DCHECK_EQ(60, list->at(2).to());
list->Rewind(0);
list->Add(CharacterRange(30, 40), &zone);
@@ -1696,26 +1711,26 @@ TEST(CanonicalizeCharacterSets) {
list->Add(CharacterRange(100, 100), &zone);
list->Add(CharacterRange(1, 1), &zone);
set.Canonicalize();
- ASSERT_EQ(5, list->length());
- ASSERT_EQ(1, list->at(0).from());
- ASSERT_EQ(1, list->at(0).to());
- ASSERT_EQ(10, list->at(1).from());
- ASSERT_EQ(20, list->at(1).to());
- ASSERT_EQ(25, list->at(2).from());
- ASSERT_EQ(25, list->at(2).to());
- ASSERT_EQ(30, list->at(3).from());
- ASSERT_EQ(40, list->at(3).to());
- ASSERT_EQ(100, list->at(4).from());
- ASSERT_EQ(100, list->at(4).to());
+ DCHECK_EQ(5, list->length());
+ DCHECK_EQ(1, list->at(0).from());
+ DCHECK_EQ(1, list->at(0).to());
+ DCHECK_EQ(10, list->at(1).from());
+ DCHECK_EQ(20, list->at(1).to());
+ DCHECK_EQ(25, list->at(2).from());
+ DCHECK_EQ(25, list->at(2).to());
+ DCHECK_EQ(30, list->at(3).from());
+ DCHECK_EQ(40, list->at(3).to());
+ DCHECK_EQ(100, list->at(4).from());
+ DCHECK_EQ(100, list->at(4).to());
list->Rewind(0);
list->Add(CharacterRange(10, 19), &zone);
list->Add(CharacterRange(21, 30), &zone);
list->Add(CharacterRange(20, 20), &zone);
set.Canonicalize();
- ASSERT_EQ(1, list->length());
- ASSERT_EQ(10, list->at(0).from());
- ASSERT_EQ(30, list->at(0).to());
+ DCHECK_EQ(1, list->length());
+ DCHECK_EQ(10, list->at(0).from());
+ DCHECK_EQ(30, list->at(0).to());
}
@@ -1798,8 +1813,8 @@ TEST(CharacterRangeMerge) {
offset += 9;
}
- ASSERT(CharacterRange::IsCanonical(&l1));
- ASSERT(CharacterRange::IsCanonical(&l2));
+ DCHECK(CharacterRange::IsCanonical(&l1));
+ DCHECK(CharacterRange::IsCanonical(&l2));
ZoneList<CharacterRange> first_only(4, &zone);
ZoneList<CharacterRange> second_only(4, &zone);
diff --git a/deps/v8/test/cctest/test-reloc-info.cc b/deps/v8/test/cctest/test-reloc-info.cc
index 5ab9e803c..94ed287c4 100644
--- a/deps/v8/test/cctest/test-reloc-info.cc
+++ b/deps/v8/test/cctest/test-reloc-info.cc
@@ -26,8 +26,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "cctest.h"
-#include "assembler.h"
+#include "src/assembler.h"
+#include "test/cctest/cctest.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/test/cctest/test-representation.cc b/deps/v8/test/cctest/test-representation.cc
index 95a65cbbf..fc1f53133 100644
--- a/deps/v8/test/cctest/test-representation.cc
+++ b/deps/v8/test/cctest/test-representation.cc
@@ -25,9 +25,10 @@
// (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 "cctest.h"
-#include "types.h"
-#include "property-details.h"
+#include "test/cctest/cctest.h"
+
+#include "src/property-details.h"
+#include "src/types.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-semaphore.cc b/deps/v8/test/cctest/test-semaphore.cc
index 895303f4f..c7fca519d 100644
--- a/deps/v8/test/cctest/test-semaphore.cc
+++ b/deps/v8/test/cctest/test-semaphore.cc
@@ -27,38 +27,39 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "platform.h"
-#include "cctest.h"
+#include "src/base/platform/platform.h"
+#include "test/cctest/cctest.h"
using namespace ::v8::internal;
-class WaitAndSignalThread V8_FINAL : public Thread {
- public:
- explicit WaitAndSignalThread(Semaphore* semaphore)
- : Thread("WaitAndSignalThread"), semaphore_(semaphore) {}
+class WaitAndSignalThread V8_FINAL : public v8::base::Thread {
+ public:
+ explicit WaitAndSignalThread(v8::base::Semaphore* semaphore)
+ : Thread(Options("WaitAndSignalThread")), semaphore_(semaphore) {}
virtual ~WaitAndSignalThread() {}
virtual void Run() V8_OVERRIDE {
for (int n = 0; n < 1000; ++n) {
semaphore_->Wait();
- bool result = semaphore_->WaitFor(TimeDelta::FromMicroseconds(1));
- ASSERT(!result);
+ bool result =
+ semaphore_->WaitFor(v8::base::TimeDelta::FromMicroseconds(1));
+ DCHECK(!result);
USE(result);
semaphore_->Signal();
}
}
- private:
- Semaphore* semaphore_;
+ private:
+ v8::base::Semaphore* semaphore_;
};
TEST(WaitAndSignal) {
- Semaphore semaphore(0);
+ v8::base::Semaphore semaphore(0);
WaitAndSignalThread t1(&semaphore);
WaitAndSignalThread t2(&semaphore);
@@ -73,33 +74,33 @@ TEST(WaitAndSignal) {
semaphore.Wait();
- bool result = semaphore.WaitFor(TimeDelta::FromMicroseconds(1));
- ASSERT(!result);
+ bool result = semaphore.WaitFor(v8::base::TimeDelta::FromMicroseconds(1));
+ DCHECK(!result);
USE(result);
}
TEST(WaitFor) {
bool ok;
- Semaphore semaphore(0);
+ v8::base::Semaphore semaphore(0);
// Semaphore not signalled - timeout.
- ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(0));
+ ok = semaphore.WaitFor(v8::base::TimeDelta::FromMicroseconds(0));
CHECK(!ok);
- ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(100));
+ ok = semaphore.WaitFor(v8::base::TimeDelta::FromMicroseconds(100));
CHECK(!ok);
- ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(1000));
+ ok = semaphore.WaitFor(v8::base::TimeDelta::FromMicroseconds(1000));
CHECK(!ok);
// Semaphore signalled - no timeout.
semaphore.Signal();
- ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(0));
+ ok = semaphore.WaitFor(v8::base::TimeDelta::FromMicroseconds(0));
CHECK(ok);
semaphore.Signal();
- ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(100));
+ ok = semaphore.WaitFor(v8::base::TimeDelta::FromMicroseconds(100));
CHECK(ok);
semaphore.Signal();
- ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(1000));
+ ok = semaphore.WaitFor(v8::base::TimeDelta::FromMicroseconds(1000));
CHECK(ok);
}
@@ -110,13 +111,13 @@ static const int kBufferSize = 4096; // GCD(buffer size, alphabet size) = 1
static char buffer[kBufferSize];
static const int kDataSize = kBufferSize * kAlphabetSize * 10;
-static Semaphore free_space(kBufferSize);
-static Semaphore used_space(0);
+static v8::base::Semaphore free_space(kBufferSize);
+static v8::base::Semaphore used_space(0);
-class ProducerThread V8_FINAL : public Thread {
- public:
- ProducerThread() : Thread("ProducerThread") {}
+class ProducerThread V8_FINAL : public v8::base::Thread {
+ public:
+ ProducerThread() : Thread(Options("ProducerThread")) {}
virtual ~ProducerThread() {}
virtual void Run() V8_OVERRIDE {
@@ -129,15 +130,15 @@ class ProducerThread V8_FINAL : public Thread {
};
-class ConsumerThread V8_FINAL : public Thread {
- public:
- ConsumerThread() : Thread("ConsumerThread") {}
+class ConsumerThread V8_FINAL : public v8::base::Thread {
+ public:
+ ConsumerThread() : Thread(Options("ConsumerThread")) {}
virtual ~ConsumerThread() {}
virtual void Run() V8_OVERRIDE {
for (int n = 0; n < kDataSize; ++n) {
used_space.Wait();
- ASSERT_EQ(static_cast<int>(alphabet[n % kAlphabetSize]),
+ DCHECK_EQ(static_cast<int>(alphabet[n % kAlphabetSize]),
static_cast<int>(buffer[n % kBufferSize]));
free_space.Signal();
}
diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc
index 10c35c1c4..9ae90c477 100644
--- a/deps/v8/test/cctest/test-serialize.cc
+++ b/deps/v8/test/cctest/test-serialize.cc
@@ -27,21 +27,22 @@
#include <signal.h>
-#include "sys/stat.h"
-
-#include "v8.h"
-
-#include "debug.h"
-#include "ic-inl.h"
-#include "runtime.h"
-#include "serialize.h"
-#include "scopeinfo.h"
-#include "snapshot.h"
-#include "cctest.h"
-#include "spaces.h"
-#include "objects.h"
-#include "natives.h"
-#include "bootstrapper.h"
+#include <sys/stat.h>
+
+#include "src/v8.h"
+
+#include "src/bootstrapper.h"
+#include "src/compilation-cache.h"
+#include "src/debug.h"
+#include "src/heap/spaces.h"
+#include "src/ic-inl.h"
+#include "src/natives.h"
+#include "src/objects.h"
+#include "src/runtime.h"
+#include "src/scopeinfo.h"
+#include "src/serialize.h"
+#include "src/snapshot.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -77,7 +78,7 @@ static int* counter_function(const char* name) {
return &local_counters[hash];
}
hash = (hash + 1) % kCounters;
- ASSERT(hash != original_hash); // Hash table has been filled up.
+ DCHECK(hash != original_hash); // Hash table has been filled up.
}
}
@@ -115,21 +116,21 @@ TEST(ExternalReferenceEncoder) {
encoder.Encode(total_compile_size.address()));
ExternalReference stack_limit_address =
ExternalReference::address_of_stack_limit(isolate);
- CHECK_EQ(make_code(UNCLASSIFIED, 4),
+ CHECK_EQ(make_code(UNCLASSIFIED, 2),
encoder.Encode(stack_limit_address.address()));
ExternalReference real_stack_limit_address =
ExternalReference::address_of_real_stack_limit(isolate);
- CHECK_EQ(make_code(UNCLASSIFIED, 5),
+ CHECK_EQ(make_code(UNCLASSIFIED, 3),
encoder.Encode(real_stack_limit_address.address()));
- CHECK_EQ(make_code(UNCLASSIFIED, 16),
+ CHECK_EQ(make_code(UNCLASSIFIED, 8),
encoder.Encode(ExternalReference::debug_break(isolate).address()));
- CHECK_EQ(make_code(UNCLASSIFIED, 10),
- encoder.Encode(
- ExternalReference::new_space_start(isolate).address()));
- CHECK_EQ(make_code(UNCLASSIFIED, 3),
- encoder.Encode(
- ExternalReference::roots_array_start(isolate).address()));
- CHECK_EQ(make_code(UNCLASSIFIED, 52),
+ CHECK_EQ(
+ make_code(UNCLASSIFIED, 4),
+ encoder.Encode(ExternalReference::new_space_start(isolate).address()));
+ CHECK_EQ(
+ make_code(UNCLASSIFIED, 1),
+ encoder.Encode(ExternalReference::roots_array_start(isolate).address()));
+ CHECK_EQ(make_code(UNCLASSIFIED, 34),
encoder.Encode(ExternalReference::cpu_features().address()));
}
@@ -152,20 +153,20 @@ TEST(ExternalReferenceDecoder) {
make_code(STATS_COUNTER,
Counters::k_total_compile_size)));
CHECK_EQ(ExternalReference::address_of_stack_limit(isolate).address(),
- decoder.Decode(make_code(UNCLASSIFIED, 4)));
+ decoder.Decode(make_code(UNCLASSIFIED, 2)));
CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(),
- decoder.Decode(make_code(UNCLASSIFIED, 5)));
+ decoder.Decode(make_code(UNCLASSIFIED, 3)));
CHECK_EQ(ExternalReference::debug_break(isolate).address(),
- decoder.Decode(make_code(UNCLASSIFIED, 16)));
+ decoder.Decode(make_code(UNCLASSIFIED, 8)));
CHECK_EQ(ExternalReference::new_space_start(isolate).address(),
- decoder.Decode(make_code(UNCLASSIFIED, 10)));
+ decoder.Decode(make_code(UNCLASSIFIED, 4)));
}
class FileByteSink : public SnapshotByteSink {
public:
explicit FileByteSink(const char* snapshot_file) {
- fp_ = OS::FOpen(snapshot_file, "wb");
+ fp_ = v8::base::OS::FOpen(snapshot_file, "wb");
file_name_ = snapshot_file;
if (fp_ == NULL) {
PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file);
@@ -177,9 +178,9 @@ class FileByteSink : public SnapshotByteSink {
fclose(fp_);
}
}
- virtual void Put(int byte, const char* description) {
+ virtual void Put(byte b, const char* description) {
if (fp_ != NULL) {
- fputc(byte, fp_);
+ fputc(b, fp_);
}
}
virtual int Position() {
@@ -210,8 +211,8 @@ void FileByteSink::WriteSpaceUsed(
int property_cell_space_used) {
int file_name_length = StrLength(file_name_) + 10;
Vector<char> name = Vector<char>::New(file_name_length + 1);
- OS::SNPrintF(name, "%s.size", file_name_);
- FILE* fp = OS::FOpen(name.start(), "w");
+ SNPrintF(name, "%s.size", file_name_);
+ FILE* fp = v8::base::OS::FOpen(name.start(), "w");
name.Dispose();
fprintf(fp, "new %d\n", new_space_used);
fprintf(fp, "pointer %d\n", pointer_space_used);
@@ -262,7 +263,7 @@ static void Serialize() {
// Test that the whole heap can be serialized.
TEST(Serialize) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
- Serializer::RequestEnable(CcTest::i_isolate());
+ CcTest::i_isolate()->enable_serializer();
v8::V8::Initialize();
Serialize();
}
@@ -272,7 +273,7 @@ TEST(Serialize) {
// Test that heap serialization is non-destructive.
TEST(SerializeTwice) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
- Serializer::RequestEnable(CcTest::i_isolate());
+ CcTest::i_isolate()->enable_serializer();
v8::V8::Initialize();
Serialize();
Serialize();
@@ -283,8 +284,60 @@ TEST(SerializeTwice) {
//----------------------------------------------------------------------------
// Tests that the heap can be deserialized.
+
+static void ReserveSpaceForSnapshot(Deserializer* deserializer,
+ const char* file_name) {
+ int file_name_length = StrLength(file_name) + 10;
+ Vector<char> name = Vector<char>::New(file_name_length + 1);
+ SNPrintF(name, "%s.size", file_name);
+ FILE* fp = v8::base::OS::FOpen(name.start(), "r");
+ name.Dispose();
+ int new_size, pointer_size, data_size, code_size, map_size, cell_size,
+ property_cell_size;
+#ifdef _MSC_VER
+ // Avoid warning about unsafe fscanf from MSVC.
+ // Please note that this is only fine if %c and %s are not being used.
+#define fscanf fscanf_s
+#endif
+ CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size));
+ CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size));
+ CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size));
+ CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
+ CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
+ CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
+ CHECK_EQ(1, fscanf(fp, "property cell %d\n", &property_cell_size));
+#ifdef _MSC_VER
+#undef fscanf
+#endif
+ fclose(fp);
+ deserializer->set_reservation(NEW_SPACE, new_size);
+ deserializer->set_reservation(OLD_POINTER_SPACE, pointer_size);
+ deserializer->set_reservation(OLD_DATA_SPACE, data_size);
+ deserializer->set_reservation(CODE_SPACE, code_size);
+ deserializer->set_reservation(MAP_SPACE, map_size);
+ deserializer->set_reservation(CELL_SPACE, cell_size);
+ deserializer->set_reservation(PROPERTY_CELL_SPACE, property_cell_size);
+}
+
+
+bool InitializeFromFile(const char* snapshot_file) {
+ int len;
+ byte* str = ReadBytes(snapshot_file, &len);
+ if (!str) return false;
+ bool success;
+ {
+ SnapshotByteSource source(str, len);
+ Deserializer deserializer(&source);
+ ReserveSpaceForSnapshot(&deserializer, snapshot_file);
+ success = V8::Initialize(&deserializer);
+ }
+ DeleteArray(str);
+ return success;
+}
+
+
static void Deserialize() {
- CHECK(Snapshot::Initialize(FLAG_testing_serialization_file));
+ CHECK(InitializeFromFile(FLAG_testing_serialization_file));
}
@@ -370,7 +423,7 @@ DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
TEST(PartialSerialization) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
Isolate* isolate = CcTest::i_isolate();
- Serializer::RequestEnable(isolate);
+ CcTest::i_isolate()->enable_serializer();
v8::V8::Initialize();
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
Heap* heap = isolate->heap();
@@ -380,7 +433,7 @@ TEST(PartialSerialization) {
HandleScope scope(isolate);
env.Reset(v8_isolate, v8::Context::New(v8_isolate));
}
- ASSERT(!env.IsEmpty());
+ DCHECK(!env.IsEmpty());
{
v8::HandleScope handle_scope(v8_isolate);
v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
@@ -398,13 +451,13 @@ TEST(PartialSerialization) {
{
v8::HandleScope handle_scope(v8_isolate);
v8::Local<v8::String> foo = v8::String::NewFromUtf8(v8_isolate, "foo");
- ASSERT(!foo.IsEmpty());
+ DCHECK(!foo.IsEmpty());
raw_foo = *(v8::Utils::OpenHandle(*foo));
}
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
- OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
+ SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
{
v8::HandleScope handle_scope(v8_isolate);
@@ -443,48 +496,13 @@ TEST(PartialSerialization) {
}
-static void ReserveSpaceForSnapshot(Deserializer* deserializer,
- const char* file_name) {
- int file_name_length = StrLength(file_name) + 10;
- Vector<char> name = Vector<char>::New(file_name_length + 1);
- OS::SNPrintF(name, "%s.size", file_name);
- FILE* fp = OS::FOpen(name.start(), "r");
- name.Dispose();
- int new_size, pointer_size, data_size, code_size, map_size, cell_size,
- property_cell_size;
-#ifdef _MSC_VER
- // Avoid warning about unsafe fscanf from MSVC.
- // Please note that this is only fine if %c and %s are not being used.
-#define fscanf fscanf_s
-#endif
- CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size));
- CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size));
- CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size));
- CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
- CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
- CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
- CHECK_EQ(1, fscanf(fp, "property cell %d\n", &property_cell_size));
-#ifdef _MSC_VER
-#undef fscanf
-#endif
- fclose(fp);
- deserializer->set_reservation(NEW_SPACE, new_size);
- deserializer->set_reservation(OLD_POINTER_SPACE, pointer_size);
- deserializer->set_reservation(OLD_DATA_SPACE, data_size);
- deserializer->set_reservation(CODE_SPACE, code_size);
- deserializer->set_reservation(MAP_SPACE, map_size);
- deserializer->set_reservation(CELL_SPACE, cell_size);
- deserializer->set_reservation(PROPERTY_CELL_SPACE, property_cell_size);
-}
-
-
DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
- if (!Snapshot::IsEnabled()) {
+ if (!Snapshot::HaveASnapshotToStartFrom()) {
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
- OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
+ SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
- CHECK(Snapshot::Initialize(startup_name.start()));
+ CHECK(InitializeFromFile(startup_name.start()));
startup_name.Dispose();
const char* file_name = FLAG_testing_serialization_file;
@@ -521,7 +539,7 @@ DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
TEST(ContextSerialization) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
Isolate* isolate = CcTest::i_isolate();
- Serializer::RequestEnable(isolate);
+ CcTest::i_isolate()->enable_serializer();
v8::V8::Initialize();
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
Heap* heap = isolate->heap();
@@ -531,7 +549,7 @@ TEST(ContextSerialization) {
HandleScope scope(isolate);
env.Reset(v8_isolate, v8::Context::New(v8_isolate));
}
- ASSERT(!env.IsEmpty());
+ DCHECK(!env.IsEmpty());
{
v8::HandleScope handle_scope(v8_isolate);
v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
@@ -548,7 +566,7 @@ TEST(ContextSerialization) {
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
- OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
+ SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
{
v8::HandleScope handle_scope(v8_isolate);
@@ -594,9 +612,9 @@ DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
- OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
+ SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
- CHECK(Snapshot::Initialize(startup_name.start()));
+ CHECK(InitializeFromFile(startup_name.start()));
startup_name.Dispose();
const char* file_name = FLAG_testing_serialization_file;
@@ -644,3 +662,185 @@ DEPENDENT_TEST(DependentTestThatAlwaysFails, TestThatAlwaysSucceeds) {
bool ArtificialFailure2 = false;
CHECK(ArtificialFailure2);
}
+
+
+int CountBuiltins() {
+ // Check that we have not deserialized any additional builtin.
+ HeapIterator iterator(CcTest::heap());
+ DisallowHeapAllocation no_allocation;
+ int counter = 0;
+ for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
+ if (obj->IsCode() && Code::cast(obj)->kind() == Code::BUILTIN) counter++;
+ }
+ return counter;
+}
+
+
+TEST(SerializeToplevelOnePlusOne) {
+ FLAG_serialize_toplevel = true;
+ LocalContext context;
+ Isolate* isolate = CcTest::i_isolate();
+ isolate->compilation_cache()->Disable(); // Disable same-isolate code cache.
+
+ v8::HandleScope scope(CcTest::isolate());
+
+ const char* source = "1 + 1";
+
+ Handle<String> orig_source = isolate->factory()
+ ->NewStringFromUtf8(CStrVector(source))
+ .ToHandleChecked();
+ Handle<String> copy_source = isolate->factory()
+ ->NewStringFromUtf8(CStrVector(source))
+ .ToHandleChecked();
+ CHECK(!orig_source.is_identical_to(copy_source));
+ CHECK(orig_source->Equals(*copy_source));
+
+ ScriptData* cache = NULL;
+
+ Handle<SharedFunctionInfo> orig = Compiler::CompileScript(
+ orig_source, Handle<String>(), 0, 0, false,
+ Handle<Context>(isolate->native_context()), NULL, &cache,
+ v8::ScriptCompiler::kProduceCodeCache, NOT_NATIVES_CODE);
+
+ int builtins_count = CountBuiltins();
+
+ Handle<SharedFunctionInfo> copy;
+ {
+ DisallowCompilation no_compile_expected(isolate);
+ copy = Compiler::CompileScript(
+ copy_source, Handle<String>(), 0, 0, false,
+ Handle<Context>(isolate->native_context()), NULL, &cache,
+ v8::ScriptCompiler::kConsumeCodeCache, NOT_NATIVES_CODE);
+ }
+
+ CHECK_NE(*orig, *copy);
+ CHECK(Script::cast(copy->script())->source() == *copy_source);
+
+ Handle<JSFunction> copy_fun =
+ isolate->factory()->NewFunctionFromSharedFunctionInfo(
+ copy, isolate->native_context());
+ Handle<JSObject> global(isolate->context()->global_object());
+ Handle<Object> copy_result =
+ Execution::Call(isolate, copy_fun, global, 0, NULL).ToHandleChecked();
+ CHECK_EQ(2, Handle<Smi>::cast(copy_result)->value());
+
+ CHECK_EQ(builtins_count, CountBuiltins());
+
+ delete cache;
+}
+
+
+TEST(SerializeToplevelInternalizedString) {
+ FLAG_serialize_toplevel = true;
+ LocalContext context;
+ Isolate* isolate = CcTest::i_isolate();
+ isolate->compilation_cache()->Disable(); // Disable same-isolate code cache.
+
+ v8::HandleScope scope(CcTest::isolate());
+
+ const char* source = "'string1'";
+
+ Handle<String> orig_source = isolate->factory()
+ ->NewStringFromUtf8(CStrVector(source))
+ .ToHandleChecked();
+ Handle<String> copy_source = isolate->factory()
+ ->NewStringFromUtf8(CStrVector(source))
+ .ToHandleChecked();
+ CHECK(!orig_source.is_identical_to(copy_source));
+ CHECK(orig_source->Equals(*copy_source));
+
+ Handle<JSObject> global(isolate->context()->global_object());
+ ScriptData* cache = NULL;
+
+ Handle<SharedFunctionInfo> orig = Compiler::CompileScript(
+ orig_source, Handle<String>(), 0, 0, false,
+ Handle<Context>(isolate->native_context()), NULL, &cache,
+ v8::ScriptCompiler::kProduceCodeCache, NOT_NATIVES_CODE);
+ Handle<JSFunction> orig_fun =
+ isolate->factory()->NewFunctionFromSharedFunctionInfo(
+ orig, isolate->native_context());
+ Handle<Object> orig_result =
+ Execution::Call(isolate, orig_fun, global, 0, NULL).ToHandleChecked();
+ CHECK(orig_result->IsInternalizedString());
+
+ int builtins_count = CountBuiltins();
+
+ Handle<SharedFunctionInfo> copy;
+ {
+ DisallowCompilation no_compile_expected(isolate);
+ copy = Compiler::CompileScript(
+ copy_source, Handle<String>(), 0, 0, false,
+ Handle<Context>(isolate->native_context()), NULL, &cache,
+ v8::ScriptCompiler::kConsumeCodeCache, NOT_NATIVES_CODE);
+ }
+ CHECK_NE(*orig, *copy);
+ CHECK(Script::cast(copy->script())->source() == *copy_source);
+
+ Handle<JSFunction> copy_fun =
+ isolate->factory()->NewFunctionFromSharedFunctionInfo(
+ copy, isolate->native_context());
+ CHECK_NE(*orig_fun, *copy_fun);
+ Handle<Object> copy_result =
+ Execution::Call(isolate, copy_fun, global, 0, NULL).ToHandleChecked();
+ CHECK(orig_result.is_identical_to(copy_result));
+ Handle<String> expected =
+ isolate->factory()->NewStringFromAsciiChecked("string1");
+
+ CHECK(Handle<String>::cast(copy_result)->Equals(*expected));
+ CHECK_EQ(builtins_count, CountBuiltins());
+
+ delete cache;
+}
+
+
+TEST(SerializeToplevelIsolates) {
+ FLAG_serialize_toplevel = true;
+
+ const char* source = "function f() { return 'abc'; }; f() + 'def'";
+ v8::ScriptCompiler::CachedData* cache;
+
+ v8::Isolate* isolate1 = v8::Isolate::New();
+ v8::Isolate* isolate2 = v8::Isolate::New();
+ {
+ v8::Isolate::Scope iscope(isolate1);
+ v8::HandleScope scope(isolate1);
+ v8::Local<v8::Context> context = v8::Context::New(isolate1);
+ v8::Context::Scope context_scope(context);
+
+ v8::Local<v8::String> source_str = v8_str(source);
+ v8::ScriptOrigin origin(v8_str("test"));
+ v8::ScriptCompiler::Source source(source_str, origin);
+ v8::Local<v8::UnboundScript> script = v8::ScriptCompiler::CompileUnbound(
+ isolate1, &source, v8::ScriptCompiler::kProduceCodeCache);
+ const v8::ScriptCompiler::CachedData* data = source.GetCachedData();
+ // Persist cached data.
+ uint8_t* buffer = NewArray<uint8_t>(data->length);
+ MemCopy(buffer, data->data, data->length);
+ cache = new v8::ScriptCompiler::CachedData(
+ buffer, data->length, v8::ScriptCompiler::CachedData::BufferOwned);
+
+ v8::Local<v8::Value> result = script->BindToCurrentContext()->Run();
+ CHECK(result->ToString()->Equals(v8_str("abcdef")));
+ }
+ isolate1->Dispose();
+
+ {
+ v8::Isolate::Scope iscope(isolate2);
+ v8::HandleScope scope(isolate2);
+ v8::Local<v8::Context> context = v8::Context::New(isolate2);
+ v8::Context::Scope context_scope(context);
+
+ v8::Local<v8::String> source_str = v8_str(source);
+ v8::ScriptOrigin origin(v8_str("test"));
+ v8::ScriptCompiler::Source source(source_str, origin, cache);
+ v8::Local<v8::UnboundScript> script;
+ {
+ DisallowCompilation no_compile(reinterpret_cast<Isolate*>(isolate2));
+ script = v8::ScriptCompiler::CompileUnbound(
+ isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache);
+ }
+ v8::Local<v8::Value> result = script->BindToCurrentContext()->Run();
+ CHECK(result->ToString()->Equals(v8_str("abcdef")));
+ }
+ isolate2->Dispose();
+}
diff --git a/deps/v8/test/cctest/test-socket.cc b/deps/v8/test/cctest/test-socket.cc
deleted file mode 100644
index 47d8b1783..000000000
--- a/deps/v8/test/cctest/test-socket.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// 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.
-
-#include "v8.h"
-#include "platform.h"
-#include "platform/socket.h"
-#include "cctest.h"
-
-
-using namespace ::v8::internal;
-
-
-class SocketListenerThread : public Thread {
- public:
- SocketListenerThread(int port, int data_size)
- : Thread("SocketListenerThread"),
- port_(port),
- data_size_(data_size),
- server_(NULL),
- client_(NULL),
- listening_(0) {
- data_ = new char[data_size_];
- }
- ~SocketListenerThread() {
- // Close both sockets.
- delete client_;
- delete server_;
- delete[] data_;
- }
-
- void Run();
- void WaitForListening() { listening_.Wait(); }
- char* data() { return data_; }
-
- private:
- int port_;
- char* data_;
- int data_size_;
- Socket* server_; // Server socket used for bind/accept.
- Socket* client_; // Single client connection used by the test.
- Semaphore listening_; // Signalled when the server socket is in listen mode.
-};
-
-
-void SocketListenerThread::Run() {
- bool ok;
-
- // Create the server socket and bind it to the requested port.
- server_ = new Socket;
- server_->SetReuseAddress(true);
- CHECK(server_ != NULL);
- ok = server_->Bind(port_);
- CHECK(ok);
-
- // Listen for new connections.
- ok = server_->Listen(1);
- CHECK(ok);
- listening_.Signal();
-
- // Accept a connection.
- client_ = server_->Accept();
- CHECK(client_ != NULL);
-
- // Read the expected niumber of bytes of data.
- int bytes_read = 0;
- while (bytes_read < data_size_) {
- bytes_read += client_->Receive(data_ + bytes_read, data_size_ - bytes_read);
- }
-}
-
-
-static bool SendAll(Socket* socket, const char* data, int len) {
- int sent_len = 0;
- while (sent_len < len) {
- int status = socket->Send(data, len);
- if (status <= 0) {
- return false;
- }
- sent_len += status;
- }
- return true;
-}
-
-
-static void SendAndReceive(int port, char *data, int len) {
- static const char* kLocalhost = "localhost";
-
- bool ok;
-
- // Make a string with the port number.
- const int kPortBuferLen = 6;
- char port_str[kPortBuferLen];
- OS::SNPrintF(Vector<char>(port_str, kPortBuferLen), "%d", port);
-
- // Create a socket listener.
- SocketListenerThread* listener = new SocketListenerThread(port, len);
- listener->Start();
- listener->WaitForListening();
-
- // Connect and write some data.
- Socket* client = new Socket;
- CHECK(client != NULL);
- ok = client->Connect(kLocalhost, port_str);
- CHECK(ok);
-
- // Send all the data.
- ok = SendAll(client, data, len);
- CHECK(ok);
-
- // Wait until data is received.
- listener->Join();
-
- // Check that data received is the same as data send.
- for (int i = 0; i < len; i++) {
- CHECK(data[i] == listener->data()[i]);
- }
-
- // Close the client before the listener to avoid TIME_WAIT issues.
- client->Shutdown();
- delete client;
- delete listener;
-}
-
-
-TEST(Socket) {
- // Make sure this port is not used by other tests to allow tests to run in
- // parallel.
- static const int kPort = 5859 + FlagDependentPortOffset();
-
- // Send and receive some data.
- static const int kBufferSizeSmall = 20;
- char small_data[kBufferSizeSmall + 1] = "1234567890abcdefghij";
- SendAndReceive(kPort, small_data, kBufferSizeSmall);
-
- // Send and receive some more data.
- static const int kBufferSizeMedium = 10000;
- char* medium_data = new char[kBufferSizeMedium];
- for (int i = 0; i < kBufferSizeMedium; i++) {
- medium_data[i] = i % 256;
- }
- SendAndReceive(kPort, medium_data, kBufferSizeMedium);
- delete[] medium_data;
-
- // Send and receive even more data.
- static const int kBufferSizeLarge = 1000000;
- char* large_data = new char[kBufferSizeLarge];
- for (int i = 0; i < kBufferSizeLarge; i++) {
- large_data[i] = i % 256;
- }
- SendAndReceive(kPort, large_data, kBufferSizeLarge);
- delete[] large_data;
-}
diff --git a/deps/v8/test/cctest/test-spaces.cc b/deps/v8/test/cctest/test-spaces.cc
index 47e2536fc..006209440 100644
--- a/deps/v8/test/cctest/test-spaces.cc
+++ b/deps/v8/test/cctest/test-spaces.cc
@@ -27,8 +27,10 @@
#include <stdlib.h>
-#include "v8.h"
-#include "cctest.h"
+#include "src/snapshot.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
using namespace v8::internal;
@@ -169,12 +171,14 @@ static void VerifyMemoryChunk(Isolate* isolate,
commit_area_size,
executable,
NULL);
- size_t alignment = code_range->exists() ?
- MemoryChunk::kAlignment : OS::CommitPageSize();
- size_t reserved_size = ((executable == EXECUTABLE))
- ? RoundUp(header_size + guard_size + reserve_area_size + guard_size,
- alignment)
- : RoundUp(header_size + reserve_area_size, OS::CommitPageSize());
+ size_t alignment = code_range != NULL && code_range->valid() ?
+ MemoryChunk::kAlignment : v8::base::OS::CommitPageSize();
+ size_t reserved_size =
+ ((executable == EXECUTABLE))
+ ? RoundUp(header_size + guard_size + reserve_area_size + guard_size,
+ alignment)
+ : RoundUp(header_size + reserve_area_size,
+ v8::base::OS::CommitPageSize());
CHECK(memory_chunk->size() == reserved_size);
CHECK(memory_chunk->area_start() < memory_chunk->address() +
memory_chunk->size());
@@ -221,7 +225,7 @@ TEST(MemoryChunk) {
// With CodeRange.
CodeRange* code_range = new CodeRange(isolate);
- const int code_range_size = 32 * MB;
+ const size_t code_range_size = 32 * MB;
if (!code_range->SetUp(code_range_size)) return;
VerifyMemoryChunk(isolate,
@@ -393,7 +397,7 @@ TEST(LargeObjectSpace) {
if (allocation.IsRetry()) break;
}
CHECK(lo->Available() < available);
- };
+ }
CHECK(!lo->IsEmpty());
@@ -403,11 +407,15 @@ TEST(LargeObjectSpace) {
TEST(SizeOfFirstPageIsLargeEnough) {
if (i::FLAG_always_opt) return;
+ // Bootstrapping without a snapshot causes more allocations.
+ if (!i::Snapshot::HaveASnapshotToStartFrom()) return;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
// Freshly initialized VM gets by with one page per space.
for (int i = FIRST_PAGED_SPACE; i <= LAST_PAGED_SPACE; i++) {
+ // Debug code can be very large, so skip CODE_SPACE if we are generating it.
+ if (i == CODE_SPACE && i::FLAG_debug_code) continue;
CHECK_EQ(1, isolate->heap()->paged_space(i)->CountTotalPages());
}
@@ -415,6 +423,8 @@ TEST(SizeOfFirstPageIsLargeEnough) {
HandleScope scope(isolate);
CompileRun("/*empty*/");
for (int i = FIRST_PAGED_SPACE; i <= LAST_PAGED_SPACE; i++) {
+ // Debug code can be very large, so skip CODE_SPACE if we are generating it.
+ if (i == CODE_SPACE && i::FLAG_debug_code) continue;
CHECK_EQ(1, isolate->heap()->paged_space(i)->CountTotalPages());
}
diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc
index 706836c1c..b55780182 100644
--- a/deps/v8/test/cctest/test-strings.cc
+++ b/deps/v8/test/cctest/test-strings.cc
@@ -32,12 +32,12 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "api.h"
-#include "factory.h"
-#include "objects.h"
-#include "cctest.h"
+#include "src/api.h"
+#include "src/factory.h"
+#include "src/objects.h"
+#include "test/cctest/cctest.h"
// Adapted from http://en.wikipedia.org/wiki/Multiply-with-carry
class MyRandomNumberGenerator {
@@ -77,7 +77,7 @@ class MyRandomNumberGenerator {
}
bool next(double threshold) {
- ASSERT(threshold >= 0.0 && threshold <= 1.0);
+ DCHECK(threshold >= 0.0 && threshold <= 1.0);
if (threshold == 1.0) return true;
if (threshold == 0.0) return false;
uint32_t value = next() % 100000;
@@ -1201,10 +1201,9 @@ TEST(SliceFromSlice) {
TEST(AsciiArrayJoin) {
// Set heap limits.
- static const int K = 1024;
v8::ResourceConstraints constraints;
- constraints.set_max_new_space_size(2 * K * K);
- constraints.set_max_old_space_size(4 * K * K);
+ constraints.set_max_semi_space_size(1);
+ constraints.set_max_old_space_size(4);
v8::SetResourceConstraints(CcTest::isolate(), &constraints);
// String s is made of 2^17 = 131072 'c' characters and a is an array
diff --git a/deps/v8/test/cctest/test-strtod.cc b/deps/v8/test/cctest/test-strtod.cc
index bebf4d14b..7c1118603 100644
--- a/deps/v8/test/cctest/test-strtod.cc
+++ b/deps/v8/test/cctest/test-strtod.cc
@@ -27,14 +27,14 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "bignum.h"
-#include "cctest.h"
-#include "diy-fp.h"
-#include "double.h"
-#include "strtod.h"
-#include "utils/random-number-generator.h"
+#include "src/base/utils/random-number-generator.h"
+#include "src/bignum.h"
+#include "src/diy-fp.h"
+#include "src/double.h"
+#include "src/strtod.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -449,7 +449,7 @@ static const int kShortStrtodRandomCount = 2;
static const int kLargeStrtodRandomCount = 2;
TEST(RandomStrtod) {
- RandomNumberGenerator rng;
+ v8::base::RandomNumberGenerator rng;
char buffer[kBufferSize];
for (int length = 1; length < 15; length++) {
for (int i = 0; i < kShortStrtodRandomCount; ++i) {
diff --git a/deps/v8/test/cctest/test-symbols.cc b/deps/v8/test/cctest/test-symbols.cc
index f0d0ed160..066c99703 100644
--- a/deps/v8/test/cctest/test-symbols.cc
+++ b/deps/v8/test/cctest/test-symbols.cc
@@ -5,10 +5,11 @@
// of ConsStrings. These operations may not be very fast, but they
// should be possible without getting errors due to too deep recursion.
-#include "v8.h"
+#include "src/v8.h"
-#include "cctest.h"
-#include "objects.h"
+#include "src/objects.h"
+#include "src/ostreams.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -21,16 +22,16 @@ TEST(Create) {
const int kNumSymbols = 30;
Handle<Symbol> symbols[kNumSymbols];
+ OFStream os(stdout);
for (int i = 0; i < kNumSymbols; ++i) {
symbols[i] = isolate->factory()->NewSymbol();
CHECK(symbols[i]->IsName());
CHECK(symbols[i]->IsSymbol());
CHECK(symbols[i]->HasHashCode());
CHECK_GT(symbols[i]->Hash(), 0);
- symbols[i]->ShortPrint();
- PrintF("\n");
+ os << Brief(*symbols[i]) << "\n";
#if OBJECT_PRINT
- symbols[i]->Print();
+ symbols[i]->Print(os);
#endif
#if VERIFY_HEAP
symbols[i]->ObjectVerify();
diff --git a/deps/v8/test/cctest/test-thread-termination.cc b/deps/v8/test/cctest/test-thread-termination.cc
index 569ee95c6..a5ed7ab9b 100644
--- a/deps/v8/test/cctest/test-thread-termination.cc
+++ b/deps/v8/test/cctest/test-thread-termination.cc
@@ -25,12 +25,13 @@
// (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 "platform.h"
-#include "cctest.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+#include "src/base/platform/platform.h"
-v8::internal::Semaphore* semaphore = NULL;
+
+v8::base::Semaphore* semaphore = NULL;
void Signal(const v8::FunctionCallbackInfo<v8::Value>& args) {
@@ -158,11 +159,11 @@ TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) {
}
-class TerminatorThread : public v8::internal::Thread {
+class TerminatorThread : public v8::base::Thread {
public:
explicit TerminatorThread(i::Isolate* isolate)
- : Thread("TerminatorThread"),
- isolate_(reinterpret_cast<v8::Isolate*>(isolate)) { }
+ : Thread(Options("TerminatorThread")),
+ isolate_(reinterpret_cast<v8::Isolate*>(isolate)) {}
void Run() {
semaphore->Wait();
CHECK(!v8::V8::IsExecutionTerminating(isolate_));
@@ -177,7 +178,7 @@ class TerminatorThread : public v8::internal::Thread {
// Test that a single thread of JavaScript execution can be terminated
// from the side by another thread.
TEST(TerminateOnlyV8ThreadFromOtherThread) {
- semaphore = new v8::internal::Semaphore(0);
+ semaphore = new v8::base::Semaphore(0);
TerminatorThread thread(CcTest::i_isolate());
thread.Start();
@@ -358,3 +359,103 @@ TEST(TerminateCancelTerminateFromThreadItself) {
// Check that execution completed with correct return value.
CHECK(v8::Script::Compile(source)->Run()->Equals(v8_str("completed")));
}
+
+
+void MicrotaskShouldNotRun(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(false);
+}
+
+
+void MicrotaskLoopForever(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Isolate* isolate = info.GetIsolate();
+ v8::HandleScope scope(isolate);
+ // Enqueue another should-not-run task to ensure we clean out the queue
+ // when we terminate.
+ isolate->EnqueueMicrotask(v8::Function::New(isolate, MicrotaskShouldNotRun));
+ CompileRun("terminate(); while (true) { }");
+ CHECK(v8::V8::IsExecutionTerminating());
+}
+
+
+TEST(TerminateFromOtherThreadWhileMicrotaskRunning) {
+ semaphore = new v8::base::Semaphore(0);
+ TerminatorThread thread(CcTest::i_isolate());
+ thread.Start();
+
+ v8::Isolate* isolate = CcTest::isolate();
+ isolate->SetAutorunMicrotasks(false);
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> global =
+ CreateGlobalTemplate(CcTest::isolate(), Signal, DoLoop);
+ v8::Handle<v8::Context> context =
+ v8::Context::New(CcTest::isolate(), NULL, global);
+ v8::Context::Scope context_scope(context);
+ isolate->EnqueueMicrotask(v8::Function::New(isolate, MicrotaskLoopForever));
+ // The second task should never be run because we bail out if we're
+ // terminating.
+ isolate->EnqueueMicrotask(v8::Function::New(isolate, MicrotaskShouldNotRun));
+ isolate->RunMicrotasks();
+
+ v8::V8::CancelTerminateExecution(isolate);
+ isolate->RunMicrotasks(); // should not run MicrotaskShouldNotRun
+
+ thread.Join();
+ delete semaphore;
+ semaphore = NULL;
+}
+
+
+static int callback_counter = 0;
+
+
+static void CounterCallback(v8::Isolate* isolate, void* data) {
+ callback_counter++;
+}
+
+
+TEST(PostponeTerminateException) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> global =
+ CreateGlobalTemplate(CcTest::isolate(), TerminateCurrentThread, DoLoop);
+ v8::Handle<v8::Context> context =
+ v8::Context::New(CcTest::isolate(), NULL, global);
+ v8::Context::Scope context_scope(context);
+
+ v8::TryCatch try_catch;
+ static const char* terminate_and_loop =
+ "terminate(); for (var i = 0; i < 10000; i++);";
+
+ { // Postpone terminate execution interrupts.
+ i::PostponeInterruptsScope p1(CcTest::i_isolate(),
+ i::StackGuard::TERMINATE_EXECUTION) ;
+
+ // API interrupts should still be triggered.
+ CcTest::isolate()->RequestInterrupt(&CounterCallback, NULL);
+ CHECK_EQ(0, callback_counter);
+ CompileRun(terminate_and_loop);
+ CHECK(!try_catch.HasTerminated());
+ CHECK_EQ(1, callback_counter);
+
+ { // Postpone API interrupts as well.
+ i::PostponeInterruptsScope p2(CcTest::i_isolate(),
+ i::StackGuard::API_INTERRUPT);
+
+ // None of the two interrupts should trigger.
+ CcTest::isolate()->RequestInterrupt(&CounterCallback, NULL);
+ CompileRun(terminate_and_loop);
+ CHECK(!try_catch.HasTerminated());
+ CHECK_EQ(1, callback_counter);
+ }
+
+ // Now the previously requested API interrupt should trigger.
+ CompileRun(terminate_and_loop);
+ CHECK(!try_catch.HasTerminated());
+ CHECK_EQ(2, callback_counter);
+ }
+
+ // Now the previously requested terminate execution interrupt should trigger.
+ CompileRun("for (var i = 0; i < 10000; i++);");
+ CHECK(try_catch.HasTerminated());
+ CHECK_EQ(2, callback_counter);
+}
diff --git a/deps/v8/test/cctest/test-threads.cc b/deps/v8/test/cctest/test-threads.cc
index 24fb1d1d7..12042261f 100644
--- a/deps/v8/test/cctest/test-threads.cc
+++ b/deps/v8/test/cctest/test-threads.cc
@@ -25,12 +25,11 @@
// (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 "src/v8.h"
+#include "test/cctest/cctest.h"
-#include "platform.h"
-#include "isolate.h"
-
-#include "cctest.h"
+#include "src/base/platform/platform.h"
+#include "src/isolate.h"
enum Turn {
@@ -43,9 +42,9 @@ enum Turn {
static Turn turn = FILL_CACHE;
-class ThreadA : public v8::internal::Thread {
+class ThreadA : public v8::base::Thread {
public:
- ThreadA() : Thread("ThreadA") { }
+ ThreadA() : Thread(Options("ThreadA")) {}
void Run() {
v8::Isolate* isolate = CcTest::isolate();
v8::Locker locker(isolate);
@@ -83,9 +82,9 @@ class ThreadA : public v8::internal::Thread {
};
-class ThreadB : public v8::internal::Thread {
+class ThreadB : public v8::base::Thread {
public:
- ThreadB() : Thread("ThreadB") { }
+ ThreadB() : Thread(Options("ThreadB")) {}
void Run() {
do {
{
@@ -123,16 +122,16 @@ TEST(JSFunctionResultCachesInTwoThreads) {
CHECK_EQ(DONE, turn);
}
-class ThreadIdValidationThread : public v8::internal::Thread {
+class ThreadIdValidationThread : public v8::base::Thread {
public:
- ThreadIdValidationThread(i::Thread* thread_to_start,
- i::List<i::ThreadId>* refs,
- unsigned int thread_no,
- i::Semaphore* semaphore)
- : Thread("ThreadRefValidationThread"),
- refs_(refs), thread_no_(thread_no), thread_to_start_(thread_to_start),
- semaphore_(semaphore) {
- }
+ ThreadIdValidationThread(v8::base::Thread* thread_to_start,
+ i::List<i::ThreadId>* refs, unsigned int thread_no,
+ v8::base::Semaphore* semaphore)
+ : Thread(Options("ThreadRefValidationThread")),
+ refs_(refs),
+ thread_no_(thread_no),
+ thread_to_start_(thread_to_start),
+ semaphore_(semaphore) {}
void Run() {
i::ThreadId thread_id = i::ThreadId::Current();
@@ -150,8 +149,8 @@ class ThreadIdValidationThread : public v8::internal::Thread {
private:
i::List<i::ThreadId>* refs_;
int thread_no_;
- i::Thread* thread_to_start_;
- i::Semaphore* semaphore_;
+ v8::base::Thread* thread_to_start_;
+ v8::base::Semaphore* semaphore_;
};
@@ -159,7 +158,7 @@ TEST(ThreadIdValidation) {
const int kNThreads = 100;
i::List<ThreadIdValidationThread*> threads(kNThreads);
i::List<i::ThreadId> refs(kNThreads);
- i::Semaphore semaphore(0);
+ v8::base::Semaphore semaphore(0);
ThreadIdValidationThread* prev = NULL;
for (int i = kNThreads - 1; i >= 0; i--) {
ThreadIdValidationThread* newThread =
@@ -176,19 +175,3 @@ TEST(ThreadIdValidation) {
delete threads[i];
}
}
-
-
-class ThreadC : public v8::internal::Thread {
- public:
- ThreadC() : Thread("ThreadC") { }
- void Run() {
- Join();
- }
-};
-
-
-TEST(ThreadJoinSelf) {
- ThreadC thread;
- thread.Start();
- thread.Join();
-}
diff --git a/deps/v8/test/cctest/test-time.cc b/deps/v8/test/cctest/test-time.cc
deleted file mode 100644
index 1ef9e08f6..000000000
--- a/deps/v8/test/cctest/test-time.cc
+++ /dev/null
@@ -1,197 +0,0 @@
-// 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"
-
-#if V8_OS_POSIX
-#include <sys/time.h> // NOLINT
-#endif
-
-#include "cctest.h"
-#if V8_OS_WIN
-#include "win32-headers.h"
-#endif
-
-using namespace v8::internal;
-
-
-TEST(TimeDeltaFromAndIn) {
- CHECK(TimeDelta::FromDays(2) == TimeDelta::FromHours(48));
- CHECK(TimeDelta::FromHours(3) == TimeDelta::FromMinutes(180));
- CHECK(TimeDelta::FromMinutes(2) == TimeDelta::FromSeconds(120));
- CHECK(TimeDelta::FromSeconds(2) == TimeDelta::FromMilliseconds(2000));
- CHECK(TimeDelta::FromMilliseconds(2) == TimeDelta::FromMicroseconds(2000));
- CHECK_EQ(static_cast<int>(13), TimeDelta::FromDays(13).InDays());
- CHECK_EQ(static_cast<int>(13), TimeDelta::FromHours(13).InHours());
- CHECK_EQ(static_cast<int>(13), TimeDelta::FromMinutes(13).InMinutes());
- CHECK_EQ(static_cast<int64_t>(13), TimeDelta::FromSeconds(13).InSeconds());
- CHECK_EQ(13.0, TimeDelta::FromSeconds(13).InSecondsF());
- CHECK_EQ(static_cast<int64_t>(13),
- TimeDelta::FromMilliseconds(13).InMilliseconds());
- CHECK_EQ(13.0, TimeDelta::FromMilliseconds(13).InMillisecondsF());
- CHECK_EQ(static_cast<int64_t>(13),
- TimeDelta::FromMicroseconds(13).InMicroseconds());
-}
-
-
-#if V8_OS_MACOSX
-TEST(TimeDeltaFromMachTimespec) {
- TimeDelta null = TimeDelta();
- CHECK(null == TimeDelta::FromMachTimespec(null.ToMachTimespec()));
- TimeDelta delta1 = TimeDelta::FromMilliseconds(42);
- CHECK(delta1 == TimeDelta::FromMachTimespec(delta1.ToMachTimespec()));
- TimeDelta delta2 = TimeDelta::FromDays(42);
- CHECK(delta2 == TimeDelta::FromMachTimespec(delta2.ToMachTimespec()));
-}
-#endif
-
-
-TEST(TimeJsTime) {
- Time t = Time::FromJsTime(700000.3);
- CHECK_EQ(700000.3, t.ToJsTime());
-}
-
-
-#if V8_OS_POSIX
-TEST(TimeFromTimespec) {
- Time null;
- CHECK(null.IsNull());
- CHECK(null == Time::FromTimespec(null.ToTimespec()));
- Time now = Time::Now();
- CHECK(now == Time::FromTimespec(now.ToTimespec()));
- Time now_sys = Time::NowFromSystemTime();
- CHECK(now_sys == Time::FromTimespec(now_sys.ToTimespec()));
- Time unix_epoch = Time::UnixEpoch();
- CHECK(unix_epoch == Time::FromTimespec(unix_epoch.ToTimespec()));
- Time max = Time::Max();
- CHECK(max.IsMax());
- CHECK(max == Time::FromTimespec(max.ToTimespec()));
-}
-
-
-TEST(TimeFromTimeval) {
- Time null;
- CHECK(null.IsNull());
- CHECK(null == Time::FromTimeval(null.ToTimeval()));
- Time now = Time::Now();
- CHECK(now == Time::FromTimeval(now.ToTimeval()));
- Time now_sys = Time::NowFromSystemTime();
- CHECK(now_sys == Time::FromTimeval(now_sys.ToTimeval()));
- Time unix_epoch = Time::UnixEpoch();
- CHECK(unix_epoch == Time::FromTimeval(unix_epoch.ToTimeval()));
- Time max = Time::Max();
- CHECK(max.IsMax());
- CHECK(max == Time::FromTimeval(max.ToTimeval()));
-}
-#endif
-
-
-#if V8_OS_WIN
-TEST(TimeFromFiletime) {
- Time null;
- CHECK(null.IsNull());
- CHECK(null == Time::FromFiletime(null.ToFiletime()));
- Time now = Time::Now();
- CHECK(now == Time::FromFiletime(now.ToFiletime()));
- Time now_sys = Time::NowFromSystemTime();
- CHECK(now_sys == Time::FromFiletime(now_sys.ToFiletime()));
- Time unix_epoch = Time::UnixEpoch();
- CHECK(unix_epoch == Time::FromFiletime(unix_epoch.ToFiletime()));
- Time max = Time::Max();
- CHECK(max.IsMax());
- CHECK(max == Time::FromFiletime(max.ToFiletime()));
-}
-#endif
-
-
-TEST(TimeTicksIsMonotonic) {
- TimeTicks previous_normal_ticks;
- TimeTicks previous_highres_ticks;
- ElapsedTimer timer;
- timer.Start();
- while (!timer.HasExpired(TimeDelta::FromMilliseconds(100))) {
- TimeTicks normal_ticks = TimeTicks::Now();
- TimeTicks highres_ticks = TimeTicks::HighResolutionNow();
- CHECK_GE(normal_ticks, previous_normal_ticks);
- CHECK_GE((normal_ticks - previous_normal_ticks).InMicroseconds(), 0);
- CHECK_GE(highres_ticks, previous_highres_ticks);
- CHECK_GE((highres_ticks - previous_highres_ticks).InMicroseconds(), 0);
- previous_normal_ticks = normal_ticks;
- previous_highres_ticks = highres_ticks;
- }
-}
-
-
-template <typename T>
-static void ResolutionTest(T (*Now)(), TimeDelta target_granularity) {
- // We're trying to measure that intervals increment in a VERY small amount
- // of time -- according to the specified target granularity. Unfortunately,
- // if we happen to have a context switch in the middle of our test, the
- // context switch could easily exceed our limit. So, we iterate on this
- // several times. As long as we're able to detect the fine-granularity
- // timers at least once, then the test has succeeded.
- static const TimeDelta kExpirationTimeout = TimeDelta::FromSeconds(1);
- ElapsedTimer timer;
- timer.Start();
- TimeDelta delta;
- do {
- T start = Now();
- T now = start;
- // Loop until we can detect that the clock has changed. Non-HighRes timers
- // will increment in chunks, i.e. 15ms. By spinning until we see a clock
- // change, we detect the minimum time between measurements.
- do {
- now = Now();
- delta = now - start;
- } while (now <= start);
- CHECK_NE(static_cast<int64_t>(0), delta.InMicroseconds());
- } while (delta > target_granularity && !timer.HasExpired(kExpirationTimeout));
- CHECK_LE(delta, target_granularity);
-}
-
-
-TEST(TimeNowResolution) {
- // We assume that Time::Now() has at least 16ms resolution.
- static const TimeDelta kTargetGranularity = TimeDelta::FromMilliseconds(16);
- ResolutionTest<Time>(&Time::Now, kTargetGranularity);
-}
-
-
-TEST(TimeTicksNowResolution) {
- // We assume that TimeTicks::Now() has at least 16ms resolution.
- static const TimeDelta kTargetGranularity = TimeDelta::FromMilliseconds(16);
- ResolutionTest<TimeTicks>(&TimeTicks::Now, kTargetGranularity);
-}
-
-
-TEST(TimeTicksHighResolutionNowResolution) {
- if (!TimeTicks::IsHighResolutionClockWorking()) return;
-
- // We assume that TimeTicks::HighResolutionNow() has sub-ms resolution.
- static const TimeDelta kTargetGranularity = TimeDelta::FromMilliseconds(1);
- ResolutionTest<TimeTicks>(&TimeTicks::HighResolutionNow, kTargetGranularity);
-}
diff --git a/deps/v8/test/cctest/test-types.cc b/deps/v8/test/cctest/test-types.cc
index 47868f648..8c5e41ca1 100644
--- a/deps/v8/test/cctest/test-types.cc
+++ b/deps/v8/test/cctest/test-types.cc
@@ -1,35 +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.
#include <vector>
-#include "cctest.h"
-#include "types.h"
-#include "utils/random-number-generator.h"
+#include "src/hydrogen-types.h"
+#include "src/isolate-inl.h"
+#include "src/types.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -41,11 +19,7 @@ struct ZoneRep {
return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag;
}
static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; }
- static bool IsClass(Type* t) { return IsStruct(t, 0); }
- static bool IsConstant(Type* t) { return IsStruct(t, 1); }
- static bool IsArray(Type* t) { return IsStruct(t, 2); }
- static bool IsFunction(Type* t) { return IsStruct(t, 3); }
- static bool IsUnion(Type* t) { return IsStruct(t, 4); }
+ static bool IsUnion(Type* t) { return IsStruct(t, 6); }
static Struct* AsStruct(Type* t) {
return reinterpret_cast<Struct*>(t);
@@ -53,12 +27,6 @@ struct ZoneRep {
static int AsBitset(Type* t) {
return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1);
}
- static Map* AsClass(Type* t) {
- return *static_cast<Map**>(AsStruct(t)[3]);
- }
- static Object* AsConstant(Type* t) {
- return *static_cast<Object**>(AsStruct(t)[3]);
- }
static Struct* AsUnion(Type* t) {
return AsStruct(t);
}
@@ -67,6 +35,13 @@ struct ZoneRep {
}
static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
+
+ struct BitsetType : Type::BitsetType {
+ using Type::BitsetType::New;
+ using Type::BitsetType::Glb;
+ using Type::BitsetType::Lub;
+ using Type::BitsetType::InherentLub;
+ };
};
@@ -77,29 +52,32 @@ struct HeapRep {
return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag;
}
static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
- static bool IsClass(Handle<HeapType> t) { return t->IsMap(); }
- static bool IsConstant(Handle<HeapType> t) { return t->IsBox(); }
- static bool IsArray(Handle<HeapType> t) { return IsStruct(t, 2); }
- static bool IsFunction(Handle<HeapType> t) { return IsStruct(t, 3); }
- static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 4); }
+ static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 6); }
static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); }
static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); }
- static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); }
- static Object* AsConstant(Handle<HeapType> t) {
- return Box::cast(*t)->value();
- }
static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); }
static int Length(Struct* structured) { return structured->length() - 1; }
static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
+
+ struct BitsetType : HeapType::BitsetType {
+ using HeapType::BitsetType::New;
+ using HeapType::BitsetType::Glb;
+ using HeapType::BitsetType::Lub;
+ using HeapType::BitsetType::InherentLub;
+ static int Glb(Handle<HeapType> type) { return Glb(*type); }
+ static int Lub(Handle<HeapType> type) { return Lub(*type); }
+ static int InherentLub(Handle<HeapType> type) { return InherentLub(*type); }
+ };
};
template<class Type, class TypeHandle, class Region>
class Types {
public:
- Types(Region* region, Isolate* isolate) : region_(region) {
+ Types(Region* region, Isolate* isolate)
+ : region_(region), rng_(isolate->random_number_generator()) {
#define DECLARE_TYPE(name, value) \
name = Type::name(region); \
types.push_back(name);
@@ -143,7 +121,16 @@ class Types {
types.push_back(Type::Constant(*it, region));
}
- FloatArray = Type::Array(Float, region);
+ doubles.push_back(-0.0);
+ doubles.push_back(+0.0);
+ doubles.push_back(-std::numeric_limits<double>::infinity());
+ doubles.push_back(+std::numeric_limits<double>::infinity());
+ for (int i = 0; i < 10; ++i) {
+ doubles.push_back(rng_->NextInt());
+ doubles.push_back(rng_->NextDouble() * rng_->NextInt());
+ }
+
+ NumberArray = Type::Array(Number, region);
StringArray = Type::Array(String, region);
AnyArray = Type::Array(Any, region);
@@ -152,7 +139,7 @@ class Types {
NumberFunction2 = Type::Function(Number, Number, Number, region);
MethodFunction = Type::Function(String, Object, 0, region);
- for (int i = 0; i < 50; ++i) {
+ for (int i = 0; i < 30; ++i) {
types.push_back(Fuzz());
}
}
@@ -183,7 +170,7 @@ class Types {
TypeHandle ArrayConstant;
TypeHandle UninitializedConstant;
- TypeHandle FloatArray;
+ TypeHandle NumberArray;
TypeHandle StringArray;
TypeHandle AnyArray;
@@ -195,9 +182,27 @@ class Types {
typedef std::vector<TypeHandle> TypeVector;
typedef std::vector<Handle<i::Map> > MapVector;
typedef std::vector<Handle<i::Object> > ValueVector;
+ typedef std::vector<double> DoubleVector;
+
TypeVector types;
MapVector maps;
ValueVector values;
+ DoubleVector doubles; // Some floating-point values, excluding NaN.
+
+ // Range type helper functions, partially copied from types.cc.
+ // Note: dle(dmin(x,y), dmax(x,y)) holds iff neither x nor y is NaN.
+ bool dle(double x, double y) {
+ return x <= y && (x != 0 || IsMinusZero(x) || !IsMinusZero(y));
+ }
+ bool deq(double x, double y) {
+ return dle(x, y) && dle(y, x);
+ }
+ double dmin(double x, double y) {
+ return dle(x, y) ? x : y;
+ }
+ double dmax(double x, double y) {
+ return dle(x, y) ? y : x;
+ }
TypeHandle Of(Handle<i::Object> value) {
return Type::Of(value, region_);
@@ -211,6 +216,10 @@ class Types {
return Type::Constant(value, region_);
}
+ TypeHandle Range(double min, double max) {
+ return Type::Range(min, max, region_);
+ }
+
TypeHandle Class(Handle<i::Map> map) {
return Type::Class(map, region_);
}
@@ -246,18 +255,18 @@ class Types {
}
TypeHandle Random() {
- return types[rng_.NextInt(static_cast<int>(types.size()))];
+ return types[rng_->NextInt(static_cast<int>(types.size()))];
}
TypeHandle Fuzz(int depth = 5) {
- switch (rng_.NextInt(depth == 0 ? 3 : 20)) {
+ switch (rng_->NextInt(depth == 0 ? 3 : 20)) {
case 0: { // bitset
int n = 0
#define COUNT_BITSET_TYPES(type, value) + 1
BITSET_TYPE_LIST(COUNT_BITSET_TYPES)
#undef COUNT_BITSET_TYPES
;
- int i = rng_.NextInt(n);
+ int i = rng_->NextInt(n);
#define PICK_BITSET_TYPE(type, value) \
if (i-- == 0) return Type::type(region_);
BITSET_TYPE_LIST(PICK_BITSET_TYPE)
@@ -265,31 +274,37 @@ class Types {
UNREACHABLE();
}
case 1: { // class
- int i = rng_.NextInt(static_cast<int>(maps.size()));
+ int i = rng_->NextInt(static_cast<int>(maps.size()));
return Type::Class(maps[i], region_);
}
case 2: { // constant
- int i = rng_.NextInt(static_cast<int>(values.size()));
+ int i = rng_->NextInt(static_cast<int>(values.size()));
return Type::Constant(values[i], region_);
}
- case 3: { // array
+ case 3: { // context
+ int depth = rng_->NextInt(3);
+ TypeHandle type = Type::Internal(region_);
+ for (int i = 0; i < depth; ++i) type = Type::Context(type, region_);
+ return type;
+ }
+ case 4: { // array
TypeHandle element = Fuzz(depth / 2);
return Type::Array(element, region_);
}
- case 4:
case 5:
case 6: { // function
TypeHandle result = Fuzz(depth / 2);
TypeHandle receiver = Fuzz(depth / 2);
- int arity = rng_.NextInt(3);
+ int arity = rng_->NextInt(3);
TypeHandle type = Type::Function(result, receiver, arity, region_);
for (int i = 0; i < type->AsFunction()->Arity(); ++i) {
- TypeHandle parameter = Fuzz(depth - 1);
+ TypeHandle parameter = Fuzz(depth / 2);
type->AsFunction()->InitParameter(i, parameter);
}
+ return type;
}
default: { // union
- int n = rng_.NextInt(10);
+ int n = rng_->NextInt(10);
TypeHandle type = None;
for (int i = 0; i < n; ++i) {
TypeHandle operand = Fuzz(depth - 1);
@@ -301,9 +316,11 @@ class Types {
UNREACHABLE();
}
+ Region* region() { return region_; }
+
private:
Region* region_;
- RandomNumberGenerator rng_;
+ v8::base::RandomNumberGenerator* rng_;
};
@@ -313,6 +330,7 @@ struct Tests : Rep {
typedef typename TypesInstance::TypeVector::iterator TypeIterator;
typedef typename TypesInstance::MapVector::iterator MapIterator;
typedef typename TypesInstance::ValueVector::iterator ValueIterator;
+ typedef typename TypesInstance::DoubleVector::iterator DoubleIterator;
Isolate* isolate;
HandleScope scope;
@@ -328,19 +346,13 @@ struct Tests : Rep {
bool Equal(TypeHandle type1, TypeHandle type2) {
return
- type1->Is(type2) && type2->Is(type1) &&
+ type1->Equals(type2) &&
Rep::IsBitset(type1) == Rep::IsBitset(type2) &&
- Rep::IsClass(type1) == Rep::IsClass(type2) &&
- Rep::IsConstant(type1) == Rep::IsConstant(type2) &&
Rep::IsUnion(type1) == Rep::IsUnion(type2) &&
type1->NumClasses() == type2->NumClasses() &&
type1->NumConstants() == type2->NumConstants() &&
(!Rep::IsBitset(type1) ||
Rep::AsBitset(type1) == Rep::AsBitset(type2)) &&
- (!Rep::IsClass(type1) ||
- Rep::AsClass(type1) == Rep::AsClass(type2)) &&
- (!Rep::IsConstant(type1) ||
- Rep::AsConstant(type1) == Rep::AsConstant(type2)) &&
(!Rep::IsUnion(type1) ||
Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2)));
}
@@ -460,7 +472,7 @@ struct Tests : Rep {
for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
Handle<i::Map> map = *mt;
TypeHandle type = T.Class(map);
- CHECK(this->IsClass(type));
+ CHECK(type->IsClass());
}
// Map attribute
@@ -487,7 +499,7 @@ struct Tests : Rep {
for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
Handle<i::Object> value = *vt;
TypeHandle type = T.Constant(value);
- CHECK(this->IsConstant(type));
+ CHECK(type->IsConstant());
}
// Value attribute
@@ -507,6 +519,93 @@ struct Tests : Rep {
CHECK(Equal(type1, type2) == (*value1 == *value2));
}
}
+
+ // Typing of numbers
+ Factory* fac = isolate->factory();
+ CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall));
+ CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall));
+ CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall));
+ CHECK(T.Constant(fac->NewNumber(-1))->Is(T.OtherSignedSmall));
+ CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.OtherSignedSmall));
+ CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.OtherSignedSmall));
+ if (SmiValuesAre31Bits()) {
+ CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
+ CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
+ CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
+ CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
+ CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
+ } else {
+ CHECK(SmiValuesAre32Bits());
+ CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall));
+ CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall));
+ CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
+ CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
+ CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSignedSmall));
+ CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSignedSmall));
+ CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSignedSmall));
+ CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
+ CHECK(!T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
+ CHECK(!T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
+ }
+ CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.OtherUnsigned32));
+ CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.OtherUnsigned32));
+ CHECK(T.Constant(fac->NewNumber(0xffffffffu+1.0))->Is(T.OtherNumber));
+ CHECK(T.Constant(fac->NewNumber(-0x7fffffff-2.0))->Is(T.OtherNumber));
+ CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.OtherNumber));
+ CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.OtherNumber));
+ CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.OtherNumber));
+ CHECK(T.Constant(fac->NewNumber(-1.0*0.0))->Is(T.MinusZero));
+ CHECK(T.Constant(fac->NewNumber(v8::base::OS::nan_value()))->Is(T.NaN));
+ CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.OtherNumber));
+ CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.OtherNumber));
+ }
+
+ void Range() {
+ // Constructor
+ for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) {
+ for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) {
+ double min = T.dmin(*i, *j);
+ double max = T.dmax(*i, *j);
+ TypeHandle type = T.Range(min, max);
+ CHECK(type->IsRange());
+ }
+ }
+
+ // Range attributes
+ for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) {
+ for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) {
+ double min = T.dmin(*i, *j);
+ double max = T.dmax(*i, *j);
+ printf("RangeType: min, max = %f, %f\n", min, max);
+ TypeHandle type = T.Range(min, max);
+ printf("RangeType: Min, Max = %f, %f\n",
+ type->AsRange()->Min(), type->AsRange()->Max());
+ CHECK(min == type->AsRange()->Min());
+ CHECK(max == type->AsRange()->Max());
+ }
+ }
+
+// TODO(neis): enable once subtyping is updated.
+// // Functionality & Injectivity: Range(min1, max1) = Range(min2, max2) <=>
+// // min1 = min2 /\ max1 = max2
+// for (DoubleIterator i1 = T.doubles.begin(); i1 != T.doubles.end(); ++i1) {
+// for (DoubleIterator j1 = T.doubles.begin(); j1 != T.doubles.end(); ++j1) {
+// for (DoubleIterator i2 = T.doubles.begin();
+// i2 != T.doubles.end(); ++i2) {
+// for (DoubleIterator j2 = T.doubles.begin();
+// j2 != T.doubles.end(); ++j2) {
+// double min1 = T.dmin(*i1, *j1);
+// double max1 = T.dmax(*i1, *j1);
+// double min2 = T.dmin(*i2, *j2);
+// double max2 = T.dmax(*i2, *j2);
+// TypeHandle type1 = T.Range(min1, max1);
+// TypeHandle type2 = T.Range(min2, max2);
+// CHECK(Equal(type1, type2) ==
+// (T.deq(min1, min2) && T.deq(max1, max2)));
+// }
+// }
+// }
+// }
}
void Array() {
@@ -514,7 +613,7 @@ struct Tests : Rep {
for (int i = 0; i < 20; ++i) {
TypeHandle type = T.Random();
TypeHandle array = T.Array1(type);
- CHECK(this->IsArray(array));
+ CHECK(array->IsArray());
}
// Attributes
@@ -669,6 +768,44 @@ struct Tests : Rep {
}
}
+ void Bounds() {
+ // Ordering: (T->BitsetGlb())->Is(T->BitsetLub())
+ for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+ TypeHandle type = *it;
+ TypeHandle glb =
+ Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region());
+ TypeHandle lub =
+ Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region());
+ CHECK(glb->Is(lub));
+ }
+
+ // Lower bound: (T->BitsetGlb())->Is(T)
+ for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+ TypeHandle type = *it;
+ TypeHandle glb =
+ Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region());
+ CHECK(glb->Is(type));
+ }
+
+ // Upper bound: T->Is(T->BitsetLub())
+ for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+ TypeHandle type = *it;
+ TypeHandle lub =
+ Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region());
+ CHECK(type->Is(lub));
+ }
+
+ // Inherent bound: (T->BitsetLub())->Is(T->InherentBitsetLub())
+ for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+ TypeHandle type = *it;
+ TypeHandle lub =
+ Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region());
+ TypeHandle inherent =
+ Rep::BitsetType::New(Rep::BitsetType::InherentLub(type), T.region());
+ CHECK(lub->Is(inherent));
+ }
+ }
+
void Is() {
// Least Element (Bottom): None->Is(T)
for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
@@ -772,10 +909,9 @@ struct Tests : Rep {
CheckSub(T.SignedSmall, T.Number);
CheckSub(T.Signed32, T.Number);
- CheckSub(T.Float, T.Number);
CheckSub(T.SignedSmall, T.Signed32);
- CheckUnordered(T.SignedSmall, T.Float);
- CheckUnordered(T.Signed32, T.Float);
+ CheckUnordered(T.SignedSmall, T.MinusZero);
+ CheckUnordered(T.Signed32, T.Unsigned32);
CheckSub(T.UniqueName, T.Name);
CheckSub(T.String, T.Name);
@@ -823,8 +959,8 @@ struct Tests : Rep {
CheckUnordered(T.ObjectConstant2, T.ArrayClass);
CheckUnordered(T.ArrayConstant, T.ObjectClass);
- CheckSub(T.FloatArray, T.Array);
- CheckSub(T.FloatArray, T.Object);
+ CheckSub(T.NumberArray, T.Array);
+ CheckSub(T.NumberArray, T.Object);
CheckUnordered(T.StringArray, T.AnyArray);
CheckSub(T.MethodFunction, T.Function);
@@ -1044,13 +1180,13 @@ struct Tests : Rep {
}
}
- // T1->Maybe(T2) iff Intersect(T1, T2) inhabited
+ // T1->Maybe(T2) implies Intersect(T1, T2) inhabited
for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
TypeHandle type1 = *it1;
TypeHandle type2 = *it2;
TypeHandle intersect12 = T.Intersect(type1, type2);
- CHECK(type1->Maybe(type2) == intersect12->IsInhabited());
+ CHECK(!type1->Maybe(type2) || intersect12->IsInhabited());
}
}
@@ -1114,8 +1250,8 @@ struct Tests : Rep {
CheckDisjoint(T.Boolean, T.Undefined, T.Semantic);
CheckOverlap(T.SignedSmall, T.Number, T.Semantic);
- CheckOverlap(T.Float, T.Number, T.Semantic);
- CheckDisjoint(T.Signed32, T.Float, T.Semantic);
+ CheckOverlap(T.NaN, T.Number, T.Semantic);
+ CheckDisjoint(T.Signed32, T.NaN, T.Semantic);
CheckOverlap(T.UniqueName, T.Name, T.Semantic);
CheckOverlap(T.String, T.Name, T.Semantic);
@@ -1145,7 +1281,6 @@ struct Tests : Rep {
CheckOverlap(T.SmiConstant, T.SignedSmall, T.Semantic);
CheckOverlap(T.SmiConstant, T.Signed32, T.Semantic);
CheckOverlap(T.SmiConstant, T.Number, T.Semantic);
- CheckDisjoint(T.SmiConstant, T.Float, T.Semantic);
CheckOverlap(T.ObjectConstant1, T.Object, T.Semantic);
CheckOverlap(T.ObjectConstant2, T.Object, T.Semantic);
CheckOverlap(T.ArrayConstant, T.Object, T.Semantic);
@@ -1160,9 +1295,9 @@ struct Tests : Rep {
CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic);
CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic);
- CheckOverlap(T.FloatArray, T.Array, T.Semantic);
- CheckDisjoint(T.FloatArray, T.AnyArray, T.Semantic);
- CheckDisjoint(T.FloatArray, T.StringArray, T.Semantic);
+ CheckOverlap(T.NumberArray, T.Array, T.Semantic);
+ CheckDisjoint(T.NumberArray, T.AnyArray, T.Semantic);
+ CheckDisjoint(T.NumberArray, T.StringArray, T.Semantic);
CheckOverlap(T.MethodFunction, T.Function, T.Semantic);
CheckDisjoint(T.SignedFunction1, T.NumberFunction1, T.Semantic);
@@ -1303,22 +1438,18 @@ struct Tests : Rep {
// Bitset-array
CHECK(this->IsBitset(T.Union(T.AnyArray, T.Array)));
- CHECK(this->IsUnion(T.Union(T.FloatArray, T.Number)));
+ CHECK(this->IsUnion(T.Union(T.NumberArray, T.Number)));
CheckEqual(T.Union(T.AnyArray, T.Array), T.Array);
- CheckSub(T.None, T.Union(T.FloatArray, T.Number));
- CheckSub(T.Union(T.FloatArray, T.Number), T.Any);
CheckUnordered(T.Union(T.AnyArray, T.String), T.Array);
- CheckOverlap(T.Union(T.FloatArray, T.String), T.Object, T.Semantic);
- CheckDisjoint(T.Union(T.FloatArray, T.String), T.Number, T.Semantic);
+ CheckOverlap(T.Union(T.NumberArray, T.String), T.Object, T.Semantic);
+ CheckDisjoint(T.Union(T.NumberArray, T.String), T.Number, T.Semantic);
// Bitset-function
CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Function)));
CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number)));
CheckEqual(T.Union(T.MethodFunction, T.Function), T.Function);
- CheckSub(T.None, T.Union(T.MethodFunction, T.Number));
- CheckSub(T.Union(T.MethodFunction, T.Number), T.Any);
CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Function);
CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object, T.Semantic);
CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number, T.Semantic);
@@ -1353,10 +1484,10 @@ struct Tests : Rep {
// Bitset-union
CheckSub(
- T.Float,
+ T.NaN,
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
CheckSub(
- T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float),
+ T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Signed32),
T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
// Class-union
@@ -1380,9 +1511,9 @@ struct Tests : Rep {
// Array-union
CheckEqual(
- T.Union(T.AnyArray, T.Union(T.FloatArray, T.AnyArray)),
- T.Union(T.AnyArray, T.FloatArray));
- CheckSub(T.Union(T.AnyArray, T.FloatArray), T.Array);
+ T.Union(T.AnyArray, T.Union(T.NumberArray, T.AnyArray)),
+ T.Union(T.AnyArray, T.NumberArray));
+ CheckSub(T.Union(T.AnyArray, T.NumberArray), T.Array);
// Function-union
CheckEqual(
@@ -1524,7 +1655,7 @@ struct Tests : Rep {
CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation);
// Bitset-array
- CheckEqual(T.Intersect(T.FloatArray, T.Object), T.FloatArray);
+ CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray);
CheckSub(T.Intersect(T.AnyArray, T.Function), T.Representation);
// Bitset-function
@@ -1535,24 +1666,24 @@ struct Tests : Rep {
CheckEqual(
T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
T.Union(T.ObjectConstant1, T.ObjectClass));
- CheckEqual(
- T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
- T.None);
+ CHECK(
+ !T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)
+ ->IsInhabited());
// Class-constant
- CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None);
- CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None);
+ CHECK(!T.Intersect(T.ObjectConstant1, T.ObjectClass)->IsInhabited());
+ CHECK(!T.Intersect(T.ArrayClass, T.ObjectConstant2)->IsInhabited());
// Array-union
CheckEqual(
- T.Intersect(T.FloatArray, T.Union(T.FloatArray, T.ArrayClass)),
- T.FloatArray);
+ T.Intersect(T.NumberArray, T.Union(T.NumberArray, T.ArrayClass)),
+ T.NumberArray);
CheckEqual(
T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)),
T.AnyArray);
- CheckEqual(
- T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.FloatArray),
- T.None);
+ CHECK(
+ !T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.NumberArray)
+ ->IsInhabited());
// Function-union
CheckEqual(
@@ -1561,9 +1692,9 @@ struct Tests : Rep {
CheckEqual(
T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)),
T.NumberFunction1);
- CheckEqual(
- T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2),
- T.None);
+ CHECK(
+ !T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2)
+ ->IsInhabited());
// Class-union
CheckEqual(
@@ -1572,9 +1703,9 @@ struct Tests : Rep {
CheckEqual(
T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
T.ArrayClass);
- CheckEqual(
- T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass),
- T.None);
+ CHECK(
+ !T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass)
+ ->IsInhabited());
// Constant-union
CheckEqual(
@@ -1584,10 +1715,10 @@ struct Tests : Rep {
CheckEqual(
T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
T.SmiConstant);
- CheckEqual(
- T.Intersect(
- T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1),
- T.None);
+ CHECK(
+ !T.Intersect(
+ T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1)
+ ->IsInhabited());
// Union-union
CheckEqual(
@@ -1615,6 +1746,46 @@ struct Tests : Rep {
T.Union(T.ObjectConstant2, T.ObjectConstant1));
}
+ void Distributivity1() {
+ // Distributivity:
+ // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3))
+ for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
+ for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
+ for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
+ TypeHandle type1 = *it1;
+ TypeHandle type2 = *it2;
+ TypeHandle type3 = *it3;
+ TypeHandle union12 = T.Union(type1, type2);
+ TypeHandle union13 = T.Union(type1, type3);
+ TypeHandle intersect23 = T.Intersect(type2, type3);
+ TypeHandle union1_23 = T.Union(type1, intersect23);
+ TypeHandle intersect12_13 = T.Intersect(union12, union13);
+ CHECK(Equal(union1_23, intersect12_13));
+ }
+ }
+ }
+ }
+
+ void Distributivity2() {
+ // Distributivity:
+ // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3))
+ for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
+ for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
+ for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
+ TypeHandle type1 = *it1;
+ TypeHandle type2 = *it2;
+ TypeHandle type3 = *it3;
+ TypeHandle intersect12 = T.Intersect(type1, type2);
+ TypeHandle intersect13 = T.Intersect(type1, type3);
+ TypeHandle union23 = T.Union(type2, type3);
+ TypeHandle intersect1_23 = T.Intersect(type1, union23);
+ TypeHandle union12_13 = T.Union(intersect12, intersect13);
+ CHECK(Equal(intersect1_23, union12_13));
+ }
+ }
+ }
+ }
+
template<class Type2, class TypeHandle2, class Region2, class Rep2>
void Convert() {
Types<Type2, TypeHandle2, Region2> T2(
@@ -1626,6 +1797,18 @@ struct Tests : Rep {
CheckEqual(type1, type3);
}
}
+
+ void HTypeFromType() {
+ for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
+ for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
+ TypeHandle type1 = *it1;
+ TypeHandle type2 = *it2;
+ HType htype1 = HType::FromType<Type>(type1);
+ HType htype2 = HType::FromType<Type>(type2);
+ CHECK(!type1->Is(type2) || htype1.IsSubtypeOf(htype2));
+ }
+ }
+ }
};
typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
@@ -1653,6 +1836,13 @@ TEST(ConstantType) {
}
+TEST(RangeType) {
+ CcTest::InitializeVM();
+ ZoneTests().Range();
+ HeapTests().Range();
+}
+
+
TEST(ArrayType) {
CcTest::InitializeVM();
ZoneTests().Array();
@@ -1681,6 +1871,13 @@ TEST(NowOf) {
}
+TEST(Bounds) {
+ CcTest::InitializeVM();
+ ZoneTests().Bounds();
+ HeapTests().Bounds();
+}
+
+
TEST(Is) {
CcTest::InitializeVM();
ZoneTests().Is();
@@ -1744,8 +1941,29 @@ TEST(Intersect2) {
}
+TEST(Distributivity1) {
+ CcTest::InitializeVM();
+ ZoneTests().Distributivity1();
+ HeapTests().Distributivity1();
+}
+
+
+TEST(Distributivity2) {
+ CcTest::InitializeVM();
+ ZoneTests().Distributivity2();
+ HeapTests().Distributivity2();
+}
+
+
TEST(Convert) {
CcTest::InitializeVM();
ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>();
HeapTests().Convert<Type, Type*, Zone, ZoneRep>();
}
+
+
+TEST(HTypeFromType) {
+ CcTest::InitializeVM();
+ ZoneTests().HTypeFromType();
+ HeapTests().HTypeFromType();
+}
diff --git a/deps/v8/test/cctest/test-unbound-queue.cc b/deps/v8/test/cctest/test-unbound-queue.cc
index dd9b9c142..6da91e694 100644
--- a/deps/v8/test/cctest/test-unbound-queue.cc
+++ b/deps/v8/test/cctest/test-unbound-queue.cc
@@ -27,9 +27,10 @@
//
// Tests of the unbound queue.
-#include "v8.h"
-#include "unbound-queue-inl.h"
-#include "cctest.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/unbound-queue-inl.h"
using i::UnboundQueue;
diff --git a/deps/v8/test/cctest/test-unique.cc b/deps/v8/test/cctest/test-unique.cc
index ad14ff133..302539a96 100644
--- a/deps/v8/test/cctest/test-unique.cc
+++ b/deps/v8/test/cctest/test-unique.cc
@@ -27,12 +27,12 @@
#include <stdlib.h>
-#include "v8.h"
+#include "src/v8.h"
-#include "factory.h"
-#include "global-handles.h"
-#include "unique.h"
-#include "cctest.h"
+#include "src/factory.h"
+#include "src/global-handles.h"
+#include "src/unique.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-unscopables-hidden-prototype.cc b/deps/v8/test/cctest/test-unscopables-hidden-prototype.cc
new file mode 100644
index 000000000..aef2ccf28
--- /dev/null
+++ b/deps/v8/test/cctest/test-unscopables-hidden-prototype.cc
@@ -0,0 +1,103 @@
+// 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 <stdlib.h>
+
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+namespace {
+
+
+static void Cleanup() {
+ CompileRun(
+ "delete object.x;"
+ "delete hidden_prototype.x;"
+ "delete object[Symbol.unscopables];"
+ "delete hidden_prototype[Symbol.unscopables];");
+}
+
+
+TEST(Unscopables) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ v8::Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate);
+ v8::Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate);
+
+ t1->SetHiddenPrototype(true);
+
+ v8::Local<v8::Object> object = t0->GetFunction()->NewInstance();
+ v8::Local<v8::Object> hidden_prototype = t1->GetFunction()->NewInstance();
+
+ object->SetPrototype(hidden_prototype);
+
+ context->Global()->Set(v8_str("object"), object);
+ context->Global()->Set(v8_str("hidden_prototype"), hidden_prototype);
+
+ CHECK_EQ(1, CompileRun(
+ "var result;"
+ "var x = 0;"
+ "object.x = 1;"
+ "with (object) {"
+ " result = x;"
+ "}"
+ "result")->Int32Value());
+
+ Cleanup();
+ CHECK_EQ(2, CompileRun(
+ "var result;"
+ "var x = 0;"
+ "hidden_prototype.x = 2;"
+ "with (object) {"
+ " result = x;"
+ "}"
+ "result")->Int32Value());
+
+ Cleanup();
+ CHECK_EQ(0, CompileRun(
+ "var result;"
+ "var x = 0;"
+ "object.x = 3;"
+ "object[Symbol.unscopables] = {x: true};"
+ "with (object) {"
+ " result = x;"
+ "}"
+ "result")->Int32Value());
+
+ Cleanup();
+ CHECK_EQ(0, CompileRun(
+ "var result;"
+ "var x = 0;"
+ "hidden_prototype.x = 4;"
+ "hidden_prototype[Symbol.unscopables] = {x: true};"
+ "with (object) {"
+ " result = x;"
+ "}"
+ "result")->Int32Value());
+
+ Cleanup();
+ CHECK_EQ(0, CompileRun(
+ "var result;"
+ "var x = 0;"
+ "object.x = 5;"
+ "hidden_prototype[Symbol.unscopables] = {x: true};"
+ "with (object) {"
+ " result = x;"
+ "}"
+ "result;")->Int32Value());
+
+ Cleanup();
+ CHECK_EQ(0, CompileRun(
+ "var result;"
+ "var x = 0;"
+ "hidden_prototype.x = 6;"
+ "object[Symbol.unscopables] = {x: true};"
+ "with (object) {"
+ " result = x;"
+ "}"
+ "result")->Int32Value());
+}
+}
diff --git a/deps/v8/test/cctest/test-utils-arm64.cc b/deps/v8/test/cctest/test-utils-arm64.cc
index 9eb32b002..b0b77bc97 100644
--- a/deps/v8/test/cctest/test-utils-arm64.cc
+++ b/deps/v8/test/cctest/test-utils-arm64.cc
@@ -25,12 +25,12 @@
// (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 "src/v8.h"
-#include "macro-assembler.h"
-#include "arm64/utils-arm64.h"
-#include "cctest.h"
-#include "test-utils-arm64.h"
+#include "src/arm64/utils-arm64.h"
+#include "src/macro-assembler.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/test-utils-arm64.h"
using namespace v8::internal;
@@ -95,7 +95,7 @@ bool EqualFP64(double expected, const RegisterDump*, double result) {
bool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg) {
- ASSERT(reg.Is32Bits());
+ DCHECK(reg.Is32Bits());
// Retrieve the corresponding X register so we can check that the upper part
// was properly cleared.
int64_t result_x = core->xreg(reg.code());
@@ -112,7 +112,7 @@ bool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg) {
bool Equal64(uint64_t expected,
const RegisterDump* core,
const Register& reg) {
- ASSERT(reg.Is64Bits());
+ DCHECK(reg.Is64Bits());
uint64_t result = core->xreg(reg.code());
return Equal64(expected, core, result);
}
@@ -121,7 +121,7 @@ bool Equal64(uint64_t expected,
bool EqualFP32(float expected,
const RegisterDump* core,
const FPRegister& fpreg) {
- ASSERT(fpreg.Is32Bits());
+ DCHECK(fpreg.Is32Bits());
// Retrieve the corresponding D register so we can check that the upper part
// was properly cleared.
uint64_t result_64 = core->dreg_bits(fpreg.code());
@@ -138,7 +138,7 @@ bool EqualFP32(float expected,
bool EqualFP64(double expected,
const RegisterDump* core,
const FPRegister& fpreg) {
- ASSERT(fpreg.Is64Bits());
+ DCHECK(fpreg.Is64Bits());
return EqualFP64(expected, core, core->dreg(fpreg.code()));
}
@@ -146,7 +146,7 @@ bool EqualFP64(double expected,
bool Equal64(const Register& reg0,
const RegisterDump* core,
const Register& reg1) {
- ASSERT(reg0.Is64Bits() && reg1.Is64Bits());
+ DCHECK(reg0.Is64Bits() && reg1.Is64Bits());
int64_t expected = core->xreg(reg0.code());
int64_t result = core->xreg(reg1.code());
return Equal64(expected, core, result);
@@ -174,8 +174,8 @@ static char FlagV(uint32_t flags) {
bool EqualNzcv(uint32_t expected, uint32_t result) {
- ASSERT((expected & ~NZCVFlag) == 0);
- ASSERT((result & ~NZCVFlag) == 0);
+ DCHECK((expected & ~NZCVFlag) == 0);
+ DCHECK((result & ~NZCVFlag) == 0);
if (result != expected) {
printf("Expected: %c%c%c%c\t Found: %c%c%c%c\n",
FlagN(expected), FlagZ(expected), FlagC(expected), FlagV(expected),
@@ -231,7 +231,7 @@ RegList PopulateRegisterArray(Register* w, Register* x, Register* r,
}
}
// Check that we got enough registers.
- ASSERT(CountSetBits(list, kNumberOfRegisters) == reg_count);
+ DCHECK(CountSetBits(list, kNumberOfRegisters) == reg_count);
return list;
}
@@ -258,7 +258,7 @@ RegList PopulateFPRegisterArray(FPRegister* s, FPRegister* d, FPRegister* v,
}
}
// Check that we got enough registers.
- ASSERT(CountSetBits(list, kNumberOfFPRegisters) == reg_count);
+ DCHECK(CountSetBits(list, kNumberOfFPRegisters) == reg_count);
return list;
}
@@ -270,7 +270,7 @@ void Clobber(MacroAssembler* masm, RegList reg_list, uint64_t const value) {
if (reg_list & (1UL << i)) {
Register xn = Register::Create(i, kXRegSizeInBits);
// We should never write into csp here.
- ASSERT(!xn.Is(csp));
+ DCHECK(!xn.Is(csp));
if (!xn.IsZero()) {
if (!first.IsValid()) {
// This is the first register we've hit, so construct the literal.
@@ -320,7 +320,7 @@ void Clobber(MacroAssembler* masm, CPURegList reg_list) {
void RegisterDump::Dump(MacroAssembler* masm) {
- ASSERT(__ StackPointer().Is(csp));
+ DCHECK(__ StackPointer().Is(csp));
// Ensure that we don't unintentionally clobber any registers.
RegList old_tmp_list = masm->TmpList()->list();
@@ -396,7 +396,7 @@ void RegisterDump::Dump(MacroAssembler* masm) {
// easily restore them.
Register dump2_base = x10;
Register dump2 = x11;
- ASSERT(!AreAliased(dump_base, dump, tmp, dump2_base, dump2));
+ DCHECK(!AreAliased(dump_base, dump, tmp, dump2_base, dump2));
// Don't lose the dump_ address.
__ Mov(dump2_base, dump_base);
diff --git a/deps/v8/test/cctest/test-utils-arm64.h b/deps/v8/test/cctest/test-utils-arm64.h
index 2ff26e49c..d00ad5e78 100644
--- a/deps/v8/test/cctest/test-utils-arm64.h
+++ b/deps/v8/test/cctest/test-utils-arm64.h
@@ -28,12 +28,12 @@
#ifndef V8_ARM64_TEST_UTILS_ARM64_H_
#define V8_ARM64_TEST_UTILS_ARM64_H_
-#include "v8.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
-#include "macro-assembler.h"
-#include "arm64/macro-assembler-arm64.h"
-#include "arm64/utils-arm64.h"
-#include "cctest.h"
+#include "src/arm64/macro-assembler-arm64.h"
+#include "src/arm64/utils-arm64.h"
+#include "src/macro-assembler.h"
using namespace v8::internal;
@@ -59,7 +59,7 @@ class RegisterDump {
if (code == kSPRegInternalCode) {
return wspreg();
}
- ASSERT(RegAliasesMatch(code));
+ DCHECK(RegAliasesMatch(code));
return dump_.w_[code];
}
@@ -67,13 +67,13 @@ class RegisterDump {
if (code == kSPRegInternalCode) {
return spreg();
}
- ASSERT(RegAliasesMatch(code));
+ DCHECK(RegAliasesMatch(code));
return dump_.x_[code];
}
// FPRegister accessors.
inline uint32_t sreg_bits(unsigned code) const {
- ASSERT(FPRegAliasesMatch(code));
+ DCHECK(FPRegAliasesMatch(code));
return dump_.s_[code];
}
@@ -82,7 +82,7 @@ class RegisterDump {
}
inline uint64_t dreg_bits(unsigned code) const {
- ASSERT(FPRegAliasesMatch(code));
+ DCHECK(FPRegAliasesMatch(code));
return dump_.d_[code];
}
@@ -92,19 +92,19 @@ class RegisterDump {
// Stack pointer accessors.
inline int64_t spreg() const {
- ASSERT(SPRegAliasesMatch());
+ DCHECK(SPRegAliasesMatch());
return dump_.sp_;
}
inline int64_t wspreg() const {
- ASSERT(SPRegAliasesMatch());
+ DCHECK(SPRegAliasesMatch());
return dump_.wsp_;
}
// Flags accessors.
inline uint64_t flags_nzcv() const {
- ASSERT(IsComplete());
- ASSERT((dump_.flags_ & ~Flags_mask) == 0);
+ DCHECK(IsComplete());
+ DCHECK((dump_.flags_ & ~Flags_mask) == 0);
return dump_.flags_ & Flags_mask;
}
@@ -120,21 +120,21 @@ class RegisterDump {
// w<code>. A failure of this test most likely represents a failure in the
// ::Dump method, or a failure in the simulator.
bool RegAliasesMatch(unsigned code) const {
- ASSERT(IsComplete());
- ASSERT(code < kNumberOfRegisters);
+ DCHECK(IsComplete());
+ DCHECK(code < kNumberOfRegisters);
return ((dump_.x_[code] & kWRegMask) == dump_.w_[code]);
}
// As RegAliasesMatch, but for the stack pointer.
bool SPRegAliasesMatch() const {
- ASSERT(IsComplete());
+ DCHECK(IsComplete());
return ((dump_.sp_ & kWRegMask) == dump_.wsp_);
}
// As RegAliasesMatch, but for floating-point registers.
bool FPRegAliasesMatch(unsigned code) const {
- ASSERT(IsComplete());
- ASSERT(code < kNumberOfFPRegisters);
+ DCHECK(IsComplete());
+ DCHECK(code < kNumberOfFPRegisters);
return (dump_.d_[code] & kSRegMask) == dump_.s_[code];
}
diff --git a/deps/v8/test/cctest/test-utils.cc b/deps/v8/test/cctest/test-utils.cc
index 86d52fa82..cf539305b 100644
--- a/deps/v8/test/cctest/test-utils.cc
+++ b/deps/v8/test/cctest/test-utils.cc
@@ -27,11 +27,13 @@
#include <stdlib.h>
-#include "v8.h"
+#include <vector>
-#include "cctest.h"
-#include "platform.h"
-#include "utils-inl.h"
+#include "src/v8.h"
+
+#include "src/base/platform/platform.h"
+#include "src/utils-inl.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -70,7 +72,7 @@ TEST(Utils1) {
CHECK_EQ(INT_MAX, FastD2IChecked(1.0e100));
CHECK_EQ(INT_MIN, FastD2IChecked(-1.0e100));
- CHECK_EQ(INT_MIN, FastD2IChecked(OS::nan_value()));
+ CHECK_EQ(INT_MIN, FastD2IChecked(v8::base::OS::nan_value()));
}
@@ -83,7 +85,7 @@ TEST(SNPrintF) {
static const char kMarker = static_cast<char>(42);
Vector<char> buffer = Vector<char>::New(i + 1);
buffer[i] = kMarker;
- int n = OS::SNPrintF(Vector<char>(buffer.start(), i), "%s", s);
+ int n = SNPrintF(Vector<char>(buffer.start(), i), "%s", s);
CHECK(n <= i);
CHECK(n == length || n == -1);
CHECK_EQ(0, strncmp(buffer.start(), s, i - 1));
@@ -110,15 +112,15 @@ void TestMemMove(byte* area1,
area1[i] = i & 0xFF;
area2[i] = i & 0xFF;
}
- OS::MemMove(area1 + dest_offset, area1 + src_offset, length);
+ MemMove(area1 + dest_offset, area1 + src_offset, length);
memmove(area2 + dest_offset, area2 + src_offset, length);
if (memcmp(area1, area2, kAreaSize) != 0) {
- printf("OS::MemMove(): src_offset: %d, dest_offset: %d, length: %d\n",
+ printf("MemMove(): src_offset: %d, dest_offset: %d, length: %d\n",
src_offset, dest_offset, length);
for (int i = 0; i < kAreaSize; i++) {
if (area1[i] == area2[i]) continue;
- printf("diff at offset %d (%p): is %d, should be %d\n",
- i, reinterpret_cast<void*>(area1 + i), area1[i], area2[i]);
+ printf("diff at offset %d (%p): is %d, should be %d\n", i,
+ reinterpret_cast<void*>(area1 + i), area1[i], area2[i]);
}
CHECK(false);
}
@@ -218,3 +220,40 @@ TEST(SequenceCollectorRegression) {
CHECK_EQ(0, strncmp("0123456789012345678901234567890123",
seq.start(), seq.length()));
}
+
+
+// TODO(svenpanne) Unconditionally test this when our infrastructure is fixed.
+#if !V8_CC_MSVC && !V8_OS_NACL
+TEST(CPlusPlus11Features) {
+ struct S {
+ bool x;
+ struct T {
+ double y;
+ int z[3];
+ } t;
+ };
+ S s{true, {3.1415, {1, 2, 3}}};
+ CHECK_EQ(2, s.t.z[1]);
+
+// TODO(svenpanne) Remove the old-skool code when we ship the new C++ headers.
+#if 0
+ std::vector<int> vec{11, 22, 33, 44};
+#else
+ std::vector<int> vec;
+ vec.push_back(11);
+ vec.push_back(22);
+ vec.push_back(33);
+ vec.push_back(44);
+#endif
+ vec.push_back(55);
+ vec.push_back(66);
+ for (auto& i : vec) {
+ ++i;
+ }
+ int j = 12;
+ for (auto i : vec) {
+ CHECK_EQ(j, i);
+ j += 11;
+ }
+}
+#endif
diff --git a/deps/v8/test/cctest/test-version.cc b/deps/v8/test/cctest/test-version.cc
index 6bec4b75e..231451d11 100644
--- a/deps/v8/test/cctest/test-version.cc
+++ b/deps/v8/test/cctest/test-version.cc
@@ -25,10 +25,10 @@
// (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 "src/v8.h"
-#include "version.h"
-#include "cctest.h"
+#include "src/version.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-weakmaps.cc b/deps/v8/test/cctest/test-weakmaps.cc
index 14a5e020a..bb412a82a 100644
--- a/deps/v8/test/cctest/test-weakmaps.cc
+++ b/deps/v8/test/cctest/test-weakmaps.cc
@@ -27,11 +27,11 @@
#include <utility>
-#include "v8.h"
+#include "src/v8.h"
-#include "global-handles.h"
-#include "snapshot.h"
-#include "cctest.h"
+#include "src/global-handles.h"
+#include "src/snapshot.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -46,10 +46,12 @@ static Handle<JSWeakMap> AllocateJSWeakMap(Isolate* isolate) {
Handle<Map> map = factory->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
Handle<JSObject> weakmap_obj = factory->NewJSObjectFromMap(map);
Handle<JSWeakMap> weakmap(JSWeakMap::cast(*weakmap_obj));
- // Do not use handles for the hash table, it would make entries strong.
- Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 1);
- weakmap->set_table(*table);
- weakmap->set_next(Smi::FromInt(0));
+ // Do not leak handles for the hash table, it would make entries strong.
+ {
+ HandleScope scope(isolate);
+ Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 1);
+ weakmap->set_table(*table);
+ }
return weakmap;
}
@@ -69,7 +71,7 @@ static void WeakPointerCallback(
std::pair<v8::Persistent<v8::Value>*, int>* p =
reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>(
data.GetParameter());
- ASSERT_EQ(1234, p->second);
+ DCHECK_EQ(1234, p->second);
NumberOfWeakCalls++;
p->first->Reset();
}
@@ -185,8 +187,8 @@ TEST(Regress2060a) {
Factory* factory = isolate->factory();
Heap* heap = isolate->heap();
HandleScope scope(isolate);
- Handle<JSFunction> function = factory->NewFunctionWithPrototype(
- factory->function_string(), factory->null_value());
+ Handle<JSFunction> function = factory->NewFunction(
+ factory->function_string());
Handle<JSObject> key = factory->NewJSObject(function);
Handle<JSWeakMap> weakmap = AllocateJSWeakMap(isolate);
@@ -225,8 +227,8 @@ TEST(Regress2060b) {
Factory* factory = isolate->factory();
Heap* heap = isolate->heap();
HandleScope scope(isolate);
- Handle<JSFunction> function = factory->NewFunctionWithPrototype(
- factory->function_string(), factory->null_value());
+ Handle<JSFunction> function = factory->NewFunction(
+ factory->function_string());
// Start second old-space page so that keys land on evacuation candidate.
Page* first_page = heap->old_pointer_space()->anchor()->next_page();
@@ -253,3 +255,20 @@ TEST(Regress2060b) {
heap->CollectAllGarbage(Heap::kNoGCFlags);
heap->CollectAllGarbage(Heap::kNoGCFlags);
}
+
+
+TEST(Regress399527) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ {
+ HandleScope scope(isolate);
+ AllocateJSWeakMap(isolate);
+ SimulateIncrementalMarking(heap);
+ }
+ // The weak map is marked black here but leaving the handle scope will make
+ // the object unreachable. Aborting incremental marking will clear all the
+ // marking bits which makes the weak map garbage.
+ heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+}
diff --git a/deps/v8/test/cctest/test-weaksets.cc b/deps/v8/test/cctest/test-weaksets.cc
index a3a947897..299cc92e9 100644
--- a/deps/v8/test/cctest/test-weaksets.cc
+++ b/deps/v8/test/cctest/test-weaksets.cc
@@ -27,11 +27,11 @@
#include <utility>
-#include "v8.h"
+#include "src/v8.h"
-#include "global-handles.h"
-#include "snapshot.h"
-#include "cctest.h"
+#include "src/global-handles.h"
+#include "src/snapshot.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -46,10 +46,12 @@ static Handle<JSWeakSet> AllocateJSWeakSet(Isolate* isolate) {
Handle<Map> map = factory->NewMap(JS_WEAK_SET_TYPE, JSWeakSet::kSize);
Handle<JSObject> weakset_obj = factory->NewJSObjectFromMap(map);
Handle<JSWeakSet> weakset(JSWeakSet::cast(*weakset_obj));
- // Do not use handles for the hash table, it would make entries strong.
- Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 1);
- weakset->set_table(*table);
- weakset->set_next(Smi::FromInt(0));
+ // Do not leak handles for the hash table, it would make entries strong.
+ {
+ HandleScope scope(isolate);
+ Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 1);
+ weakset->set_table(*table);
+ }
return weakset;
}
@@ -69,7 +71,7 @@ static void WeakPointerCallback(
std::pair<v8::Persistent<v8::Value>*, int>* p =
reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>(
data.GetParameter());
- ASSERT_EQ(1234, p->second);
+ DCHECK_EQ(1234, p->second);
NumberOfWeakCalls++;
p->first->Reset();
}
@@ -185,8 +187,8 @@ TEST(WeakSet_Regress2060a) {
Factory* factory = isolate->factory();
Heap* heap = isolate->heap();
HandleScope scope(isolate);
- Handle<JSFunction> function = factory->NewFunctionWithPrototype(
- factory->function_string(), factory->null_value());
+ Handle<JSFunction> function = factory->NewFunction(
+ factory->function_string());
Handle<JSObject> key = factory->NewJSObject(function);
Handle<JSWeakSet> weakset = AllocateJSWeakSet(isolate);
@@ -225,8 +227,8 @@ TEST(WeakSet_Regress2060b) {
Factory* factory = isolate->factory();
Heap* heap = isolate->heap();
HandleScope scope(isolate);
- Handle<JSFunction> function = factory->NewFunctionWithPrototype(
- factory->function_string(), factory->null_value());
+ Handle<JSFunction> function = factory->NewFunction(
+ factory->function_string());
// Start second old-space page so that keys land on evacuation candidate.
Page* first_page = heap->old_pointer_space()->anchor()->next_page();
diff --git a/deps/v8/test/cctest/test-weaktypedarrays.cc b/deps/v8/test/cctest/test-weaktypedarrays.cc
index daf07eed0..d40b7e95a 100644
--- a/deps/v8/test/cctest/test-weaktypedarrays.cc
+++ b/deps/v8/test/cctest/test-weaktypedarrays.cc
@@ -27,12 +27,12 @@
#include <stdlib.h>
-#include "v8.h"
-#include "api.h"
-#include "heap.h"
-#include "objects.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
-#include "cctest.h"
+#include "src/api.h"
+#include "src/heap/heap.h"
+#include "src/objects.h"
using namespace v8::internal;
@@ -155,7 +155,7 @@ TEST(WeakArrayBuffersFromScript) {
}
i::ScopedVector<char> source(1024);
- i::OS::SNPrintF(source, "ab%d = null;", i);
+ i::SNPrintF(source, "ab%d = null;", i);
CompileRun(source.start());
isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
@@ -165,7 +165,7 @@ TEST(WeakArrayBuffersFromScript) {
v8::HandleScope s2(context->GetIsolate());
for (int j = 1; j <= 3; j++) {
if (j == i) continue;
- i::OS::SNPrintF(source, "ab%d", j);
+ i::SNPrintF(source, "ab%d", j);
v8::Handle<v8::ArrayBuffer> ab =
v8::Handle<v8::ArrayBuffer>::Cast(CompileRun(source.start()));
CHECK(HasArrayBufferInWeakList(isolate->heap(),
@@ -282,11 +282,11 @@ static void TestTypedArrayFromScript(const char* constructor) {
{
v8::HandleScope s1(context->GetIsolate());
- i::OS::SNPrintF(source,
- "var ta1 = new %s(ab);"
- "var ta2 = new %s(ab);"
- "var ta3 = new %s(ab)",
- constructor, constructor, constructor);
+ i::SNPrintF(source,
+ "var ta1 = new %s(ab);"
+ "var ta2 = new %s(ab);"
+ "var ta3 = new %s(ab)",
+ constructor, constructor, constructor);
CompileRun(source.start());
v8::Handle<v8::ArrayBuffer> ab =
@@ -305,7 +305,7 @@ static void TestTypedArrayFromScript(const char* constructor) {
CHECK(HasViewInWeakList(*iab, *v8::Utils::OpenHandle(*ta3)));
}
- i::OS::SNPrintF(source, "ta%d = null;", i);
+ i::SNPrintF(source, "ta%d = null;", i);
CompileRun(source.start());
isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
@@ -319,7 +319,7 @@ static void TestTypedArrayFromScript(const char* constructor) {
CHECK_EQ(2, CountViews(*iab));
for (int j = 1; j <= 3; j++) {
if (j == i) continue;
- i::OS::SNPrintF(source, "ta%d", j);
+ i::SNPrintF(source, "ta%d", j);
v8::Handle<TypedArray> ta =
v8::Handle<TypedArray>::Cast(CompileRun(source.start()));
CHECK(HasViewInWeakList(*iab, *v8::Utils::OpenHandle(*ta)));
diff --git a/deps/v8/test/cctest/trace-extension.cc b/deps/v8/test/cctest/trace-extension.cc
index 2da681316..8f390e4bc 100644
--- a/deps/v8/test/cctest/trace-extension.cc
+++ b/deps/v8/test/cctest/trace-extension.cc
@@ -25,10 +25,10 @@
// (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 "trace-extension.h"
+#include "test/cctest/trace-extension.h"
-#include "cctest.h"
-#include "sampler.h"
+#include "src/sampler.h"
+#include "test/cctest/cctest.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/test/cctest/trace-extension.h b/deps/v8/test/cctest/trace-extension.h
index b80b3d45d..919eda5bb 100644
--- a/deps/v8/test/cctest/trace-extension.h
+++ b/deps/v8/test/cctest/trace-extension.h
@@ -28,7 +28,7 @@
#ifndef V8_TEST_CCTEST_TRACE_EXTENSION_H_
#define V8_TEST_CCTEST_TRACE_EXTENSION_H_
-#include "v8.h"
+#include "src/v8.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/test/compiler-unittests/DEPS b/deps/v8/test/compiler-unittests/DEPS
new file mode 100644
index 000000000..8aa02395f
--- /dev/null
+++ b/deps/v8/test/compiler-unittests/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+ "+src",
+ "+testing/gtest",
+ "+testing/gtest-type-names.h",
+ "+testing/gmock",
+]
diff --git a/deps/v8/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc b/deps/v8/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc
new file mode 100644
index 000000000..b781ac8f9
--- /dev/null
+++ b/deps/v8/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc
@@ -0,0 +1,27 @@
+// 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 "test/compiler-unittests/instruction-selector-unittest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class InstructionSelectorARMTest : public InstructionSelectorTest {};
+
+
+TARGET_TEST_F(InstructionSelectorARMTest, Int32AddP) {
+ StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
+ m.Return(m.Int32Add(m.Parameter(0), m.Parameter(1)));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+ EXPECT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/compiler-unittests/change-lowering-unittest.cc b/deps/v8/test/compiler-unittests/change-lowering-unittest.cc
new file mode 100644
index 000000000..68de48013
--- /dev/null
+++ b/deps/v8/test/compiler-unittests/change-lowering-unittest.cc
@@ -0,0 +1,257 @@
+// 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 "src/compiler/change-lowering.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/simplified-operator.h"
+#include "src/factory.h"
+#include "test/compiler-unittests/compiler-unittests.h"
+#include "test/compiler-unittests/node-matchers.h"
+#include "testing/gtest-type-names.h"
+
+using testing::_;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+template <typename T>
+class ChangeLoweringTest : public CompilerTest {
+ public:
+ static const size_t kPointerSize = sizeof(T);
+
+ explicit ChangeLoweringTest(int num_parameters = 1)
+ : graph_(zone()), common_(zone()), simplified_(zone()) {
+ graph()->SetStart(graph()->NewNode(common()->Start(num_parameters)));
+ }
+ virtual ~ChangeLoweringTest() {}
+
+ protected:
+ Node* Parameter(int32_t index = 0) {
+ return graph()->NewNode(common()->Parameter(index), graph()->start());
+ }
+
+ Reduction Reduce(Node* node) {
+ CompilationInfo info(isolate(), zone());
+ Linkage linkage(&info);
+ ChangeLowering<kPointerSize> reducer(graph(), &linkage);
+ return reducer.Reduce(node);
+ }
+
+ Graph* graph() { return &graph_; }
+ Factory* factory() const { return isolate()->factory(); }
+ CommonOperatorBuilder* common() { return &common_; }
+ SimplifiedOperatorBuilder* simplified() { return &simplified_; }
+
+ PrintableUnique<HeapObject> true_unique() {
+ return PrintableUnique<HeapObject>::CreateImmovable(
+ zone(), factory()->true_value());
+ }
+ PrintableUnique<HeapObject> false_unique() {
+ return PrintableUnique<HeapObject>::CreateImmovable(
+ zone(), factory()->false_value());
+ }
+
+ private:
+ Graph graph_;
+ CommonOperatorBuilder common_;
+ SimplifiedOperatorBuilder simplified_;
+};
+
+
+typedef ::testing::Types<int32_t, int64_t> ChangeLoweringTypes;
+TYPED_TEST_CASE(ChangeLoweringTest, ChangeLoweringTypes);
+
+
+TARGET_TYPED_TEST(ChangeLoweringTest, ChangeBitToBool) {
+ Node* val = this->Parameter(0);
+ Node* node =
+ this->graph()->NewNode(this->simplified()->ChangeBitToBool(), val);
+ Reduction reduction = this->Reduce(node);
+ ASSERT_TRUE(reduction.Changed());
+
+ Node* phi = reduction.replacement();
+ EXPECT_THAT(phi, IsPhi(IsHeapConstant(this->true_unique()),
+ IsHeapConstant(this->false_unique()), _));
+
+ Node* merge = NodeProperties::GetControlInput(phi);
+ ASSERT_EQ(IrOpcode::kMerge, merge->opcode());
+
+ Node* if_true = NodeProperties::GetControlInput(merge, 0);
+ ASSERT_EQ(IrOpcode::kIfTrue, if_true->opcode());
+
+ Node* if_false = NodeProperties::GetControlInput(merge, 1);
+ ASSERT_EQ(IrOpcode::kIfFalse, if_false->opcode());
+
+ Node* branch = NodeProperties::GetControlInput(if_true);
+ EXPECT_EQ(branch, NodeProperties::GetControlInput(if_false));
+ EXPECT_THAT(branch, IsBranch(val, this->graph()->start()));
+}
+
+
+TARGET_TYPED_TEST(ChangeLoweringTest, StringAdd) {
+ Node* node = this->graph()->NewNode(this->simplified()->StringAdd(),
+ this->Parameter(0), this->Parameter(1));
+ Reduction reduction = this->Reduce(node);
+ EXPECT_FALSE(reduction.Changed());
+}
+
+
+class ChangeLowering32Test : public ChangeLoweringTest<int32_t> {
+ public:
+ virtual ~ChangeLowering32Test() {}
+};
+
+
+TARGET_TEST_F(ChangeLowering32Test, ChangeBoolToBit) {
+ Node* val = Parameter(0);
+ Node* node = graph()->NewNode(simplified()->ChangeBoolToBit(), val);
+ Reduction reduction = Reduce(node);
+ ASSERT_TRUE(reduction.Changed());
+
+ EXPECT_THAT(reduction.replacement(),
+ IsWord32Equal(val, IsHeapConstant(true_unique())));
+}
+
+
+TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) {
+ Node* val = Parameter(0);
+ Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val);
+ Reduction reduction = Reduce(node);
+ ASSERT_TRUE(reduction.Changed());
+
+ Node* phi = reduction.replacement();
+ ASSERT_EQ(IrOpcode::kPhi, phi->opcode());
+
+ Node* smi = NodeProperties::GetValueInput(phi, 1);
+ ASSERT_THAT(smi, IsProjection(0, IsInt32AddWithOverflow(val, val)));
+
+ Node* heap_number = NodeProperties::GetValueInput(phi, 0);
+ ASSERT_EQ(IrOpcode::kCall, heap_number->opcode());
+
+ Node* merge = NodeProperties::GetControlInput(phi);
+ ASSERT_EQ(IrOpcode::kMerge, merge->opcode());
+
+ const int32_t kValueOffset = HeapNumber::kValueOffset - kHeapObjectTag;
+ EXPECT_THAT(NodeProperties::GetControlInput(merge, 0),
+ IsStore(kMachineFloat64, kNoWriteBarrier, heap_number,
+ IsInt32Constant(kValueOffset),
+ IsChangeInt32ToFloat64(val), _, heap_number));
+
+ Node* if_true = NodeProperties::GetControlInput(heap_number);
+ ASSERT_EQ(IrOpcode::kIfTrue, if_true->opcode());
+
+ Node* if_false = NodeProperties::GetControlInput(merge, 1);
+ ASSERT_EQ(IrOpcode::kIfFalse, if_false->opcode());
+
+ Node* branch = NodeProperties::GetControlInput(if_true);
+ EXPECT_EQ(branch, NodeProperties::GetControlInput(if_false));
+ EXPECT_THAT(branch,
+ IsBranch(IsProjection(1, IsInt32AddWithOverflow(val, val)),
+ graph()->start()));
+}
+
+
+TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToFloat64) {
+ Node* val = Parameter(0);
+ Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val);
+ Reduction reduction = Reduce(node);
+ ASSERT_TRUE(reduction.Changed());
+
+ const int32_t kShiftAmount =
+ kSmiTagSize + SmiTagging<kPointerSize>::kSmiShiftSize;
+ const int32_t kValueOffset = HeapNumber::kValueOffset - kHeapObjectTag;
+ Node* phi = reduction.replacement();
+ ASSERT_THAT(
+ phi, IsPhi(IsLoad(kMachineFloat64, val, IsInt32Constant(kValueOffset), _),
+ IsChangeInt32ToFloat64(
+ IsWord32Sar(val, IsInt32Constant(kShiftAmount))),
+ _));
+
+ Node* merge = NodeProperties::GetControlInput(phi);
+ ASSERT_EQ(IrOpcode::kMerge, merge->opcode());
+
+ Node* if_true = NodeProperties::GetControlInput(merge, 0);
+ ASSERT_EQ(IrOpcode::kIfTrue, if_true->opcode());
+
+ Node* if_false = NodeProperties::GetControlInput(merge, 1);
+ ASSERT_EQ(IrOpcode::kIfFalse, if_false->opcode());
+
+ Node* branch = NodeProperties::GetControlInput(if_true);
+ EXPECT_EQ(branch, NodeProperties::GetControlInput(if_false));
+ STATIC_ASSERT(kSmiTag == 0);
+ STATIC_ASSERT(kSmiTagSize == 1);
+ EXPECT_THAT(branch, IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
+ graph()->start()));
+}
+
+
+class ChangeLowering64Test : public ChangeLoweringTest<int64_t> {
+ public:
+ virtual ~ChangeLowering64Test() {}
+};
+
+
+TARGET_TEST_F(ChangeLowering64Test, ChangeBoolToBit) {
+ Node* val = Parameter(0);
+ Node* node = graph()->NewNode(simplified()->ChangeBoolToBit(), val);
+ Reduction reduction = Reduce(node);
+ ASSERT_TRUE(reduction.Changed());
+
+ EXPECT_THAT(reduction.replacement(),
+ IsWord64Equal(val, IsHeapConstant(true_unique())));
+}
+
+
+TARGET_TEST_F(ChangeLowering64Test, ChangeInt32ToTagged) {
+ Node* val = Parameter(0);
+ Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val);
+ Reduction reduction = Reduce(node);
+ ASSERT_TRUE(reduction.Changed());
+
+ const int32_t kShiftAmount =
+ kSmiTagSize + SmiTagging<kPointerSize>::kSmiShiftSize;
+ EXPECT_THAT(reduction.replacement(),
+ IsWord64Shl(val, IsInt32Constant(kShiftAmount)));
+}
+
+
+TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToFloat64) {
+ Node* val = Parameter(0);
+ Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val);
+ Reduction reduction = Reduce(node);
+ ASSERT_TRUE(reduction.Changed());
+
+ const int32_t kShiftAmount =
+ kSmiTagSize + SmiTagging<kPointerSize>::kSmiShiftSize;
+ const int32_t kValueOffset = HeapNumber::kValueOffset - kHeapObjectTag;
+ Node* phi = reduction.replacement();
+ ASSERT_THAT(
+ phi, IsPhi(IsLoad(kMachineFloat64, val, IsInt32Constant(kValueOffset), _),
+ IsChangeInt32ToFloat64(IsConvertInt64ToInt32(
+ IsWord64Sar(val, IsInt32Constant(kShiftAmount)))),
+ _));
+
+ Node* merge = NodeProperties::GetControlInput(phi);
+ ASSERT_EQ(IrOpcode::kMerge, merge->opcode());
+
+ Node* if_true = NodeProperties::GetControlInput(merge, 0);
+ ASSERT_EQ(IrOpcode::kIfTrue, if_true->opcode());
+
+ Node* if_false = NodeProperties::GetControlInput(merge, 1);
+ ASSERT_EQ(IrOpcode::kIfFalse, if_false->opcode());
+
+ Node* branch = NodeProperties::GetControlInput(if_true);
+ EXPECT_EQ(branch, NodeProperties::GetControlInput(if_false));
+ STATIC_ASSERT(kSmiTag == 0);
+ STATIC_ASSERT(kSmiTagSize == 1);
+ EXPECT_THAT(branch, IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
+ graph()->start()));
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/compiler-unittests/compiler-unittests.cc b/deps/v8/test/compiler-unittests/compiler-unittests.cc
new file mode 100644
index 000000000..2ce4c93ee
--- /dev/null
+++ b/deps/v8/test/compiler-unittests/compiler-unittests.cc
@@ -0,0 +1,86 @@
+// 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 "include/libplatform/libplatform.h"
+#include "test/compiler-unittests/compiler-unittests.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using testing::IsNull;
+using testing::NotNull;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// static
+v8::Isolate* CompilerTest::isolate_ = NULL;
+
+
+CompilerTest::CompilerTest()
+ : isolate_scope_(isolate_),
+ handle_scope_(isolate_),
+ context_scope_(v8::Context::New(isolate_)),
+ zone_(isolate()) {}
+
+
+CompilerTest::~CompilerTest() {}
+
+
+// static
+void CompilerTest::SetUpTestCase() {
+ Test::SetUpTestCase();
+ EXPECT_THAT(isolate_, IsNull());
+ isolate_ = v8::Isolate::New();
+ ASSERT_THAT(isolate_, NotNull());
+}
+
+
+// static
+void CompilerTest::TearDownTestCase() {
+ ASSERT_THAT(isolate_, NotNull());
+ isolate_->Dispose();
+ isolate_ = NULL;
+ Test::TearDownTestCase();
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
+
+
+namespace {
+
+class CompilerTestEnvironment V8_FINAL : public ::testing::Environment {
+ public:
+ CompilerTestEnvironment() : platform_(NULL) {}
+ ~CompilerTestEnvironment() {}
+
+ virtual void SetUp() V8_OVERRIDE {
+ EXPECT_THAT(platform_, IsNull());
+ platform_ = v8::platform::CreateDefaultPlatform();
+ v8::V8::InitializePlatform(platform_);
+ ASSERT_TRUE(v8::V8::Initialize());
+ }
+
+ virtual void TearDown() V8_OVERRIDE {
+ ASSERT_THAT(platform_, NotNull());
+ v8::V8::Dispose();
+ v8::V8::ShutdownPlatform();
+ delete platform_;
+ platform_ = NULL;
+ }
+
+ private:
+ v8::Platform* platform_;
+};
+
+}
+
+
+int main(int argc, char** argv) {
+ testing::InitGoogleMock(&argc, argv);
+ testing::AddGlobalTestEnvironment(new CompilerTestEnvironment);
+ v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
+ return RUN_ALL_TESTS();
+}
diff --git a/deps/v8/test/compiler-unittests/compiler-unittests.gyp b/deps/v8/test/compiler-unittests/compiler-unittests.gyp
new file mode 100644
index 000000000..c1de0c423
--- /dev/null
+++ b/deps/v8/test/compiler-unittests/compiler-unittests.gyp
@@ -0,0 +1,61 @@
+# 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.
+
+{
+ 'variables': {
+ 'v8_code': 1,
+ },
+ 'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
+ 'targets': [
+ {
+ 'target_name': 'compiler-unittests',
+ 'type': 'executable',
+ 'dependencies': [
+ '../../testing/gmock.gyp:gmock',
+ '../../testing/gtest.gyp:gtest',
+ '../../tools/gyp/v8.gyp:v8_libplatform',
+ ],
+ 'include_dirs': [
+ '../..',
+ ],
+ 'sources': [ ### gcmole(all) ###
+ 'change-lowering-unittest.cc',
+ 'compiler-unittests.cc',
+ 'instruction-selector-unittest.cc',
+ 'node-matchers.cc',
+ 'node-matchers.h',
+ ],
+ 'conditions': [
+ ['v8_target_arch=="arm"', {
+ 'sources': [ ### gcmole(arch:arm) ###
+ 'arm/instruction-selector-arm-unittest.cc',
+ ],
+ }],
+ ['component=="shared_library"', {
+ # compiler-unittests can't be built against a shared library, so we
+ # need to depend on the underlying static target in that case.
+ 'conditions': [
+ ['v8_use_snapshot=="true"', {
+ 'dependencies': ['../../tools/gyp/v8.gyp:v8_snapshot'],
+ },
+ {
+ 'dependencies': [
+ '../../tools/gyp/v8.gyp:v8_nosnapshot',
+ ],
+ }],
+ ],
+ }, {
+ 'dependencies': ['../../tools/gyp/v8.gyp:v8'],
+ }],
+ ['os_posix == 1', {
+ # TODO(svenpanne): This is a temporary work-around to fix the warnings
+ # that show up because we use -std=gnu++0x instead of -std=c++11.
+ 'cflags!': [
+ '-pedantic',
+ ],
+ }],
+ ],
+ },
+ ],
+}
diff --git a/deps/v8/test/compiler-unittests/compiler-unittests.h b/deps/v8/test/compiler-unittests/compiler-unittests.h
new file mode 100644
index 000000000..091b13706
--- /dev/null
+++ b/deps/v8/test/compiler-unittests/compiler-unittests.h
@@ -0,0 +1,69 @@
+// 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_COMPILER_UNITTESTS_COMPILER_UNITTESTS_H_
+#define V8_COMPILER_UNITTESTS_COMPILER_UNITTESTS_H_
+
+#include "include/v8.h"
+#include "src/zone.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// The TARGET_TEST(Case, Name) macro works just like
+// TEST(Case, Name), except that the test is disabled
+// if the platform is not a supported TurboFan target.
+#if V8_TURBOFAN_TARGET
+#define TARGET_TEST(Case, Name) TEST(Case, Name)
+#else
+#define TARGET_TEST(Case, Name) TEST(Case, DISABLED_##Name)
+#endif
+
+
+// The TARGET_TEST_F(Case, Name) macro works just like
+// TEST_F(Case, Name), except that the test is disabled
+// if the platform is not a supported TurboFan target.
+#if V8_TURBOFAN_TARGET
+#define TARGET_TEST_F(Case, Name) TEST_F(Case, Name)
+#else
+#define TARGET_TEST_F(Case, Name) TEST_F(Case, DISABLED_##Name)
+#endif
+
+
+// The TARGET_TYPED_TEST(Case, Name) macro works just like
+// TYPED_TEST(Case, Name), except that the test is disabled
+// if the platform is not a supported TurboFan target.
+#if V8_TURBOFAN_TARGET
+#define TARGET_TYPED_TEST(Case, Name) TYPED_TEST(Case, Name)
+#else
+#define TARGET_TYPED_TEST(Case, Name) TYPED_TEST(Case, DISABLED_##Name)
+#endif
+
+
+class CompilerTest : public ::testing::Test {
+ public:
+ CompilerTest();
+ virtual ~CompilerTest();
+
+ Isolate* isolate() const { return reinterpret_cast<Isolate*>(isolate_); }
+ Zone* zone() { return &zone_; }
+
+ static void SetUpTestCase();
+ static void TearDownTestCase();
+
+ private:
+ static v8::Isolate* isolate_;
+ v8::Isolate::Scope isolate_scope_;
+ v8::HandleScope handle_scope_;
+ v8::Context::Scope context_scope_;
+ Zone zone_;
+};
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
+
+#endif // V8_COMPILER_UNITTESTS_COMPILER_UNITTESTS_H_
diff --git a/deps/v8/test/compiler-unittests/compiler-unittests.status b/deps/v8/test/compiler-unittests/compiler-unittests.status
new file mode 100644
index 000000000..d439913cc
--- /dev/null
+++ b/deps/v8/test/compiler-unittests/compiler-unittests.status
@@ -0,0 +1,6 @@
+# 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.
+
+[
+]
diff --git a/deps/v8/test/compiler-unittests/instruction-selector-unittest.cc b/deps/v8/test/compiler-unittests/instruction-selector-unittest.cc
new file mode 100644
index 000000000..70186529a
--- /dev/null
+++ b/deps/v8/test/compiler-unittests/instruction-selector-unittest.cc
@@ -0,0 +1,92 @@
+// 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 "test/compiler-unittests/instruction-selector-unittest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+InstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build(
+ InstructionSelector::Features features,
+ InstructionSelectorTest::StreamBuilderMode mode) {
+ Schedule* schedule = Export();
+ EXPECT_NE(0, graph()->NodeCount());
+ CompilationInfo info(test_->isolate(), test_->zone());
+ Linkage linkage(&info, call_descriptor());
+ InstructionSequence sequence(&linkage, graph(), schedule);
+ SourcePositionTable source_position_table(graph());
+ InstructionSelector selector(&sequence, &source_position_table, features);
+ selector.SelectInstructions();
+ if (FLAG_trace_turbo) {
+ OFStream out(stdout);
+ out << "--- Code sequence after instruction selection ---" << endl
+ << sequence;
+ }
+ Stream s;
+ for (InstructionSequence::const_iterator i = sequence.begin();
+ i != sequence.end(); ++i) {
+ Instruction* instr = *i;
+ if (instr->opcode() < 0) continue;
+ if (mode == kTargetInstructions) {
+ switch (instr->arch_opcode()) {
+#define CASE(Name) \
+ case k##Name: \
+ break;
+ TARGET_ARCH_OPCODE_LIST(CASE)
+#undef CASE
+ default:
+ continue;
+ }
+ }
+ for (size_t i = 0; i < instr->OutputCount(); ++i) {
+ InstructionOperand* output = instr->OutputAt(i);
+ EXPECT_NE(InstructionOperand::IMMEDIATE, output->kind());
+ if (output->IsConstant()) {
+ s.constants_.insert(std::make_pair(
+ output->index(), sequence.GetConstant(output->index())));
+ }
+ }
+ for (size_t i = 0; i < instr->InputCount(); ++i) {
+ InstructionOperand* input = instr->InputAt(i);
+ EXPECT_NE(InstructionOperand::CONSTANT, input->kind());
+ if (input->IsImmediate()) {
+ s.immediates_.insert(std::make_pair(
+ input->index(), sequence.GetImmediate(input->index())));
+ }
+ }
+ s.instructions_.push_back(instr);
+ }
+ return s;
+}
+
+
+TARGET_TEST_F(InstructionSelectorTest, ReturnP) {
+ StreamBuilder m(this, kMachineWord32, kMachineWord32);
+ m.Return(m.Parameter(0));
+ Stream s = m.Build(kAllInstructions);
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArchNop, s[0]->arch_opcode());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(kArchRet, s[1]->arch_opcode());
+ EXPECT_EQ(1U, s[1]->InputCount());
+}
+
+
+TARGET_TEST_F(InstructionSelectorTest, ReturnImm) {
+ StreamBuilder m(this, kMachineWord32);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build(kAllInstructions);
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArchNop, s[0]->arch_opcode());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind());
+ EXPECT_EQ(0, s.ToInt32(s[0]->OutputAt(0)));
+ EXPECT_EQ(kArchRet, s[1]->arch_opcode());
+ EXPECT_EQ(1U, s[1]->InputCount());
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/compiler-unittests/instruction-selector-unittest.h b/deps/v8/test/compiler-unittests/instruction-selector-unittest.h
new file mode 100644
index 000000000..3a7b59075
--- /dev/null
+++ b/deps/v8/test/compiler-unittests/instruction-selector-unittest.h
@@ -0,0 +1,129 @@
+// 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_COMPILER_UNITTESTS_INSTRUCTION_SELECTOR_UNITTEST_H_
+#define V8_COMPILER_UNITTESTS_INSTRUCTION_SELECTOR_UNITTEST_H_
+
+#include <deque>
+
+#include "src/compiler/instruction-selector.h"
+#include "src/compiler/raw-machine-assembler.h"
+#include "test/compiler-unittests/compiler-unittests.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class InstructionSelectorTest : public CompilerTest {
+ public:
+ InstructionSelectorTest() {}
+ virtual ~InstructionSelectorTest() {}
+
+ protected:
+ class Stream;
+
+ enum StreamBuilderMode { kAllInstructions, kTargetInstructions };
+
+ class StreamBuilder V8_FINAL : public RawMachineAssembler {
+ public:
+ StreamBuilder(InstructionSelectorTest* test, MachineType return_type)
+ : RawMachineAssembler(new (test->zone()) Graph(test->zone()),
+ CallDescriptorBuilder(test->zone(), return_type)),
+ test_(test) {}
+ StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
+ MachineType parameter0_type)
+ : RawMachineAssembler(new (test->zone()) Graph(test->zone()),
+ CallDescriptorBuilder(test->zone(), return_type,
+ parameter0_type)),
+ test_(test) {}
+ StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
+ MachineType parameter0_type, MachineType parameter1_type)
+ : RawMachineAssembler(
+ new (test->zone()) Graph(test->zone()),
+ CallDescriptorBuilder(test->zone(), return_type, parameter0_type,
+ parameter1_type)),
+ test_(test) {}
+
+ Stream Build(CpuFeature feature) {
+ return Build(InstructionSelector::Features(feature));
+ }
+ Stream Build(CpuFeature feature1, CpuFeature feature2) {
+ return Build(InstructionSelector::Features(feature1, feature2));
+ }
+ Stream Build(StreamBuilderMode mode = kTargetInstructions) {
+ return Build(InstructionSelector::Features(), mode);
+ }
+ Stream Build(InstructionSelector::Features features,
+ StreamBuilderMode mode = kTargetInstructions);
+
+ private:
+ MachineCallDescriptorBuilder* CallDescriptorBuilder(
+ Zone* zone, MachineType return_type) {
+ return new (zone) MachineCallDescriptorBuilder(return_type, 0, NULL);
+ }
+
+ MachineCallDescriptorBuilder* CallDescriptorBuilder(
+ Zone* zone, MachineType return_type, MachineType parameter0_type) {
+ MachineType* parameter_types = zone->NewArray<MachineType>(1);
+ parameter_types[0] = parameter0_type;
+ return new (zone)
+ MachineCallDescriptorBuilder(return_type, 1, parameter_types);
+ }
+
+ MachineCallDescriptorBuilder* CallDescriptorBuilder(
+ Zone* zone, MachineType return_type, MachineType parameter0_type,
+ MachineType parameter1_type) {
+ MachineType* parameter_types = zone->NewArray<MachineType>(2);
+ parameter_types[0] = parameter0_type;
+ parameter_types[1] = parameter1_type;
+ return new (zone)
+ MachineCallDescriptorBuilder(return_type, 2, parameter_types);
+ }
+
+ private:
+ InstructionSelectorTest* test_;
+ };
+
+ class Stream V8_FINAL {
+ public:
+ size_t size() const { return instructions_.size(); }
+ const Instruction* operator[](size_t index) const {
+ EXPECT_LT(index, size());
+ return instructions_[index];
+ }
+
+ int32_t ToInt32(const InstructionOperand* operand) const {
+ return ToConstant(operand).ToInt32();
+ }
+
+ private:
+ Constant ToConstant(const InstructionOperand* operand) const {
+ ConstantMap::const_iterator i;
+ if (operand->IsConstant()) {
+ i = constants_.find(operand->index());
+ EXPECT_NE(constants_.end(), i);
+ } else {
+ EXPECT_EQ(InstructionOperand::IMMEDIATE, operand->kind());
+ i = immediates_.find(operand->index());
+ EXPECT_NE(immediates_.end(), i);
+ }
+ EXPECT_EQ(operand->index(), i->first);
+ return i->second;
+ }
+
+ friend class StreamBuilder;
+
+ typedef std::map<int, Constant> ConstantMap;
+
+ ConstantMap constants_;
+ ConstantMap immediates_;
+ std::deque<Instruction*> instructions_;
+ };
+};
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
+
+#endif // V8_COMPILER_UNITTESTS_INSTRUCTION_SELECTOR_UNITTEST_H_
diff --git a/deps/v8/test/compiler-unittests/node-matchers.cc b/deps/v8/test/compiler-unittests/node-matchers.cc
new file mode 100644
index 000000000..d58083411
--- /dev/null
+++ b/deps/v8/test/compiler-unittests/node-matchers.cc
@@ -0,0 +1,454 @@
+// 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 "test/compiler-unittests/node-matchers.h"
+
+#include <ostream> // NOLINT(readability/streams)
+
+#include "src/compiler/node-properties-inl.h"
+
+using testing::MakeMatcher;
+using testing::MatcherInterface;
+using testing::MatchResultListener;
+using testing::StringMatchResultListener;
+
+namespace v8 {
+namespace internal {
+
+// TODO(bmeurer): Find a new home for these functions.
+template <typename T>
+inline std::ostream& operator<<(std::ostream& os,
+ const PrintableUnique<T>& value) {
+ return os << value.string();
+}
+
+namespace compiler {
+
+namespace {
+
+template <typename T>
+bool PrintMatchAndExplain(const T& value, const char* value_name,
+ const Matcher<T>& value_matcher,
+ MatchResultListener* listener) {
+ StringMatchResultListener value_listener;
+ if (!value_matcher.MatchAndExplain(value, &value_listener)) {
+ *listener << "whose " << value_name << " " << value << " doesn't match";
+ if (value_listener.str() != "") {
+ *listener << ", " << value_listener.str();
+ }
+ return false;
+ }
+ return true;
+}
+
+
+class NodeMatcher : public MatcherInterface<Node*> {
+ public:
+ explicit NodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {}
+
+ virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+ *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node";
+ }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+ V8_OVERRIDE {
+ if (node == NULL) {
+ *listener << "which is NULL";
+ return false;
+ }
+ if (node->opcode() != opcode_) {
+ *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode());
+ return false;
+ }
+ return true;
+ }
+
+ private:
+ const IrOpcode::Value opcode_;
+};
+
+
+class IsBranchMatcher V8_FINAL : public NodeMatcher {
+ public:
+ IsBranchMatcher(const Matcher<Node*>& value_matcher,
+ const Matcher<Node*>& control_matcher)
+ : NodeMatcher(IrOpcode::kBranch),
+ value_matcher_(value_matcher),
+ control_matcher_(control_matcher) {}
+
+ virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+ NodeMatcher::DescribeTo(os);
+ *os << " whose value (";
+ value_matcher_.DescribeTo(os);
+ *os << ") and control (";
+ control_matcher_.DescribeTo(os);
+ *os << ")";
+ }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+ V8_OVERRIDE {
+ return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+ "value", value_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+ "control", control_matcher_, listener));
+ }
+
+ private:
+ const Matcher<Node*> value_matcher_;
+ const Matcher<Node*> control_matcher_;
+};
+
+
+template <typename T>
+class IsConstantMatcher V8_FINAL : public NodeMatcher {
+ public:
+ IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher)
+ : NodeMatcher(opcode), value_matcher_(value_matcher) {}
+
+ virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+ NodeMatcher::DescribeTo(os);
+ *os << " whose value (";
+ value_matcher_.DescribeTo(os);
+ *os << ")";
+ }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+ V8_OVERRIDE {
+ return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(OpParameter<T>(node), "value", value_matcher_,
+ listener));
+ }
+
+ private:
+ const Matcher<T> value_matcher_;
+};
+
+
+class IsPhiMatcher V8_FINAL : public NodeMatcher {
+ public:
+ IsPhiMatcher(const Matcher<Node*>& value0_matcher,
+ const Matcher<Node*>& value1_matcher,
+ const Matcher<Node*>& control_matcher)
+ : NodeMatcher(IrOpcode::kPhi),
+ value0_matcher_(value0_matcher),
+ value1_matcher_(value1_matcher),
+ control_matcher_(control_matcher) {}
+
+ virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+ NodeMatcher::DescribeTo(os);
+ *os << " whose value0 (";
+ value0_matcher_.DescribeTo(os);
+ *os << "), value1 (";
+ value1_matcher_.DescribeTo(os);
+ *os << ") and control (";
+ control_matcher_.DescribeTo(os);
+ *os << ")";
+ }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+ V8_OVERRIDE {
+ return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+ "value0", value0_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+ "value1", value1_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+ "control", control_matcher_, listener));
+ }
+
+ private:
+ const Matcher<Node*> value0_matcher_;
+ const Matcher<Node*> value1_matcher_;
+ const Matcher<Node*> control_matcher_;
+};
+
+
+class IsProjectionMatcher V8_FINAL : public NodeMatcher {
+ public:
+ IsProjectionMatcher(const Matcher<int32_t>& index_matcher,
+ const Matcher<Node*>& base_matcher)
+ : NodeMatcher(IrOpcode::kProjection),
+ index_matcher_(index_matcher),
+ base_matcher_(base_matcher) {}
+
+ virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+ NodeMatcher::DescribeTo(os);
+ *os << " whose index (";
+ index_matcher_.DescribeTo(os);
+ *os << ") and base (";
+ base_matcher_.DescribeTo(os);
+ *os << ")";
+ }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+ V8_OVERRIDE {
+ return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(OpParameter<int32_t>(node), "index",
+ index_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+ base_matcher_, listener));
+ }
+
+ private:
+ const Matcher<int32_t> index_matcher_;
+ const Matcher<Node*> base_matcher_;
+};
+
+
+class IsLoadMatcher V8_FINAL : public NodeMatcher {
+ public:
+ IsLoadMatcher(const Matcher<MachineType>& type_matcher,
+ const Matcher<Node*>& base_matcher,
+ const Matcher<Node*>& index_matcher,
+ const Matcher<Node*>& effect_matcher)
+ : NodeMatcher(IrOpcode::kLoad),
+ type_matcher_(type_matcher),
+ base_matcher_(base_matcher),
+ index_matcher_(index_matcher),
+ effect_matcher_(effect_matcher) {}
+
+ virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+ NodeMatcher::DescribeTo(os);
+ *os << " whose type (";
+ type_matcher_.DescribeTo(os);
+ *os << "), base (";
+ base_matcher_.DescribeTo(os);
+ *os << "), index (";
+ index_matcher_.DescribeTo(os);
+ *os << ") and effect (";
+ effect_matcher_.DescribeTo(os);
+ *os << ")";
+ }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+ V8_OVERRIDE {
+ return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(OpParameter<MachineType>(node), "type",
+ type_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+ base_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+ "index", index_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+ effect_matcher_, listener));
+ }
+
+ private:
+ const Matcher<MachineType> type_matcher_;
+ const Matcher<Node*> base_matcher_;
+ const Matcher<Node*> index_matcher_;
+ const Matcher<Node*> effect_matcher_;
+};
+
+
+class IsStoreMatcher V8_FINAL : public NodeMatcher {
+ public:
+ IsStoreMatcher(const Matcher<MachineType>& type_matcher,
+ const Matcher<WriteBarrierKind> write_barrier_matcher,
+ const Matcher<Node*>& base_matcher,
+ const Matcher<Node*>& index_matcher,
+ const Matcher<Node*>& value_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher)
+ : NodeMatcher(IrOpcode::kStore),
+ type_matcher_(type_matcher),
+ write_barrier_matcher_(write_barrier_matcher),
+ base_matcher_(base_matcher),
+ index_matcher_(index_matcher),
+ value_matcher_(value_matcher),
+ effect_matcher_(effect_matcher),
+ control_matcher_(control_matcher) {}
+
+ virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+ NodeMatcher::DescribeTo(os);
+ *os << " whose type (";
+ type_matcher_.DescribeTo(os);
+ *os << "), write barrier (";
+ write_barrier_matcher_.DescribeTo(os);
+ *os << "), base (";
+ base_matcher_.DescribeTo(os);
+ *os << "), index (";
+ index_matcher_.DescribeTo(os);
+ *os << "), value (";
+ value_matcher_.DescribeTo(os);
+ *os << "), effect (";
+ effect_matcher_.DescribeTo(os);
+ *os << ") and control (";
+ control_matcher_.DescribeTo(os);
+ *os << ")";
+ }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+ V8_OVERRIDE {
+ return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(OpParameter<StoreRepresentation>(node).rep,
+ "type", type_matcher_, listener) &&
+ PrintMatchAndExplain(
+ OpParameter<StoreRepresentation>(node).write_barrier_kind,
+ "write barrier", write_barrier_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+ base_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+ "index", index_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
+ "value", value_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+ effect_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+ "control", control_matcher_, listener));
+ }
+
+ private:
+ const Matcher<MachineType> type_matcher_;
+ const Matcher<WriteBarrierKind> write_barrier_matcher_;
+ const Matcher<Node*> base_matcher_;
+ const Matcher<Node*> index_matcher_;
+ const Matcher<Node*> value_matcher_;
+ const Matcher<Node*> effect_matcher_;
+ const Matcher<Node*> control_matcher_;
+};
+
+
+class IsBinopMatcher V8_FINAL : public NodeMatcher {
+ public:
+ IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher)
+ : NodeMatcher(opcode),
+ lhs_matcher_(lhs_matcher),
+ rhs_matcher_(rhs_matcher) {}
+
+ virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+ NodeMatcher::DescribeTo(os);
+ *os << " whose lhs (";
+ lhs_matcher_.DescribeTo(os);
+ *os << ") and rhs (";
+ rhs_matcher_.DescribeTo(os);
+ *os << ")";
+ }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+ V8_OVERRIDE {
+ return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
+ lhs_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
+ rhs_matcher_, listener));
+ }
+
+ private:
+ const Matcher<Node*> lhs_matcher_;
+ const Matcher<Node*> rhs_matcher_;
+};
+
+
+class IsUnopMatcher V8_FINAL : public NodeMatcher {
+ public:
+ IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher)
+ : NodeMatcher(opcode), input_matcher_(input_matcher) {}
+
+ virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+ NodeMatcher::DescribeTo(os);
+ *os << " whose input (";
+ input_matcher_.DescribeTo(os);
+ *os << ")";
+ }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+ V8_OVERRIDE {
+ return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+ "input", input_matcher_, listener));
+ }
+
+ private:
+ const Matcher<Node*> input_matcher_;
+};
+
+}
+
+
+Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
+ const Matcher<Node*>& control_matcher) {
+ return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher));
+}
+
+
+Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) {
+ return MakeMatcher(
+ new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher));
+}
+
+
+Matcher<Node*> IsHeapConstant(
+ const Matcher<PrintableUnique<HeapObject> >& value_matcher) {
+ return MakeMatcher(new IsConstantMatcher<PrintableUnique<HeapObject> >(
+ IrOpcode::kHeapConstant, value_matcher));
+}
+
+
+Matcher<Node*> IsPhi(const Matcher<Node*>& value0_matcher,
+ const Matcher<Node*>& value1_matcher,
+ const Matcher<Node*>& merge_matcher) {
+ return MakeMatcher(
+ new IsPhiMatcher(value0_matcher, value1_matcher, merge_matcher));
+}
+
+
+Matcher<Node*> IsProjection(const Matcher<int32_t>& index_matcher,
+ const Matcher<Node*>& base_matcher) {
+ return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher));
+}
+
+
+Matcher<Node*> IsLoad(const Matcher<MachineType>& type_matcher,
+ const Matcher<Node*>& base_matcher,
+ const Matcher<Node*>& index_matcher,
+ const Matcher<Node*>& effect_matcher) {
+ return MakeMatcher(new IsLoadMatcher(type_matcher, base_matcher,
+ index_matcher, effect_matcher));
+}
+
+
+Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher,
+ const Matcher<WriteBarrierKind>& write_barrier_matcher,
+ const Matcher<Node*>& base_matcher,
+ const Matcher<Node*>& index_matcher,
+ const Matcher<Node*>& value_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher) {
+ return MakeMatcher(new IsStoreMatcher(
+ type_matcher, write_barrier_matcher, base_matcher, index_matcher,
+ value_matcher, effect_matcher, control_matcher));
+}
+
+
+#define IS_BINOP_MATCHER(Name) \
+ Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher, \
+ const Matcher<Node*>& rhs_matcher) { \
+ return MakeMatcher( \
+ new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \
+ }
+IS_BINOP_MATCHER(Word32And)
+IS_BINOP_MATCHER(Word32Sar)
+IS_BINOP_MATCHER(Word32Equal)
+IS_BINOP_MATCHER(Word64And)
+IS_BINOP_MATCHER(Word64Sar)
+IS_BINOP_MATCHER(Word64Shl)
+IS_BINOP_MATCHER(Word64Equal)
+IS_BINOP_MATCHER(Int32AddWithOverflow)
+#undef IS_BINOP_MATCHER
+
+
+#define IS_UNOP_MATCHER(Name) \
+ Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) { \
+ return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \
+ }
+IS_UNOP_MATCHER(ConvertInt64ToInt32)
+IS_UNOP_MATCHER(ChangeInt32ToFloat64)
+#undef IS_UNOP_MATCHER
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/compiler-unittests/node-matchers.h b/deps/v8/test/compiler-unittests/node-matchers.h
new file mode 100644
index 000000000..09da07a7f
--- /dev/null
+++ b/deps/v8/test/compiler-unittests/node-matchers.h
@@ -0,0 +1,71 @@
+// 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_COMPILER_UNITTESTS_NODE_MATCHERS_H_
+#define V8_COMPILER_UNITTESTS_NODE_MATCHERS_H_
+
+#include "src/compiler/machine-operator.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class HeapObject;
+template <class T>
+class PrintableUnique;
+
+namespace compiler {
+
+// Forward declarations.
+class Node;
+
+using testing::Matcher;
+
+Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
+ const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsHeapConstant(
+ const Matcher<PrintableUnique<HeapObject> >& value_matcher);
+Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher);
+Matcher<Node*> IsPhi(const Matcher<Node*>& value0_matcher,
+ const Matcher<Node*>& value1_matcher,
+ const Matcher<Node*>& merge_matcher);
+Matcher<Node*> IsProjection(const Matcher<int32_t>& index_matcher,
+ const Matcher<Node*>& base_matcher);
+
+Matcher<Node*> IsLoad(const Matcher<MachineType>& type_matcher,
+ const Matcher<Node*>& base_matcher,
+ const Matcher<Node*>& index_matcher,
+ const Matcher<Node*>& effect_matcher);
+Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher,
+ const Matcher<WriteBarrierKind>& write_barrier_matcher,
+ const Matcher<Node*>& base_matcher,
+ const Matcher<Node*>& index_matcher,
+ const Matcher<Node*>& value_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsWord32And(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord32Sar(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord32Equal(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64And(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64Shl(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64Sar(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64Equal(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsInt32AddWithOverflow(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsConvertInt64ToInt32(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsChangeInt32ToFloat64(const Matcher<Node*>& input_matcher);
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
+
+#endif // V8_COMPILER_UNITTESTS_NODE_MATCHERS_H_
diff --git a/deps/v8/test/compiler-unittests/testcfg.py b/deps/v8/test/compiler-unittests/testcfg.py
new file mode 100644
index 000000000..4eec956f7
--- /dev/null
+++ b/deps/v8/test/compiler-unittests/testcfg.py
@@ -0,0 +1,51 @@
+# 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.
+
+import os
+import shutil
+
+from testrunner.local import commands
+from testrunner.local import testsuite
+from testrunner.local import utils
+from testrunner.objects import testcase
+
+
+class CompilerUnitTestsSuite(testsuite.TestSuite):
+ def __init__(self, name, root):
+ super(CompilerUnitTestsSuite, self).__init__(name, root)
+
+ def ListTests(self, context):
+ shell = os.path.abspath(os.path.join(context.shell_dir, self.shell()))
+ if utils.IsWindows():
+ shell += ".exe"
+ output = commands.Execute(context.command_prefix +
+ [shell, "--gtest_list_tests"] +
+ context.extra_flags)
+ if output.exit_code != 0:
+ print output.stdout
+ print output.stderr
+ return []
+ tests = []
+ test_case = ''
+ for test_desc in output.stdout.strip().split():
+ if test_desc.endswith('.'):
+ test_case = test_desc
+ else:
+ test = testcase.TestCase(self, test_case + test_desc, dependency=None)
+ tests.append(test)
+ tests.sort()
+ return tests
+
+ def GetFlagsForTestCase(self, testcase, context):
+ return (testcase.flags + ["--gtest_filter=" + testcase.path] +
+ ["--gtest_random_seed=%s" % context.random_seed] +
+ ["--gtest_print_time=0"] +
+ context.mode_flags)
+
+ def shell(self):
+ return "compiler-unittests"
+
+
+def GetSuite(name, root):
+ return CompilerUnitTestsSuite(name, root)
diff --git a/deps/v8/test/fuzz-natives/base.js b/deps/v8/test/fuzz-natives/base.js
index b9f70043f..d1f721d0c 100644
--- a/deps/v8/test/fuzz-natives/base.js
+++ b/deps/v8/test/fuzz-natives/base.js
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// Flags: --allow-natives-syntax
+
// TODO(jkummerow): There are many ways to improve these tests, e.g.:
// - more variance in randomized inputs
// - better time complexity management
@@ -15,7 +17,9 @@ function makeArguments() {
result.push(17);
result.push(-31);
result.push(new Array(100));
- result.push(new Array(100003));
+ var a = %NormalizeElements([]);
+ a.length = 100003;
+ result.push(a);
result.push(Number.MIN_VALUE);
result.push("whoops");
result.push("x");
diff --git a/deps/v8/test/fuzz-natives/fuzz-natives.status b/deps/v8/test/fuzz-natives/fuzz-natives.status
index fb3cae902..7165c3845 100644
--- a/deps/v8/test/fuzz-natives/fuzz-natives.status
+++ b/deps/v8/test/fuzz-natives/fuzz-natives.status
@@ -31,6 +31,27 @@
"CreateDateTimeFormat": [SKIP],
"CreateNumberFormat": [SKIP],
+ # TODO(danno): Fix these internal function that are only callable form stubs
+ # and un-blacklist them!
+ "CompileUnoptimized": [SKIP],
+ "NotifyDeoptimized": [SKIP],
+ "NotifyStubFailure": [SKIP],
+ "NewSloppyArguments": [SKIP],
+ "NewStrictArguments": [SKIP],
+ "ArrayConstructor": [SKIP],
+ "InternalArrayConstructor": [SKIP],
+ "FinalizeInstanceSize": [SKIP],
+ "PromoteScheduledException": [SKIP],
+ "NewFunctionContext": [SKIP],
+ "PushWithContext": [SKIP],
+ "PushCatchContext": [SKIP],
+ "PushModuleContext": [SKIP],
+ "LoadLookupSlot": [SKIP],
+ "LoadLookupSlotNoReferenceError": [SKIP],
+ "ResolvePossiblyDirectEval": [SKIP],
+ "ForInInit": [SKIP],
+ "ForInNext": [SKIP],
+
# TODO(jkummerow): Figure out what to do about inlined functions.
"_GeneratorNext": [SKIP],
"_GeneratorThrow": [SKIP],
diff --git a/deps/v8/test/fuzz-natives/testcfg.py b/deps/v8/test/fuzz-natives/testcfg.py
index d8e3f056c..5e00b404b 100644
--- a/deps/v8/test/fuzz-natives/testcfg.py
+++ b/deps/v8/test/fuzz-natives/testcfg.py
@@ -28,14 +28,19 @@ class FuzzNativesTestSuite(testsuite.TestSuite):
if output.exit_code != 0:
print output.stdout
print output.stderr
- assert false, "Failed to get natives list."
+ assert False, "Failed to get natives list."
tests = []
for line in output.stdout.strip().split():
- (name, argc) = line.split(",")
- flags = ["--allow-natives-syntax",
- "-e", "var NAME = '%s', ARGC = %s;" % (name, argc)]
- test = testcase.TestCase(self, name, flags)
- tests.append(test)
+ try:
+ (name, argc) = line.split(",")
+ flags = ["--allow-natives-syntax",
+ "-e", "var NAME = '%s', ARGC = %s;" % (name, argc)]
+ test = testcase.TestCase(self, name, flags)
+ tests.append(test)
+ except:
+ # Work-around: If parsing didn't work, it might have been due to output
+ # caused by other d8 flags.
+ pass
return tests
def GetFlagsForTestCase(self, testcase, context):
diff --git a/deps/v8/test/intl/intl.status b/deps/v8/test/intl/intl.status
index 4ecbf325a..007943a32 100644
--- a/deps/v8/test/intl/intl.status
+++ b/deps/v8/test/intl/intl.status
@@ -38,5 +38,11 @@
# BUG(2899): default locale for search fails on mac and on android.
'collator/default-locale': [['system == macos or arch == android_arm or arch == android_ia32', FAIL]],
+
+ # BUG(v8:3454).
+ 'date-format/parse-MMMdy': [FAIL],
+ 'date-format/parse-mdyhms': [FAIL],
+ 'number-format/parse-decimal': [FAIL],
+ 'number-format/parse-percent': [FAIL],
}], # ALWAYS
]
diff --git a/deps/v8/test/mjsunit/allocation-site-info.js b/deps/v8/test/mjsunit/allocation-site-info.js
index 35b60ee26..9984f5bd2 100644
--- a/deps/v8/test/mjsunit/allocation-site-info.js
+++ b/deps/v8/test/mjsunit/allocation-site-info.js
@@ -25,25 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+// Flags: --allow-natives-syntax --expose-gc
// Flags: --noalways-opt
-// Test element kind of objects.
-// Since --smi-only-arrays affects builtins, its default setting at compile
-// time sticks if built with snapshot. If --smi-only-arrays is deactivated
-// by default, only a no-snapshot build actually has smi-only arrays enabled
-// in this test case. Depending on whether smi-only arrays are actually
-// enabled, this test takes the appropriate code path to check smi-only arrays.
-
-// support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
-support_smi_only_arrays = true;
-
-if (support_smi_only_arrays) {
- print("Tests include smi-only arrays.");
-} else {
- print("Tests do NOT include smi-only arrays.");
-}
-
var elements_kind = {
fast_smi_only : 'fast smi only elements',
fast : 'fast elements',
@@ -73,10 +57,6 @@ function isHoley(obj) {
}
function assertKind(expected, obj, name_opt) {
- if (!support_smi_only_arrays &&
- expected == elements_kind.fast_smi_only) {
- expected = elements_kind.fast;
- }
assertEquals(expected, getKind(obj), name_opt);
}
@@ -88,403 +68,402 @@ function assertNotHoley(obj, name_opt) {
assertEquals(false, isHoley(obj), name_opt);
}
-if (support_smi_only_arrays) {
- obj = [];
- assertNotHoley(obj);
- assertKind(elements_kind.fast_smi_only, obj);
+obj = [];
+assertNotHoley(obj);
+assertKind(elements_kind.fast_smi_only, obj);
- obj = [1, 2, 3];
- assertNotHoley(obj);
- assertKind(elements_kind.fast_smi_only, obj);
+obj = [1, 2, 3];
+assertNotHoley(obj);
+assertKind(elements_kind.fast_smi_only, obj);
- obj = new Array();
- assertNotHoley(obj);
- assertKind(elements_kind.fast_smi_only, obj);
+obj = new Array();
+assertNotHoley(obj);
+assertKind(elements_kind.fast_smi_only, obj);
- obj = new Array(0);
- assertNotHoley(obj);
- assertKind(elements_kind.fast_smi_only, obj);
+obj = new Array(0);
+assertNotHoley(obj);
+assertKind(elements_kind.fast_smi_only, obj);
- obj = new Array(2);
- assertHoley(obj);
- assertKind(elements_kind.fast_smi_only, obj);
+obj = new Array(2);
+assertHoley(obj);
+assertKind(elements_kind.fast_smi_only, obj);
- obj = new Array(1,2,3);
- assertNotHoley(obj);
- assertKind(elements_kind.fast_smi_only, obj);
+obj = new Array(1,2,3);
+assertNotHoley(obj);
+assertKind(elements_kind.fast_smi_only, obj);
- obj = new Array(1, "hi", 2, undefined);
- assertNotHoley(obj);
- assertKind(elements_kind.fast, obj);
+obj = new Array(1, "hi", 2, undefined);
+assertNotHoley(obj);
+assertKind(elements_kind.fast, obj);
- function fastliteralcase(literal, value) {
- literal[0] = value;
- return literal;
- }
+function fastliteralcase(literal, value) {
+ literal[0] = value;
+ return literal;
+}
- function get_standard_literal() {
- var literal = [1, 2, 3];
- return literal;
- }
+function get_standard_literal() {
+ var literal = [1, 2, 3];
+ return literal;
+}
- // Case: [1,2,3] as allocation site
- obj = fastliteralcase(get_standard_literal(), 1);
- assertKind(elements_kind.fast_smi_only, obj);
- obj = fastliteralcase(get_standard_literal(), 1.5);
+// Case: [1,2,3] as allocation site
+obj = fastliteralcase(get_standard_literal(), 1);
+assertKind(elements_kind.fast_smi_only, obj);
+obj = fastliteralcase(get_standard_literal(), 1.5);
+assertKind(elements_kind.fast_double, obj);
+obj = fastliteralcase(get_standard_literal(), 2);
+assertKind(elements_kind.fast_double, obj);
+
+// The test below is in a loop because arrays that live
+// at global scope without the chance of being recreated
+// don't have allocation site information attached.
+for (i = 0; i < 2; i++) {
+ obj = fastliteralcase([5, 3, 2], 1.5);
assertKind(elements_kind.fast_double, obj);
- obj = fastliteralcase(get_standard_literal(), 2);
+ obj = fastliteralcase([3, 6, 2], 1.5);
assertKind(elements_kind.fast_double, obj);
- // The test below is in a loop because arrays that live
- // at global scope without the chance of being recreated
- // don't have allocation site information attached.
- for (i = 0; i < 2; i++) {
- obj = fastliteralcase([5, 3, 2], 1.5);
- assertKind(elements_kind.fast_double, obj);
- obj = fastliteralcase([3, 6, 2], 1.5);
- assertKind(elements_kind.fast_double, obj);
-
- // Note: thanks to pessimistic transition store stubs, we'll attempt
- // to transition to the most general elements kind seen at a particular
- // store site. So, the elements kind will be double.
- obj = fastliteralcase([2, 6, 3], 2);
- assertKind(elements_kind.fast_double, obj);
- }
+ // Note: thanks to pessimistic transition store stubs, we'll attempt
+ // to transition to the most general elements kind seen at a particular
+ // store site. So, the elements kind will be double.
+ obj = fastliteralcase([2, 6, 3], 2);
+ assertKind(elements_kind.fast_double, obj);
+}
- // Verify that we will not pretransition the double->fast path.
- obj = fastliteralcase(get_standard_literal(), "elliot");
- assertKind(elements_kind.fast, obj);
- obj = fastliteralcase(get_standard_literal(), 3);
- assertKind(elements_kind.fast, obj);
+// Verify that we will not pretransition the double->fast path.
+obj = fastliteralcase(get_standard_literal(), "elliot");
+assertKind(elements_kind.fast, obj);
+obj = fastliteralcase(get_standard_literal(), 3);
+assertKind(elements_kind.fast, obj);
- // Make sure this works in crankshafted code too.
+// Make sure this works in crankshafted code too.
%OptimizeFunctionOnNextCall(get_standard_literal);
- get_standard_literal();
- obj = get_standard_literal();
- assertKind(elements_kind.fast, obj);
+get_standard_literal();
+obj = get_standard_literal();
+assertKind(elements_kind.fast, obj);
+
+function fastliteralcase_smifast(value) {
+ var literal = [1, 2, 3, 4];
+ literal[0] = value;
+ return literal;
+}
- function fastliteralcase_smifast(value) {
- var literal = [1, 2, 3, 4];
- literal[0] = value;
- return literal;
- }
+obj = fastliteralcase_smifast(1);
+assertKind(elements_kind.fast_smi_only, obj);
+obj = fastliteralcase_smifast("carter");
+assertKind(elements_kind.fast, obj);
+obj = fastliteralcase_smifast(2);
+assertKind(elements_kind.fast, obj);
+
+// Case: make sure transitions from packed to holey are tracked
+function fastliteralcase_smiholey(index, value) {
+ var literal = [1, 2, 3, 4];
+ literal[index] = value;
+ return literal;
+}
- obj = fastliteralcase_smifast(1);
- assertKind(elements_kind.fast_smi_only, obj);
- obj = fastliteralcase_smifast("carter");
- assertKind(elements_kind.fast, obj);
- obj = fastliteralcase_smifast(2);
- assertKind(elements_kind.fast, obj);
+obj = fastliteralcase_smiholey(5, 1);
+assertKind(elements_kind.fast_smi_only, obj);
+assertHoley(obj);
+obj = fastliteralcase_smiholey(0, 1);
+assertKind(elements_kind.fast_smi_only, obj);
+assertHoley(obj);
+
+function newarraycase_smidouble(value) {
+ var a = new Array();
+ a[0] = value;
+ return a;
+}
- // Case: make sure transitions from packed to holey are tracked
- function fastliteralcase_smiholey(index, value) {
- var literal = [1, 2, 3, 4];
- literal[index] = value;
- return literal;
- }
+// Case: new Array() as allocation site, smi->double
+obj = newarraycase_smidouble(1);
+assertKind(elements_kind.fast_smi_only, obj);
+obj = newarraycase_smidouble(1.5);
+assertKind(elements_kind.fast_double, obj);
+obj = newarraycase_smidouble(2);
+assertKind(elements_kind.fast_double, obj);
+
+function newarraycase_smiobj(value) {
+ var a = new Array();
+ a[0] = value;
+ return a;
+}
- obj = fastliteralcase_smiholey(5, 1);
- assertKind(elements_kind.fast_smi_only, obj);
- assertHoley(obj);
- obj = fastliteralcase_smiholey(0, 1);
- assertKind(elements_kind.fast_smi_only, obj);
- assertHoley(obj);
+// Case: new Array() as allocation site, smi->fast
+obj = newarraycase_smiobj(1);
+assertKind(elements_kind.fast_smi_only, obj);
+obj = newarraycase_smiobj("gloria");
+assertKind(elements_kind.fast, obj);
+obj = newarraycase_smiobj(2);
+assertKind(elements_kind.fast, obj);
+
+function newarraycase_length_smidouble(value) {
+ var a = new Array(3);
+ a[0] = value;
+ return a;
+}
- function newarraycase_smidouble(value) {
- var a = new Array();
- a[0] = value;
- return a;
- }
+// Case: new Array(length) as allocation site
+obj = newarraycase_length_smidouble(1);
+assertKind(elements_kind.fast_smi_only, obj);
+obj = newarraycase_length_smidouble(1.5);
+assertKind(elements_kind.fast_double, obj);
+obj = newarraycase_length_smidouble(2);
+assertKind(elements_kind.fast_double, obj);
+
+// Try to continue the transition to fast object.
+// TODO(mvstanton): re-enable commented out code when
+// FLAG_pretenuring_call_new is turned on in the build.
+obj = newarraycase_length_smidouble("coates");
+assertKind(elements_kind.fast, obj);
+obj = newarraycase_length_smidouble(2);
+// assertKind(elements_kind.fast, obj);
+
+function newarraycase_length_smiobj(value) {
+ var a = new Array(3);
+ a[0] = value;
+ return a;
+}
- // Case: new Array() as allocation site, smi->double
- obj = newarraycase_smidouble(1);
- assertKind(elements_kind.fast_smi_only, obj);
- obj = newarraycase_smidouble(1.5);
- assertKind(elements_kind.fast_double, obj);
- obj = newarraycase_smidouble(2);
- assertKind(elements_kind.fast_double, obj);
+// Case: new Array(<length>) as allocation site, smi->fast
+obj = newarraycase_length_smiobj(1);
+assertKind(elements_kind.fast_smi_only, obj);
+obj = newarraycase_length_smiobj("gloria");
+assertKind(elements_kind.fast, obj);
+obj = newarraycase_length_smiobj(2);
+assertKind(elements_kind.fast, obj);
+
+function newarraycase_list_smidouble(value) {
+ var a = new Array(1, 2, 3);
+ a[0] = value;
+ return a;
+}
+
+obj = newarraycase_list_smidouble(1);
+assertKind(elements_kind.fast_smi_only, obj);
+obj = newarraycase_list_smidouble(1.5);
+assertKind(elements_kind.fast_double, obj);
+obj = newarraycase_list_smidouble(2);
+assertKind(elements_kind.fast_double, obj);
+
+function newarraycase_list_smiobj(value) {
+ var a = new Array(4, 5, 6);
+ a[0] = value;
+ return a;
+}
- function newarraycase_smiobj(value) {
- var a = new Array();
- a[0] = value;
+obj = newarraycase_list_smiobj(1);
+assertKind(elements_kind.fast_smi_only, obj);
+obj = newarraycase_list_smiobj("coates");
+assertKind(elements_kind.fast, obj);
+obj = newarraycase_list_smiobj(2);
+assertKind(elements_kind.fast, obj);
+
+// Case: array constructor calls with out of date feedback.
+// The boilerplate should incorporate all feedback, but the input array
+// should be minimally transitioned based on immediate need.
+(function() {
+ function foo(i) {
+ // We have two cases, one for literals one for constructed arrays.
+ var a = (i == 0)
+ ? [1, 2, 3]
+ : new Array(1, 2, 3);
return a;
}
- // Case: new Array() as allocation site, smi->fast
- obj = newarraycase_smiobj(1);
- assertKind(elements_kind.fast_smi_only, obj);
- obj = newarraycase_smiobj("gloria");
- assertKind(elements_kind.fast, obj);
- obj = newarraycase_smiobj(2);
- assertKind(elements_kind.fast, obj);
-
- function newarraycase_length_smidouble(value) {
- var a = new Array(3);
- a[0] = value;
- return a;
+ for (i = 0; i < 2; i++) {
+ a = foo(i);
+ b = foo(i);
+ b[5] = 1; // boilerplate goes holey
+ assertHoley(foo(i));
+ a[0] = 3.5; // boilerplate goes holey double
+ assertKind(elements_kind.fast_double, a);
+ assertNotHoley(a);
+ c = foo(i);
+ assertKind(elements_kind.fast_double, c);
+ assertHoley(c);
}
+})();
- // Case: new Array(length) as allocation site
- obj = newarraycase_length_smidouble(1);
- assertKind(elements_kind.fast_smi_only, obj);
- obj = newarraycase_length_smidouble(1.5);
- assertKind(elements_kind.fast_double, obj);
- obj = newarraycase_length_smidouble(2);
- assertKind(elements_kind.fast_double, obj);
+function newarraycase_onearg(len, value) {
+ var a = new Array(len);
+ a[0] = value;
+ return a;
+}
- // Try to continue the transition to fast object.
- // TODO(mvstanton): re-enable commented out code when
- // FLAG_pretenuring_call_new is turned on in the build.
- obj = newarraycase_length_smidouble("coates");
- assertKind(elements_kind.fast, obj);
- obj = newarraycase_length_smidouble(2);
- // assertKind(elements_kind.fast, obj);
+obj = newarraycase_onearg(5, 3.5);
+assertKind(elements_kind.fast_double, obj);
+obj = newarraycase_onearg(10, 5);
+assertKind(elements_kind.fast_double, obj);
+obj = newarraycase_onearg(0, 5);
+assertKind(elements_kind.fast_double, obj);
+
+// Verify that cross context calls work
+var realmA = Realm.current();
+var realmB = Realm.create();
+assertEquals(0, realmA);
+assertEquals(1, realmB);
+
+function instanceof_check(type) {
+ assertTrue(new type() instanceof type);
+ assertTrue(new type(5) instanceof type);
+ assertTrue(new type(1,2,3) instanceof type);
+}
- function newarraycase_length_smiobj(value) {
- var a = new Array(3);
- a[0] = value;
- return a;
- }
+function instanceof_check2(type) {
+ assertTrue(new type() instanceof type);
+ assertTrue(new type(5) instanceof type);
+ assertTrue(new type(1,2,3) instanceof type);
+}
- // Case: new Array(<length>) as allocation site, smi->fast
- obj = newarraycase_length_smiobj(1);
- assertKind(elements_kind.fast_smi_only, obj);
- obj = newarraycase_length_smiobj("gloria");
- assertKind(elements_kind.fast, obj);
- obj = newarraycase_length_smiobj(2);
- assertKind(elements_kind.fast, obj);
+var realmBArray = Realm.eval(realmB, "Array");
+instanceof_check(Array);
+instanceof_check(realmBArray);
- function newarraycase_list_smidouble(value) {
- var a = new Array(1, 2, 3);
- a[0] = value;
- return a;
- }
+// instanceof_check2 is here because the call site goes through a state.
+// Since instanceof_check(Array) was first called with the current context
+// Array function, it went from (uninit->Array) then (Array->megamorphic).
+// We'll get a different state traversal if we start with realmBArray.
+// It'll go (uninit->realmBArray) then (realmBArray->megamorphic). Recognize
+// that state "Array" implies an AllocationSite is present, and code is
+// configured to use it.
+instanceof_check2(realmBArray);
+instanceof_check2(Array);
- obj = newarraycase_list_smidouble(1);
- assertKind(elements_kind.fast_smi_only, obj);
- obj = newarraycase_list_smidouble(1.5);
- assertKind(elements_kind.fast_double, obj);
- obj = newarraycase_list_smidouble(2);
- assertKind(elements_kind.fast_double, obj);
+ %OptimizeFunctionOnNextCall(instanceof_check);
- function newarraycase_list_smiobj(value) {
- var a = new Array(4, 5, 6);
- a[0] = value;
- return a;
+// No de-opt will occur because HCallNewArray wasn't selected, on account of
+// the call site not being monomorphic to Array.
+instanceof_check(Array);
+assertOptimized(instanceof_check);
+instanceof_check(realmBArray);
+assertOptimized(instanceof_check);
+
+// Try to optimize again, but first clear all type feedback, and allow it
+// to be monomorphic on first call. Only after crankshafting do we introduce
+// realmBArray. This should deopt the method.
+ %DeoptimizeFunction(instanceof_check);
+ %ClearFunctionTypeFeedback(instanceof_check);
+instanceof_check(Array);
+instanceof_check(Array);
+ %OptimizeFunctionOnNextCall(instanceof_check);
+instanceof_check(Array);
+assertOptimized(instanceof_check);
+
+instanceof_check(realmBArray);
+assertUnoptimized(instanceof_check);
+
+// Case: make sure nested arrays benefit from allocation site feedback as
+// well.
+(function() {
+ // Make sure we handle nested arrays
+ function get_nested_literal() {
+ var literal = [[1,2,3,4], [2], [3]];
+ return literal;
}
- obj = newarraycase_list_smiobj(1);
- assertKind(elements_kind.fast_smi_only, obj);
- obj = newarraycase_list_smiobj("coates");
- assertKind(elements_kind.fast, obj);
- obj = newarraycase_list_smiobj(2);
+ obj = get_nested_literal();
assertKind(elements_kind.fast, obj);
-
- // Case: array constructor calls with out of date feedback.
- // The boilerplate should incorporate all feedback, but the input array
- // should be minimally transitioned based on immediate need.
- (function() {
- function foo(i) {
- // We have two cases, one for literals one for constructed arrays.
- var a = (i == 0)
- ? [1, 2, 3]
- : new Array(1, 2, 3);
- return a;
- }
-
- for (i = 0; i < 2; i++) {
- a = foo(i);
- b = foo(i);
- b[5] = 1; // boilerplate goes holey
- assertHoley(foo(i));
- a[0] = 3.5; // boilerplate goes holey double
- assertKind(elements_kind.fast_double, a);
- assertNotHoley(a);
- c = foo(i);
- assertKind(elements_kind.fast_double, c);
- assertHoley(c);
- }
- })();
-
- function newarraycase_onearg(len, value) {
- var a = new Array(len);
- a[0] = value;
- return a;
+ obj[0][0] = 3.5;
+ obj[2][0] = "hello";
+ obj = get_nested_literal();
+ assertKind(elements_kind.fast_double, obj[0]);
+ assertKind(elements_kind.fast_smi_only, obj[1]);
+ assertKind(elements_kind.fast, obj[2]);
+
+ // A more complex nested literal case.
+ function get_deep_nested_literal() {
+ var literal = [[1], [[2], "hello"], 3, [4]];
+ return literal;
}
- obj = newarraycase_onearg(5, 3.5);
- assertKind(elements_kind.fast_double, obj);
- obj = newarraycase_onearg(10, 5);
- assertKind(elements_kind.fast_double, obj);
- obj = newarraycase_onearg(0, 5);
- assertKind(elements_kind.fast_double, obj);
- // Now pass a length that forces the dictionary path.
- obj = newarraycase_onearg(100000, 5);
- assertKind(elements_kind.dictionary, obj);
- assertTrue(obj.length == 100000);
-
- // Verify that cross context calls work
- var realmA = Realm.current();
- var realmB = Realm.create();
- assertEquals(0, realmA);
- assertEquals(1, realmB);
-
- function instanceof_check(type) {
- assertTrue(new type() instanceof type);
- assertTrue(new type(5) instanceof type);
- assertTrue(new type(1,2,3) instanceof type);
+ obj = get_deep_nested_literal();
+ assertKind(elements_kind.fast_smi_only, obj[1][0]);
+ obj[0][0] = 3.5;
+ obj[1][0][0] = "goodbye";
+ assertKind(elements_kind.fast_double, obj[0]);
+ assertKind(elements_kind.fast, obj[1][0]);
+
+ obj = get_deep_nested_literal();
+ assertKind(elements_kind.fast_double, obj[0]);
+ assertKind(elements_kind.fast, obj[1][0]);
+})();
+
+// Perform a gc because without it the test below can experience an
+// allocation failure at an inconvenient point. Allocation mementos get
+// cleared on gc, and they can't deliver elements kind feedback when that
+// happens.
+gc();
+
+// Make sure object literals with array fields benefit from the type feedback
+// that allocation mementos provide.
+(function() {
+ // A literal in an object
+ function get_object_literal() {
+ var literal = {
+ array: [1,2,3],
+ data: 3.5
+ };
+ return literal;
}
- function instanceof_check2(type) {
- assertTrue(new type() instanceof type);
- assertTrue(new type(5) instanceof type);
- assertTrue(new type(1,2,3) instanceof type);
+ obj = get_object_literal();
+ assertKind(elements_kind.fast_smi_only, obj.array);
+ obj.array[1] = 3.5;
+ assertKind(elements_kind.fast_double, obj.array);
+ obj = get_object_literal();
+ assertKind(elements_kind.fast_double, obj.array);
+
+ function get_nested_object_literal() {
+ var literal = {
+ array: [[1],[2],[3]],
+ data: 3.5
+ };
+ return literal;
}
- var realmBArray = Realm.eval(realmB, "Array");
- instanceof_check(Array);
- instanceof_check(realmBArray);
-
- // instanceof_check2 is here because the call site goes through a state.
- // Since instanceof_check(Array) was first called with the current context
- // Array function, it went from (uninit->Array) then (Array->megamorphic).
- // We'll get a different state traversal if we start with realmBArray.
- // It'll go (uninit->realmBArray) then (realmBArray->megamorphic). Recognize
- // that state "Array" implies an AllocationSite is present, and code is
- // configured to use it.
- instanceof_check2(realmBArray);
- instanceof_check2(Array);
+ obj = get_nested_object_literal();
+ assertKind(elements_kind.fast, obj.array);
+ assertKind(elements_kind.fast_smi_only, obj.array[1]);
+ obj.array[1][0] = 3.5;
+ assertKind(elements_kind.fast_double, obj.array[1]);
+ obj = get_nested_object_literal();
+ assertKind(elements_kind.fast_double, obj.array[1]);
- %OptimizeFunctionOnNextCall(instanceof_check);
+ %OptimizeFunctionOnNextCall(get_nested_object_literal);
+ get_nested_object_literal();
+ obj = get_nested_object_literal();
+ assertKind(elements_kind.fast_double, obj.array[1]);
- // No de-opt will occur because HCallNewArray wasn't selected, on account of
- // the call site not being monomorphic to Array.
- instanceof_check(Array);
- assertOptimized(instanceof_check);
- instanceof_check(realmBArray);
- assertOptimized(instanceof_check);
+ // Make sure we handle nested arrays
+ function get_nested_literal() {
+ var literal = [[1,2,3,4], [2], [3]];
+ return literal;
+ }
- // Try to optimize again, but first clear all type feedback, and allow it
- // to be monomorphic on first call. Only after crankshafting do we introduce
- // realmBArray. This should deopt the method.
- %DeoptimizeFunction(instanceof_check);
- %ClearFunctionTypeFeedback(instanceof_check);
- instanceof_check(Array);
- instanceof_check(Array);
- %OptimizeFunctionOnNextCall(instanceof_check);
- instanceof_check(Array);
- assertOptimized(instanceof_check);
-
- instanceof_check(realmBArray);
- assertUnoptimized(instanceof_check);
-
- // Case: make sure nested arrays benefit from allocation site feedback as
- // well.
- (function() {
- // Make sure we handle nested arrays
- function get_nested_literal() {
- var literal = [[1,2,3,4], [2], [3]];
- return literal;
- }
-
- obj = get_nested_literal();
- assertKind(elements_kind.fast, obj);
- obj[0][0] = 3.5;
- obj[2][0] = "hello";
- obj = get_nested_literal();
- assertKind(elements_kind.fast_double, obj[0]);
- assertKind(elements_kind.fast_smi_only, obj[1]);
- assertKind(elements_kind.fast, obj[2]);
-
- // A more complex nested literal case.
- function get_deep_nested_literal() {
- var literal = [[1], [[2], "hello"], 3, [4]];
- return literal;
- }
-
- obj = get_deep_nested_literal();
- assertKind(elements_kind.fast_smi_only, obj[1][0]);
- obj[0][0] = 3.5;
- obj[1][0][0] = "goodbye";
- assertKind(elements_kind.fast_double, obj[0]);
- assertKind(elements_kind.fast, obj[1][0]);
-
- obj = get_deep_nested_literal();
- assertKind(elements_kind.fast_double, obj[0]);
- assertKind(elements_kind.fast, obj[1][0]);
- })();
-
-
- // Make sure object literals with array fields benefit from the type feedback
- // that allocation mementos provide.
- (function() {
- // A literal in an object
- function get_object_literal() {
- var literal = {
- array: [1,2,3],
- data: 3.5
- };
- return literal;
- }
-
- obj = get_object_literal();
- assertKind(elements_kind.fast_smi_only, obj.array);
- obj.array[1] = 3.5;
- assertKind(elements_kind.fast_double, obj.array);
- obj = get_object_literal();
- assertKind(elements_kind.fast_double, obj.array);
-
- function get_nested_object_literal() {
- var literal = {
- array: [[1],[2],[3]],
- data: 3.5
- };
- return literal;
- }
-
- obj = get_nested_object_literal();
- assertKind(elements_kind.fast, obj.array);
- assertKind(elements_kind.fast_smi_only, obj.array[1]);
- obj.array[1][0] = 3.5;
- assertKind(elements_kind.fast_double, obj.array[1]);
- obj = get_nested_object_literal();
- assertKind(elements_kind.fast_double, obj.array[1]);
+ obj = get_nested_literal();
+ assertKind(elements_kind.fast, obj);
+ obj[0][0] = 3.5;
+ obj[2][0] = "hello";
+ obj = get_nested_literal();
+ assertKind(elements_kind.fast_double, obj[0]);
+ assertKind(elements_kind.fast_smi_only, obj[1]);
+ assertKind(elements_kind.fast, obj[2]);
+
+ // A more complex nested literal case.
+ function get_deep_nested_literal() {
+ var literal = [[1], [[2], "hello"], 3, [4]];
+ return literal;
+ }
- %OptimizeFunctionOnNextCall(get_nested_object_literal);
- get_nested_object_literal();
- obj = get_nested_object_literal();
- assertKind(elements_kind.fast_double, obj.array[1]);
-
- // Make sure we handle nested arrays
- function get_nested_literal() {
- var literal = [[1,2,3,4], [2], [3]];
- return literal;
- }
-
- obj = get_nested_literal();
- assertKind(elements_kind.fast, obj);
- obj[0][0] = 3.5;
- obj[2][0] = "hello";
- obj = get_nested_literal();
- assertKind(elements_kind.fast_double, obj[0]);
- assertKind(elements_kind.fast_smi_only, obj[1]);
- assertKind(elements_kind.fast, obj[2]);
-
- // A more complex nested literal case.
- function get_deep_nested_literal() {
- var literal = [[1], [[2], "hello"], 3, [4]];
- return literal;
- }
-
- obj = get_deep_nested_literal();
- assertKind(elements_kind.fast_smi_only, obj[1][0]);
- obj[0][0] = 3.5;
- obj[1][0][0] = "goodbye";
- assertKind(elements_kind.fast_double, obj[0]);
- assertKind(elements_kind.fast, obj[1][0]);
-
- obj = get_deep_nested_literal();
- assertKind(elements_kind.fast_double, obj[0]);
- assertKind(elements_kind.fast, obj[1][0]);
- })();
-}
+ obj = get_deep_nested_literal();
+ assertKind(elements_kind.fast_smi_only, obj[1][0]);
+ obj[0][0] = 3.5;
+ obj[1][0][0] = "goodbye";
+ assertKind(elements_kind.fast_double, obj[0]);
+ assertKind(elements_kind.fast, obj[1][0]);
+
+ obj = get_deep_nested_literal();
+ assertKind(elements_kind.fast_double, obj[0]);
+ assertKind(elements_kind.fast, obj[1][0]);
+})();
diff --git a/deps/v8/test/mjsunit/apply.js b/deps/v8/test/mjsunit/apply.js
index 413ee937c..abbc9a11b 100644
--- a/deps/v8/test/mjsunit/apply.js
+++ b/deps/v8/test/mjsunit/apply.js
@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
+
function f0() {
return this;
}
@@ -114,7 +116,8 @@ function al() {
for (var j = 1; j < 0x40000000; j <<= 1) {
try {
- var a = new Array(j);
+ var a = %NormalizeElements([]);
+ a.length = j;
a[j - 1] = 42;
assertEquals(42 + j, al.apply(345, a));
} catch (e) {
@@ -122,7 +125,8 @@ for (var j = 1; j < 0x40000000; j <<= 1) {
for (; j < 0x40000000; j <<= 1) {
var caught = false;
try {
- a = new Array(j);
+ a = %NormalizeElements([]);
+ a.length = j;
a[j - 1] = 42;
al.apply(345, a);
assertUnreachable("Apply of array with length " + a.length +
diff --git a/deps/v8/test/mjsunit/array-construct-transition.js b/deps/v8/test/mjsunit/array-construct-transition.js
index f8d7c830e..3847f9405 100644
--- a/deps/v8/test/mjsunit/array-construct-transition.js
+++ b/deps/v8/test/mjsunit/array-construct-transition.js
@@ -25,15 +25,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays
+// Flags: --allow-natives-syntax
-support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6));
-
-if (support_smi_only_arrays) {
- var a = new Array(0, 1, 2);
- assertTrue(%HasFastSmiElements(a));
- var b = new Array(0.5, 1.2, 2.3);
- assertTrue(%HasFastDoubleElements(b));
- var c = new Array(0.5, 1.2, new Object());
- assertTrue(%HasFastObjectElements(c));
-}
+var a = new Array(0, 1, 2);
+assertTrue(%HasFastSmiElements(a));
+var b = new Array(0.5, 1.2, 2.3);
+assertTrue(%HasFastDoubleElements(b));
+var c = new Array(0.5, 1.2, new Object());
+assertTrue(%HasFastObjectElements(c));
diff --git a/deps/v8/test/mjsunit/array-constructor-feedback.js b/deps/v8/test/mjsunit/array-constructor-feedback.js
index 45d5c58c7..c2c1a1842 100644
--- a/deps/v8/test/mjsunit/array-constructor-feedback.js
+++ b/deps/v8/test/mjsunit/array-constructor-feedback.js
@@ -25,24 +25,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+// Flags: --allow-natives-syntax --expose-gc
// Flags: --noalways-opt
// Test element kind of objects.
-// Since --smi-only-arrays affects builtins, its default setting at compile
-// time sticks if built with snapshot. If --smi-only-arrays is deactivated
-// by default, only a no-snapshot build actually has smi-only arrays enabled
-// in this test case. Depending on whether smi-only arrays are actually
-// enabled, this test takes the appropriate code path to check smi-only arrays.
-
-// support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
-support_smi_only_arrays = true;
-
-if (support_smi_only_arrays) {
- print("Tests include smi-only arrays.");
-} else {
- print("Tests do NOT include smi-only arrays.");
-}
var elements_kind = {
fast_smi_only : 'fast smi only elements',
@@ -73,183 +59,161 @@ function isHoley(obj) {
}
function assertKind(expected, obj, name_opt) {
- if (!support_smi_only_arrays &&
- expected == elements_kind.fast_smi_only) {
- expected = elements_kind.fast;
- }
assertEquals(expected, getKind(obj), name_opt);
}
-if (support_smi_only_arrays) {
-
- // Test: If a call site goes megamorphic, it retains the ability to
- // use allocation site feedback (if FLAG_allocation_site_pretenuring
- // is on).
- (function() {
- function bar(t, len) {
- return new t(len);
- }
-
- a = bar(Array, 10);
- a[0] = 3.5;
- b = bar(Array, 1);
- assertKind(elements_kind.fast_double, b);
- c = bar(Object, 3);
- b = bar(Array, 10);
- // TODO(mvstanton): re-enable when FLAG_allocation_site_pretenuring
- // is on in the build.
- // assertKind(elements_kind.fast_double, b);
- })();
-
-
- // Test: ensure that crankshafted array constructor sites are deopted
- // if another function is used.
- (function() {
- function bar0(t) {
- return new t();
- }
- a = bar0(Array);
- a[0] = 3.5;
- b = bar0(Array);
- assertKind(elements_kind.fast_double, b);
+// Test: If a call site goes megamorphic, it retains the ability to
+// use allocation site feedback (if FLAG_allocation_site_pretenuring
+// is on).
+(function() {
+ function bar(t, len) {
+ return new t(len);
+ }
+
+ a = bar(Array, 10);
+ a[0] = 3.5;
+ b = bar(Array, 1);
+ assertKind(elements_kind.fast_double, b);
+ c = bar(Object, 3);
+ b = bar(Array, 10);
+ // TODO(mvstanton): re-enable when FLAG_allocation_site_pretenuring
+ // is on in the build.
+ // assertKind(elements_kind.fast_double, b);
+})();
+
+
+// Test: ensure that crankshafted array constructor sites are deopted
+// if another function is used.
+(function() {
+ function bar0(t) {
+ return new t();
+ }
+ a = bar0(Array);
+ a[0] = 3.5;
+ b = bar0(Array);
+ assertKind(elements_kind.fast_double, b);
%OptimizeFunctionOnNextCall(bar0);
- b = bar0(Array);
- assertKind(elements_kind.fast_double, b);
- assertOptimized(bar0);
- // bar0 should deopt
- b = bar0(Object);
- assertUnoptimized(bar0)
- // When it's re-optimized, we should call through the full stub
- bar0(Array);
+ b = bar0(Array);
+ assertKind(elements_kind.fast_double, b);
+ assertOptimized(bar0);
+ // bar0 should deopt
+ b = bar0(Object);
+ assertUnoptimized(bar0)
+ // When it's re-optimized, we should call through the full stub
+ bar0(Array);
%OptimizeFunctionOnNextCall(bar0);
- b = bar0(Array);
- // This only makes sense to test if we allow crankshafting
- if (4 != %GetOptimizationStatus(bar0)) {
- // We also lost our ability to record kind feedback, as the site
- // is megamorphic now.
- assertKind(elements_kind.fast_smi_only, b);
- assertOptimized(bar0);
- b[0] = 3.5;
- c = bar0(Array);
- assertKind(elements_kind.fast_smi_only, c);
- }
- })();
-
-
- // Test: Ensure that inlined array calls in crankshaft learn from deopts
- // based on the move to a dictionary for the array.
- (function() {
- function bar(len) {
- return new Array(len);
- }
- a = bar(10);
- a[0] = "a string";
- a = bar(10);
- assertKind(elements_kind.fast, a);
- %OptimizeFunctionOnNextCall(bar);
- a = bar(10);
- assertKind(elements_kind.fast, a);
- assertOptimized(bar);
- // bar should deopt because the length is too large.
- a = bar(100000);
- assertUnoptimized(bar);
- assertKind(elements_kind.dictionary, a);
- // The allocation site now has feedback that means the array constructor
- // will not be inlined.
- %OptimizeFunctionOnNextCall(bar);
- a = bar(100000);
- assertKind(elements_kind.dictionary, a);
- assertOptimized(bar);
+ b = bar0(Array);
+ // This only makes sense to test if we allow crankshafting
+ if (4 != %GetOptimizationStatus(bar0)) {
+ // We also lost our ability to record kind feedback, as the site
+ // is megamorphic now.
+ assertKind(elements_kind.fast_smi_only, b);
+ assertOptimized(bar0);
+ b[0] = 3.5;
+ c = bar0(Array);
+ assertKind(elements_kind.fast_smi_only, c);
+ }
+})();
- // If the argument isn't a smi, it bails out as well
- a = bar("oops");
- assertOptimized(bar);
- assertKind(elements_kind.fast, a);
- function barn(one, two, three) {
- return new Array(one, two, three);
- }
+// Test: Ensure that inlined array calls in crankshaft learn from deopts
+// based on the move to a dictionary for the array.
+(function() {
+ function bar(len) {
+ return new Array(len);
+ }
+ a = bar(10);
+ a[0] = "a string";
+ a = bar(10);
+ assertKind(elements_kind.fast, a);
+ %OptimizeFunctionOnNextCall(bar);
+ a = bar(10);
+ assertKind(elements_kind.fast, a);
+ assertOptimized(bar);
+ bar(100000);
+ assertOptimized(bar);
+
+ // If the argument isn't a smi, things should still work.
+ a = bar("oops");
+ assertOptimized(bar);
+ assertKind(elements_kind.fast, a);
+
+ function barn(one, two, three) {
+ return new Array(one, two, three);
+ }
- barn(1, 2, 3);
- barn(1, 2, 3);
- %OptimizeFunctionOnNextCall(barn);
- barn(1, 2, 3);
- assertOptimized(barn);
- a = barn(1, "oops", 3);
- // The method should deopt, but learn from the failure to avoid inlining
- // the array.
- assertKind(elements_kind.fast, a);
- assertUnoptimized(barn);
+ barn(1, 2, 3);
+ barn(1, 2, 3);
%OptimizeFunctionOnNextCall(barn);
- a = barn(1, "oops", 3);
- assertOptimized(barn);
- })();
-
-
- // Test: When a method with array constructor is crankshafted, the type
- // feedback for elements kind is baked in. Verify that transitions don't
- // change it anymore
- (function() {
- function bar() {
- return new Array();
- }
- a = bar();
- bar();
+ barn(1, 2, 3);
+ assertOptimized(barn);
+ a = barn(1, "oops", 3);
+ assertOptimized(barn);
+})();
+
+
+// Test: When a method with array constructor is crankshafted, the type
+// feedback for elements kind is baked in. Verify that transitions don't
+// change it anymore
+(function() {
+ function bar() {
+ return new Array();
+ }
+ a = bar();
+ bar();
%OptimizeFunctionOnNextCall(bar);
- b = bar();
- // This only makes sense to test if we allow crankshafting
- if (4 != %GetOptimizationStatus(bar)) {
- assertOptimized(bar);
+ b = bar();
+ // This only makes sense to test if we allow crankshafting
+ if (4 != %GetOptimizationStatus(bar)) {
+ assertOptimized(bar);
%DebugPrint(3);
- b[0] = 3.5;
- c = bar();
- assertKind(elements_kind.fast_smi_only, c);
- assertOptimized(bar);
- }
- })();
-
-
- // Test: create arrays in two contexts, verifying that the correct
- // map for Array in that context will be used.
- (function() {
- function bar() { return new Array(); }
- bar();
- bar();
+ b[0] = 3.5;
+ c = bar();
+ assertKind(elements_kind.fast_smi_only, c);
+ assertOptimized(bar);
+ }
+})();
+
+
+// Test: create arrays in two contexts, verifying that the correct
+// map for Array in that context will be used.
+(function() {
+ function bar() { return new Array(); }
+ bar();
+ bar();
%OptimizeFunctionOnNextCall(bar);
- a = bar();
- assertTrue(a instanceof Array);
-
- var contextB = Realm.create();
- Realm.eval(contextB, "function bar2() { return new Array(); };");
- Realm.eval(contextB, "bar2(); bar2();");
- Realm.eval(contextB, "%OptimizeFunctionOnNextCall(bar2);");
- Realm.eval(contextB, "bar2();");
- assertFalse(Realm.eval(contextB, "bar2();") instanceof Array);
- assertTrue(Realm.eval(contextB, "bar2() instanceof Array"));
- })();
-
- // Test: create array with packed feedback, then optimize/inline
- // function. Verify that if we ask for a holey array then we deopt.
- // Reoptimization will proceed with the correct feedback and we
- // won't deopt anymore.
- (function() {
- function bar(len) { return new Array(len); }
- bar(0);
- bar(0);
+ a = bar();
+ assertTrue(a instanceof Array);
+
+ var contextB = Realm.create();
+ Realm.eval(contextB, "function bar2() { return new Array(); };");
+ Realm.eval(contextB, "bar2(); bar2();");
+ Realm.eval(contextB, "%OptimizeFunctionOnNextCall(bar2);");
+ Realm.eval(contextB, "bar2();");
+ assertFalse(Realm.eval(contextB, "bar2();") instanceof Array);
+ assertTrue(Realm.eval(contextB, "bar2() instanceof Array"));
+})();
+
+// Test: create array with packed feedback, then optimize function, which
+// should deal with arguments that create holey arrays.
+(function() {
+ function bar(len) { return new Array(len); }
+ bar(0);
+ bar(0);
%OptimizeFunctionOnNextCall(bar);
- a = bar(0);
- assertOptimized(bar);
+ a = bar(0);
+ assertOptimized(bar);
+ assertFalse(isHoley(a));
+ a = bar(1); // ouch!
+ assertOptimized(bar);
+ assertTrue(isHoley(a));
+ a = bar(100);
+ assertTrue(isHoley(a));
+ a = bar(0);
+ assertOptimized(bar);
+ // Crankshafted functions don't use mementos, so feedback still
+ // indicates a packed array is desired. (unless --nocrankshaft is in use).
+ if (4 != %GetOptimizationStatus(bar)) {
assertFalse(isHoley(a));
- a = bar(1); // ouch!
- assertUnoptimized(bar);
- assertTrue(isHoley(a));
- // Try again
- %OptimizeFunctionOnNextCall(bar);
- a = bar(100);
- assertOptimized(bar);
- assertTrue(isHoley(a));
- a = bar(0);
- assertOptimized(bar);
- assertTrue(isHoley(a));
- })();
-}
+ }
+})();
diff --git a/deps/v8/test/mjsunit/array-feedback.js b/deps/v8/test/mjsunit/array-feedback.js
index 4129be1f8..ffbb49b19 100644
--- a/deps/v8/test/mjsunit/array-feedback.js
+++ b/deps/v8/test/mjsunit/array-feedback.js
@@ -25,25 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+// Flags: --allow-natives-syntax --expose-gc
// Flags: --noalways-opt
-// Test element kind of objects.
-// Since --smi-only-arrays affects builtins, its default setting at compile
-// time sticks if built with snapshot. If --smi-only-arrays is deactivated
-// by default, only a no-snapshot build actually has smi-only arrays enabled
-// in this test case. Depending on whether smi-only arrays are actually
-// enabled, this test takes the appropriate code path to check smi-only arrays.
-
-// support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
-support_smi_only_arrays = true;
-
-if (support_smi_only_arrays) {
- print("Tests include smi-only arrays.");
-} else {
- print("Tests do NOT include smi-only arrays.");
-}
-
var elements_kind = {
fast_smi_only : 'fast smi only elements',
fast : 'fast elements',
@@ -73,144 +57,153 @@ function isHoley(obj) {
}
function assertKind(expected, obj, name_opt) {
- if (!support_smi_only_arrays &&
- expected == elements_kind.fast_smi_only) {
- expected = elements_kind.fast;
- }
assertEquals(expected, getKind(obj), name_opt);
}
-if (support_smi_only_arrays) {
-
- // Verify that basic elements kind feedback works for non-constructor
- // array calls (as long as the call is made through an IC, and not
- // a CallStub).
- // (function (){
- // function create0() {
- // return Array();
- // }
-
- // // Calls through ICs need warm up through uninitialized, then
- // // premonomorphic first.
- // create0();
- // create0();
- // a = create0();
- // assertKind(elements_kind.fast_smi_only, a);
- // a[0] = 3.5;
- // b = create0();
- // assertKind(elements_kind.fast_double, b);
-
- // function create1(arg) {
- // return Array(arg);
- // }
-
- // create1(0);
- // create1(0);
- // a = create1(0);
- // assertFalse(isHoley(a));
- // assertKind(elements_kind.fast_smi_only, a);
- // a[0] = "hello";
- // b = create1(10);
- // assertTrue(isHoley(b));
- // assertKind(elements_kind.fast, b);
-
- // a = create1(100000);
- // assertKind(elements_kind.dictionary, a);
-
- // function create3(arg1, arg2, arg3) {
- // return Array(arg1, arg2, arg3);
- // }
-
- // create3();
- // create3();
- // a = create3(1,2,3);
- // a[0] = 3.5;
- // b = create3(1,2,3);
- // assertKind(elements_kind.fast_double, b);
- // assertFalse(isHoley(b));
- // })();
-
-
- // Verify that keyed calls work
- // (function (){
- // function create0(name) {
- // return this[name]();
- // }
-
- // name = "Array";
- // create0(name);
- // create0(name);
- // a = create0(name);
- // a[0] = 3.5;
- // b = create0(name);
- // assertKind(elements_kind.fast_double, b);
- // })();
-
-
- // Verify that the IC can't be spoofed by patching
- (function (){
- function create0() {
- return Array();
- }
-
- create0();
- create0();
- a = create0();
- assertKind(elements_kind.fast_smi_only, a);
- var oldArray = this.Array;
- this.Array = function() { return ["hi"]; };
- b = create0();
- assertEquals(["hi"], b);
- this.Array = oldArray;
- })();
-
- // Verify that calls are still made through an IC after crankshaft,
- // though the type information is reset.
- // TODO(mvstanton): instead, consume the type feedback gathered up
- // until crankshaft time.
- // (function (){
- // function create0() {
- // return Array();
- // }
-
- // create0();
- // create0();
- // a = create0();
- // a[0] = 3.5;
- // %OptimizeFunctionOnNextCall(create0);
- // create0();
- // // This test only makes sense if crankshaft is allowed
- // if (4 != %GetOptimizationStatus(create0)) {
- // create0();
- // b = create0();
- // assertKind(elements_kind.fast_smi_only, b);
- // b[0] = 3.5;
- // c = create0();
- // assertKind(elements_kind.fast_double, c);
- // assertOptimized(create0);
- // }
- // })();
-
-
- // Verify that cross context calls work
- (function (){
- var realmA = Realm.current();
- var realmB = Realm.create();
- assertEquals(0, realmA);
- assertEquals(1, realmB);
-
- function instanceof_check(type) {
- assertTrue(type() instanceof type);
- assertTrue(type(5) instanceof type);
- assertTrue(type(1,2,3) instanceof type);
- }
-
- var realmBArray = Realm.eval(realmB, "Array");
- instanceof_check(Array);
- instanceof_check(Array);
- instanceof_check(Array);
- instanceof_check(realmBArray);
- instanceof_check(realmBArray);
- instanceof_check(realmBArray);
- })();
-}
+// Verify that basic elements kind feedback works for non-constructor
+// array calls (as long as the call is made through an IC, and not
+// a CallStub).
+(function (){
+ function create0() {
+ return Array();
+ }
+
+ // Calls through ICs need warm up through uninitialized, then
+ // premonomorphic first.
+ create0();
+ a = create0();
+ assertKind(elements_kind.fast_smi_only, a);
+ a[0] = 3.5;
+ b = create0();
+ assertKind(elements_kind.fast_double, b);
+
+ function create1(arg) {
+ return Array(arg);
+ }
+
+ create1(0);
+ create1(0);
+ a = create1(0);
+ assertFalse(isHoley(a));
+ assertKind(elements_kind.fast_smi_only, a);
+ a[0] = "hello";
+ b = create1(10);
+ assertTrue(isHoley(b));
+ assertKind(elements_kind.fast, b);
+
+ a = create1(100000);
+ assertKind(elements_kind.fast_smi_only, a);
+
+ function create3(arg1, arg2, arg3) {
+ return Array(arg1, arg2, arg3);
+ }
+
+ create3(1,2,3);
+ create3(1,2,3);
+ a = create3(1,2,3);
+ a[0] = 3.035;
+ assertKind(elements_kind.fast_double, a);
+ b = create3(1,2,3);
+ assertKind(elements_kind.fast_double, b);
+ assertFalse(isHoley(b));
+})();
+
+
+// Verify that keyed calls work
+(function (){
+ function create0(name) {
+ return this[name]();
+ }
+
+ name = "Array";
+ create0(name);
+ create0(name);
+ a = create0(name);
+ a[0] = 3.5;
+ b = create0(name);
+ assertKind(elements_kind.fast_double, b);
+})();
+
+
+// Verify that feedback is turned off if the call site goes megamorphic.
+(function (){
+ function foo(arg) { return arg(); }
+ foo(Array);
+ foo(function() {});
+ foo(Array);
+
+ gc();
+
+ a = foo(Array);
+ a[0] = 3.5;
+ b = foo(Array);
+ // b doesn't benefit from elements kind feedback at a megamorphic site.
+ assertKind(elements_kind.fast_smi_only, b);
+})();
+
+
+// Verify that crankshaft consumes type feedback.
+(function (){
+ function create0() {
+ return Array();
+ }
+
+ create0();
+ create0();
+ a = create0();
+ a[0] = 3.5;
+ %OptimizeFunctionOnNextCall(create0);
+ create0();
+ create0();
+ b = create0();
+ assertKind(elements_kind.fast_double, b);
+ assertOptimized(create0);
+
+ function create1(arg) {
+ return Array(arg);
+ }
+
+ create1(8);
+ create1(8);
+ a = create1(8);
+ a[0] = 3.5;
+ %OptimizeFunctionOnNextCall(create1);
+ b = create1(8);
+ assertKind(elements_kind.fast_double, b);
+ assertOptimized(create1);
+
+ function createN(arg1, arg2, arg3) {
+ return Array(arg1, arg2, arg3);
+ }
+
+ createN(1, 2, 3);
+ createN(1, 2, 3);
+ a = createN(1, 2, 3);
+ a[0] = 3.5;
+ %OptimizeFunctionOnNextCall(createN);
+ b = createN(1, 2, 3);
+ assertKind(elements_kind.fast_double, b);
+ assertOptimized(createN);
+})();
+
+// Verify that cross context calls work
+(function (){
+ var realmA = Realm.current();
+ var realmB = Realm.create();
+ assertEquals(0, realmA);
+ assertEquals(1, realmB);
+
+ function instanceof_check(type) {
+ assertTrue(type() instanceof type);
+ assertTrue(type(5) instanceof type);
+ assertTrue(type(1,2,3) instanceof type);
+ }
+
+ var realmBArray = Realm.eval(realmB, "Array");
+ instanceof_check(Array);
+ instanceof_check(Array);
+ instanceof_check(Array);
+ instanceof_check(realmBArray);
+ instanceof_check(realmBArray);
+ instanceof_check(realmBArray);
+})();
diff --git a/deps/v8/test/mjsunit/array-literal-feedback.js b/deps/v8/test/mjsunit/array-literal-feedback.js
index cfda0f6d5..ed9c4e879 100644
--- a/deps/v8/test/mjsunit/array-literal-feedback.js
+++ b/deps/v8/test/mjsunit/array-literal-feedback.js
@@ -25,25 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+// Flags: --allow-natives-syntax --expose-gc
// Flags: --noalways-opt
-// Test element kind of objects.
-// Since --smi-only-arrays affects builtins, its default setting at compile
-// time sticks if built with snapshot. If --smi-only-arrays is deactivated
-// by default, only a no-snapshot build actually has smi-only arrays enabled
-// in this test case. Depending on whether smi-only arrays are actually
-// enabled, this test takes the appropriate code path to check smi-only arrays.
-
-// support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
-support_smi_only_arrays = true;
-
-if (support_smi_only_arrays) {
- print("Tests include smi-only arrays.");
-} else {
- print("Tests do NOT include smi-only arrays.");
-}
-
var elements_kind = {
fast_smi_only : 'fast smi only elements',
fast : 'fast elements',
@@ -73,58 +57,51 @@ function isHoley(obj) {
}
function assertKind(expected, obj, name_opt) {
- if (!support_smi_only_arrays &&
- expected == elements_kind.fast_smi_only) {
- expected = elements_kind.fast;
- }
assertEquals(expected, getKind(obj), name_opt);
}
-if (support_smi_only_arrays) {
-
- function get_literal(x) {
- var literal = [1, 2, x];
- return literal;
- }
+function get_literal(x) {
+ var literal = [1, 2, x];
+ return literal;
+}
- get_literal(3);
- // It's important to store a from before we crankshaft get_literal, because
- // mementos won't be created from crankshafted code at all.
- a = get_literal(3);
+get_literal(3);
+// It's important to store a from before we crankshaft get_literal, because
+// mementos won't be created from crankshafted code at all.
+a = get_literal(3);
%OptimizeFunctionOnNextCall(get_literal);
- get_literal(3);
- assertOptimized(get_literal);
- assertTrue(%HasFastSmiElements(a));
- // a has a memento so the transition caused by the store will affect the
- // boilerplate.
- a[0] = 3.5;
-
- // We should have transitioned the boilerplate array to double, and
- // crankshafted code should de-opt on the unexpected elements kind
- b = get_literal(3);
- assertTrue(%HasFastDoubleElements(b));
- assertEquals([1, 2, 3], b);
- assertUnoptimized(get_literal);
-
- // Optimize again
- get_literal(3);
+get_literal(3);
+assertOptimized(get_literal);
+assertTrue(%HasFastSmiElements(a));
+// a has a memento so the transition caused by the store will affect the
+// boilerplate.
+a[0] = 3.5;
+
+// We should have transitioned the boilerplate array to double, and
+// crankshafted code should de-opt on the unexpected elements kind
+b = get_literal(3);
+assertTrue(%HasFastDoubleElements(b));
+assertEquals([1, 2, 3], b);
+assertUnoptimized(get_literal);
+
+// Optimize again
+get_literal(3);
%OptimizeFunctionOnNextCall(get_literal);
- b = get_literal(3);
- assertTrue(%HasFastDoubleElements(b));
- assertOptimized(get_literal);
+b = get_literal(3);
+assertTrue(%HasFastDoubleElements(b));
+assertOptimized(get_literal);
- // Test: make sure allocation site information is updated through a
- // transition from SMI->DOUBLE->FAST
- (function() {
- function bar(a, b, c) {
- return [a, b, c];
- }
+// Test: make sure allocation site information is updated through a
+// transition from SMI->DOUBLE->FAST
+(function() {
+ function bar(a, b, c) {
+ return [a, b, c];
+ }
- a = bar(1, 2, 3);
- a[0] = 3.5;
- a[1] = 'hi';
- b = bar(1, 2, 3);
- assertKind(elements_kind.fast, b);
- })();
-}
+ a = bar(1, 2, 3);
+ a[0] = 3.5;
+ a[1] = 'hi';
+ b = bar(1, 2, 3);
+ assertKind(elements_kind.fast, b);
+})();
diff --git a/deps/v8/test/mjsunit/array-literal-transitions.js b/deps/v8/test/mjsunit/array-literal-transitions.js
index ca6033b21..e1624553f 100644
--- a/deps/v8/test/mjsunit/array-literal-transitions.js
+++ b/deps/v8/test/mjsunit/array-literal-transitions.js
@@ -25,22 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
-
-// Test element kind of objects.
-// Since --smi-only-arrays affects builtins, its default setting at compile
-// time sticks if built with snapshot. If --smi-only-arrays is deactivated
-// by default, only a no-snapshot build actually has smi-only arrays enabled
-// in this test case. Depending on whether smi-only arrays are actually
-// enabled, this test takes the appropriate code path to check smi-only arrays.
-
-support_smi_only_arrays = %HasFastSmiElements([1,2,3,4,5,6,7,8,9,10]);
-
-if (support_smi_only_arrays) {
- print("Tests include smi-only arrays.");
-} else {
- print("Tests do NOT include smi-only arrays.");
-}
+// Flags: --allow-natives-syntax --expose-gc
// IC and Crankshaft support for smi-only elements in dynamic array literals.
function get(foo) { return foo; } // Used to generate dynamic values.
@@ -94,114 +79,112 @@ function array_literal_test() {
assertEquals(1, f0[0]);
}
-if (support_smi_only_arrays) {
- for (var i = 0; i < 3; i++) {
- array_literal_test();
- }
- %OptimizeFunctionOnNextCall(array_literal_test);
+for (var i = 0; i < 3; i++) {
array_literal_test();
+}
+ %OptimizeFunctionOnNextCall(array_literal_test);
+array_literal_test();
+
+function test_large_literal() {
- function test_large_literal() {
-
- function d() {
- gc();
- return 2.5;
- }
-
- function o() {
- gc();
- return new Object();
- }
-
- large =
- [ 0, 1, 2, 3, 4, 5, d(), d(), d(), d(), d(), d(), o(), o(), o(), o() ];
- assertFalse(%HasDictionaryElements(large));
- assertFalse(%HasFastSmiElements(large));
- assertFalse(%HasFastDoubleElements(large));
- assertTrue(%HasFastObjectElements(large));
- assertEquals(large,
- [0, 1, 2, 3, 4, 5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5,
- new Object(), new Object(), new Object(), new Object()]);
+ function d() {
+ gc();
+ return 2.5;
}
- for (var i = 0; i < 3; i++) {
- test_large_literal();
+ function o() {
+ gc();
+ return new Object();
}
- %OptimizeFunctionOnNextCall(test_large_literal);
+
+ large =
+ [ 0, 1, 2, 3, 4, 5, d(), d(), d(), d(), d(), d(), o(), o(), o(), o() ];
+ assertFalse(%HasDictionaryElements(large));
+ assertFalse(%HasFastSmiElements(large));
+ assertFalse(%HasFastDoubleElements(large));
+ assertTrue(%HasFastObjectElements(large));
+ assertEquals(large,
+ [0, 1, 2, 3, 4, 5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5,
+ new Object(), new Object(), new Object(), new Object()]);
+}
+
+for (var i = 0; i < 3; i++) {
test_large_literal();
+}
+ %OptimizeFunctionOnNextCall(test_large_literal);
+test_large_literal();
- function deopt_array(use_literal) {
- if (use_literal) {
- return [.5, 3, 4];
- } else {
- return new Array();
- }
+function deopt_array(use_literal) {
+ if (use_literal) {
+ return [.5, 3, 4];
+ } else {
+ return new Array();
}
+}
- deopt_array(false);
- deopt_array(false);
- deopt_array(false);
+deopt_array(false);
+deopt_array(false);
+deopt_array(false);
%OptimizeFunctionOnNextCall(deopt_array);
- var array = deopt_array(false);
- assertOptimized(deopt_array);
- deopt_array(true);
- assertOptimized(deopt_array);
- array = deopt_array(false);
- assertOptimized(deopt_array);
-
- // Check that unexpected changes in the objects stored into the boilerplate
- // also force a deopt.
- function deopt_array_literal_all_smis(a) {
- return [0, 1, a];
- }
+var array = deopt_array(false);
+assertOptimized(deopt_array);
+deopt_array(true);
+assertOptimized(deopt_array);
+array = deopt_array(false);
+assertOptimized(deopt_array);
+
+// Check that unexpected changes in the objects stored into the boilerplate
+// also force a deopt.
+function deopt_array_literal_all_smis(a) {
+ return [0, 1, a];
+}
- deopt_array_literal_all_smis(2);
- deopt_array_literal_all_smis(3);
- deopt_array_literal_all_smis(4);
- array = deopt_array_literal_all_smis(4);
- assertEquals(0, array[0]);
- assertEquals(1, array[1]);
- assertEquals(4, array[2]);
+deopt_array_literal_all_smis(2);
+deopt_array_literal_all_smis(3);
+deopt_array_literal_all_smis(4);
+array = deopt_array_literal_all_smis(4);
+assertEquals(0, array[0]);
+assertEquals(1, array[1]);
+assertEquals(4, array[2]);
%OptimizeFunctionOnNextCall(deopt_array_literal_all_smis);
- array = deopt_array_literal_all_smis(5);
- array = deopt_array_literal_all_smis(6);
- assertOptimized(deopt_array_literal_all_smis);
- assertEquals(0, array[0]);
- assertEquals(1, array[1]);
- assertEquals(6, array[2]);
-
- array = deopt_array_literal_all_smis(.5);
- assertUnoptimized(deopt_array_literal_all_smis);
- assertEquals(0, array[0]);
- assertEquals(1, array[1]);
- assertEquals(.5, array[2]);
-
- function deopt_array_literal_all_doubles(a) {
- return [0.5, 1, a];
- }
+array = deopt_array_literal_all_smis(5);
+array = deopt_array_literal_all_smis(6);
+assertOptimized(deopt_array_literal_all_smis);
+assertEquals(0, array[0]);
+assertEquals(1, array[1]);
+assertEquals(6, array[2]);
+
+array = deopt_array_literal_all_smis(.5);
+assertUnoptimized(deopt_array_literal_all_smis);
+assertEquals(0, array[0]);
+assertEquals(1, array[1]);
+assertEquals(.5, array[2]);
+
+function deopt_array_literal_all_doubles(a) {
+ return [0.5, 1, a];
+}
- deopt_array_literal_all_doubles(.5);
- deopt_array_literal_all_doubles(.5);
- deopt_array_literal_all_doubles(.5);
- array = deopt_array_literal_all_doubles(0.5);
- assertEquals(0.5, array[0]);
- assertEquals(1, array[1]);
- assertEquals(0.5, array[2]);
+deopt_array_literal_all_doubles(.5);
+deopt_array_literal_all_doubles(.5);
+deopt_array_literal_all_doubles(.5);
+array = deopt_array_literal_all_doubles(0.5);
+assertEquals(0.5, array[0]);
+assertEquals(1, array[1]);
+assertEquals(0.5, array[2]);
%OptimizeFunctionOnNextCall(deopt_array_literal_all_doubles);
- array = deopt_array_literal_all_doubles(5);
- array = deopt_array_literal_all_doubles(6);
- assertOptimized(deopt_array_literal_all_doubles);
- assertEquals(0.5, array[0]);
- assertEquals(1, array[1]);
- assertEquals(6, array[2]);
-
- var foo = new Object();
- array = deopt_array_literal_all_doubles(foo);
- assertUnoptimized(deopt_array_literal_all_doubles);
- assertEquals(0.5, array[0]);
- assertEquals(1, array[1]);
- assertEquals(foo, array[2]);
-}
+array = deopt_array_literal_all_doubles(5);
+array = deopt_array_literal_all_doubles(6);
+assertOptimized(deopt_array_literal_all_doubles);
+assertEquals(0.5, array[0]);
+assertEquals(1, array[1]);
+assertEquals(6, array[2]);
+
+var foo = new Object();
+array = deopt_array_literal_all_doubles(foo);
+assertUnoptimized(deopt_array_literal_all_doubles);
+assertEquals(0.5, array[0]);
+assertEquals(1, array[1]);
+assertEquals(foo, array[2]);
(function literals_after_osr() {
var color = [0];
diff --git a/deps/v8/test/mjsunit/array-natives-elements.js b/deps/v8/test/mjsunit/array-natives-elements.js
index cf848bb4b..d63346d0a 100644
--- a/deps/v8/test/mjsunit/array-natives-elements.js
+++ b/deps/v8/test/mjsunit/array-natives-elements.js
@@ -25,22 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays
-
-// Test element kind of objects.
-// Since --smi-only-arrays affects builtins, its default setting at compile time
-// sticks if built with snapshot. If --smi-only-arrays is deactivated by
-// default, only a no-snapshot build actually has smi-only arrays enabled in
-// this test case. Depending on whether smi-only arrays are actually enabled,
-// this test takes the appropriate code path to check smi-only arrays.
-
-support_smi_only_arrays = %HasFastSmiElements([1,2,3,4,5,6,7,8,9,10]);
-
-if (support_smi_only_arrays) {
- print("Tests include smi-only arrays.");
-} else {
- print("Tests do NOT include smi-only arrays.");
-}
+// Flags: --allow-natives-syntax
// IC and Crankshaft support for smi-only elements in dynamic array literals.
function get(foo) { return foo; } // Used to generate dynamic values.
@@ -54,29 +39,30 @@ function array_natives_test() {
assertTrue(%HasFastDoubleElements([1.1]));
assertTrue(%HasFastDoubleElements([1.1,2]));
- // Push
- var a0 = [1, 2, 3];
- if (%HasFastSmiElements(a0)) {
- assertTrue(%HasFastSmiElements(a0));
- a0.push(4);
- assertTrue(%HasFastSmiElements(a0));
- a0.push(1.3);
- assertTrue(%HasFastDoubleElements(a0));
- a0.push(1.5);
- assertTrue(%HasFastDoubleElements(a0));
- a0.push({});
- assertTrue(%HasFastObjectElements(a0));
- a0.push({});
- assertTrue(%HasFastObjectElements(a0));
- } else {
- assertTrue(%HasFastObjectElements(a0));
- a0.push(4);
- a0.push(1.3);
- a0.push(1.5);
- a0.push({});
- a0.push({});
- assertTrue(%HasFastObjectElements(a0));
+ // This code exists to eliminate the learning influence of AllocationSites
+ // on the following tests.
+ var __sequence = 0;
+ function make_array_string(literal) {
+ this.__sequence = this.__sequence + 1;
+ return "/* " + this.__sequence + " */ " + literal;
}
+ function make_array(literal) {
+ return eval(make_array_string(literal));
+ }
+
+ // Push
+ var a0 = make_array("[1, 2, 3]");
+ assertTrue(%HasFastSmiElements(a0));
+ a0.push(4);
+ assertTrue(%HasFastSmiElements(a0));
+ a0.push(1.3);
+ assertTrue(%HasFastDoubleElements(a0));
+ a0.push(1.5);
+ assertTrue(%HasFastDoubleElements(a0));
+ a0.push({});
+ assertTrue(%HasFastObjectElements(a0));
+ a0.push({});
+ assertTrue(%HasFastObjectElements(a0));
assertEquals([1,2,3,4,1.3,1.5,{},{}], a0);
// Concat
@@ -307,10 +293,8 @@ function array_natives_test() {
assertEquals([1.1,{},2,3], a4);
}
-if (support_smi_only_arrays) {
- for (var i = 0; i < 3; i++) {
- array_natives_test();
- }
- %OptimizeFunctionOnNextCall(array_natives_test);
+for (var i = 0; i < 3; i++) {
array_natives_test();
}
+%OptimizeFunctionOnNextCall(array_natives_test);
+array_natives_test();
diff --git a/deps/v8/test/mjsunit/array-push-unshift-read-only-length.js b/deps/v8/test/mjsunit/array-push-unshift-read-only-length.js
new file mode 100644
index 000000000..67aa39787
--- /dev/null
+++ b/deps/v8/test/mjsunit/array-push-unshift-read-only-length.js
@@ -0,0 +1,107 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function test(mode) {
+ var a = [];
+ Object.defineProperty(a, "length", { writable : false});
+
+ function check(f) {
+ try {
+ f(a);
+ } catch(e) { }
+ assertFalse(0 in a);
+ assertEquals(0, a.length);
+ }
+
+ function push(a) {
+ a.push(3);
+ }
+
+ if (mode == "fast properties") %ToFastProperties(a);
+
+ check(push);
+ check(push);
+ check(push);
+ %OptimizeFunctionOnNextCall(push);
+ check(push);
+
+ function unshift(a) {
+ a.unshift(3);
+ }
+
+ check(unshift);
+ check(unshift);
+ check(unshift);
+ %OptimizeFunctionOnNextCall(unshift);
+ check(unshift);
+}
+
+test("fast properties");
+
+test("normalized");
+
+var b = [];
+Object.defineProperty(b.__proto__, "0", {
+ set : function(v) {
+ b.x = v;
+ Object.defineProperty(b, "length", { writable : false });
+ },
+ get: function() {
+ return b.x;
+ }
+});
+
+b = [];
+try {
+ b.push(3, 4, 5);
+} catch(e) { }
+assertFalse(1 in b);
+assertFalse(2 in b);
+assertEquals(0, b.length);
+
+b = [];
+try {
+ b.unshift(3, 4, 5);
+} catch(e) { }
+assertFalse(1 in b);
+assertFalse(2 in b);
+assertEquals(0, b.length);
+
+b = [1, 2];
+try {
+ b.unshift(3, 4, 5);
+} catch(e) { }
+assertEquals(3, b[0]);
+assertEquals(4, b[1]);
+assertEquals(5, b[2]);
+assertEquals(1, b[3]);
+assertEquals(2, b[4]);
+assertEquals(5, b.length);
+
+b = [1, 2];
+
+Object.defineProperty(b.__proto__, "4", {
+ set : function(v) {
+ b.z = v;
+ Object.defineProperty(b, "length", { writable : false });
+ },
+ get: function() {
+ return b.z;
+ }
+});
+
+try {
+ b.unshift(3, 4, 5);
+} catch(e) { }
+
+// TODO(ulan): According to the ECMA-262 unshift should throw an exception
+// when moving b[0] to b[3] (see 15.4.4.13 step 6.d.ii). This is difficult
+// to do with our current implementation of SmartMove() in src/array.js and
+// it will regress performance. Uncomment the following line once acceptable
+// solution is found:
+// assertFalse(2 in b);
+// assertFalse(3 in b);
+// assertEquals(2, b.length);
diff --git a/deps/v8/test/mjsunit/array-shift2.js b/deps/v8/test/mjsunit/array-shift2.js
new file mode 100644
index 000000000..73d8cd4ff
--- /dev/null
+++ b/deps/v8/test/mjsunit/array-shift2.js
@@ -0,0 +1,18 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+Object.defineProperty(Array.prototype, "1", {
+ get: function() { return "element 1"; },
+ set: function(value) { }
+});
+function test(array) {
+ array.shift();
+ return array;
+}
+assertEquals(["element 1",2], test(["0",,2]));
+assertEquals(["element 1",{}], test([{},,{}]));
+%OptimizeFunctionOnNextCall(test);
+assertEquals(["element 1",0], test([{},,0]));
diff --git a/deps/v8/test/mjsunit/array-shift3.js b/deps/v8/test/mjsunit/array-shift3.js
new file mode 100644
index 000000000..3a0afc596
--- /dev/null
+++ b/deps/v8/test/mjsunit/array-shift3.js
@@ -0,0 +1,15 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+Array.prototype[1] = "element 1";
+function test(a) {
+ a.shift();
+ return a;
+}
+assertEquals(["element 1",{}], test([0,,{}]));
+assertEquals(["element 1",10], test([9,,10]));
+%OptimizeFunctionOnNextCall(test);
+assertEquals(["element 1",10], test([9,,10]));
diff --git a/deps/v8/test/mjsunit/assert-opt-and-deopt.js b/deps/v8/test/mjsunit/assert-opt-and-deopt.js
index d0caafa27..e9aba1d3c 100644
--- a/deps/v8/test/mjsunit/assert-opt-and-deopt.js
+++ b/deps/v8/test/mjsunit/assert-opt-and-deopt.js
@@ -137,7 +137,7 @@ OptTracker.prototype.DisableAsserts_ = function(func) {
case OptTracker.OptimizationState.NEVER:
return true;
}
- return false;
+ return true;
}
// (End of class OptTracker.)
diff --git a/deps/v8/test/mjsunit/binary-op-newspace.js b/deps/v8/test/mjsunit/binary-op-newspace.js
index dac7d24db..52903f051 100644
--- a/deps/v8/test/mjsunit/binary-op-newspace.js
+++ b/deps/v8/test/mjsunit/binary-op-newspace.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --max-new-space-size=2 --noopt
+// Flags: --max-semi-space-size=1 --noopt
// Check that a mod where the stub code hits a failure in heap number
// allocation still works.
diff --git a/deps/v8/test/mjsunit/bounds-checks-elimination.js b/deps/v8/test/mjsunit/bounds-checks-elimination.js
new file mode 100644
index 000000000..4ea7f17e5
--- /dev/null
+++ b/deps/v8/test/mjsunit/bounds-checks-elimination.js
@@ -0,0 +1,123 @@
+// 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.
+
+// Flags: --allow-natives-syntax --array-bounds-checks-elimination
+
+var a = []
+for (var i = 0; i < 9; i++) a[i] = i + 1;
+
+function test(f, arg1, arg2, expected) {
+ assertEquals(expected, f(arg1));
+ f(arg2);
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(expected, f(arg1));
+}
+
+test(function f0() {
+ return a[7] * a[6] * a[5] * a[4] * a[3] * a[2] * a[1] * a[0];
+}, 0, 1, 40320);
+
+test(function f1() {
+ return a[7] * a[6] * a[5] * a[4] * a[10] * a[2] * a[1] * a[0];
+}, 0, 1, NaN);
+
+test(function f2() {
+ return a[0] * a[1] * a[2] * a[3] * a[4] * a[5] * a[6] * a[7];
+}, 0, 1, 40320);
+
+test(function f3() {
+ return a[3] * a[0] * a[6] * a[7] * a[5] * a[1] * a[4] * a[2];
+}, 0, 1, 40320);
+
+test(function f4(b) {
+ return a[b+3] * a[0] * a[b+6] * a[7] * a[b+5] * a[1] * a[b+4] * a[2];
+}, 0, 1, 40320);
+
+test(function f5(b) {
+ return a[b+1] * a[0] * a[b+4] * a[7] * a[b+3] * a[1] * a[b+2] * a[2];
+}, 2, 3, 40320);
+
+test(function f6(b) {
+ var c;
+ if (b) c = a[3] * a[0] * a[6] * a[7];
+ return c * a[5] * a[1] * a[4] * a[2];
+}, true, false, 40320);
+
+test(function f7(b) {
+ var c = a[7];
+ if (b) c *= a[3] * a[0] * a[6];
+ return c * a[5] * a[1] * a[4] * a[2];
+}, true, false, 40320);
+
+test(function f8(b) {
+ var c = a[7];
+ if (b) c *= a[3] * a[0] * a[6];
+ return c * a[5] * a[10] * a[4] * a[2];
+}, true, false, NaN);
+
+test(function f9(b) {
+ var c = a[1];
+ if (b) {
+ c *= a[3] * a[0] * a[6];
+ } else {
+ c = a[6] * a[5] * a[4];
+ }
+ return c * a[5] * a[7] * a[4] * a[2];
+}, true, false, 40320);
+
+test(function fa(b) {
+ var c = a[1];
+ if (b) {
+ c = a[6] * a[b+5] * a[4];
+ } else {
+ c *= a[b+3] * a[0] * a[b+6];
+ }
+ return c * a[5] * a[b+7] * a[4] * a[2];
+}, 0, 1, 40320);
+
+test(function fb(b) {
+ var c = a[b-3];
+ if (b != 4) {
+ c = a[6] * a[b+1] * a[4];
+ } else {
+ c *= a[b-1] * a[0] * a[b+2];
+ }
+ return c * a[5] * a[b+3] * a[4] * a[b-2];
+}, 4, 3, 40320);
+
+test(function fc(b) {
+ var c = a[b-3];
+ if (b != 4) {
+ c = a[6] * a[b+1] * a[4];
+ } else {
+ c *= a[b-1] * a[0] * a[b+2];
+ }
+ return c * a[5] * a[b+3] * a[4] * a[b-2];
+}, 6, 3, NaN);
+
+test(function fd(b) {
+ var c = a[b-3];
+ if (b != 4) {
+ c = a[6] * a[b+1] * a[4];
+ } else {
+ c *= a[b-1] * a[0] * a[b+2];
+ }
+ return c * a[5] * a[b+3] * a[4] * a[b-2];
+}, 1, 4, NaN);
+
+test(function fe(b) {
+ var c = 1;
+ for (var i = 1; i < b-1; i++) {
+ c *= a[i-1] * a[i] * a[i+1];
+ }
+ return c;
+}, 8, 4, (40320 / 8 / 7) * (40320 / 8) * (40320 / 2));
+
+test(function ff(b) {
+ var c = 0;
+ for (var i = 0; i < b; i++) {
+ c += a[3] * a[0] * a[6] * a[7] * a[5] * a[1] * a[4] * a[2];
+ }
+ return c;
+}, 100, 4, 40320 * 100);
diff --git a/deps/v8/test/mjsunit/builtins.js b/deps/v8/test/mjsunit/builtins.js
index ce2c6802f..fe7d35d8e 100644
--- a/deps/v8/test/mjsunit/builtins.js
+++ b/deps/v8/test/mjsunit/builtins.js
@@ -38,6 +38,14 @@ function isFunction(obj) {
return typeof obj == "function";
}
+function isV8Native(name) {
+ return name == "GeneratorFunctionPrototype" ||
+ name == "SetIterator" ||
+ name == "MapIterator" ||
+ name == "ArrayIterator" ||
+ name == "StringIterator";
+}
+
function checkConstructor(func, name) {
// A constructor is a function with a prototype and properties on the
// prototype object besides "constructor";
@@ -54,12 +62,13 @@ function checkConstructor(func, name) {
assertFalse(proto_desc.writable, name);
assertFalse(proto_desc.configurable, name);
var prototype = proto_desc.value;
- assertEquals(name == "GeneratorFunctionPrototype" ? Object.prototype : null,
+ assertEquals(isV8Native(name) ? Object.prototype : null,
Object.getPrototypeOf(prototype),
name);
for (var i = 0; i < propNames.length; i++) {
var propName = propNames[i];
if (propName == "constructor") continue;
+ if (isV8Native(name)) continue;
var testName = name + "-" + propName;
var propDesc = Object.getOwnPropertyDescriptor(prototype, propName);
assertTrue(propDesc.hasOwnProperty("value"), testName);
diff --git a/deps/v8/test/mjsunit/compiler/inline-arguments.js b/deps/v8/test/mjsunit/compiler/inline-arguments.js
index 1337ab237..d52f31b5e 100644
--- a/deps/v8/test/mjsunit/compiler/inline-arguments.js
+++ b/deps/v8/test/mjsunit/compiler/inline-arguments.js
@@ -309,3 +309,29 @@ test_toarr(toarr2);
delete forceDeopt.deopt;
outer();
})();
+
+
+// Test inlining of functions with %_Arguments and %_ArgumentsLength intrinsic.
+(function () {
+ function inner(len,a,b,c) {
+ assertSame(len, %_ArgumentsLength());
+ for (var i = 1; i < len; ++i) {
+ var c = String.fromCharCode(96 + i);
+ assertSame(c, %_Arguments(i));
+ }
+ }
+
+ function outer() {
+ inner(1);
+ inner(2, 'a');
+ inner(3, 'a', 'b');
+ inner(4, 'a', 'b', 'c');
+ inner(5, 'a', 'b', 'c', 'd');
+ inner(6, 'a', 'b', 'c', 'd', 'e');
+ }
+
+ outer();
+ outer();
+ %OptimizeFunctionOnNextCall(outer);
+ outer();
+})();
diff --git a/deps/v8/test/mjsunit/compiler/math-floor-global.js b/deps/v8/test/mjsunit/compiler/math-floor-global.js
index 4a3bcb722..9ee649cb2 100644
--- a/deps/v8/test/mjsunit/compiler/math-floor-global.js
+++ b/deps/v8/test/mjsunit/compiler/math-floor-global.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --max-new-space-size=2 --allow-natives-syntax
+// Flags: --max-semi-space-size=1 --allow-natives-syntax
// Test inlining of Math.floor when assigned to a global.
var flo = Math.floor;
diff --git a/deps/v8/test/mjsunit/compiler/math-floor-local.js b/deps/v8/test/mjsunit/compiler/math-floor-local.js
index 8424ac96d..5ebe90b70 100644
--- a/deps/v8/test/mjsunit/compiler/math-floor-local.js
+++ b/deps/v8/test/mjsunit/compiler/math-floor-local.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --max-new-space-size=2 --allow-natives-syntax
+// Flags: --max-semi-space-size=1 --allow-natives-syntax
// Test inlining of Math.floor when assigned to a local.
var test_id = 0;
diff --git a/deps/v8/test/mjsunit/const-eval-init.js b/deps/v8/test/mjsunit/const-eval-init.js
index d3503845d..50e3a8d0b 100644
--- a/deps/v8/test/mjsunit/const-eval-init.js
+++ b/deps/v8/test/mjsunit/const-eval-init.js
@@ -36,29 +36,29 @@ function testIntroduceGlobal() {
var source =
// Deleting 'x' removes the local const property.
"delete x;" +
- // Initialization turns into assignment to global 'x'.
+ // Initialization redefines global 'x'.
"const x = 3; assertEquals(3, x);" +
- // No constness of the global 'x'.
- "x = 4; assertEquals(4, x);";
+ // Test constness of the global 'x'.
+ "x = 4; assertEquals(3, x);";
eval(source);
}
testIntroduceGlobal();
-assertEquals(4, x);
+assertEquals("undefined", typeof x);
function testAssignExistingGlobal() {
var source =
// Delete 'x' to remove the local const property.
"delete x;" +
- // Initialization turns into assignment to global 'x'.
+ // Initialization redefines global 'x'.
"const x = 5; assertEquals(5, x);" +
- // No constness of the global 'x'.
- "x = 6; assertEquals(6, x);";
+ // Test constness of the global 'x'.
+ "x = 6; assertEquals(5, x);";
eval(source);
}
testAssignExistingGlobal();
-assertEquals(6, x);
+assertEquals("undefined", typeof x);
function testAssignmentArgument(x) {
function local() {
@@ -66,7 +66,7 @@ function testAssignmentArgument(x) {
eval(source);
}
local();
- assertEquals(7, x);
+ assertEquals("undefined", typeof x);
}
for (var i = 0; i < 5; i++) {
@@ -74,17 +74,18 @@ for (var i = 0; i < 5; i++) {
}
%OptimizeFunctionOnNextCall(testAssignmentArgument);
testAssignmentArgument();
-assertEquals(6, x);
+assertEquals("undefined", typeof x);
__defineSetter__('x', function() { throw 42; });
-function testAssignGlobalThrows() {
- // Initialization turns into assignment to global 'x' which
- // throws an exception.
- var source = "delete x; const x = 8";
+var finished = false;
+function testRedefineGlobal() {
+ // Initialization redefines global 'x'.
+ var source = "delete x; const x = 8; finished = true;";
eval(source);
}
-assertThrows("testAssignGlobalThrows()");
+testRedefineGlobal();
+assertTrue(finished);
function testInitFastCaseExtension() {
var source = "const x = 9; assertEquals(9, x); x = 10; assertEquals(9, x)";
@@ -111,7 +112,7 @@ function testAssignSurroundingContextSlot() {
eval(source);
}
local();
- assertEquals(13, x);
+ assertEquals(12, x);
}
testAssignSurroundingContextSlot();
diff --git a/deps/v8/test/mjsunit/const-redecl.js b/deps/v8/test/mjsunit/const-redecl.js
index c0b97e6ce..f311f0de6 100644
--- a/deps/v8/test/mjsunit/const-redecl.js
+++ b/deps/v8/test/mjsunit/const-redecl.js
@@ -49,37 +49,6 @@ function TestLocal(s,e) {
}
-// NOTE: TestGlobal usually only tests the given string in the context
-// of a global object in dictionary mode. This is because we use
-// delete to get rid of any added properties.
-function TestGlobal(s,e) {
- // Collect the global properties before the call.
- var properties = [];
- for (var key in this) properties.push(key);
- // Compute the result.
- var result;
- try {
- var code = s + (e ? "; $$$result=" + e : "");
- if (this.execScript) {
- execScript(code);
- } else {
- this.eval(code);
- }
- // Avoid issues if $$$result is not defined by
- // reading it through this.
- result = this.$$$result;
- } catch (x) {
- result = CheckException(x);
- }
- // Get rid of any introduced global properties before
- // returning the result.
- for (var key in this) {
- if (properties.indexOf(key) == -1) delete this[key];
- }
- return result;
-}
-
-
function TestContext(s,e) {
try {
// Use a with-statement to force the system to do dynamic
@@ -98,8 +67,6 @@ function TestAll(expected,s,opt_e) {
var msg = s;
if (opt_e) { e = opt_e; msg += "; " + opt_e; }
assertEquals(expected, TestLocal(s,e), "local:'" + msg + "'");
- // Redeclarations of global consts do not throw, they are silently ignored.
- assertEquals(42, TestGlobal(s, 42), "global:'" + msg + "'");
assertEquals(expected, TestContext(s,e), "context:'" + msg + "'");
}
@@ -112,7 +79,7 @@ function TestConflict(def0, def1) {
// Eval first definition.
TestAll("TypeError", 'eval("' + def0 +'"); ' + def1);
// Eval second definition.
- TestAll("TypeError", def0 + '; eval("' + def1 + '")');
+ TestAll("TypeError", def0 + '; eval("' + def1 +'")');
// Eval both definitions separately.
TestAll("TypeError", 'eval("' + def0 +'"); eval("' + def1 + '")');
}
@@ -234,47 +201,26 @@ var undefined = 1; // Should be silently ignored.
assertEquals(original_undef, undefined, "undefined got overwritten");
undefined = original_undef;
-var a; const a; const a = 1;
-assertEquals(1, a, "a has wrong value");
-a = 2;
-assertEquals(2, a, "a should be writable");
-
-var b = 1; const b = 2;
-assertEquals(2, b, "b has wrong value");
-
-var c = 1; const c = 2; const c = 3;
-assertEquals(3, c, "c has wrong value");
-
-const d = 1; const d = 2;
-assertEquals(1, d, "d has wrong value");
-
-const e = 1; var e = 2;
+const e = 1; eval('var e = 2');
assertEquals(1, e, "e has wrong value");
-const f = 1; const f;
-assertEquals(1, f, "f has wrong value");
-
-var g; const g = 1;
-assertEquals(1, g, "g has wrong value");
-g = 2;
-assertEquals(2, g, "g should be writable");
-
-const h; var h = 1;
-assertEquals(undefined,h, "h has wrong value");
+const h; eval('var h = 1');
+assertEquals(undefined, h, "h has wrong value");
eval("Object.defineProperty(this, 'i', { writable: true });"
+ "const i = 7;"
+ "assertEquals(7, i, \"i has wrong value\");");
var global = this;
-assertThrows(function() {
- Object.defineProperty(global, 'j', { writable: true })
-}, TypeError);
-const j = 2; // This is what makes the function above throw, because the
-// const declaration gets hoisted and makes the property non-configurable.
+Object.defineProperty(global, 'j', { value: 100, writable: true });
+assertEquals(100, j);
+// The const declaration stays configurable, so the declaration above goes
+// through even though the const declaration is hoisted above.
+const j = 2;
assertEquals(2, j, "j has wrong value");
-var k = 1; const k;
-// You could argue about the expected result here. For now, the winning
-// argument is that "const k;" is equivalent to "const k = undefined;".
-assertEquals(undefined, k, "k has wrong value");
+var k = 1;
+try { eval('const k'); } catch(e) { }
+assertEquals(1, k, "k has wrong value");
+try { eval('const k = 10'); } catch(e) { }
+assertEquals(1, k, "k has wrong value");
diff --git a/deps/v8/test/mjsunit/constant-folding-2.js b/deps/v8/test/mjsunit/constant-folding-2.js
index f429c6ca1..73cf040f5 100644
--- a/deps/v8/test/mjsunit/constant-folding-2.js
+++ b/deps/v8/test/mjsunit/constant-folding-2.js
@@ -181,6 +181,17 @@ test(function mathRound() {
assertEquals(Math.pow(2, 52) + 1, Math.round(Math.pow(2, 52) + 1));
});
+test(function mathFround() {
+ assertTrue(isNaN(Math.fround(NaN)));
+ assertEquals("Infinity", String(1/Math.fround(0)));
+ assertEquals("-Infinity", String(1/Math.fround(-0)));
+ assertEquals("Infinity", String(Math.fround(Infinity)));
+ assertEquals("-Infinity", String(Math.fround(-Infinity)));
+ assertEquals("Infinity", String(Math.fround(1E200)));
+ assertEquals("-Infinity", String(Math.fround(-1E200)));
+ assertEquals(3.1415927410125732, Math.fround(Math.PI));
+});
+
test(function mathFloor() {
assertEquals(1, Math.floor(1.5));
assertEquals(-2, Math.floor(-1.5));
diff --git a/deps/v8/test/mjsunit/cross-realm-filtering.js b/deps/v8/test/mjsunit/cross-realm-filtering.js
new file mode 100644
index 000000000..902cceb58
--- /dev/null
+++ b/deps/v8/test/mjsunit/cross-realm-filtering.js
@@ -0,0 +1,141 @@
+// 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.
+
+var realms = [Realm.current(), Realm.create()];
+
+// Check stack trace filtering across security contexts.
+var thrower_script =
+ "(function () { Realm.eval(Realm.current(), 'throw Error()') })";
+Realm.shared = {
+ thrower_0: Realm.eval(realms[0], thrower_script),
+ thrower_1: Realm.eval(realms[1], thrower_script),
+};
+
+var script = " \
+ Error.prepareStackTrace = function(a, b) { return b; }; \
+ try { \
+ Realm.shared.thrower_0(); \
+ } catch (e) { \
+ Realm.shared.error_0 = e.stack; \
+ } \
+ try { \
+ Realm.shared.thrower_1(); \
+ } catch (e) { \
+ Realm.shared.error_1 = e.stack; \
+ } \
+";
+
+function assertNotIn(thrower, error) {
+ for (var i = 0; i < error.length; i++) {
+ assertFalse(false === error[i].getFunction());
+ }
+}
+
+Realm.eval(realms[1], script);
+assertSame(3, Realm.shared.error_0.length);
+assertSame(4, Realm.shared.error_1.length);
+
+assertTrue(Realm.shared.thrower_1 === Realm.shared.error_1[2].getFunction());
+assertNotIn(Realm.shared.thrower_0, Realm.shared.error_0);
+assertNotIn(Realm.shared.thrower_0, Realm.shared.error_1);
+
+Realm.eval(realms[0], script);
+assertSame(5, Realm.shared.error_0.length);
+assertSame(4, Realm.shared.error_1.length);
+
+assertTrue(Realm.shared.thrower_0 === Realm.shared.error_0[2].getFunction());
+assertNotIn(Realm.shared.thrower_1, Realm.shared.error_0);
+assertNotIn(Realm.shared.thrower_1, Realm.shared.error_1);
+
+
+// Check .caller filtering across security contexts.
+var caller_script = "(function (f) { f(); })";
+Realm.shared = {
+ caller_0 : Realm.eval(realms[0], caller_script),
+ caller_1 : Realm.eval(realms[1], caller_script),
+}
+
+script = " \
+ function f_0() { Realm.shared.result_0 = arguments.callee.caller; }; \
+ function f_1() { Realm.shared.result_1 = arguments.callee.caller; }; \
+ Realm.shared.caller_0(f_0); \
+ Realm.shared.caller_1(f_1); \
+";
+
+Realm.eval(realms[1], script);
+assertSame(null, Realm.shared.result_0);
+assertSame(Realm.shared.caller_1, Realm.shared.result_1);
+
+Realm.eval(realms[0], script);
+assertSame(Realm.shared.caller_0, Realm.shared.result_0);
+assertSame(null, Realm.shared.result_1);
+
+
+// Check function constructor.
+var ctor_script = "Function.constructor";
+var ctor_a_script =
+ "(function() { return Function.constructor.apply(this, ['return 1;']); })";
+var ctor_b_script = "Function.constructor.bind(this, 'return 1;')";
+var ctor_c_script =
+ "(function() { return Function.constructor.call(this, 'return 1;'); })";
+Realm.shared = {
+ ctor_0 : Realm.eval(realms[0], ctor_script),
+ ctor_1 : Realm.eval(realms[1], ctor_script),
+ ctor_a_0 : Realm.eval(realms[0], ctor_a_script),
+ ctor_a_1 : Realm.eval(realms[1], ctor_a_script),
+ ctor_b_0 : Realm.eval(realms[0], ctor_b_script),
+ ctor_b_1 : Realm.eval(realms[1], ctor_b_script),
+ ctor_c_0 : Realm.eval(realms[0], ctor_c_script),
+ ctor_c_1 : Realm.eval(realms[1], ctor_c_script),
+}
+
+var script_0 = " \
+ var ctor_0 = Realm.shared.ctor_0; \
+ Realm.shared.direct_0 = ctor_0('return 1'); \
+ Realm.shared.indirect_0 = (function() { return ctor_0('return 1;'); })(); \
+ Realm.shared.apply_0 = ctor_0.apply(this, ['return 1']); \
+ Realm.shared.bind_0 = ctor_0.bind(this, 'return 1')(); \
+ Realm.shared.call_0 = ctor_0.call(this, 'return 1'); \
+ Realm.shared.a_0 = Realm.shared.ctor_a_0(); \
+ Realm.shared.b_0 = Realm.shared.ctor_b_0(); \
+ Realm.shared.c_0 = Realm.shared.ctor_c_0(); \
+";
+
+script = script_0 + script_0.replace(/_0/g, "_1");
+
+Realm.eval(realms[0], script);
+assertSame(1, Realm.shared.direct_0());
+assertSame(1, Realm.shared.indirect_0());
+assertSame(1, Realm.shared.apply_0());
+assertSame(1, Realm.shared.bind_0());
+assertSame(1, Realm.shared.call_0());
+assertSame(1, Realm.shared.a_0());
+assertSame(1, Realm.shared.b_0());
+assertSame(1, Realm.shared.c_0());
+assertSame(undefined, Realm.shared.direct_1);
+assertSame(undefined, Realm.shared.indirect_1);
+assertSame(undefined, Realm.shared.apply_1);
+assertSame(undefined, Realm.shared.bind_1);
+assertSame(undefined, Realm.shared.call_1);
+assertSame(1, Realm.shared.a_1());
+assertSame(undefined, Realm.shared.b_1);
+assertSame(1, Realm.shared.c_1());
+
+Realm.eval(realms[1], script);
+assertSame(undefined, Realm.shared.direct_0);
+assertSame(undefined, Realm.shared.indirect_0);
+assertSame(undefined, Realm.shared.apply_0);
+assertSame(undefined, Realm.shared.bind_0);
+assertSame(undefined, Realm.shared.call_0);
+assertSame(1, Realm.shared.a_0());
+assertSame(undefined, Realm.shared.b_0);
+assertSame(1, Realm.shared.c_1());
+assertSame(1, Realm.shared.direct_1());
+assertSame(1, Realm.shared.indirect_1());
+assertSame(1, Realm.shared.apply_1());
+assertSame(1, Realm.shared.bind_1());
+assertSame(1, Realm.shared.call_1());
+assertSame(1, Realm.shared.a_1());
+assertSame(1, Realm.shared.b_1());
+assertSame(1, Realm.shared.c_1());
diff --git a/deps/v8/test/mjsunit/debug-break-native.js b/deps/v8/test/mjsunit/debug-break-native.js
new file mode 100644
index 000000000..11d727492
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-break-native.js
@@ -0,0 +1,42 @@
+// 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.
+
+// Flags: --expose-debug-as debug
+
+Debug = debug.Debug
+var exception = null;
+
+function breakListener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ exec_state.prepareStep(Debug.StepAction.StepIn, 1);
+ // Assert that the break happens at an intended location.
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// break") > 0);
+ } catch (e) {
+ exception = e;
+ }
+}
+
+Debug.setListener(breakListener);
+
+debugger; // break
+
+function f(x) {
+ return x; // break
+} // break
+
+Debug.setBreakPoint(f, 0, 0); // break
+Debug.scripts(); // break
+debug.MakeMirror(f); // break
+
+new Error("123").stack; // break
+Math.sin(0); // break
+
+f("this should break"); // break
+
+Debug.setListener(null); // break
+
+f("this should not break");
+
+assertNull(exception);
diff --git a/deps/v8/test/mjsunit/debug-compile-event.js b/deps/v8/test/mjsunit/debug-compile-event.js
index 89a71ddb5..c38cd8477 100644
--- a/deps/v8/test/mjsunit/debug-compile-event.js
+++ b/deps/v8/test/mjsunit/debug-compile-event.js
@@ -32,6 +32,7 @@ Debug = debug.Debug
var exception = false; // Exception in debug event listener.
var before_compile_count = 0;
var after_compile_count = 0;
+var compile_error_count = 0;
var current_source = ''; // Current source being compiled.
var source_count = 0; // Total number of scources compiled.
var host_compilations = 0; // Number of scources compiled through the API.
@@ -48,11 +49,12 @@ function compileSource(source) {
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.BeforeCompile ||
- event == Debug.DebugEvent.AfterCompile) {
+ event == Debug.DebugEvent.AfterCompile ||
+ event == Debug.DebugEvent.CompileError) {
// Count the events.
if (event == Debug.DebugEvent.BeforeCompile) {
before_compile_count++;
- } else {
+ } else if (event == Debug.DebugEvent.AfterCompile) {
after_compile_count++;
switch (event_data.script().compilationType()) {
case Debug.ScriptCompilationType.Host:
@@ -62,6 +64,8 @@ function listener(event, exec_state, event_data, data) {
eval_compilations++;
break;
}
+ } else {
+ compile_error_count++;
}
// If the compiled source contains 'eval' there will be additional compile
@@ -81,9 +85,11 @@ function listener(event, exec_state, event_data, data) {
assertTrue('context' in msg.body.script);
// Check that we pick script name from //# sourceURL, iff present
- assertEquals(current_source.indexOf('sourceURL') >= 0 ?
- 'myscript.js' : undefined,
- event_data.script().name());
+ if (event == Debug.DebugEvent.AfterCompile) {
+ assertEquals(current_source.indexOf('sourceURL') >= 0 ?
+ 'myscript.js' : undefined,
+ event_data.script().name());
+ }
}
} catch (e) {
exception = e
@@ -105,11 +111,17 @@ compileSource('JSON.parse(\'{"a":1,"b":2}\')');
// Using JSON.parse does not causes additional compilation events.
compileSource('x=1; //# sourceURL=myscript.js');
+try {
+ compileSource('}');
+} catch(e) {
+}
+
// Make sure that the debug event listener was invoked.
assertFalse(exception, "exception in listener")
-// Number of before and after compile events should be the same.
-assertEquals(before_compile_count, after_compile_count);
+// Number of before and after + error events should be the same.
+assertEquals(before_compile_count, after_compile_count + compile_error_count);
+assertEquals(compile_error_count, 1);
// Check the actual number of events (no compilation through the API as all
// source compiled through eval).
diff --git a/deps/v8/test/mjsunit/debug-compile-optimized.js b/deps/v8/test/mjsunit/debug-compile-optimized.js
new file mode 100644
index 000000000..468605aba
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-compile-optimized.js
@@ -0,0 +1,18 @@
+// 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --crankshaft
+
+Debug = debug.Debug;
+
+Debug.setListener(function() {});
+
+function f() {}
+f();
+f();
+%OptimizeFunctionOnNextCall(f);
+f();
+assertOptimized(f);
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/debug-is-active.js b/deps/v8/test/mjsunit/debug-is-active.js
new file mode 100644
index 000000000..19968f0c1
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-is-active.js
@@ -0,0 +1,28 @@
+// 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+Debug = debug.Debug;
+
+function f() { return %_DebugIsActive() != 0; }
+
+assertFalse(f());
+assertFalse(f());
+Debug.setListener(function() {});
+assertTrue(f());
+Debug.setListener(null);
+assertFalse(f());
+
+%OptimizeFunctionOnNextCall(f);
+assertFalse(f());
+assertOptimized(f);
+
+Debug.setListener(function() {});
+assertTrue(f());
+assertOptimized(f);
+
+Debug.setListener(null);
+assertFalse(f());
+assertOptimized(f);
diff --git a/deps/v8/test/mjsunit/debug-mirror-cache.js b/deps/v8/test/mjsunit/debug-mirror-cache.js
index 07aaf880d..c690aa013 100644
--- a/deps/v8/test/mjsunit/debug-mirror-cache.js
+++ b/deps/v8/test/mjsunit/debug-mirror-cache.js
@@ -62,6 +62,9 @@ function listener(event, exec_state, event_data, data) {
json = '{"seq":0,"type":"request","command":"backtrace"}'
dcp.processDebugJSONRequest(json);
+ // Make sure looking up loaded scripts does not clear the cache.
+ Debug.scripts();
+
// Some mirrors where cached.
assertFalse(debug.next_handle_ == 0, "Mirror cache not used");
assertFalse(debug.mirror_cache_.length == 0, "Mirror cache not used");
diff --git a/deps/v8/test/mjsunit/debug-script.js b/deps/v8/test/mjsunit/debug-script.js
index 80d423e10..5b5e75962 100644
--- a/deps/v8/test/mjsunit/debug-script.js
+++ b/deps/v8/test/mjsunit/debug-script.js
@@ -59,7 +59,7 @@ for (i = 0; i < scripts.length; i++) {
}
// This has to be updated if the number of native scripts change.
-assertTrue(named_native_count == 19 || named_native_count == 20);
+assertTrue(named_native_count == 25 || named_native_count == 26);
// Only the 'gc' extension is loaded.
assertEquals(1, extension_count);
// This script and mjsunit.js has been loaded. If using d8, d8 loads
diff --git a/deps/v8/test/mjsunit/debug-scripts-request.js b/deps/v8/test/mjsunit/debug-scripts-request.js
index e027563b9..f9fdde634 100644
--- a/deps/v8/test/mjsunit/debug-scripts-request.js
+++ b/deps/v8/test/mjsunit/debug-scripts-request.js
@@ -108,3 +108,5 @@ debugger;
assertTrue(listenerComplete,
"listener did not run to completion, exception: " + exception);
assertFalse(exception, "exception in listener")
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/debug-stepin-positions.js b/deps/v8/test/mjsunit/debug-stepin-positions.js
index 722df5366..ff532e3dd 100644
--- a/deps/v8/test/mjsunit/debug-stepin-positions.js
+++ b/deps/v8/test/mjsunit/debug-stepin-positions.js
@@ -37,12 +37,13 @@ function TestCase(fun, frame_number) {
var exception = false;
var codeSnippet = undefined;
var resultPositions = undefined;
+ var step = 0;
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Break ||
event == Debug.DebugEvent.Exception) {
- Debug.setListener(null);
+ if (step++ > 0) return;
assertHasLineMark(/pause/, exec_state.frame(0));
assertHasLineMark(/positions/, exec_state.frame(frame_number));
var frame = exec_state.frame(frame_number);
diff --git a/deps/v8/test/cctest/test-cpu-x64.cc b/deps/v8/test/mjsunit/debug-toggle-mirror-cache.js
index a2c45cf86..a44c11551 100644
--- a/deps/v8/test/cctest/test-cpu-x64.cc
+++ b/deps/v8/test/mjsunit/debug-toggle-mirror-cache.js
@@ -1,4 +1,4 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
+// 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:
@@ -25,20 +25,16 @@
// (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"
+// Flags: --expose-debug-as debug
-#include "cctest.h"
-#include "cpu.h"
+var handle1 = debug.MakeMirror(123).handle();
+assertEquals("number", debug.LookupMirror(handle1).type());
-using namespace v8::internal;
+debug.ToggleMirrorCache(false);
+var handle2 = debug.MakeMirror(123).handle();
+assertEquals(undefined, handle2);
+assertThrows(function() { debug.LookupMirror(handle2) });
-
-TEST(RequiredFeaturesX64) {
- // Test for the features required by every x64 CPU.
- CPU cpu;
- CHECK(cpu.has_fpu());
- CHECK(cpu.has_cmov());
- CHECK(cpu.has_mmx());
- CHECK(cpu.has_sse());
- CHECK(cpu.has_sse2());
-}
+debug.ToggleMirrorCache(true);
+var handle3 = debug.MakeMirror(123).handle();
+assertEquals("number", debug.LookupMirror(handle3).type());
diff --git a/deps/v8/test/mjsunit/define-property-gc.js b/deps/v8/test/mjsunit/define-property-gc.js
index 573a7edbd..b130b164b 100644
--- a/deps/v8/test/mjsunit/define-property-gc.js
+++ b/deps/v8/test/mjsunit/define-property-gc.js
@@ -26,7 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Tests the handling of GC issues in the defineProperty method.
-// Flags: --max-new-space-size=2
+// Flags: --max-semi-space-size=1
function Regular() {
this[0] = 0;
diff --git a/deps/v8/test/mjsunit/deserialize-reference.js b/deps/v8/test/mjsunit/deserialize-reference.js
new file mode 100644
index 000000000..b03201315
--- /dev/null
+++ b/deps/v8/test/mjsunit/deserialize-reference.js
@@ -0,0 +1,8 @@
+// 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.
+
+// Flags: --cache=code --serialize-toplevel
+
+var a = "123";
+assertEquals(a, "123");
diff --git a/deps/v8/test/mjsunit/dictionary-properties.js b/deps/v8/test/mjsunit/dictionary-properties.js
new file mode 100644
index 000000000..0659268ba
--- /dev/null
+++ b/deps/v8/test/mjsunit/dictionary-properties.js
@@ -0,0 +1,48 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+// Test loading existent and nonexistent properties from dictionary
+// mode objects.
+
+function SlowObject() {
+ this.foo = 1;
+ this.bar = 2;
+ this.qux = 3;
+ delete this.qux;
+ assertFalse(%HasFastProperties(this));
+}
+function SlowObjectWithBaz() {
+ var o = new SlowObject();
+ o.baz = 4;
+ return o;
+}
+
+function Load(o) {
+ return o.baz;
+}
+
+for (var i = 0; i < 10; i++) {
+ var o1 = new SlowObject();
+ var o2 = SlowObjectWithBaz();
+ assertEquals(undefined, Load(o1));
+ assertEquals(4, Load(o2));
+}
+
+// Test objects getting optimized as fast prototypes.
+
+function SlowPrototype() {
+ this.foo = 1;
+}
+SlowPrototype.prototype.bar = 2;
+SlowPrototype.prototype.baz = 3;
+delete SlowPrototype.prototype.baz;
+new SlowPrototype;
+
+// Prototypes stay fast even after deleting properties.
+assertTrue(%HasFastProperties(SlowPrototype.prototype));
+var fast_proto = new SlowPrototype();
+assertTrue(%HasFastProperties(SlowPrototype.prototype));
+assertTrue(%HasFastProperties(fast_proto.__proto__));
diff --git a/deps/v8/test/mjsunit/elements-kind-depends.js b/deps/v8/test/mjsunit/elements-kind-depends.js
index 82f188b71..539fbd0e4 100644
--- a/deps/v8/test/mjsunit/elements-kind-depends.js
+++ b/deps/v8/test/mjsunit/elements-kind-depends.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays
+// Flags: --allow-natives-syntax
function burn() {
var a = new Array(3);
diff --git a/deps/v8/test/mjsunit/elements-kind.js b/deps/v8/test/mjsunit/elements-kind.js
index 3aa513a37..64b4a094f 100644
--- a/deps/v8/test/mjsunit/elements-kind.js
+++ b/deps/v8/test/mjsunit/elements-kind.js
@@ -25,22 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc --nostress-opt --typed-array-max_size_in-heap=2048
-
-// Test element kind of objects.
-// Since --smi-only-arrays affects builtins, its default setting at compile
-// time sticks if built with snapshot. If --smi-only-arrays is deactivated
-// by default, only a no-snapshot build actually has smi-only arrays enabled
-// in this test case. Depending on whether smi-only arrays are actually
-// enabled, this test takes the appropriate code path to check smi-only arrays.
-
-support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
-
-if (support_smi_only_arrays) {
- print("Tests include smi-only arrays.");
-} else {
- print("Tests do NOT include smi-only arrays.");
-}
+// Flags: --allow-natives-syntax --expose-gc --nostress-opt --typed-array-max_size_in-heap=2048
var elements_kind = {
fast_smi_only : 'fast smi only elements',
@@ -131,10 +116,6 @@ function getKind(obj) {
}
function assertKind(expected, obj, name_opt) {
- if (!support_smi_only_arrays &&
- expected == elements_kind.fast_smi_only) {
- expected = elements_kind.fast;
- }
assertEquals(expected, getKind(obj), name_opt);
}
@@ -144,13 +125,11 @@ me.dance = 0xD15C0;
me.drink = 0xC0C0A;
assertKind(elements_kind.fast, me);
-if (support_smi_only_arrays) {
- var too = [1,2,3];
- assertKind(elements_kind.fast_smi_only, too);
- too.dance = 0xD15C0;
- too.drink = 0xC0C0A;
- assertKind(elements_kind.fast_smi_only, too);
-}
+var too = [1,2,3];
+assertKind(elements_kind.fast_smi_only, too);
+too.dance = 0xD15C0;
+too.drink = 0xC0C0A;
+assertKind(elements_kind.fast_smi_only, too);
// Make sure the element kind transitions from smi when a non-smi is stored.
function test_wrapper() {
@@ -166,7 +145,9 @@ function test_wrapper() {
}
assertKind(elements_kind.fast, you);
- assertKind(elements_kind.dictionary, new Array(0xDECAF));
+ var temp = [];
+ temp[0xDECAF] = 0;
+ assertKind(elements_kind.dictionary, temp);
var fast_double_array = new Array(0xDECAF);
for (var i = 0; i < 0xDECAF; i++) fast_double_array[i] = i / 2;
@@ -217,111 +198,106 @@ function test_wrapper() {
test_wrapper();
%ClearFunctionTypeFeedback(test_wrapper);
-if (support_smi_only_arrays) {
- %NeverOptimizeFunction(construct_smis);
+%NeverOptimizeFunction(construct_smis);
- // This code exists to eliminate the learning influence of AllocationSites
- // on the following tests.
- var __sequence = 0;
- function make_array_string() {
- this.__sequence = this.__sequence + 1;
- return "/* " + this.__sequence + " */ [0, 0, 0];"
- }
- function make_array() {
- return eval(make_array_string());
- }
+// This code exists to eliminate the learning influence of AllocationSites
+// on the following tests.
+var __sequence = 0;
+function make_array_string() {
+ this.__sequence = this.__sequence + 1;
+ return "/* " + this.__sequence + " */ [0, 0, 0];"
+}
+function make_array() {
+ return eval(make_array_string());
+}
- function construct_smis() {
- var a = make_array();
- a[0] = 0; // Send the COW array map to the steak house.
- assertKind(elements_kind.fast_smi_only, a);
- return a;
- }
+function construct_smis() {
+ var a = make_array();
+ a[0] = 0; // Send the COW array map to the steak house.
+ assertKind(elements_kind.fast_smi_only, a);
+ return a;
+}
%NeverOptimizeFunction(construct_doubles);
- function construct_doubles() {
- var a = construct_smis();
- a[0] = 1.5;
- assertKind(elements_kind.fast_double, a);
- return a;
- }
+function construct_doubles() {
+ var a = construct_smis();
+ a[0] = 1.5;
+ assertKind(elements_kind.fast_double, a);
+ return a;
+}
%NeverOptimizeFunction(construct_objects);
- function construct_objects() {
- var a = construct_smis();
- a[0] = "one";
- assertKind(elements_kind.fast, a);
- return a;
- }
+function construct_objects() {
+ var a = construct_smis();
+ a[0] = "one";
+ assertKind(elements_kind.fast, a);
+ return a;
+}
- // Test crankshafted transition SMI->DOUBLE.
+// Test crankshafted transition SMI->DOUBLE.
%NeverOptimizeFunction(convert_to_double);
- function convert_to_double(array) {
- array[1] = 2.5;
- assertKind(elements_kind.fast_double, array);
- assertEquals(2.5, array[1]);
- }
- var smis = construct_smis();
- for (var i = 0; i < 3; i++) convert_to_double(smis);
+function convert_to_double(array) {
+ array[1] = 2.5;
+ assertKind(elements_kind.fast_double, array);
+ assertEquals(2.5, array[1]);
+}
+var smis = construct_smis();
+for (var i = 0; i < 3; i++) convert_to_double(smis);
%OptimizeFunctionOnNextCall(convert_to_double);
- smis = construct_smis();
- convert_to_double(smis);
- // Test crankshafted transitions SMI->FAST and DOUBLE->FAST.
+smis = construct_smis();
+convert_to_double(smis);
+// Test crankshafted transitions SMI->FAST and DOUBLE->FAST.
%NeverOptimizeFunction(convert_to_fast);
- function convert_to_fast(array) {
- array[1] = "two";
- assertKind(elements_kind.fast, array);
- assertEquals("two", array[1]);
- }
- smis = construct_smis();
- for (var i = 0; i < 3; i++) convert_to_fast(smis);
- var doubles = construct_doubles();
- for (var i = 0; i < 3; i++) convert_to_fast(doubles);
- smis = construct_smis();
- doubles = construct_doubles();
+function convert_to_fast(array) {
+ array[1] = "two";
+ assertKind(elements_kind.fast, array);
+ assertEquals("two", array[1]);
+}
+smis = construct_smis();
+for (var i = 0; i < 3; i++) convert_to_fast(smis);
+var doubles = construct_doubles();
+for (var i = 0; i < 3; i++) convert_to_fast(doubles);
+smis = construct_smis();
+doubles = construct_doubles();
%OptimizeFunctionOnNextCall(convert_to_fast);
- convert_to_fast(smis);
- convert_to_fast(doubles);
- // Test transition chain SMI->DOUBLE->FAST (crankshafted function will
- // transition to FAST directly).
+convert_to_fast(smis);
+convert_to_fast(doubles);
+// Test transition chain SMI->DOUBLE->FAST (crankshafted function will
+// transition to FAST directly).
%NeverOptimizeFunction(convert_mixed);
- function convert_mixed(array, value, kind) {
- array[1] = value;
- assertKind(kind, array);
- assertEquals(value, array[1]);
- }
- smis = construct_smis();
- for (var i = 0; i < 3; i++) {
- convert_mixed(smis, 1.5, elements_kind.fast_double);
- }
- doubles = construct_doubles();
- for (var i = 0; i < 3; i++) {
- convert_mixed(doubles, "three", elements_kind.fast);
- }
- convert_mixed(construct_smis(), "three", elements_kind.fast);
- convert_mixed(construct_doubles(), "three", elements_kind.fast);
- %OptimizeFunctionOnNextCall(convert_mixed);
- smis = construct_smis();
- doubles = construct_doubles();
- convert_mixed(smis, 1, elements_kind.fast);
- convert_mixed(doubles, 1, elements_kind.fast);
- assertTrue(%HaveSameMap(smis, doubles));
+function convert_mixed(array, value, kind) {
+ array[1] = value;
+ assertKind(kind, array);
+ assertEquals(value, array[1]);
+}
+smis = construct_smis();
+for (var i = 0; i < 3; i++) {
+ convert_mixed(smis, 1.5, elements_kind.fast_double);
}
+doubles = construct_doubles();
+for (var i = 0; i < 3; i++) {
+ convert_mixed(doubles, "three", elements_kind.fast);
+}
+convert_mixed(construct_smis(), "three", elements_kind.fast);
+convert_mixed(construct_doubles(), "three", elements_kind.fast);
+ %OptimizeFunctionOnNextCall(convert_mixed);
+smis = construct_smis();
+doubles = construct_doubles();
+convert_mixed(smis, 1, elements_kind.fast);
+convert_mixed(doubles, 1, elements_kind.fast);
+assertTrue(%HaveSameMap(smis, doubles));
// Crankshaft support for smi-only elements in dynamic array literals.
function get(foo) { return foo; } // Used to generate dynamic values.
function crankshaft_test() {
- if (support_smi_only_arrays) {
- var a1 = [get(1), get(2), get(3)];
- assertKind(elements_kind.fast_smi_only, a1);
- }
+ var a1 = [get(1), get(2), get(3)];
+ assertKind(elements_kind.fast_smi_only, a1);
+
var a2 = new Array(get(1), get(2), get(3));
assertKind(elements_kind.fast_smi_only, a2);
var b = [get(1), get(2), get("three")];
assertKind(elements_kind.fast, b);
var c = [get(1), get(2), get(3.5)];
- if (support_smi_only_arrays) {
- assertKind(elements_kind.fast_double, c);
- }
+ assertKind(elements_kind.fast_double, c);
}
for (var i = 0; i < 3; i++) {
crankshaft_test();
@@ -335,85 +311,76 @@ crankshaft_test();
// DOUBLE->OBJECT, and SMI->OBJECT. No matter in which order these three are
// created, they must always end up with the same FAST map.
-// This test is meaningless without FAST_SMI_ONLY_ELEMENTS.
-if (support_smi_only_arrays) {
- // Preparation: create one pair of identical objects for each case.
- var a = [1, 2, 3];
- var b = [1, 2, 3];
- assertTrue(%HaveSameMap(a, b));
- assertKind(elements_kind.fast_smi_only, a);
- var c = [1, 2, 3];
- c["case2"] = true;
- var d = [1, 2, 3];
- d["case2"] = true;
- assertTrue(%HaveSameMap(c, d));
- assertFalse(%HaveSameMap(a, c));
- assertKind(elements_kind.fast_smi_only, c);
- var e = [1, 2, 3];
- e["case3"] = true;
- var f = [1, 2, 3];
- f["case3"] = true;
- assertTrue(%HaveSameMap(e, f));
- assertFalse(%HaveSameMap(a, e));
- assertFalse(%HaveSameMap(c, e));
- assertKind(elements_kind.fast_smi_only, e);
- // Case 1: SMI->DOUBLE, DOUBLE->OBJECT, SMI->OBJECT.
- a[0] = 1.5;
- assertKind(elements_kind.fast_double, a);
- a[0] = "foo";
- assertKind(elements_kind.fast, a);
- b[0] = "bar";
- assertTrue(%HaveSameMap(a, b));
- // Case 2: SMI->DOUBLE, SMI->OBJECT, DOUBLE->OBJECT.
- c[0] = 1.5;
- assertKind(elements_kind.fast_double, c);
- assertFalse(%HaveSameMap(c, d));
- d[0] = "foo";
- assertKind(elements_kind.fast, d);
- assertFalse(%HaveSameMap(c, d));
- c[0] = "bar";
- assertTrue(%HaveSameMap(c, d));
- // Case 3: SMI->OBJECT, SMI->DOUBLE, DOUBLE->OBJECT.
- e[0] = "foo";
- assertKind(elements_kind.fast, e);
- assertFalse(%HaveSameMap(e, f));
- f[0] = 1.5;
- assertKind(elements_kind.fast_double, f);
- assertFalse(%HaveSameMap(e, f));
- f[0] = "bar";
- assertKind(elements_kind.fast, f);
- assertTrue(%HaveSameMap(e, f));
-}
+// Preparation: create one pair of identical objects for each case.
+var a = [1, 2, 3];
+var b = [1, 2, 3];
+assertTrue(%HaveSameMap(a, b));
+assertKind(elements_kind.fast_smi_only, a);
+var c = [1, 2, 3];
+c["case2"] = true;
+var d = [1, 2, 3];
+d["case2"] = true;
+assertTrue(%HaveSameMap(c, d));
+assertFalse(%HaveSameMap(a, c));
+assertKind(elements_kind.fast_smi_only, c);
+var e = [1, 2, 3];
+e["case3"] = true;
+var f = [1, 2, 3];
+f["case3"] = true;
+assertTrue(%HaveSameMap(e, f));
+assertFalse(%HaveSameMap(a, e));
+assertFalse(%HaveSameMap(c, e));
+assertKind(elements_kind.fast_smi_only, e);
+// Case 1: SMI->DOUBLE, DOUBLE->OBJECT, SMI->OBJECT.
+a[0] = 1.5;
+assertKind(elements_kind.fast_double, a);
+a[0] = "foo";
+assertKind(elements_kind.fast, a);
+b[0] = "bar";
+assertTrue(%HaveSameMap(a, b));
+// Case 2: SMI->DOUBLE, SMI->OBJECT, DOUBLE->OBJECT.
+c[0] = 1.5;
+assertKind(elements_kind.fast_double, c);
+assertFalse(%HaveSameMap(c, d));
+d[0] = "foo";
+assertKind(elements_kind.fast, d);
+assertFalse(%HaveSameMap(c, d));
+c[0] = "bar";
+assertTrue(%HaveSameMap(c, d));
+// Case 3: SMI->OBJECT, SMI->DOUBLE, DOUBLE->OBJECT.
+e[0] = "foo";
+assertKind(elements_kind.fast, e);
+assertFalse(%HaveSameMap(e, f));
+f[0] = 1.5;
+assertKind(elements_kind.fast_double, f);
+assertFalse(%HaveSameMap(e, f));
+f[0] = "bar";
+assertKind(elements_kind.fast, f);
+assertTrue(%HaveSameMap(e, f));
// Test if Array.concat() works correctly with DOUBLE elements.
-if (support_smi_only_arrays) {
- var a = [1, 2];
- assertKind(elements_kind.fast_smi_only, a);
- var b = [4.5, 5.5];
- assertKind(elements_kind.fast_double, b);
- var c = a.concat(b);
- assertEquals([1, 2, 4.5, 5.5], c);
- assertKind(elements_kind.fast_double, c);
-}
+var a = [1, 2];
+assertKind(elements_kind.fast_smi_only, a);
+var b = [4.5, 5.5];
+assertKind(elements_kind.fast_double, b);
+var c = a.concat(b);
+assertEquals([1, 2, 4.5, 5.5], c);
+assertKind(elements_kind.fast_double, c);
// Test that Array.push() correctly handles SMI elements.
-if (support_smi_only_arrays) {
- var a = [1, 2];
- assertKind(elements_kind.fast_smi_only, a);
- a.push(3, 4, 5);
- assertKind(elements_kind.fast_smi_only, a);
- assertEquals([1, 2, 3, 4, 5], a);
-}
+var a = [1, 2];
+assertKind(elements_kind.fast_smi_only, a);
+a.push(3, 4, 5);
+assertKind(elements_kind.fast_smi_only, a);
+assertEquals([1, 2, 3, 4, 5], a);
// Test that Array.splice() and Array.slice() return correct ElementsKinds.
-if (support_smi_only_arrays) {
- var a = ["foo", "bar"];
- assertKind(elements_kind.fast, a);
- var b = a.splice(0, 1);
- assertKind(elements_kind.fast, b);
- var c = a.slice(0, 1);
- assertKind(elements_kind.fast, c);
-}
+var a = ["foo", "bar"];
+assertKind(elements_kind.fast, a);
+var b = a.splice(0, 1);
+assertKind(elements_kind.fast, b);
+var c = a.slice(0, 1);
+assertKind(elements_kind.fast, c);
// Throw away type information in the ICs for next stress run.
gc();
diff --git a/deps/v8/test/mjsunit/elements-transition-hoisting.js b/deps/v8/test/mjsunit/elements-transition-hoisting.js
index 76027b9ed..9f229d2e1 100644
--- a/deps/v8/test/mjsunit/elements-transition-hoisting.js
+++ b/deps/v8/test/mjsunit/elements-transition-hoisting.js
@@ -25,21 +25,13 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays
+// Flags: --allow-natives-syntax
// Flags: --nostress-opt
// Ensure that ElementsKind transitions in various situations are hoisted (or
// not hoisted) correctly, don't change the semantics programs and don't trigger
// deopt through hoisting in important situations.
-support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6));
-
-if (support_smi_only_arrays) {
- print("Tests include smi-only arrays.");
-} else {
- print("Tests do NOT include smi-only arrays.");
-}
-
function test_wrapper() {
// Make sure that a simple elements array transitions inside a loop before
// stores to an array gets hoisted in a way that doesn't generate a deopt in
@@ -238,9 +230,7 @@ function test_wrapper() {
%ClearFunctionTypeFeedback(testStraightLineDupeElinination);
}
-if (support_smi_only_arrays) {
- // The test is called in a test wrapper that has type feedback cleared to
- // prevent the influence of allocation-sites, which learn from transitions.
- test_wrapper();
- %ClearFunctionTypeFeedback(test_wrapper);
-}
+// The test is called in a test wrapper that has type feedback cleared to
+// prevent the influence of allocation-sites, which learn from transitions.
+test_wrapper();
+%ClearFunctionTypeFeedback(test_wrapper);
diff --git a/deps/v8/test/mjsunit/elements-transition.js b/deps/v8/test/mjsunit/elements-transition.js
index 7298e68a1..f6a8188e2 100644
--- a/deps/v8/test/mjsunit/elements-transition.js
+++ b/deps/v8/test/mjsunit/elements-transition.js
@@ -25,107 +25,95 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays
+// Flags: --allow-natives-syntax
// Flags: --nostress-opt
-support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
-
-if (support_smi_only_arrays) {
- print("Tests include smi-only arrays.");
-} else {
- print("Tests do NOT include smi-only arrays.");
+// This code exists to eliminate the learning influence of AllocationSites
+// on the following tests.
+var __sequence = 0;
+function make_array_string(length) {
+ this.__sequence = this.__sequence + 1;
+ return "/* " + this.__sequence + " */ new Array(" + length + ");";
+}
+function make_array(length) {
+ return eval(make_array_string(length));
}
-if (support_smi_only_arrays) {
- // This code exists to eliminate the learning influence of AllocationSites
- // on the following tests.
- var __sequence = 0;
- function make_array_string(length) {
- this.__sequence = this.__sequence + 1;
- return "/* " + this.__sequence + " */ new Array(" + length + ");";
- }
- function make_array(length) {
- return eval(make_array_string(length));
- }
-
- function test(test_double, test_object, set, length) {
- // We apply the same operations to two identical arrays. The first array
- // triggers an IC miss, upon which the conversion stub is generated, but the
- // actual conversion is done in runtime. The second array, arriving at
- // the previously patched IC, is then converted using the conversion stub.
- var array_1 = make_array(length);
- var array_2 = make_array(length);
+function test(test_double, test_object, set, length) {
+ // We apply the same operations to two identical arrays. The first array
+ // triggers an IC miss, upon which the conversion stub is generated, but the
+ // actual conversion is done in runtime. The second array, arriving at
+ // the previously patched IC, is then converted using the conversion stub.
+ var array_1 = make_array(length);
+ var array_2 = make_array(length);
- // false, true, nice setter function, 20
- assertTrue(%HasFastSmiElements(array_1));
- assertTrue(%HasFastSmiElements(array_2));
- for (var i = 0; i < length; i++) {
- if (i == length - 5 && test_double) {
- // Trigger conversion to fast double elements at length-5.
- set(array_1, i, 0.5);
- set(array_2, i, 0.5);
- assertTrue(%HasFastDoubleElements(array_1));
- assertTrue(%HasFastDoubleElements(array_2));
- } else if (i == length - 3 && test_object) {
- // Trigger conversion to fast object elements at length-3.
- set(array_1, i, 'object');
- set(array_2, i, 'object');
- assertTrue(%HasFastObjectElements(array_1));
- assertTrue(%HasFastObjectElements(array_2));
- } else if (i != length - 7) {
- // Set the element to an integer but leave a hole at length-7.
- set(array_1, i, 2*i+1);
- set(array_2, i, 2*i+1);
- }
+ // false, true, nice setter function, 20
+ assertTrue(%HasFastSmiElements(array_1));
+ assertTrue(%HasFastSmiElements(array_2));
+ for (var i = 0; i < length; i++) {
+ if (i == length - 5 && test_double) {
+ // Trigger conversion to fast double elements at length-5.
+ set(array_1, i, 0.5);
+ set(array_2, i, 0.5);
+ assertTrue(%HasFastDoubleElements(array_1));
+ assertTrue(%HasFastDoubleElements(array_2));
+ } else if (i == length - 3 && test_object) {
+ // Trigger conversion to fast object elements at length-3.
+ set(array_1, i, 'object');
+ set(array_2, i, 'object');
+ assertTrue(%HasFastObjectElements(array_1));
+ assertTrue(%HasFastObjectElements(array_2));
+ } else if (i != length - 7) {
+ // Set the element to an integer but leave a hole at length-7.
+ set(array_1, i, 2*i+1);
+ set(array_2, i, 2*i+1);
}
+ }
- for (var i = 0; i < length; i++) {
- if (i == length - 5 && test_double) {
- assertEquals(0.5, array_1[i]);
- assertEquals(0.5, array_2[i]);
- } else if (i == length - 3 && test_object) {
- assertEquals('object', array_1[i]);
- assertEquals('object', array_2[i]);
- } else if (i != length - 7) {
- assertEquals(2*i+1, array_1[i]);
- assertEquals(2*i+1, array_2[i]);
- } else {
- assertEquals(undefined, array_1[i]);
- assertEquals(undefined, array_2[i]);
- }
+ for (var i = 0; i < length; i++) {
+ if (i == length - 5 && test_double) {
+ assertEquals(0.5, array_1[i]);
+ assertEquals(0.5, array_2[i]);
+ } else if (i == length - 3 && test_object) {
+ assertEquals('object', array_1[i]);
+ assertEquals('object', array_2[i]);
+ } else if (i != length - 7) {
+ assertEquals(2*i+1, array_1[i]);
+ assertEquals(2*i+1, array_2[i]);
+ } else {
+ assertEquals(undefined, array_1[i]);
+ assertEquals(undefined, array_2[i]);
}
-
- assertEquals(length, array_1.length);
- assertEquals(length, array_2.length);
}
- function run_test(test_double, test_object, set, length) {
- test(test_double, test_object, set, length);
+ assertEquals(length, array_1.length);
+ assertEquals(length, array_2.length);
+}
+
+function run_test(test_double, test_object, set, length) {
+ test(test_double, test_object, set, length);
%ClearFunctionTypeFeedback(test);
- }
+}
- run_test(false, false, function(a,i,v){ a[i] = v; }, 20);
- run_test(true, false, function(a,i,v){ a[i] = v; }, 20);
- run_test(false, true, function(a,i,v){ a[i] = v; }, 20);
- run_test(true, true, function(a,i,v){ a[i] = v; }, 20);
+run_test(false, false, function(a,i,v){ a[i] = v; }, 20);
+run_test(true, false, function(a,i,v){ a[i] = v; }, 20);
+run_test(false, true, function(a,i,v){ a[i] = v; }, 20);
+run_test(true, true, function(a,i,v){ a[i] = v; }, 20);
- run_test(false, false, function(a,i,v){ a[i] = v; }, 10000);
- run_test(true, false, function(a,i,v){ a[i] = v; }, 10000);
- run_test(false, true, function(a,i,v){ a[i] = v; }, 10000);
- run_test(true, true, function(a,i,v){ a[i] = v; }, 10000);
+run_test(false, false, function(a,i,v){ a[i] = v; }, 10000);
+run_test(true, false, function(a,i,v){ a[i] = v; }, 10000);
+run_test(false, true, function(a,i,v){ a[i] = v; }, 10000);
+run_test(true, true, function(a,i,v){ a[i] = v; }, 10000);
- // Check COW arrays
- function get_cow() { return [1, 2, 3]; }
+// Check COW arrays
+function get_cow() { return [1, 2, 3]; }
- function transition(x) { x[0] = 1.5; }
+function transition(x) { x[0] = 1.5; }
- var ignore = get_cow();
- transition(ignore); // Handled by runtime.
- var a = get_cow();
- var b = get_cow();
- transition(a); // Handled by IC.
- assertEquals(1.5, a[0]);
- assertEquals(1, b[0]);
-} else {
- print("Test skipped because smi only arrays are not supported.");
-}
+var ignore = get_cow();
+transition(ignore); // Handled by runtime.
+var a = get_cow();
+var b = get_cow();
+transition(a); // Handled by IC.
+assertEquals(1.5, a[0]);
+assertEquals(1, b[0]);
diff --git a/deps/v8/test/mjsunit/error-tostring-omit.js b/deps/v8/test/mjsunit/error-tostring-omit.js
index 111adfc21..9ff43fa9b 100644
--- a/deps/v8/test/mjsunit/error-tostring-omit.js
+++ b/deps/v8/test/mjsunit/error-tostring-omit.js
@@ -37,23 +37,15 @@ function veryLongString() {
"Nam accumsan dignissim turpis a turpis duis.";
}
+assertTrue(veryLongString().length > 256);
-var re = /omitted/;
+var re = /...<omitted>.../;
try {
- veryLongString.nonexistentMethod();
+ Number.prototype.toFixed.call(veryLongString);
} catch (e) {
- assertTrue(e.message.length < 350);
- // TODO(verwaest): Proper error message.
- // assertTrue(re.test(e.message));
-}
-
-try {
- veryLongString().nonexistentMethod();
-} catch (e) {
- assertTrue(e.message.length < 350);
- // TODO(verwaest): Proper error message.
- // assertTrue(re.test(e.message));
+ assertTrue(e.message.length < 256);
+ assertTrue(re.test(e.message));
}
try {
diff --git a/deps/v8/test/mjsunit/harmony/array-iterator.js b/deps/v8/test/mjsunit/es6/array-iterator.js
index 6a402e739..63a7415b9 100644
--- a/deps/v8/test/mjsunit/harmony/array-iterator.js
+++ b/deps/v8/test/mjsunit/es6/array-iterator.js
@@ -25,23 +25,40 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-iteration --allow-natives-syntax
+// Flags: --allow-natives-syntax
+
+
+var NONE = 0;
+var READ_ONLY = 1;
+var DONT_ENUM = 2;
+var DONT_DELETE = 4;
+
+
+function assertHasOwnProperty(object, name, attrs) {
+ assertTrue(object.hasOwnProperty(name));
+ var desc = Object.getOwnPropertyDescriptor(object, name);
+ assertEquals(desc.writable, !(attrs & READ_ONLY));
+ assertEquals(desc.enumerable, !(attrs & DONT_ENUM));
+ assertEquals(desc.configurable, !(attrs & DONT_DELETE));
+}
+
function TestArrayPrototype() {
- assertTrue(Array.prototype.hasOwnProperty('entries'));
- assertTrue(Array.prototype.hasOwnProperty('values'));
- assertTrue(Array.prototype.hasOwnProperty('keys'));
+ assertHasOwnProperty(Array.prototype, 'entries', DONT_ENUM);
+ assertHasOwnProperty(Array.prototype, 'values', DONT_ENUM);
+ assertHasOwnProperty(Array.prototype, 'keys', DONT_ENUM);
+ assertHasOwnProperty(Array.prototype, Symbol.iterator, DONT_ENUM);
- assertFalse(Array.prototype.propertyIsEnumerable('entries'));
- assertFalse(Array.prototype.propertyIsEnumerable('values'));
- assertFalse(Array.prototype.propertyIsEnumerable('keys'));
+ assertEquals(Array.prototype.values, Array.prototype[Symbol.iterator]);
}
TestArrayPrototype();
+
function assertIteratorResult(value, done, result) {
assertEquals({value: value, done: done}, result);
}
+
function TestValues() {
var array = ['a', 'b', 'c'];
var iterator = array.values();
@@ -55,6 +72,7 @@ function TestValues() {
}
TestValues();
+
function TestValuesMutate() {
var array = ['a', 'b', 'c'];
var iterator = array.values();
@@ -67,6 +85,7 @@ function TestValuesMutate() {
}
TestValuesMutate();
+
function TestKeys() {
var array = ['a', 'b', 'c'];
var iterator = array.keys();
@@ -80,6 +99,7 @@ function TestKeys() {
}
TestKeys();
+
function TestKeysMutate() {
var array = ['a', 'b', 'c'];
var iterator = array.keys();
@@ -92,6 +112,7 @@ function TestKeysMutate() {
}
TestKeysMutate();
+
function TestEntries() {
var array = ['a', 'b', 'c'];
var iterator = array.entries();
@@ -105,6 +126,7 @@ function TestEntries() {
}
TestEntries();
+
function TestEntriesMutate() {
var array = ['a', 'b', 'c'];
var iterator = array.entries();
@@ -117,29 +139,32 @@ function TestEntriesMutate() {
}
TestEntriesMutate();
+
function TestArrayIteratorPrototype() {
var array = [];
var iterator = array.values();
- var ArrayIterator = iterator.constructor;
- assertEquals(ArrayIterator.prototype, array.values().__proto__);
- assertEquals(ArrayIterator.prototype, array.keys().__proto__);
- assertEquals(ArrayIterator.prototype, array.entries().__proto__);
+ var ArrayIteratorPrototype = iterator.__proto__;
+
+ assertEquals(ArrayIteratorPrototype, array.values().__proto__);
+ assertEquals(ArrayIteratorPrototype, array.keys().__proto__);
+ assertEquals(ArrayIteratorPrototype, array.entries().__proto__);
- assertEquals(Object.prototype, ArrayIterator.prototype.__proto__);
+ assertEquals(Object.prototype, ArrayIteratorPrototype.__proto__);
assertEquals('Array Iterator', %_ClassOf(array.values()));
assertEquals('Array Iterator', %_ClassOf(array.keys()));
assertEquals('Array Iterator', %_ClassOf(array.entries()));
- var prototypeDescriptor =
- Object.getOwnPropertyDescriptor(ArrayIterator, 'prototype');
- assertFalse(prototypeDescriptor.configurable);
- assertFalse(prototypeDescriptor.enumerable);
- assertFalse(prototypeDescriptor.writable);
+ assertFalse(ArrayIteratorPrototype.hasOwnProperty('constructor'));
+ assertArrayEquals(['next'],
+ Object.getOwnPropertyNames(ArrayIteratorPrototype));
+ assertHasOwnProperty(ArrayIteratorPrototype, 'next', DONT_ENUM);
+ assertHasOwnProperty(ArrayIteratorPrototype, Symbol.iterator, DONT_ENUM);
}
TestArrayIteratorPrototype();
+
function TestForArrayValues() {
var buffer = [];
var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
@@ -151,12 +176,13 @@ function TestForArrayValues() {
assertEquals(8, buffer.length);
for (var i = 0; i < buffer.length - 1; i++) {
- assertEquals(array[i], buffer[i]);
+ assertSame(array[i], buffer[i]);
}
assertTrue(isNaN(buffer[buffer.length - 1]));
}
TestForArrayValues();
+
function TestForArrayKeys() {
var buffer = [];
var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
@@ -173,6 +199,7 @@ function TestForArrayKeys() {
}
TestForArrayKeys();
+
function TestForArrayEntries() {
var buffer = [];
var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
@@ -184,7 +211,7 @@ function TestForArrayEntries() {
assertEquals(8, buffer.length);
for (var i = 0; i < buffer.length - 1; i++) {
- assertEquals(array[i], buffer[i][1]);
+ assertSame(array[i], buffer[i][1]);
}
assertTrue(isNaN(buffer[buffer.length - 1][1]));
@@ -193,3 +220,33 @@ function TestForArrayEntries() {
}
}
TestForArrayEntries();
+
+
+function TestForArray() {
+ var buffer = [];
+ var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
+ var i = 0;
+ for (var value of array) {
+ buffer[i++] = value;
+ }
+
+ assertEquals(8, buffer.length);
+
+ for (var i = 0; i < buffer.length - 1; i++) {
+ assertSame(array[i], buffer[i]);
+ }
+ assertTrue(isNaN(buffer[buffer.length - 1]));
+}
+TestForArrayValues();
+
+
+function TestNonOwnSlots() {
+ var array = [0];
+ var iterator = array.values();
+ var object = {__proto__: iterator};
+
+ assertThrows(function() {
+ object.next();
+ }, TypeError);
+}
+TestNonOwnSlots();
diff --git a/deps/v8/test/mjsunit/es6/collection-iterator.js b/deps/v8/test/mjsunit/es6/collection-iterator.js
new file mode 100644
index 000000000..5503fe58c
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/collection-iterator.js
@@ -0,0 +1,200 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+
+(function TestSetIterator() {
+ var s = new Set;
+ var iter = s.values();
+ assertEquals('Set Iterator', %_ClassOf(iter));
+
+ var SetIteratorPrototype = iter.__proto__;
+ assertFalse(SetIteratorPrototype.hasOwnProperty('constructor'));
+ assertEquals(SetIteratorPrototype.__proto__, Object.prototype);
+
+ var propertyNames = Object.getOwnPropertyNames(SetIteratorPrototype);
+ assertArrayEquals(['next'], propertyNames);
+
+ assertEquals(new Set().values().__proto__, SetIteratorPrototype);
+ assertEquals(new Set().entries().__proto__, SetIteratorPrototype);
+})();
+
+
+(function TestSetIteratorValues() {
+ var s = new Set;
+ s.add(1);
+ s.add(2);
+ s.add(3);
+ var iter = s.values();
+
+ assertEquals({value: 1, done: false}, iter.next());
+ assertEquals({value: 2, done: false}, iter.next());
+ assertEquals({value: 3, done: false}, iter.next());
+ assertEquals({value: undefined, done: true}, iter.next());
+ assertEquals({value: undefined, done: true}, iter.next());
+})();
+
+
+(function TestSetIteratorKeys() {
+ assertEquals(Set.prototype.keys, Set.prototype.values);
+})();
+
+
+(function TestSetIteratorEntries() {
+ var s = new Set;
+ s.add(1);
+ s.add(2);
+ s.add(3);
+ var iter = s.entries();
+
+ assertEquals({value: [1, 1], done: false}, iter.next());
+ assertEquals({value: [2, 2], done: false}, iter.next());
+ assertEquals({value: [3, 3], done: false}, iter.next());
+ assertEquals({value: undefined, done: true}, iter.next());
+ assertEquals({value: undefined, done: true}, iter.next());
+})();
+
+
+(function TestSetIteratorMutations() {
+ var s = new Set;
+ s.add(1);
+ var iter = s.values();
+ assertEquals({value: 1, done: false}, iter.next());
+ s.add(2);
+ s.add(3);
+ s.add(4);
+ s.add(5);
+ assertEquals({value: 2, done: false}, iter.next());
+ s.delete(3);
+ assertEquals({value: 4, done: false}, iter.next());
+ s.delete(5);
+ assertEquals({value: undefined, done: true}, iter.next());
+ s.add(4);
+ assertEquals({value: undefined, done: true}, iter.next());
+})();
+
+
+(function TestSetInvalidReceiver() {
+ assertThrows(function() {
+ Set.prototype.values.call({});
+ }, TypeError);
+ assertThrows(function() {
+ Set.prototype.entries.call({});
+ }, TypeError);
+})();
+
+
+(function TestSetIteratorInvalidReceiver() {
+ var iter = new Set().values();
+ assertThrows(function() {
+ iter.next.call({});
+ });
+})();
+
+
+(function TestSetIteratorSymbol() {
+ assertEquals(Set.prototype[Symbol.iterator], Set.prototype.values);
+ assertTrue(Set.prototype.hasOwnProperty(Symbol.iterator));
+ assertFalse(Set.prototype.propertyIsEnumerable(Symbol.iterator));
+
+ var iter = new Set().values();
+ assertEquals(iter, iter[Symbol.iterator]());
+ assertEquals(iter[Symbol.iterator].name, '[Symbol.iterator]');
+})();
+
+
+(function TestMapIterator() {
+ var m = new Map;
+ var iter = m.values();
+ assertEquals('Map Iterator', %_ClassOf(iter));
+
+ var MapIteratorPrototype = iter.__proto__;
+ assertFalse(MapIteratorPrototype.hasOwnProperty('constructor'));
+ assertEquals(MapIteratorPrototype.__proto__, Object.prototype);
+
+ var propertyNames = Object.getOwnPropertyNames(MapIteratorPrototype);
+ assertArrayEquals(['next'], propertyNames);
+
+ assertEquals(new Map().values().__proto__, MapIteratorPrototype);
+ assertEquals(new Map().keys().__proto__, MapIteratorPrototype);
+ assertEquals(new Map().entries().__proto__, MapIteratorPrototype);
+})();
+
+
+(function TestMapIteratorValues() {
+ var m = new Map;
+ m.set(1, 11);
+ m.set(2, 22);
+ m.set(3, 33);
+ var iter = m.values();
+
+ assertEquals({value: 11, done: false}, iter.next());
+ assertEquals({value: 22, done: false}, iter.next());
+ assertEquals({value: 33, done: false}, iter.next());
+ assertEquals({value: undefined, done: true}, iter.next());
+ assertEquals({value: undefined, done: true}, iter.next());
+})();
+
+
+(function TestMapIteratorKeys() {
+ var m = new Map;
+ m.set(1, 11);
+ m.set(2, 22);
+ m.set(3, 33);
+ var iter = m.keys();
+
+ assertEquals({value: 1, done: false}, iter.next());
+ assertEquals({value: 2, done: false}, iter.next());
+ assertEquals({value: 3, done: false}, iter.next());
+ assertEquals({value: undefined, done: true}, iter.next());
+ assertEquals({value: undefined, done: true}, iter.next());
+})();
+
+
+(function TestMapIteratorEntries() {
+ var m = new Map;
+ m.set(1, 11);
+ m.set(2, 22);
+ m.set(3, 33);
+ var iter = m.entries();
+
+ assertEquals({value: [1, 11], done: false}, iter.next());
+ assertEquals({value: [2, 22], done: false}, iter.next());
+ assertEquals({value: [3, 33], done: false}, iter.next());
+ assertEquals({value: undefined, done: true}, iter.next());
+ assertEquals({value: undefined, done: true}, iter.next());
+})();
+
+
+(function TestMapInvalidReceiver() {
+ assertThrows(function() {
+ Map.prototype.values.call({});
+ }, TypeError);
+ assertThrows(function() {
+ Map.prototype.keys.call({});
+ }, TypeError);
+ assertThrows(function() {
+ Map.prototype.entries.call({});
+ }, TypeError);
+})();
+
+
+(function TestMapIteratorInvalidReceiver() {
+ var iter = new Map().values();
+ assertThrows(function() {
+ iter.next.call({});
+ }, TypeError);
+})();
+
+
+(function TestMapIteratorSymbol() {
+ assertEquals(Map.prototype[Symbol.iterator], Map.prototype.entries);
+ assertTrue(Map.prototype.hasOwnProperty(Symbol.iterator));
+ assertFalse(Map.prototype.propertyIsEnumerable(Symbol.iterator));
+
+ var iter = new Map().values();
+ assertEquals(iter, iter[Symbol.iterator]());
+ assertEquals(iter[Symbol.iterator].name, '[Symbol.iterator]');
+})();
diff --git a/deps/v8/test/mjsunit/harmony/collections.js b/deps/v8/test/mjsunit/es6/collections.js
index 7bf7bf706..1e2f232ee 100644
--- a/deps/v8/test/mjsunit/harmony/collections.js
+++ b/deps/v8/test/mjsunit/es6/collections.js
@@ -25,10 +25,16 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-collections
// Flags: --expose-gc --allow-natives-syntax
+function assertSize(expected, collection) {
+ if (collection instanceof Map || collection instanceof Set) {
+ assertEquals(expected, collection.size);
+ }
+}
+
+
// Test valid getter and setter calls on Sets and WeakSets
function TestValidSetCalls(m) {
assertDoesNotThrow(function () { m.add(new Object) });
@@ -67,7 +73,7 @@ TestInvalidCalls(new WeakMap);
// Test expected behavior for Sets and WeakSets
function TestSet(set, key) {
assertFalse(set.has(key));
- assertSame(undefined, set.add(key));
+ assertSame(set, set.add(key));
assertTrue(set.has(key));
assertTrue(set.delete(key));
assertFalse(set.has(key));
@@ -92,7 +98,7 @@ TestSet(new WeakSet, new Object);
// Test expected mapping behavior for Maps and WeakMaps
function TestMapping(map, key, value) {
- assertSame(undefined, map.set(key, value));
+ assertSame(map, map.set(key, value));
assertSame(value, map.get(key));
}
function TestMapBehavior1(m) {
@@ -290,20 +296,19 @@ assertEquals("WeakSet", WeakSet.name);
// Test prototype property of Set, Map, WeakMap and WeakSet.
-// TODO(2793): Should all be non-writable, and the extra flag removed.
-function TestPrototype(C, writable) {
+function TestPrototype(C) {
assertTrue(C.prototype instanceof Object);
assertEquals({
value: {},
- writable: writable,
+ writable: false,
enumerable: false,
configurable: false
}, Object.getOwnPropertyDescriptor(C, "prototype"));
}
-TestPrototype(Set, true);
-TestPrototype(Map, true);
-TestPrototype(WeakMap, false);
-TestPrototype(WeakSet, false);
+TestPrototype(Set);
+TestPrototype(Map);
+TestPrototype(WeakMap);
+TestPrototype(WeakSet);
// Test constructor property of the Set, Map, WeakMap and WeakSet prototype.
@@ -311,6 +316,7 @@ function TestConstructor(C) {
assertFalse(C === Object.prototype.constructor);
assertSame(C, C.prototype.constructor);
assertSame(C, (new C).__proto__.constructor);
+ assertEquals(1, C.length);
}
TestConstructor(Set);
TestConstructor(Map);
@@ -852,3 +858,431 @@ for (var i = 9; i >= 0; i--) {
});
assertEquals(4950, accumulated);
})();
+
+
+(function TestMapForEachAllRemovedTransition() {
+ var map = new Map;
+ map.set(0, 0);
+
+ var buffer = [];
+ map.forEach(function(v) {
+ buffer.push(v);
+ if (v === 0) {
+ for (var i = 1; i < 4; i++) {
+ map.set(i, i);
+ }
+ }
+
+ if (v === 3) {
+ for (var i = 0; i < 4; i++) {
+ map.delete(i);
+ }
+ for (var i = 4; i < 8; i++) {
+ map.set(i, i);
+ }
+ }
+ });
+
+ assertArrayEquals([0, 1, 2, 3, 4, 5, 6, 7], buffer);
+})();
+
+
+(function TestMapForEachClearTransition() {
+ var map = new Map;
+ map.set(0, 0);
+
+ var i = 0;
+ var buffer = [];
+ map.forEach(function(v) {
+ buffer.push(v);
+ if (++i < 5) {
+ for (var j = 0; j < 5; j++) {
+ map.clear();
+ map.set(i, i);
+ }
+ }
+ });
+
+ assertArrayEquals([0, 1, 2, 3, 4], buffer);
+})();
+
+
+(function TestMapForEachNestedNonTrivialTransition() {
+ var map = new Map;
+ map.set(0, 0);
+ map.set(1, 1);
+ map.set(2, 2);
+ map.set(3, 3);
+ map.delete(0);
+
+ var i = 0;
+ var buffer = [];
+ map.forEach(function(v) {
+ if (++i > 10) return;
+
+ buffer.push(v);
+
+ if (v == 3) {
+ map.delete(1);
+ for (var j = 4; j < 10; j++) {
+ map.set(j, j);
+ }
+ for (var j = 4; j < 10; j += 2) {
+ map.delete(j);
+ }
+ map.delete(2);
+
+ for (var j = 10; j < 20; j++) {
+ map.set(j, j);
+ }
+ for (var j = 10; j < 20; j += 2) {
+ map.delete(j);
+ }
+
+ map.delete(3);
+ }
+ });
+
+ assertArrayEquals([1, 2, 3, 5, 7, 9, 11, 13, 15, 17], buffer);
+})();
+
+
+(function TestMapForEachAllRemovedTransitionNoClear() {
+ var map = new Map;
+ map.set(0, 0);
+
+ var buffer = [];
+ map.forEach(function(v) {
+ buffer.push(v);
+ if (v === 0) {
+ for (var i = 1; i < 8; i++) {
+ map.set(i, i);
+ }
+ }
+
+ if (v === 4) {
+ for (var i = 0; i < 8; i++) {
+ map.delete(i);
+ }
+ }
+ });
+
+ assertArrayEquals([0, 1, 2, 3, 4], buffer);
+})();
+
+
+(function TestMapForEachNoMoreElementsAfterTransition() {
+ var map = new Map;
+ map.set(0, 0);
+
+ var buffer = [];
+ map.forEach(function(v) {
+ buffer.push(v);
+ if (v === 0) {
+ for (var i = 1; i < 16; i++) {
+ map.set(i, i);
+ }
+ }
+
+ if (v === 4) {
+ for (var i = 5; i < 16; i++) {
+ map.delete(i);
+ }
+ }
+ });
+
+ assertArrayEquals([0, 1, 2, 3, 4], buffer);
+})();
+
+
+// Allows testing iterator-based constructors easily.
+var oneAndTwo = new Map();
+var k0 = {key: 0};
+var k1 = {key: 1};
+var k2 = {key: 2};
+oneAndTwo.set(k1, 1);
+oneAndTwo.set(k2, 2);
+
+
+function TestSetConstructor(ctor) {
+ var s = new ctor(null);
+ assertSize(0, s);
+
+ s = new ctor(undefined);
+ assertSize(0, s);
+
+ // No @@iterator
+ assertThrows(function() {
+ new ctor({});
+ }, TypeError);
+
+ // @@iterator not callable
+ assertThrows(function() {
+ var object = {};
+ object[Symbol.iterator] = 42;
+ new ctor(object);
+ }, TypeError);
+
+ // @@iterator result not object
+ assertThrows(function() {
+ var object = {};
+ object[Symbol.iterator] = function() {
+ return 42;
+ };
+ new ctor(object);
+ }, TypeError);
+
+ var s2 = new Set();
+ s2.add(k0);
+ s2.add(k1);
+ s2.add(k2);
+ s = new ctor(s2.values());
+ assertSize(3, s);
+ assertTrue(s.has(k0));
+ assertTrue(s.has(k1));
+ assertTrue(s.has(k2));
+}
+TestSetConstructor(Set);
+TestSetConstructor(WeakSet);
+
+
+function TestSetConstructorAddNotCallable(ctor) {
+ var originalPrototypeAdd = ctor.prototype.add;
+ assertThrows(function() {
+ ctor.prototype.add = 42;
+ new ctor(oneAndTwo.values());
+ }, TypeError);
+ ctor.prototype.add = originalPrototypeAdd;
+}
+TestSetConstructorAddNotCallable(Set);
+TestSetConstructorAddNotCallable(WeakSet);
+
+
+function TestSetConstructorGetAddOnce(ctor) {
+ var originalPrototypeAdd = ctor.prototype.add;
+ var getAddCount = 0;
+ Object.defineProperty(ctor.prototype, 'add', {
+ get: function() {
+ getAddCount++;
+ return function() {};
+ }
+ });
+ var s = new ctor(oneAndTwo.values());
+ assertEquals(1, getAddCount);
+ assertSize(0, s);
+ Object.defineProperty(ctor.prototype, 'add', {
+ value: originalPrototypeAdd,
+ writable: true
+ });
+}
+TestSetConstructorGetAddOnce(Set);
+TestSetConstructorGetAddOnce(WeakSet);
+
+
+function TestSetConstructorAddReplaced(ctor) {
+ var originalPrototypeAdd = ctor.prototype.add;
+ var addCount = 0;
+ ctor.prototype.add = function(value) {
+ addCount++;
+ originalPrototypeAdd.call(this, value);
+ ctor.prototype.add = null;
+ };
+ var s = new ctor(oneAndTwo.keys());
+ assertEquals(2, addCount);
+ assertSize(2, s);
+ ctor.prototype.add = originalPrototypeAdd;
+}
+TestSetConstructorAddReplaced(Set);
+TestSetConstructorAddReplaced(WeakSet);
+
+
+function TestSetConstructorOrderOfDoneValue(ctor) {
+ var valueCount = 0, doneCount = 0;
+ var iterator = {
+ next: function() {
+ return {
+ get value() {
+ valueCount++;
+ },
+ get done() {
+ doneCount++;
+ throw new Error();
+ }
+ };
+ }
+ };
+ iterator[Symbol.iterator] = function() {
+ return this;
+ };
+ assertThrows(function() {
+ new ctor(iterator);
+ });
+ assertEquals(1, doneCount);
+ assertEquals(0, valueCount);
+}
+TestSetConstructorOrderOfDoneValue(Set);
+TestSetConstructorOrderOfDoneValue(WeakSet);
+
+
+function TestSetConstructorNextNotAnObject(ctor) {
+ var iterator = {
+ next: function() {
+ return 'abc';
+ }
+ };
+ iterator[Symbol.iterator] = function() {
+ return this;
+ };
+ assertThrows(function() {
+ new ctor(iterator);
+ }, TypeError);
+}
+TestSetConstructorNextNotAnObject(Set);
+TestSetConstructorNextNotAnObject(WeakSet);
+
+
+function TestMapConstructor(ctor) {
+ var m = new ctor(null);
+ assertSize(0, m);
+
+ m = new ctor(undefined);
+ assertSize(0, m);
+
+ // No @@iterator
+ assertThrows(function() {
+ new ctor({});
+ }, TypeError);
+
+ // @@iterator not callable
+ assertThrows(function() {
+ var object = {};
+ object[Symbol.iterator] = 42;
+ new ctor(object);
+ }, TypeError);
+
+ // @@iterator result not object
+ assertThrows(function() {
+ var object = {};
+ object[Symbol.iterator] = function() {
+ return 42;
+ };
+ new ctor(object);
+ }, TypeError);
+
+ var m2 = new Map();
+ m2.set(k0, 'a');
+ m2.set(k1, 'b');
+ m2.set(k2, 'c');
+ m = new ctor(m2.entries());
+ assertSize(3, m);
+ assertEquals('a', m.get(k0));
+ assertEquals('b', m.get(k1));
+ assertEquals('c', m.get(k2));
+}
+TestMapConstructor(Map);
+TestMapConstructor(WeakMap);
+
+
+function TestMapConstructorSetNotCallable(ctor) {
+ var originalPrototypeSet = ctor.prototype.set;
+ assertThrows(function() {
+ ctor.prototype.set = 42;
+ new ctor(oneAndTwo.entries());
+ }, TypeError);
+ ctor.prototype.set = originalPrototypeSet;
+}
+TestMapConstructorSetNotCallable(Map);
+TestMapConstructorSetNotCallable(WeakMap);
+
+
+function TestMapConstructorGetAddOnce(ctor) {
+ var originalPrototypeSet = ctor.prototype.set;
+ var getSetCount = 0;
+ Object.defineProperty(ctor.prototype, 'set', {
+ get: function() {
+ getSetCount++;
+ return function() {};
+ }
+ });
+ var m = new ctor(oneAndTwo.entries());
+ assertEquals(1, getSetCount);
+ assertSize(0, m);
+ Object.defineProperty(ctor.prototype, 'set', {
+ value: originalPrototypeSet,
+ writable: true
+ });
+}
+TestMapConstructorGetAddOnce(Map);
+TestMapConstructorGetAddOnce(WeakMap);
+
+
+function TestMapConstructorSetReplaced(ctor) {
+ var originalPrototypeSet = ctor.prototype.set;
+ var setCount = 0;
+ ctor.prototype.set = function(key, value) {
+ setCount++;
+ originalPrototypeSet.call(this, key, value);
+ ctor.prototype.set = null;
+ };
+ var m = new ctor(oneAndTwo.entries());
+ assertEquals(2, setCount);
+ assertSize(2, m);
+ ctor.prototype.set = originalPrototypeSet;
+}
+TestMapConstructorSetReplaced(Map);
+TestMapConstructorSetReplaced(WeakMap);
+
+
+function TestMapConstructorOrderOfDoneValue(ctor) {
+ var valueCount = 0, doneCount = 0;
+ function FakeError() {}
+ var iterator = {
+ next: function() {
+ return {
+ get value() {
+ valueCount++;
+ },
+ get done() {
+ doneCount++;
+ throw new FakeError();
+ }
+ };
+ }
+ };
+ iterator[Symbol.iterator] = function() {
+ return this;
+ };
+ assertThrows(function() {
+ new ctor(iterator);
+ }, FakeError);
+ assertEquals(1, doneCount);
+ assertEquals(0, valueCount);
+}
+TestMapConstructorOrderOfDoneValue(Map);
+TestMapConstructorOrderOfDoneValue(WeakMap);
+
+
+function TestMapConstructorNextNotAnObject(ctor) {
+ var iterator = {
+ next: function() {
+ return 'abc';
+ }
+ };
+ iterator[Symbol.iterator] = function() {
+ return this;
+ };
+ assertThrows(function() {
+ new ctor(iterator);
+ }, TypeError);
+}
+TestMapConstructorNextNotAnObject(Map);
+TestMapConstructorNextNotAnObject(WeakMap);
+
+
+function TestMapConstructorIteratorNotObjectValues(ctor) {
+ assertThrows(function() {
+ new ctor(oneAndTwo.values());
+ }, TypeError);
+}
+TestMapConstructorIteratorNotObjectValues(Map);
+TestMapConstructorIteratorNotObjectValues(WeakMap);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises-throw-in-reject.js b/deps/v8/test/mjsunit/es6/debug-promises-throw-in-reject.js
deleted file mode 100644
index cdf759606..000000000
--- a/deps/v8/test/mjsunit/es6/debug-promises-throw-in-reject.js
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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.
-
-// Flags: --harmony-promises --expose-debug-as debug
-
-// Test debug events when an exception is thrown inside a Promise, which is
-// caught by a custom promise, which throws a new exception in its reject
-// handler. We expect an Exception debug event with a promise to be triggered.
-
-Debug = debug.Debug;
-
-var log = [];
-var step = 0;
-
-var p = new Promise(function(resolve, reject) {
- log.push("resolve");
- resolve();
-});
-
-function MyPromise(resolver) {
- var reject = function() {
- log.push("throw reject");
- throw new Error("reject"); // event
- };
- var resolve = function() { };
- log.push("construct");
- resolver(resolve, reject);
-};
-
-MyPromise.prototype = p;
-p.constructor = MyPromise;
-
-var q = p.chain(
- function() {
- log.push("throw caught");
- throw new Error("caught");
- });
-
-function listener(event, exec_state, event_data, data) {
- try {
- if (event == Debug.DebugEvent.Exception) {
- assertEquals(["resolve", "construct", "end main",
- "throw caught", "throw reject"], log);
- assertEquals("reject", event_data.exception().message);
- assertEquals(q, event_data.promise());
- assertTrue(exec_state.frame(0).sourceLineText().indexOf('// event') > 0);
- }
- } catch (e) {
- // Signal a failure with exit code 1. This is necessary since the
- // debugger swallows exceptions and we expect the chained function
- // and this listener to be executed after the main script is finished.
- print("Unexpected exception: " + e + "\n" + e.stack);
- quit(1);
- }
-}
-
-Debug.setBreakOnUncaughtException();
-Debug.setListener(listener);
-
-log.push("end main");
diff --git a/deps/v8/test/mjsunit/es6/debug-promises-undefined-reject.js b/deps/v8/test/mjsunit/es6/debug-promises-undefined-reject.js
deleted file mode 100644
index 5bad5bd37..000000000
--- a/deps/v8/test/mjsunit/es6/debug-promises-undefined-reject.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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.
-
-// Flags: --harmony-promises --expose-debug-as debug
-
-// Test debug events when an exception is thrown inside a Promise, which is
-// caught by a custom promise, which has no reject handler.
-// We expect an Exception event with a promise to be triggered.
-
-Debug = debug.Debug;
-
-var log = [];
-var step = 0;
-
-var p = new Promise(function(resolve, reject) {
- log.push("resolve");
- resolve();
-});
-
-function MyPromise(resolver) {
- var reject = undefined;
- var resolve = function() { };
- log.push("construct");
- resolver(resolve, reject);
-};
-
-MyPromise.prototype = p;
-p.constructor = MyPromise;
-
-var q = p.chain(
- function() {
- log.push("throw caught");
- throw new Error("caught"); // event
- });
-
-function listener(event, exec_state, event_data, data) {
- try {
- if (event == Debug.DebugEvent.Exception) {
- assertEquals(["resolve", "construct", "end main", "throw caught"], log);
- assertEquals("undefined is not a function",
- event_data.exception().message);
- assertEquals(q, event_data.promise());
- }
- } catch (e) {
- // Signal a failure with exit code 1. This is necessary since the
- // debugger swallows exceptions and we expect the chained function
- // and this listener to be executed after the main script is finished.
- print("Unexpected exception: " + e + "\n" + e.stack);
- quit(1);
- }
-}
-
-Debug.setBreakOnUncaughtException();
-Debug.setListener(listener);
-
-log.push("end main");
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/async-task-event.js b/deps/v8/test/mjsunit/es6/debug-promises/async-task-event.js
new file mode 100644
index 000000000..88030a2e7
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/async-task-event.js
@@ -0,0 +1,61 @@
+// 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.
+
+// Flags: --expose-debug-as debug
+
+Debug = debug.Debug;
+
+var base_id = -1;
+var exception = null;
+var expected = [
+ "enqueue #1",
+ "willHandle #1",
+ "then #1",
+ "enqueue #2",
+ "didHandle #1",
+ "willHandle #2",
+ "then #2",
+ "enqueue #3",
+ "didHandle #2",
+ "willHandle #3",
+ "didHandle #3"
+];
+
+function assertLog(msg) {
+ print(msg);
+ assertTrue(expected.length > 0);
+ assertEquals(expected.shift(), msg);
+ if (!expected.length) {
+ Debug.setListener(null);
+ }
+}
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.AsyncTaskEvent) return;
+ try {
+ if (base_id < 0)
+ base_id = event_data.id();
+ var id = event_data.id() - base_id + 1;
+ assertEquals("Promise.resolve", event_data.name());
+ assertLog(event_data.type() + " #" + id);
+ } catch (e) {
+ print(e + e.stack)
+ exception = e;
+ }
+}
+
+Debug.setListener(listener);
+
+var resolver;
+var p = new Promise(function(resolve, reject) {
+ resolver = resolve;
+});
+p.then(function() {
+ assertLog("then #1");
+}).then(function() {
+ assertLog("then #2");
+});
+resolver();
+
+assertNull(exception);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/events.js b/deps/v8/test/mjsunit/es6/debug-promises/events.js
new file mode 100644
index 000000000..a9f94543f
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/events.js
@@ -0,0 +1,124 @@
+// 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.
+
+// Flags: --allow-natives-syntax --expose-debug-as debug
+
+Debug = debug.Debug;
+
+var eventsExpected = 16;
+var exception = null;
+var result = [];
+
+function updatePromise(promise, parentPromise, status, value) {
+ var i;
+ for (i = 0; i < result.length; ++i) {
+ if (result[i].promise === promise) {
+ result[i].parentPromise = parentPromise || result[i].parentPromise;
+ result[i].status = status || result[i].status;
+ result[i].value = value || result[i].value;
+ break;
+ }
+ }
+ assertTrue(i < result.length);
+}
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.PromiseEvent) return;
+ try {
+ eventsExpected--;
+ assertTrue(event_data.promise().isPromise());
+ if (event_data.status() === 0) {
+ // New promise.
+ assertEquals("pending", event_data.promise().status());
+ result.push({ promise: event_data.promise().value(), status: 0 });
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
+ } else if (event_data.status() !== undefined) {
+ // Resolve/reject promise.
+ updatePromise(event_data.promise().value(),
+ undefined,
+ event_data.status(),
+ event_data.value().value());
+ } else {
+ // Chain promises.
+ assertTrue(event_data.parentPromise().isPromise());
+ updatePromise(event_data.promise().value(),
+ event_data.parentPromise().value());
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
+ }
+ } catch (e) {
+ print(e + e.stack)
+ exception = e;
+ }
+}
+
+Debug.setListener(listener);
+
+function resolver(resolve, reject) { resolve(); }
+
+var p1 = new Promise(resolver); // event
+var p2 = p1.then().then(); // event
+var p3 = new Promise(function(resolve, reject) { // event
+ reject("rejected");
+});
+var p4 = p3.then(); // event
+var p5 = p1.then(); // event
+
+function assertAsync(b, s) {
+ if (b) {
+ print(s, "succeeded");
+ } else {
+ %AbortJS(s + " FAILED!");
+ }
+}
+
+function testDone(iteration) {
+ function checkResult() {
+ if (eventsExpected === 0) {
+ assertAsync(result.length === 6, "result.length");
+
+ assertAsync(result[0].promise === p1, "result[0].promise");
+ assertAsync(result[0].parentPromise === undefined,
+ "result[0].parentPromise");
+ assertAsync(result[0].status === 1, "result[0].status");
+ assertAsync(result[0].value === undefined, "result[0].value");
+
+ assertAsync(result[1].parentPromise === p1,
+ "result[1].parentPromise");
+ assertAsync(result[1].status === 1, "result[1].status");
+
+ assertAsync(result[2].promise === p2, "result[2].promise");
+
+ assertAsync(result[3].promise === p3, "result[3].promise");
+ assertAsync(result[3].parentPromise === undefined,
+ "result[3].parentPromise");
+ assertAsync(result[3].status === -1, "result[3].status");
+ assertAsync(result[3].value === "rejected", "result[3].value");
+
+ assertAsync(result[4].promise === p4, "result[4].promise");
+ assertAsync(result[4].parentPromise === p3,
+ "result[4].parentPromise");
+ assertAsync(result[4].status === -1, "result[4].status");
+ assertAsync(result[4].value === "rejected", "result[4].value");
+
+ assertAsync(result[5].promise === p5, "result[5].promise");
+ assertAsync(result[5].parentPromise === p1,
+ "result[5].parentPromise");
+ assertAsync(result[5].status === 1, "result[5].status");
+
+ assertAsync(exception === null, "exception === null");
+ Debug.setListener(null);
+ } else if (iteration > 10) {
+ %AbortJS("Not all events were received!");
+ } else {
+ testDone(iteration + 1);
+ }
+ }
+
+ var iteration = iteration || 0;
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone();
diff --git a/deps/v8/test/mjsunit/es6/debug-promises-reentry.js b/deps/v8/test/mjsunit/es6/debug-promises/reentry.js
index 03c7fc2c8..fbe54242d 100644
--- a/deps/v8/test/mjsunit/es6/debug-promises-reentry.js
+++ b/deps/v8/test/mjsunit/es6/debug-promises/reentry.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-promises --expose-debug-as debug
+// Flags: --expose-debug-as debug
// Test reentry of special try catch for Promises.
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-after-resolve.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-after-resolve.js
new file mode 100644
index 000000000..a0036cfd0
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-after-resolve.js
@@ -0,0 +1,37 @@
+// 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we listen to uncaught exceptions and
+// the Promise is rejected in a chained closure after it has been resolved.
+// We expect no Exception debug event to be triggered.
+
+Debug = debug.Debug;
+
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve(reject);
+});
+
+var q = p.chain(
+ function(value) {
+ assertEquals(["resolve", "end main"], log);
+ value(new Error("reject"));
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ assertTrue(event != Debug.DebugEvent.Exception);
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnException();
+Debug.setListener(listener);
+
+log.push("end main");
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-all.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-all.js
new file mode 100644
index 000000000..0fca57730
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-all.js
@@ -0,0 +1,72 @@
+// 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we listen to all exceptions and
+// there is a catch handler for the to-be-rejected Promise.
+// We expect a normal Exception debug event to be triggered.
+
+Debug = debug.Debug;
+
+var log = [];
+var expected_events = 1;
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+var q = p.chain(
+ function(value) {
+ log.push("reject");
+ return Promise.reject(new Error("reject"));
+ });
+
+q.catch(
+ function(e) {
+ assertEquals("reject", e.message);
+ });
+
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("reject", event_data.exception().message);
+ assertSame(q, event_data.promise());
+ assertFalse(event_data.uncaught());
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "end main", "reject"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-late.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-late.js
new file mode 100644
index 000000000..2ff13d560
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-late.js
@@ -0,0 +1,34 @@
+// 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we only listen to uncaught exceptions, the Promise
+// is rejected, and a catch handler is installed right before the rejection.
+// We expect no debug event to be triggered.
+
+Debug = debug.Debug;
+
+var p = new Promise(function(resolve, reject) {
+ resolve();
+});
+
+var q = p.chain(
+ function() {
+ q.catch(function(e) {
+ assertEquals("caught", e.message);
+ });
+ return Promise.reject(Error("caught"));
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ assertTrue(event != Debug.DebugEvent.Exception);
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-uncaught.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-uncaught.js
new file mode 100644
index 000000000..d3fd9f3ae
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-uncaught.js
@@ -0,0 +1,36 @@
+// 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we only listen to uncaught exceptions and
+// there is a catch handler for the to-be-rejected Promise.
+// We expect no debug event to be triggered.
+
+Debug = debug.Debug;
+
+var p = new Promise(function(resolve, reject) {
+ resolve();
+});
+
+var q = p.chain(
+ function() {
+ return Promise.reject(Error("caught reject"));
+ });
+
+q.catch(
+ function(e) {
+ assertEquals("caught reject", e.message);
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ assertTrue(event != Debug.DebugEvent.Exception);
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-in-constructor.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-in-constructor.js
new file mode 100644
index 000000000..a05b3ac5d
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-in-constructor.js
@@ -0,0 +1,39 @@
+// 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.
+
+// Flags: --expose-debug-as debug
+
+// Test debug events when we only listen to uncaught exceptions and
+// the Promise is rejected in the Promise constructor.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var steps = 0;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ steps++;
+ assertEquals("uncaught", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertTrue(event_data.uncaught());
+ // Assert that the debug event is triggered at the throw site.
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
+ }
+ } catch (e) {
+ exception = e;
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+var p = new Promise(function(resolve, reject) {
+ reject(new Error("uncaught")); // event
+});
+
+assertEquals(1, steps);
+assertNull(exception);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-all.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-all.js
new file mode 100644
index 000000000..beaf1878f
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-all.js
@@ -0,0 +1,69 @@
+// 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we listen to all exceptions and
+// there is a catch handler for the to-be-rejected Promise.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+var q = p.chain(
+ function() {
+ log.push("reject");
+ return Promise.reject(new Error("uncaught reject"));
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("uncaught reject", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertSame(q, event_data.promise());
+ assertTrue(event_data.uncaught());
+ // All of the frames on the stack are from native Javascript.
+ assertEquals(0, exec_state.frameCount());
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "end main", "reject"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-late.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-late.js
new file mode 100644
index 000000000..4a883da13
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-late.js
@@ -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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we only listen to uncaught exceptions and
+// there is a catch handler for the to-be-rejected Promise.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var reject_closure;
+
+var p = new Promise(function(resolve, reject) {
+ log.push("postpone p");
+ reject_closure = reject;
+});
+
+var q = new Promise(function(resolve, reject) {
+ log.push("resolve q");
+ resolve();
+});
+
+q.then(function() {
+ log.push("reject p");
+ reject_closure(new Error("uncaught reject p")); // event
+})
+
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("uncaught reject p", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertSame(p, event_data.promise());
+ assertTrue(event_data.uncaught());
+ // Assert that the debug event is triggered at the throw site.
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["postpone p", "resolve q", "end main", "reject p"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js
new file mode 100644
index 000000000..86e2a815e
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js
@@ -0,0 +1,69 @@
+// 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we only listen to uncaught exceptions and
+// there is no catch handler for the to-be-rejected Promise.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+var q = p.chain(
+ function() {
+ log.push("reject");
+ return Promise.reject(Error("uncaught reject")); // event
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("uncaught reject", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertSame(q, event_data.promise());
+ assertTrue(event_data.uncaught());
+ // All of the frames on the stack are from native Javascript.
+ assertEquals(0, exec_state.frameCount());
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "end main", "reject"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js
new file mode 100644
index 000000000..fc6233da8
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js
@@ -0,0 +1,77 @@
+// 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when a Promise is rejected, which is caught by a custom
+// promise, which has a number for reject closure. We expect an Exception debug
+// events trying to call the invalid reject closure.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+function MyPromise(resolver) {
+ var reject = 1;
+ var resolve = function() { };
+ log.push("construct");
+ resolver(resolve, reject);
+};
+
+MyPromise.prototype = new Promise(function() {});
+p.constructor = MyPromise;
+
+var q = p.chain(
+ function() {
+ log.push("reject caught");
+ return Promise.reject(new Error("caught"));
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("number is not a function", event_data.exception().message);
+ // All of the frames on the stack are from native Javascript.
+ assertEquals(0, exec_state.frameCount());
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "construct", "end main", "reject caught"],
+ log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
+
+log.push("end main");
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js
new file mode 100644
index 000000000..15e464ec6
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js
@@ -0,0 +1,87 @@
+// 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when a Promise is rejected, which is caught by a
+// custom promise, which throws a new exception in its reject handler.
+// We expect two Exception debug events:
+// 1) when promise q is rejected.
+// 2) when the custom reject closure in MyPromise throws an exception.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+function MyPromise(resolver) {
+ var reject = function() {
+ log.push("throw in reject");
+ throw new Error("reject"); // event
+ };
+ var resolve = function() { };
+ log.push("construct");
+ resolver(resolve, reject);
+};
+
+MyPromise.prototype = new Promise(function() {});
+p.constructor = MyPromise;
+
+var q = p.chain(
+ function() {
+ log.push("reject caught");
+ return Promise.reject(new Error("caught"));
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("reject", event_data.exception().message);
+ // Assert that the debug event is triggered at the throw site.
+ assertTrue(
+ exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
+ }
+ } catch (e) {
+ // Signal a failure with exit code 1. This is necessary since the
+ // debugger swallows exceptions and we expect the chained function
+ // and this listener to be executed after the main script is finished.
+ print("Unexpected exception: " + e + "\n" + e.stack);
+ quit(1);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "construct", "end main",
+ "reject caught", "throw in reject"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js
new file mode 100644
index 000000000..d11c01ff7
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js
@@ -0,0 +1,77 @@
+// 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when a Promise is rejected, which is caught by a custom
+// promise, which has undefined for reject closure. We expect an Exception
+// debug even calling the (undefined) custom rejected closure.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+function MyPromise(resolver) {
+ var reject = undefined;
+ var resolve = function() { };
+ log.push("construct");
+ resolver(resolve, reject);
+};
+
+MyPromise.prototype = new Promise(function() {});
+p.constructor = MyPromise;
+
+var q = p.chain(
+ function() {
+ log.push("reject caught");
+ return Promise.reject(new Error("caught"));
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("caught", event_data.exception().message);
+ // All of the frames on the stack are from native Javascript.
+ assertEquals(0, exec_state.frameCount());
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "construct", "end main", "reject caught"],
+ log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
+
+log.push("end main");
diff --git a/deps/v8/test/mjsunit/es6/debug-promises-caught-all.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-all.js
index 5189373e1..2fbf05141 100644
--- a/deps/v8/test/mjsunit/es6/debug-promises-caught-all.js
+++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-all.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-promises --expose-debug-as debug
+// Flags: --expose-debug-as debug --allow-natives-syntax
// Test debug events when we listen to all exceptions and
// there is a catch handler for the exception thrown in a Promise.
@@ -10,8 +10,8 @@
Debug = debug.Debug;
+var expected_events = 1;
var log = [];
-var step = 0;
var p = new Promise(function(resolve, reject) {
log.push("resolve");
@@ -31,21 +31,15 @@ q.catch(
function listener(event, exec_state, event_data, data) {
try {
- // Ignore exceptions during startup in stress runs.
- if (step >= 1) return;
- assertEquals(["resolve", "end main", "throw"], log);
if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
assertEquals("caught", event_data.exception().message);
- assertEquals(undefined, event_data.promise());
+ assertSame(q, event_data.promise());
assertFalse(event_data.uncaught());
- step++;
}
} catch (e) {
- // Signal a failure with exit code 1. This is necessary since the
- // debugger swallows exceptions and we expect the chained function
- // and this listener to be executed after the main script is finished.
- print("Unexpected exception: " + e + "\n" + e.stack);
- quit(1);
+ %AbortJS(e + "\n" + e.stack);
}
}
@@ -53,3 +47,25 @@ Debug.setBreakOnException();
Debug.setListener(listener);
log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "end main", "throw"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises-caught-late.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-late.js
index 66e073d4a..ac79aba76 100644
--- a/deps/v8/test/mjsunit/es6/debug-promises-caught-late.js
+++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-late.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-promises --expose-debug-as debug
+// Flags: --expose-debug-as debug --allow-natives-syntax
// Test debug events when we only listen to uncaught exceptions, the Promise
// throws, and a catch handler is installed right before throwing.
@@ -26,11 +26,7 @@ function listener(event, exec_state, event_data, data) {
try {
assertTrue(event != Debug.DebugEvent.Exception);
} catch (e) {
- // Signal a failure with exit code 1. This is necessary since the
- // debugger swallows exceptions and we expect the chained function
- // and this listener to be executed after the main script is finished.
- print("Unexpected exception: " + e + "\n" + e.stack);
- quit(1);
+ %AbortJS(e + "\n" + e.stack);
}
}
diff --git a/deps/v8/test/mjsunit/es6/debug-promises-caught-uncaught.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-uncaught.js
index 9620d31bd..0ad9ce48a 100644
--- a/deps/v8/test/mjsunit/es6/debug-promises-caught-uncaught.js
+++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-uncaught.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-promises --expose-debug-as debug
+// Flags: --expose-debug-as debug --allow-natives-syntax
// Test debug events when we only listen to uncaught exceptions and
// there is a catch handler for the exception thrown in a Promise.
@@ -16,23 +16,19 @@ var p = new Promise(function(resolve, reject) {
var q = p.chain(
function() {
- throw new Error("caught");
+ throw new Error("caught throw");
});
q.catch(
function(e) {
- assertEquals("caught", e.message);
+ assertEquals("caught throw", e.message);
});
function listener(event, exec_state, event_data, data) {
try {
assertTrue(event != Debug.DebugEvent.Exception);
} catch (e) {
- // Signal a failure with exit code 1. This is necessary since the
- // debugger swallows exceptions and we expect the chained function
- // and this listener to be executed after the main script is finished.
- print("Unexpected exception: " + e + "\n" + e.stack);
- quit(1);
+ %AbortJS(e + "\n" + e.stack);
}
}
diff --git a/deps/v8/test/mjsunit/es6/debug-promises-throw-in-constructor.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-in-constructor.js
index d0267cefb..fd6b4dd34 100644
--- a/deps/v8/test/mjsunit/es6/debug-promises-throw-in-constructor.js
+++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-in-constructor.js
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-promises --expose-debug-as debug
+// Flags: --expose-debug-as debug
// Test debug events when we only listen to uncaught exceptions and
-// an exception is thrown in the the Promise constructor.
+// an exception is thrown in the Promise constructor.
// We expect an Exception debug event with a promise to be triggered.
Debug = debug.Debug;
@@ -15,8 +15,6 @@ var exception = null;
function listener(event, exec_state, event_data, data) {
try {
- // Ignore exceptions during startup in stress runs.
- if (step >= 1) return;
if (event == Debug.DebugEvent.Exception) {
assertEquals(0, step);
assertEquals("uncaught", event_data.exception().message);
@@ -27,10 +25,6 @@ function listener(event, exec_state, event_data, data) {
step++;
}
} catch (e) {
- // Signal a failure with exit code 1. This is necessary since the
- // debugger swallows exceptions and we expect the chained function
- // and this listener to be executed after the main script is finished.
- print("Unexpected exception: " + e + "\n" + e.stack);
exception = e;
}
}
diff --git a/deps/v8/test/mjsunit/es6/debug-promises-uncaught-all.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-all.js
index 714e7da9c..72f800bf5 100644
--- a/deps/v8/test/mjsunit/es6/debug-promises-uncaught-all.js
+++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-all.js
@@ -2,17 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-promises --expose-debug-as debug
+// Flags: --expose-debug-as debug --allow-natives-syntax
// Test debug events when we listen to all exceptions and
-// there is a catch handler for the exception thrown in a Promise.
+// there is no catch handler for the exception thrown in a Promise.
// We expect an Exception debug event with a promise to be triggered.
Debug = debug.Debug;
+var expected_events = 1;
var log = [];
-var step = 0;
-var exception = undefined;
var p = new Promise(function(resolve, reject) {
log.push("resolve");
@@ -28,24 +27,18 @@ var q = p.chain(
function listener(event, exec_state, event_data, data) {
try {
// Ignore exceptions during startup in stress runs.
- if (step >= 1) return;
- assertEquals(["resolve", "end main", "throw"], log);
if (event == Debug.DebugEvent.Exception) {
- assertEquals(0, step);
+ expected_events--;
+ assertTrue(expected_events >= 0);
assertEquals("uncaught", event_data.exception().message);
assertTrue(event_data.promise() instanceof Promise);
- assertEquals(q, event_data.promise());
+ assertSame(q, event_data.promise());
assertTrue(event_data.uncaught());
// Assert that the debug event is triggered at the throw site.
assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
- step++;
}
} catch (e) {
- // Signal a failure with exit code 1. This is necessary since the
- // debugger swallows exceptions and we expect the chained function
- // and this listener to be executed after the main script is finished.
- print("Unexpected exception: " + e + "\n" + e.stack);
- quit(1);
+ %AbortJS(e + "\n" + e.stack);
}
}
@@ -53,3 +46,25 @@ Debug.setBreakOnException();
Debug.setListener(listener);
log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "end main", "throw"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Rerun testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises-uncaught-uncaught.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-uncaught.js
index fa97ac0d8..69aa8ebbd 100644
--- a/deps/v8/test/mjsunit/es6/debug-promises-uncaught-uncaught.js
+++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-uncaught.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-promises --expose-debug-as debug
+// Flags: --expose-debug-as debug --allow-natives-syntax
// Test debug events when we only listen to uncaught exceptions and
// there is a catch handler for the exception thrown in a Promise.
@@ -10,8 +10,8 @@
Debug = debug.Debug;
+var expected_events = 1;
var log = [];
-var step = 0;
var p = new Promise(function(resolve, reject) {
log.push("resolve");
@@ -25,26 +25,20 @@ var q = p.chain(
});
function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.AsyncTaskEvent) return;
try {
- // Ignore exceptions during startup in stress runs.
- if (step >= 1) return;
- assertEquals(["resolve", "end main", "throw"], log);
if (event == Debug.DebugEvent.Exception) {
- assertEquals(0, step);
+ expected_events--;
+ assertTrue(expected_events >= 0);
assertEquals("uncaught", event_data.exception().message);
assertTrue(event_data.promise() instanceof Promise);
- assertEquals(q, event_data.promise());
+ assertSame(q, event_data.promise());
assertTrue(event_data.uncaught());
// Assert that the debug event is triggered at the throw site.
assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
- step++;
}
} catch (e) {
- // Signal a failure with exit code 1. This is necessary since the
- // debugger swallows exceptions and we expect the chained function
- // and this listener to be executed after the main script is finished.
- print("Unexpected exception: " + e + "\n" + e.stack);
- quit(1);
+ %AbortJS(e + "\n" + e.stack);
}
}
@@ -52,3 +46,25 @@ Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "end main", "throw"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js
new file mode 100644
index 000000000..1ea1c7f9f
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js
@@ -0,0 +1,90 @@
+// 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when an exception is thrown inside a Promise, which is
+// caught by a custom promise, which throws a new exception in its reject
+// handler. We expect two Exception debug events:
+// 1) when the exception is thrown in the promise q.
+// 2) when the custom reject closure in MyPromise throws an exception.
+
+Debug = debug.Debug;
+
+var expected_events = 2;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+function MyPromise(resolver) {
+ var reject = function() {
+ log.push("throw in reject");
+ throw new Error("reject"); // event
+ };
+ var resolve = function() { };
+ log.push("construct");
+ resolver(resolve, reject);
+};
+
+MyPromise.prototype = new Promise(function() {});
+p.constructor = MyPromise;
+
+var q = p.chain(
+ function() {
+ log.push("throw caught");
+ throw new Error("caught"); // event
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ if (expected_events == 1) {
+ assertEquals(["resolve", "construct", "end main",
+ "throw caught"], log);
+ assertEquals("caught", event_data.exception().message);
+ } else if (expected_events == 0) {
+ assertEquals("reject", event_data.exception().message);
+ } else {
+ assertUnreachable();
+ }
+ assertSame(q, event_data.promise());
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf('// event') > 0);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "construct", "end main",
+ "throw caught", "throw in reject"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-with-undefined-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-with-undefined-reject.js
new file mode 100644
index 000000000..94dcdffa2
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-with-undefined-reject.js
@@ -0,0 +1,88 @@
+// 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when an exception is thrown inside a Promise, which is
+// caught by a custom promise, which has no reject handler.
+// We expect two Exception debug events:
+// 1) when the exception is thrown in the promise q.
+// 2) when calling the undefined custom reject closure in MyPromise throws.
+
+Debug = debug.Debug;
+
+var expected_events = 2;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+function MyPromise(resolver) {
+ var reject = undefined;
+ var resolve = function() { };
+ log.push("construct");
+ resolver(resolve, reject);
+};
+
+MyPromise.prototype = new Promise(function() {});
+p.constructor = MyPromise;
+
+var q = p.chain(
+ function() {
+ log.push("throw caught");
+ throw new Error("caught"); // event
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ if (expected_events == 1) {
+ assertTrue(
+ exec_state.frame(0).sourceLineText().indexOf('// event') > 0);
+ assertEquals("caught", event_data.exception().message);
+ } else if (expected_events == 0) {
+ // All of the frames on the stack are from native Javascript.
+ assertEquals(0, exec_state.frameCount());
+ assertEquals("undefined is not a function",
+ event_data.exception().message);
+ } else {
+ assertUnreachable();
+ }
+ assertSame(q, event_data.promise());
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "construct", "end main", "throw caught"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/try-reject-in-constructor.js b/deps/v8/test/mjsunit/es6/debug-promises/try-reject-in-constructor.js
new file mode 100644
index 000000000..00981a67d
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/try-reject-in-constructor.js
@@ -0,0 +1,42 @@
+// 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.
+
+// Flags: --expose-debug-as debug
+
+// Test debug events when we only listen to uncaught exceptions and
+// the Promise is rejected within a try-catch in the Promise constructor.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var step = 0;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ assertEquals(0, step);
+ assertEquals("uncaught", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertTrue(event_data.uncaught());
+ // Assert that the debug event is triggered at the throw site.
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
+ step++;
+ }
+ } catch (e) {
+ exception = e;
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+var p = new Promise(function(resolve, reject) {
+ try { // This try-catch must not prevent this uncaught reject event.
+ reject(new Error("uncaught")); // event
+ } catch (e) { }
+});
+
+assertEquals(1, step);
+assertNull(exception);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/try-throw-reject-in-constructor.js b/deps/v8/test/mjsunit/es6/debug-promises/try-throw-reject-in-constructor.js
new file mode 100644
index 000000000..feff81da9
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/try-throw-reject-in-constructor.js
@@ -0,0 +1,44 @@
+// 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.
+
+// Flags: --expose-debug-as debug
+
+// Test debug events when we only listen to uncaught exceptions and
+// an exception is thrown in the Promise constructor, but caught in an
+// inner try-catch. The Promise is rejected afterwards.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var step = 0;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ assertEquals(0, step);
+ assertEquals("uncaught", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertTrue(event_data.uncaught());
+ // Assert that the debug event is triggered at the throw site.
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
+ step++;
+ }
+ } catch (e) {
+ exception = e;
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+var p = new Promise(function(resolve, reject) {
+ try { // This try-catch must not prevent this uncaught reject event.
+ throw new Error("caught");
+ } catch (e) { }
+ reject(new Error("uncaught")); // event
+});
+
+assertEquals(1, step);
+assertNull(exception);
diff --git a/deps/v8/test/mjsunit/es6/debug-stepin-collections-foreach.js b/deps/v8/test/mjsunit/es6/debug-stepin-collections-foreach.js
new file mode 100644
index 000000000..08938f775
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-stepin-collections-foreach.js
@@ -0,0 +1,118 @@
+// 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.
+//
+// Flags: --expose-debug-as debug
+
+Debug = debug.Debug
+
+var exception = false;
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Break) {
+ if (breaks == 0) {
+ exec_state.prepareStep(Debug.StepAction.StepIn, 2);
+ breaks = 1;
+ } else if (breaks <= 3) {
+ breaks++;
+ // Check whether we break at the expected line.
+ print(event_data.sourceLineText());
+ assertTrue(event_data.sourceLineText().indexOf("Expected to step") > 0);
+ exec_state.prepareStep(Debug.StepAction.StepIn, 3);
+ }
+ }
+ } catch (e) {
+ exception = true;
+ }
+}
+
+function cb_set(num) {
+ print("element " + num); // Expected to step to this point.
+ return true;
+}
+
+function cb_map(key, val) {
+ print("key " + key + ", value " + val); // Expected to step to this point.
+ return true;
+}
+
+var s = new Set();
+s.add(1);
+s.add(2);
+s.add(3);
+s.add(4);
+
+var m = new Map();
+m.set('foo', 1);
+m.set('bar', 2);
+m.set('baz', 3);
+m.set('bat', 4);
+
+Debug.setListener(listener);
+
+var breaks = 0;
+debugger;
+s.forEach(cb_set);
+assertFalse(exception);
+assertEquals(4, breaks);
+
+breaks = 0;
+debugger;
+m.forEach(cb_map);
+assertFalse(exception);
+assertEquals(4, breaks);
+
+Debug.setListener(null);
+
+
+// Test two levels of builtin callbacks:
+// Array.forEach calls a callback function, which by itself uses
+// Array.forEach with another callback function.
+
+function second_level_listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Break) {
+ if (breaks == 0) {
+ exec_state.prepareStep(Debug.StepAction.StepIn, 3);
+ breaks = 1;
+ } else if (breaks <= 16) {
+ breaks++;
+ // Check whether we break at the expected line.
+ assertTrue(event_data.sourceLineText().indexOf("Expected to step") > 0);
+ // Step two steps further every four breaks to skip the
+ // forEach call in the first level of recurision.
+ var step = (breaks % 4 == 1) ? 6 : 3;
+ exec_state.prepareStep(Debug.StepAction.StepIn, step);
+ }
+ }
+ } catch (e) {
+ exception = true;
+ }
+}
+
+function cb_set_foreach(num) {
+ s.forEach(cb_set);
+ print("back to the first level of recursion.");
+}
+
+function cb_map_foreach(key, val) {
+ m.forEach(cb_set);
+ print("back to the first level of recursion.");
+}
+
+Debug.setListener(second_level_listener);
+
+breaks = 0;
+debugger;
+s.forEach(cb_set_foreach);
+assertFalse(exception);
+assertEquals(17, breaks);
+
+breaks = 0;
+debugger;
+m.forEach(cb_map_foreach);
+assertFalse(exception);
+assertEquals(17, breaks);
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/harmony/iteration-semantics.js b/deps/v8/test/mjsunit/es6/iteration-semantics.js
index 2449115dd..7849b29ab 100644
--- a/deps/v8/test/mjsunit/harmony/iteration-semantics.js
+++ b/deps/v8/test/mjsunit/es6/iteration-semantics.js
@@ -25,7 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-iteration
// Flags: --harmony-generators --harmony-scoping --harmony-proxies
// Test for-of semantics.
@@ -41,13 +40,19 @@ function* values() {
}
}
+function wrap_iterator(iterator) {
+ var iterable = {};
+ iterable[Symbol.iterator] = function() { return iterator; };
+ return iterable;
+}
+
function integers_until(max) {
function next() {
var ret = { value: this.n, done: this.n == max };
this.n++;
return ret;
}
- return { next: next, n: 0 }
+ return wrap_iterator({ next: next, n: 0 });
}
function results(results) {
@@ -55,7 +60,7 @@ function results(results) {
function next() {
return results[i++];
}
- return { next: next }
+ return wrap_iterator({ next: next });
}
function* integers_from(n) {
@@ -72,44 +77,44 @@ function sum(x, tail) {
return x + tail;
}
-function fold(cons, seed, iter) {
- for (var x of iter) {
+function fold(cons, seed, iterable) {
+ for (var x of iterable) {
seed = cons(x, seed);
}
return seed;
}
-function* take(iter, n) {
+function* take(iterable, n) {
if (n == 0) return;
- for (let x of iter) {
+ for (let x of iterable) {
yield x;
if (--n == 0) break;
}
}
-function nth(iter, n) {
- for (let x of iter) {
+function nth(iterable, n) {
+ for (let x of iterable) {
if (n-- == 0) return x;
}
throw "unreachable";
}
-function* skip_every(iter, n) {
+function* skip_every(iterable, n) {
var i = 0;
- for (let x of iter) {
+ for (let x of iterable) {
if (++i % n == 0) continue;
yield x;
}
}
-function* iter_map(iter, f) {
- for (var x of iter) {
+function* iter_map(iterable, f) {
+ for (var x of iterable) {
yield f(x);
}
}
-function nested_fold(cons, seed, iter) {
+function nested_fold(cons, seed, iterable) {
var visited = []
- for (let x of iter) {
+ for (let x of iterable) {
for (let y of x) {
seed = cons(y, seed);
}
@@ -117,8 +122,8 @@ function nested_fold(cons, seed, iter) {
return seed;
}
-function* unreachable(iter) {
- for (let x of iter) {
+function* unreachable(iterable) {
+ for (let x of iterable) {
throw "not reached";
}
}
@@ -141,17 +146,19 @@ function never_getter(o, prop) {
return o;
}
-function remove_next_after(iter, n) {
+function remove_next_after(iterable, n) {
+ var iterator = iterable[Symbol.iterator]();
function next() {
if (n-- == 0) delete this.next;
- return iter.next();
+ return iterator.next();
}
- return { next: next }
+ return wrap_iterator({ next: next });
}
-function poison_next_after(iter, n) {
+function poison_next_after(iterable, n) {
+ var iterator = iterable[Symbol.iterator]();
function next() {
- return iter.next();
+ return iterator.next();
}
function next_getter() {
if (n-- < 0)
@@ -160,7 +167,7 @@ function poison_next_after(iter, n) {
}
var o = {};
Object.defineProperty(o, 'next', { get: next_getter });
- return o;
+ return wrap_iterator(o);
}
// Now, the tests.
@@ -204,13 +211,13 @@ assertEquals([1, 2],
{ value: 37, done: true },
never_getter(never_getter({}, 'done'), 'value')])));
-// Null and undefined do not cause an error.
-assertEquals(0, fold(sum, 0, unreachable(null)));
-assertEquals(0, fold(sum, 0, unreachable(undefined)));
+// Unlike the case with for-in, null and undefined cause an error.
+assertThrows('fold(sum, 0, unreachable(null))', TypeError);
+assertThrows('fold(sum, 0, unreachable(undefined))', TypeError);
// Other non-iterators do cause an error.
assertThrows('fold(sum, 0, unreachable({}))', TypeError);
-assertThrows('fold(sum, 0, unreachable("foo"))', TypeError);
+assertThrows('fold(sum, 0, unreachable(false))', TypeError);
assertThrows('fold(sum, 0, unreachable(37))', TypeError);
// "next" is looked up each time.
@@ -223,33 +230,33 @@ assertEquals(45,
assertEquals(45,
fold(sum, 0, poison_next_after(integers_until(10), 10)));
-function labelled_continue(iter) {
+function labelled_continue(iterable) {
var n = 0;
outer:
while (true) {
n++;
- for (var x of iter) continue outer;
+ for (var x of iterable) continue outer;
break;
}
return n;
}
assertEquals(11, labelled_continue(integers_until(10)));
-function labelled_break(iter) {
+function labelled_break(iterable) {
var n = 0;
outer:
while (true) {
n++;
- for (var x of iter) break outer;
+ for (var x of iterable) break outer;
}
return n;
}
assertEquals(1, labelled_break(integers_until(10)));
// Test continue/break in catch.
-function catch_control(iter, k) {
+function catch_control(iterable, k) {
var n = 0;
- for (var x of iter) {
+ for (var x of iterable) {
try {
return k(x);
} catch (e) {
@@ -274,9 +281,9 @@ assertEquals(5,
}));
// Test continue/break in try.
-function try_control(iter, k) {
+function try_control(iterable, k) {
var n = 0;
- for (var x of iter) {
+ for (var x of iterable) {
try {
var e = k(x);
if (e == "continue") continue;
@@ -313,16 +320,17 @@ assertEquals([1, 2],
.map(transparent_proxy))));
// Proxy iterators.
-function poison_proxy_after(x, n) {
- return Proxy.create({
+function poison_proxy_after(iterable, n) {
+ var iterator = iterable[Symbol.iterator]();
+ return wrap_iterator(Proxy.create({
get: function(receiver, name) {
if (name == 'next' && n-- < 0) throw "unreachable";
- return x[name];
+ return iterator[name];
},
// Needed for integers_until(10)'s this.n++.
set: function(receiver, name, val) {
- return x[name] = val;
+ return iterator[name] = val;
}
- });
+ }));
}
assertEquals(45, fold(sum, 0, poison_proxy_after(integers_until(10), 10)));
diff --git a/deps/v8/test/mjsunit/harmony/iteration-syntax.js b/deps/v8/test/mjsunit/es6/iteration-syntax.js
index 3bda78ed4..356a97898 100644
--- a/deps/v8/test/mjsunit/harmony/iteration-syntax.js
+++ b/deps/v8/test/mjsunit/es6/iteration-syntax.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-iteration --harmony-scoping
+// Flags: --harmony-scoping --use-strict
// Test for-of syntax.
diff --git a/deps/v8/test/mjsunit/es6/math-cbrt.js b/deps/v8/test/mjsunit/es6/math-cbrt.js
index 83d9eb5d7..713c020e4 100644
--- a/deps/v8/test/mjsunit/es6/math-cbrt.js
+++ b/deps/v8/test/mjsunit/es6/math-cbrt.js
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-maths
-
assertTrue(isNaN(Math.cbrt(NaN)));
assertTrue(isNaN(Math.cbrt(function() {})));
assertTrue(isNaN(Math.cbrt({ toString: function() { return NaN; } })));
diff --git a/deps/v8/test/mjsunit/es6/math-clz32.js b/deps/v8/test/mjsunit/es6/math-clz32.js
index 816f6a936..3cbd4c3fc 100644
--- a/deps/v8/test/mjsunit/es6/math-clz32.js
+++ b/deps/v8/test/mjsunit/es6/math-clz32.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-maths --allow-natives-syntax
+// Flags: --allow-natives-syntax
[NaN, Infinity, -Infinity, 0, -0, "abc", "Infinity", "-Infinity", {}].forEach(
function(x) {
diff --git a/deps/v8/test/mjsunit/es6/math-expm1.js b/deps/v8/test/mjsunit/es6/math-expm1.js
index de915c096..b4e31a959 100644
--- a/deps/v8/test/mjsunit/es6/math-expm1.js
+++ b/deps/v8/test/mjsunit/es6/math-expm1.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-maths --no-fast-math
+// Flags: --no-fast-math
assertTrue(isNaN(Math.expm1(NaN)));
assertTrue(isNaN(Math.expm1(function() {})));
diff --git a/deps/v8/test/mjsunit/es6/math-fround.js b/deps/v8/test/mjsunit/es6/math-fround.js
index ea432ea2d..c53396a38 100644
--- a/deps/v8/test/mjsunit/es6/math-fround.js
+++ b/deps/v8/test/mjsunit/es6/math-fround.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-maths
+// Flags: --allow-natives-syntax
// Monkey-patch Float32Array.
Float32Array = function(x) { this[0] = 0; };
@@ -11,15 +11,33 @@ assertTrue(isNaN(Math.fround(NaN)));
assertTrue(isNaN(Math.fround(function() {})));
assertTrue(isNaN(Math.fround({ toString: function() { return NaN; } })));
assertTrue(isNaN(Math.fround({ valueOf: function() { return "abc"; } })));
-assertEquals("Infinity", String(1/Math.fround(0)));
-assertEquals("-Infinity", String(1/Math.fround(-0)));
-assertEquals("Infinity", String(Math.fround(Infinity)));
-assertEquals("-Infinity", String(Math.fround(-Infinity)));
+assertTrue(isNaN(Math.fround(NaN)));
+assertTrue(isNaN(Math.fround(function() {})));
+assertTrue(isNaN(Math.fround({ toString: function() { return NaN; } })));
+assertTrue(isNaN(Math.fround({ valueOf: function() { return "abc"; } })));
+
+function unopt(x) { return Math.fround(x); }
+function opt(y) { return Math.fround(y); }
-assertEquals("Infinity", String(Math.fround(1E200)));
-assertEquals("-Infinity", String(Math.fround(-1E200)));
-assertEquals("Infinity", String(1/Math.fround(1E-300)));
-assertEquals("-Infinity", String(1/Math.fround(-1E-300)));
+opt(0.1);
+opt(0.1);
+unopt(0.1);
+%NeverOptimizeFunction(unopt);
+%OptimizeFunctionOnNextCall(opt);
+
+function test(f) {
+ assertEquals("Infinity", String(1/f(0)));
+ assertEquals("-Infinity", String(1/f(-0)));
+ assertEquals("Infinity", String(f(Infinity)));
+ assertEquals("-Infinity", String(f(-Infinity)));
+ assertEquals("Infinity", String(f(1E200)));
+ assertEquals("-Infinity", String(f(-1E200)));
+ assertEquals("Infinity", String(1/f(1E-300)));
+ assertEquals("-Infinity", String(1/f(-1E-300)));
+}
+
+test(opt);
+test(unopt);
mantissa_23_shift = Math.pow(2, -23);
mantissa_29_shift = Math.pow(2, -23-29);
@@ -81,13 +99,16 @@ ieee754float.prototype.toSingleSubnormal = function(sign, exponent) {
var pi = new ieee754float(0, 0x400, 0x490fda, 0x14442d18);
-assertEquals(pi.toSingle(), Math.fround(pi.toDouble()));
+assertEquals(pi.toSingle(), opt(pi.toDouble()));
+assertEquals(pi.toSingle(), unopt(pi.toDouble()));
+
function fuzz_mantissa(sign, exp, m1inc, m2inc) {
for (var m1 = 0; m1 < (1 << 23); m1 += m1inc) {
for (var m2 = 0; m2 < (1 << 29); m2 += m2inc) {
var float = new ieee754float(sign, exp, m1, m2);
- assertEquals(float.toSingle(), Math.fround(float.toDouble()));
+ assertEquals(float.toSingle(), unopt(float.toDouble()));
+ assertEquals(float.toSingle(), opt(float.toDouble()));
}
}
}
diff --git a/deps/v8/test/mjsunit/es6/math-hyperbolic.js b/deps/v8/test/mjsunit/es6/math-hyperbolic.js
index c45a19c52..1ceb95182 100644
--- a/deps/v8/test/mjsunit/es6/math-hyperbolic.js
+++ b/deps/v8/test/mjsunit/es6/math-hyperbolic.js
@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-maths
-
[Math.sinh, Math.cosh, Math.tanh, Math.asinh, Math.acosh, Math.atanh].
forEach(function(fun) {
assertTrue(isNaN(fun(NaN)));
diff --git a/deps/v8/test/mjsunit/es6/math-hypot.js b/deps/v8/test/mjsunit/es6/math-hypot.js
index 105262721..d2392df3a 100644
--- a/deps/v8/test/mjsunit/es6/math-hypot.js
+++ b/deps/v8/test/mjsunit/es6/math-hypot.js
@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-maths
-
assertTrue(isNaN(Math.hypot({})));
assertTrue(isNaN(Math.hypot(undefined, 1)));
assertTrue(isNaN(Math.hypot(1, undefined)));
diff --git a/deps/v8/test/mjsunit/es6/math-log1p.js b/deps/v8/test/mjsunit/es6/math-log1p.js
index eefea6ee3..5468444fd 100644
--- a/deps/v8/test/mjsunit/es6/math-log1p.js
+++ b/deps/v8/test/mjsunit/es6/math-log1p.js
@@ -2,22 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-maths
-
assertTrue(isNaN(Math.log1p(NaN)));
assertTrue(isNaN(Math.log1p(function() {})));
assertTrue(isNaN(Math.log1p({ toString: function() { return NaN; } })));
assertTrue(isNaN(Math.log1p({ valueOf: function() { return "abc"; } })));
-assertEquals("Infinity", String(1/Math.log1p(0)));
-assertEquals("-Infinity", String(1/Math.log1p(-0)));
-assertEquals("Infinity", String(Math.log1p(Infinity)));
-assertEquals("-Infinity", String(Math.log1p(-1)));
+assertEquals(Infinity, 1/Math.log1p(0));
+assertEquals(-Infinity, 1/Math.log1p(-0));
+assertEquals(Infinity, Math.log1p(Infinity));
+assertEquals(-Infinity, Math.log1p(-1));
assertTrue(isNaN(Math.log1p(-2)));
assertTrue(isNaN(Math.log1p(-Infinity)));
-for (var x = 1E300; x > 1E-1; x *= 0.8) {
+for (var x = 1E300; x > 1E16; x *= 0.8) {
var expected = Math.log(x + 1);
- assertEqualsDelta(expected, Math.log1p(x), expected * 1E-14);
+ assertEqualsDelta(expected, Math.log1p(x), expected * 1E-16);
}
// Values close to 0:
@@ -37,5 +35,36 @@ function log1p(x) {
for (var x = 1E-1; x > 1E-300; x *= 0.8) {
var expected = log1p(x);
- assertEqualsDelta(expected, Math.log1p(x), expected * 1E-14);
+ assertEqualsDelta(expected, Math.log1p(x), expected * 1E-16);
}
+
+// Issue 3481.
+assertEquals(6.9756137364252422e-03,
+ Math.log1p(8070450532247929/Math.pow(2,60)));
+
+// Tests related to the fdlibm implementation.
+// Test largest double value.
+assertEquals(709.782712893384, Math.log1p(1.7976931348623157e308));
+// Test small values.
+assertEquals(Math.pow(2, -55), Math.log1p(Math.pow(2, -55)));
+assertEquals(9.313225741817976e-10, Math.log1p(Math.pow(2, -30)));
+// Cover various code paths.
+// -.2929 < x < .41422, k = 0
+assertEquals(-0.2876820724517809, Math.log1p(-0.25));
+assertEquals(0.22314355131420976, Math.log1p(0.25));
+// 0.41422 < x < 9.007e15
+assertEquals(2.3978952727983707, Math.log1p(10));
+// x > 9.007e15
+assertEquals(36.841361487904734, Math.log1p(10e15));
+// Normalize u.
+assertEquals(37.08337388996168, Math.log1p(12738099905822720));
+// Normalize u/2.
+assertEquals(37.08336444902049, Math.log1p(12737979646738432));
+// |f| = 0, k != 0
+assertEquals(1.3862943611198906, Math.log1p(3));
+// |f| != 0, k != 0
+assertEquals(1.3862945995384413, Math.log1p(3 + Math.pow(2,-20)));
+// final if-clause: k = 0
+assertEquals(0.5596157879354227, Math.log1p(0.75));
+// final if-clause: k != 0
+assertEquals(0.8109302162163288, Math.log1p(1.25));
diff --git a/deps/v8/test/mjsunit/es6/math-log2-log10.js b/deps/v8/test/mjsunit/es6/math-log2-log10.js
index 2ab496012..4479894d7 100644
--- a/deps/v8/test/mjsunit/es6/math-log2-log10.js
+++ b/deps/v8/test/mjsunit/es6/math-log2-log10.js
@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-maths
-
[Math.log10, Math.log2].forEach( function(fun) {
assertTrue(isNaN(fun(NaN)));
assertTrue(isNaN(fun(fun)));
diff --git a/deps/v8/test/mjsunit/es6/math-sign.js b/deps/v8/test/mjsunit/es6/math-sign.js
index 8a89d6282..65f1609d6 100644
--- a/deps/v8/test/mjsunit/es6/math-sign.js
+++ b/deps/v8/test/mjsunit/es6/math-sign.js
@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-maths
-
assertEquals("Infinity", String(1/Math.sign(0)));
assertEquals("-Infinity", String(1/Math.sign(-0)));
assertEquals(1, Math.sign(100));
diff --git a/deps/v8/test/mjsunit/es6/math-trunc.js b/deps/v8/test/mjsunit/es6/math-trunc.js
index ed91ed138..9231576dd 100644
--- a/deps/v8/test/mjsunit/es6/math-trunc.js
+++ b/deps/v8/test/mjsunit/es6/math-trunc.js
@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-maths
-
assertEquals("Infinity", String(1/Math.trunc(0)));
assertEquals("-Infinity", String(1/Math.trunc(-0)));
assertEquals("Infinity", String(1/Math.trunc(Math.PI/4)));
diff --git a/deps/v8/test/mjsunit/es6/mirror-collections.js b/deps/v8/test/mjsunit/es6/mirror-collections.js
new file mode 100644
index 000000000..e10f5c1a9
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/mirror-collections.js
@@ -0,0 +1,144 @@
+// 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.
+
+// Flags: --expose-debug-as debug --expose-gc
+
+function testMapMirror(mirror) {
+ // Create JSON representation.
+ var serializer = debug.MakeMirrorSerializer();
+ var json = JSON.stringify(serializer.serializeValue(mirror));
+
+ // Check the mirror hierachy.
+ assertTrue(mirror instanceof debug.Mirror);
+ assertTrue(mirror instanceof debug.ValueMirror);
+ assertTrue(mirror instanceof debug.ObjectMirror);
+ assertTrue(mirror instanceof debug.MapMirror);
+
+ assertTrue(mirror.isMap());
+
+ // Parse JSON representation and check.
+ var fromJSON = eval('(' + json + ')');
+ assertEquals('map', fromJSON.type);
+}
+
+function testSetMirror(mirror) {
+ // Create JSON representation.
+ var serializer = debug.MakeMirrorSerializer();
+ var json = JSON.stringify(serializer.serializeValue(mirror));
+
+ // Check the mirror hierachy.
+ assertTrue(mirror instanceof debug.Mirror);
+ assertTrue(mirror instanceof debug.ValueMirror);
+ assertTrue(mirror instanceof debug.ObjectMirror);
+ assertTrue(mirror instanceof debug.SetMirror);
+
+ assertTrue(mirror.isSet());
+
+ // Parse JSON representation and check.
+ var fromJSON = eval('(' + json + ')');
+ assertEquals('set', fromJSON.type);
+}
+
+var o1 = new Object();
+var o2 = new Object();
+var o3 = new Object();
+
+// Test the mirror object for Maps
+var map = new Map();
+map.set(o1, 11);
+map.set(o2, 22);
+map.delete(o1);
+var mapMirror = debug.MakeMirror(map);
+testMapMirror(mapMirror);
+var entries = mapMirror.entries();
+assertEquals(1, entries.length);
+assertSame(o2, entries[0].key);
+assertEquals(22, entries[0].value);
+map.set(o1, 33);
+map.set(o3, o2);
+map.delete(o2);
+map.set(undefined, 44);
+entries = mapMirror.entries();
+assertEquals(3, entries.length);
+assertSame(o1, entries[0].key);
+assertEquals(33, entries[0].value);
+assertSame(o3, entries[1].key);
+assertSame(o2, entries[1].value);
+assertEquals(undefined, entries[2].key);
+assertEquals(44, entries[2].value);
+
+// Test the mirror object for Sets
+var set = new Set();
+set.add(o1);
+set.add(o2);
+set.delete(o1);
+set.add(undefined);
+var setMirror = debug.MakeMirror(set);
+testSetMirror(setMirror);
+var values = setMirror.values();
+assertEquals(2, values.length);
+assertSame(o2, values[0]);
+assertEquals(undefined, values[1]);
+
+// Test the mirror object for WeakMaps
+var weakMap = new WeakMap();
+weakMap.set(o1, 11);
+weakMap.set(new Object(), 22);
+weakMap.set(o3, 33);
+weakMap.set(new Object(), 44);
+var weakMapMirror = debug.MakeMirror(weakMap);
+testMapMirror(weakMapMirror);
+weakMap.set(new Object(), 55);
+assertTrue(weakMapMirror.entries().length <= 5);
+gc();
+
+function testWeakMapEntries(weakMapMirror) {
+ var entries = weakMapMirror.entries();
+ assertEquals(2, entries.length);
+ var found = 0;
+ for (var i = 0; i < entries.length; i++) {
+ if (Object.is(entries[i].key, o1)) {
+ assertEquals(11, entries[i].value);
+ found++;
+ }
+ if (Object.is(entries[i].key, o3)) {
+ assertEquals(33, entries[i].value);
+ found++;
+ }
+ }
+ assertEquals(2, found);
+}
+
+testWeakMapEntries(weakMapMirror);
+
+// Test the mirror object for WeakSets
+var weakSet = new WeakSet();
+weakSet.add(o1);
+weakSet.add(new Object());
+weakSet.add(o2);
+weakSet.add(new Object());
+weakSet.add(new Object());
+weakSet.add(o3);
+weakSet.delete(o2);
+var weakSetMirror = debug.MakeMirror(weakSet);
+testSetMirror(weakSetMirror);
+assertTrue(weakSetMirror.values().length <= 5);
+gc();
+
+function testWeakSetValues(weakSetMirror) {
+ var values = weakSetMirror.values();
+ assertEquals(2, values.length);
+ var found = 0;
+ for (var i = 0; i < values.length; i++) {
+ if (Object.is(values[i], o1)) {
+ found++;
+ }
+ if (Object.is(values[i], o3)) {
+ found++;
+ }
+ }
+ assertEquals(2, found);
+}
+
+testWeakSetValues(weakSetMirror);
diff --git a/deps/v8/test/mjsunit/es6/mirror-promises.js b/deps/v8/test/mjsunit/es6/mirror-promises.js
index 5a21a6b9e..deeba8f54 100644
--- a/deps/v8/test/mjsunit/es6/mirror-promises.js
+++ b/deps/v8/test/mjsunit/es6/mirror-promises.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --expose-debug-as debug --harmony-promises
+// Flags: --expose-debug-as debug
// Test the mirror object for promises.
function MirrorRefCache(json_refs) {
@@ -39,7 +39,8 @@ function testPromiseMirror(promise, status, value) {
assertEquals("Object", mirror.className());
assertEquals("#<Promise>", mirror.toText());
assertSame(promise, mirror.value());
- assertEquals(value, mirror.promiseValue());
+ assertTrue(mirror.promiseValue() instanceof debug.Mirror);
+ assertEquals(value, mirror.promiseValue().value());
// Parse JSON representation and check.
var fromJSON = eval('(' + json + ')');
@@ -48,7 +49,7 @@ function testPromiseMirror(promise, status, value) {
assertEquals('function', refs.lookup(fromJSON.constructorFunction.ref).type);
assertEquals('Promise', refs.lookup(fromJSON.constructorFunction.ref).name);
assertEquals(status, fromJSON.status);
- assertEquals(value, fromJSON.promiseValue);
+ assertEquals(value, refs.lookup(fromJSON.promiseValue.ref).value);
}
// Test a number of different promises.
@@ -67,3 +68,23 @@ var thrownv = new Promise(function(resolve, reject) { throw 'throw' });
testPromiseMirror(resolvedv, "resolved", 'resolve');
testPromiseMirror(rejectedv, "rejected", 'reject');
testPromiseMirror(thrownv, "rejected", 'throw');
+
+// Test internal properties of different promises.
+var m1 = debug.MakeMirror(new Promise(
+ function(resolve, reject) { resolve(1) }));
+var ip = m1.internalProperties();
+assertEquals(2, ip.length);
+assertEquals("[[PromiseStatus]]", ip[0].name());
+assertEquals("[[PromiseValue]]", ip[1].name());
+assertEquals("resolved", ip[0].value().value());
+assertEquals(1, ip[1].value().value());
+
+var m2 = debug.MakeMirror(new Promise(function(resolve, reject) { reject(2) }));
+ip = m2.internalProperties();
+assertEquals("rejected", ip[0].value().value());
+assertEquals(2, ip[1].value().value());
+
+var m3 = debug.MakeMirror(new Promise(function(resolve, reject) { }));
+ip = m3.internalProperties();
+assertEquals("pending", ip[0].value().value());
+assertEquals("undefined", typeof(ip[1].value().value()));
diff --git a/deps/v8/test/mjsunit/es6/mirror-symbols.js b/deps/v8/test/mjsunit/es6/mirror-symbols.js
new file mode 100644
index 000000000..f218332ab
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/mirror-symbols.js
@@ -0,0 +1,38 @@
+// 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.
+
+// Flags: --expose-debug-as debug
+// Test the mirror object for symbols.
+
+function testSymbolMirror(symbol, description) {
+ // Create mirror and JSON representation.
+ var mirror = debug.MakeMirror(symbol);
+ var serializer = debug.MakeMirrorSerializer();
+ var json = JSON.stringify(serializer.serializeValue(mirror));
+
+ // Check the mirror hierachy.
+ assertTrue(mirror instanceof debug.Mirror);
+ assertTrue(mirror instanceof debug.ValueMirror);
+ assertTrue(mirror instanceof debug.SymbolMirror);
+
+ // Check the mirror properties.
+ assertTrue(mirror.isSymbol());
+ assertEquals(description, mirror.description());
+ assertEquals('symbol', mirror.type());
+ assertTrue(mirror.isPrimitive());
+ var description_text = description === undefined ? "" : description;
+ assertEquals('Symbol(' + description_text + ')', mirror.toText());
+ assertSame(symbol, mirror.value());
+
+ // Parse JSON representation and check.
+ var fromJSON = eval('(' + json + ')');
+ assertEquals('symbol', fromJSON.type);
+ assertEquals(description, fromJSON.description);
+}
+
+// Test a number of different symbols.
+testSymbolMirror(Symbol("a"), "a");
+testSymbolMirror(Symbol(12), "12");
+testSymbolMirror(Symbol.for("b"), "b");
+testSymbolMirror(Symbol(), undefined);
diff --git a/deps/v8/test/mjsunit/es6/promises.js b/deps/v8/test/mjsunit/es6/promises.js
index 6dfe9261a..faf154ee0 100644
--- a/deps/v8/test/mjsunit/es6/promises.js
+++ b/deps/v8/test/mjsunit/es6/promises.js
@@ -27,6 +27,42 @@
// Flags: --allow-natives-syntax
+// Make sure we don't rely on functions patchable by monkeys.
+var call = Function.prototype.call.call.bind(Function.prototype.call)
+var observe = Object.observe;
+var getOwnPropertyNames = Object.getOwnPropertyNames
+var defineProperty = Object.defineProperty
+
+function clear(o) {
+ if (o === null || (typeof o !== 'object' && typeof o !== 'function')) return
+ clear(o.__proto__)
+ var properties = getOwnPropertyNames(o)
+ for (var i in properties) {
+ clearProp(o, properties[i])
+ }
+}
+
+function clearProp(o, name) {
+ var poisoned = {caller: 0, callee: 0, arguments: 0}
+ try {
+ var x = o[name]
+ o[name] = undefined
+ clear(x)
+ } catch(e) {} // assertTrue(name in poisoned) }
+}
+
+// Find intrinsics and null them out.
+var globals = Object.getOwnPropertyNames(this)
+var whitelist = {Promise: true, TypeError: true}
+for (var i in globals) {
+ var name = globals[i]
+ if (name in whitelist || name[0] === name[0].toLowerCase()) delete globals[i]
+}
+for (var i in globals) {
+ if (globals[i]) clearProp(this, globals[i])
+}
+
+
var asyncAssertsExpected = 0;
function assertAsyncRan() { ++asyncAssertsExpected }
@@ -43,7 +79,7 @@ function assertAsync(b, s) {
function assertAsyncDone(iteration) {
var iteration = iteration || 0
var dummy = {}
- Object.observe(dummy,
+ observe(dummy,
function() {
if (asyncAssertsExpected === 0)
assertAsync(true, "all")
@@ -777,13 +813,13 @@ function assertAsyncDone(iteration) {
MyPromise.__proto__ = Promise
MyPromise.defer = function() {
log += "d"
- return this.__proto__.defer.call(this)
+ return call(this.__proto__.defer, this)
}
MyPromise.prototype.__proto__ = Promise.prototype
MyPromise.prototype.chain = function(resolve, reject) {
log += "c"
- return this.__proto__.__proto__.chain.call(this, resolve, reject)
+ return call(this.__proto__.__proto__.chain, this, resolve, reject)
}
log = ""
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-2186.js b/deps/v8/test/mjsunit/es6/regress/regress-2186.js
index 0921dcead..c82242a10 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-2186.js
+++ b/deps/v8/test/mjsunit/es6/regress/regress-2186.js
@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-collections
-
function heapify(i) {
return 2.0 * (i / 2);
}
diff --git a/deps/v8/test/cctest/test-cpu-ia32.cc b/deps/v8/test/mjsunit/es6/regress/regress-cr372788.js
index 245450bf9..9b66a7e08 100644
--- a/deps/v8/test/cctest/test-cpu-ia32.cc
+++ b/deps/v8/test/mjsunit/es6/regress/regress-cr372788.js
@@ -1,4 +1,4 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
+// 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:
@@ -25,16 +25,21 @@
// (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"
+// Flags: --allow-natives-syntax
-#include "cctest.h"
-#include "cpu.h"
+var x = 0;
+var y = 0;
-using namespace v8::internal;
+var thenable = { then: function(f) { x++; f(); } };
-
-TEST(RequiredFeaturesX64) {
- // Test for the features required by every x86 CPU in compat/legacy mode.
- CPU cpu;
- CHECK(cpu.has_sahf());
+for (var i = 0; i < 3; ++i) {
+ Promise.resolve(thenable).then(function() { x++; y++; });
}
+assertEquals(0, x);
+
+(function check() {
+ Promise.resolve().chain(function() {
+ // Delay check until all handlers have run.
+ if (y < 3) check(); else assertEquals(6, x);
+ }).catch(function(e) { %AbortJS("FAILURE: " + e) });
+})();
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-crbug-248025.js b/deps/v8/test/mjsunit/es6/regress/regress-crbug-248025.js
index c59885956..b7982cda7 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-crbug-248025.js
+++ b/deps/v8/test/mjsunit/es6/regress/regress-crbug-248025.js
@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-iteration
-
// Filler long enough to trigger lazy parsing.
var filler = "//" + new Array(1024).join('x');
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-crbug-346141.js b/deps/v8/test/mjsunit/es6/regress/regress-crbug-346141.js
index 798b7704e..2b9655e17 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-crbug-346141.js
+++ b/deps/v8/test/mjsunit/es6/regress/regress-crbug-346141.js
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-symbols
-
var s = Symbol()
var o = {}
o[s] = 2
diff --git a/deps/v8/test/mjsunit/es6/string-html.js b/deps/v8/test/mjsunit/es6/string-html.js
new file mode 100644
index 000000000..4f3feb56d
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/string-html.js
@@ -0,0 +1,159 @@
+// 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.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+assertEquals('_'.anchor('b'), '<a name="b">_</a>');
+assertEquals('<'.anchor('<'), '<a name="<"><</a>');
+assertEquals('_'.anchor(0x2A), '<a name="42">_</a>');
+assertEquals('_'.anchor('\x22'), '<a name="&quot;">_</a>');
+assertEquals(String.prototype.anchor.call(0x2A, 0x2A), '<a name="42">42</a>');
+assertThrows(function() {
+ String.prototype.anchor.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.anchor.call(null);
+}, TypeError);
+assertEquals(String.prototype.anchor.length, 1);
+
+assertEquals('_'.big(), '<big>_</big>');
+assertEquals('<'.big(), '<big><</big>');
+assertEquals(String.prototype.big.call(0x2A), '<big>42</big>');
+assertThrows(function() {
+ String.prototype.big.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.big.call(null);
+}, TypeError);
+assertEquals(String.prototype.big.length, 0);
+
+assertEquals('_'.blink(), '<blink>_</blink>');
+assertEquals('<'.blink(), '<blink><</blink>');
+assertEquals(String.prototype.blink.call(0x2A), '<blink>42</blink>');
+assertThrows(function() {
+ String.prototype.blink.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.blink.call(null);
+}, TypeError);
+assertEquals(String.prototype.blink.length, 0);
+
+assertEquals('_'.bold(), '<b>_</b>');
+assertEquals('<'.bold(), '<b><</b>');
+assertEquals(String.prototype.bold.call(0x2A), '<b>42</b>');
+assertThrows(function() {
+ String.prototype.bold.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.bold.call(null);
+}, TypeError);
+assertEquals(String.prototype.bold.length, 0);
+
+assertEquals('_'.fixed(), '<tt>_</tt>');
+assertEquals('<'.fixed(), '<tt><</tt>');
+assertEquals(String.prototype.fixed.call(0x2A), '<tt>42</tt>');
+assertThrows(function() {
+ String.prototype.fixed.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.fixed.call(null);
+}, TypeError);
+assertEquals(String.prototype.fixed.length, 0);
+
+assertEquals('_'.fontcolor('b'), '<font color="b">_</font>');
+assertEquals('<'.fontcolor('<'), '<font color="<"><</font>');
+assertEquals('_'.fontcolor(0x2A), '<font color="42">_</font>');
+assertEquals('_'.fontcolor('\x22'), '<font color="&quot;">_</font>');
+assertEquals(String.prototype.fontcolor.call(0x2A, 0x2A),
+ '<font color="42">42</font>');
+assertThrows(function() {
+ String.prototype.fontcolor.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.fontcolor.call(null);
+}, TypeError);
+assertEquals(String.prototype.fontcolor.length, 1);
+
+assertEquals('_'.fontsize('b'), '<font size="b">_</font>');
+assertEquals('<'.fontsize('<'), '<font size="<"><</font>');
+assertEquals('_'.fontsize(0x2A), '<font size="42">_</font>');
+assertEquals('_'.fontsize('\x22'), '<font size="&quot;">_</font>');
+assertEquals(String.prototype.fontsize.call(0x2A, 0x2A),
+ '<font size="42">42</font>');
+assertThrows(function() {
+ String.prototype.fontsize.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.fontsize.call(null);
+}, TypeError);
+assertEquals(String.prototype.fontsize.length, 1);
+
+assertEquals('_'.italics(), '<i>_</i>');
+assertEquals('<'.italics(), '<i><</i>');
+assertEquals(String.prototype.italics.call(0x2A), '<i>42</i>');
+assertThrows(function() {
+ String.prototype.italics.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.italics.call(null);
+}, TypeError);
+assertEquals(String.prototype.italics.length, 0);
+
+assertEquals('_'.link('b'), '<a href="b">_</a>');
+assertEquals('<'.link('<'), '<a href="<"><</a>');
+assertEquals('_'.link(0x2A), '<a href="42">_</a>');
+assertEquals('_'.link('\x22'), '<a href="&quot;">_</a>');
+assertEquals(String.prototype.link.call(0x2A, 0x2A), '<a href="42">42</a>');
+assertThrows(function() {
+ String.prototype.link.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.link.call(null);
+}, TypeError);
+assertEquals(String.prototype.link.length, 1);
+
+assertEquals('_'.small(), '<small>_</small>');
+assertEquals('<'.small(), '<small><</small>');
+assertEquals(String.prototype.small.call(0x2A), '<small>42</small>');
+assertThrows(function() {
+ String.prototype.small.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.small.call(null);
+}, TypeError);
+assertEquals(String.prototype.small.length, 0);
+
+assertEquals('_'.strike(), '<strike>_</strike>');
+assertEquals('<'.strike(), '<strike><</strike>');
+assertEquals(String.prototype.strike.call(0x2A), '<strike>42</strike>');
+assertThrows(function() {
+ String.prototype.strike.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.strike.call(null);
+}, TypeError);
+assertEquals(String.prototype.strike.length, 0);
+
+assertEquals('_'.sub(), '<sub>_</sub>');
+assertEquals('<'.sub(), '<sub><</sub>');
+assertEquals(String.prototype.sub.call(0x2A), '<sub>42</sub>');
+assertThrows(function() {
+ String.prototype.sub.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.sub.call(null);
+}, TypeError);
+assertEquals(String.prototype.sub.length, 0);
+
+assertEquals('_'.sup(), '<sup>_</sup>');
+assertEquals('<'.sup(), '<sup><</sup>');
+assertEquals(String.prototype.sup.call(0x2A), '<sup>42</sup>');
+assertThrows(function() {
+ String.prototype.sup.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.sup.call(null);
+}, TypeError);
+assertEquals(String.prototype.sup.length, 0);
diff --git a/deps/v8/test/mjsunit/es6/string-iterator.js b/deps/v8/test/mjsunit/es6/string-iterator.js
new file mode 100644
index 000000000..e6bea6dfe
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/string-iterator.js
@@ -0,0 +1,89 @@
+// 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.
+
+
+function TestStringPrototypeIterator() {
+ assertTrue(String.prototype.hasOwnProperty(Symbol.iterator));
+ assertFalse("".hasOwnProperty(Symbol.iterator));
+ assertFalse("".propertyIsEnumerable(Symbol.iterator));
+}
+TestStringPrototypeIterator();
+
+
+function assertIteratorResult(value, done, result) {
+ assertEquals({value: value, done: done}, result);
+}
+
+
+function TestManualIteration() {
+ var string = "abc";
+ var iterator = string[Symbol.iterator]();
+ assertIteratorResult('a', false, iterator.next());
+ assertIteratorResult('b', false, iterator.next());
+ assertIteratorResult('c', false, iterator.next());
+ assertIteratorResult(void 0, true, iterator.next());
+ assertIteratorResult(void 0, true, iterator.next());
+}
+TestManualIteration();
+
+
+function TestSurrogatePairs() {
+ var lo = "\uD834";
+ var hi = "\uDF06";
+ var pair = lo + hi;
+ var string = "abc" + pair + "def" + lo + pair + hi + lo;
+ var iterator = string[Symbol.iterator]();
+ assertIteratorResult('a', false, iterator.next());
+ assertIteratorResult('b', false, iterator.next());
+ assertIteratorResult('c', false, iterator.next());
+ assertIteratorResult(pair, false, iterator.next());
+ assertIteratorResult('d', false, iterator.next());
+ assertIteratorResult('e', false, iterator.next());
+ assertIteratorResult('f', false, iterator.next());
+ assertIteratorResult(lo, false, iterator.next());
+ assertIteratorResult(pair, false, iterator.next());
+ assertIteratorResult(hi, false, iterator.next());
+ assertIteratorResult(lo, false, iterator.next());
+ assertIteratorResult(void 0, true, iterator.next());
+ assertIteratorResult(void 0, true, iterator.next());
+}
+TestSurrogatePairs();
+
+
+function TestStringIteratorPrototype() {
+ var iterator = ""[Symbol.iterator]();
+ var StringIteratorPrototype = iterator.__proto__;
+ assertFalse(StringIteratorPrototype.hasOwnProperty('constructor'));
+ assertEquals(StringIteratorPrototype.__proto__, Object.prototype);
+ assertArrayEquals(['next'],
+ Object.getOwnPropertyNames(StringIteratorPrototype));
+ assertEquals('[object String Iterator]', "" + iterator);
+}
+TestStringIteratorPrototype();
+
+
+function TestForOf() {
+ var lo = "\uD834";
+ var hi = "\uDF06";
+ var pair = lo + hi;
+ var string = "abc" + pair + "def" + lo + pair + hi + lo;
+ var expected = ['a', 'b', 'c', pair, 'd', 'e', 'f', lo, pair, hi, lo];
+
+ var i = 0;
+ for (var char of string) {
+ assertEquals(expected[i++], char);
+ }
+
+ assertEquals(expected.length, i);
+}
+TestForOf();
+
+
+function TestNonOwnSlots() {
+ var iterator = ""[Symbol.iterator]();
+ var object = {__proto__: iterator};
+
+ assertThrows(function() { object.next(); }, TypeError);
+}
+TestNonOwnSlots();
diff --git a/deps/v8/test/mjsunit/harmony/symbols.js b/deps/v8/test/mjsunit/es6/symbols.js
index 220439291..0b0700270 100644
--- a/deps/v8/test/mjsunit/harmony/symbols.js
+++ b/deps/v8/test/mjsunit/es6/symbols.js
@@ -25,7 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-symbols --harmony-collections
// Flags: --expose-gc --allow-natives-syntax
var symbols = []
@@ -102,7 +101,9 @@ TestConstructor()
function TestValueOf() {
for (var i in symbols) {
+ assertTrue(symbols[i] === Object(symbols[i]).valueOf())
assertTrue(symbols[i] === symbols[i].valueOf())
+ assertTrue(Symbol.prototype.valueOf.call(Object(symbols[i])) === symbols[i])
assertTrue(Symbol.prototype.valueOf.call(symbols[i]) === symbols[i])
}
}
@@ -113,7 +114,7 @@ function TestToString() {
for (var i in symbols) {
assertThrows(function() { String(symbols[i]) }, TypeError)
assertThrows(function() { symbols[i] + "" }, TypeError)
- assertTrue(isValidSymbolString(String(Object(symbols[i]))))
+ assertThrows(function() { String(Object(symbols[i])) }, TypeError)
assertTrue(isValidSymbolString(symbols[i].toString()))
assertTrue(isValidSymbolString(Object(symbols[i]).toString()))
assertTrue(
@@ -127,6 +128,8 @@ TestToString()
function TestToBoolean() {
for (var i in symbols) {
+ assertTrue(Boolean(Object(symbols[i])))
+ assertFalse(!Object(symbols[i]))
assertTrue(Boolean(symbols[i]).valueOf())
assertFalse(!symbols[i])
assertTrue(!!symbols[i])
@@ -144,8 +147,10 @@ TestToBoolean()
function TestToNumber() {
for (var i in symbols) {
- assertSame(NaN, Number(symbols[i]).valueOf())
- assertSame(NaN, symbols[i] + 0)
+ assertThrows(function() { Number(Object(symbols[i])) }, TypeError)
+ assertThrows(function() { +Object(symbols[i]) }, TypeError)
+ assertThrows(function() { Number(symbols[i]) }, TypeError)
+ assertThrows(function() { symbols[i] + 0 }, TypeError)
}
}
TestToNumber()
@@ -367,6 +372,34 @@ for (var i in objs) {
}
+function TestDefineProperties() {
+ var properties = {}
+ for (var i in symbols) {
+ Object.defineProperty(
+ properties, symbols[i], {value: {value: i}, enumerable: i % 2 === 0})
+ }
+ var o = Object.defineProperties({}, properties)
+ for (var i in symbols) {
+ assertEquals(i % 2 === 0, symbols[i] in o)
+ }
+}
+TestDefineProperties()
+
+
+function TestCreate() {
+ var properties = {}
+ for (var i in symbols) {
+ Object.defineProperty(
+ properties, symbols[i], {value: {value: i}, enumerable: i % 2 === 0})
+ }
+ var o = Object.create(Object.prototype, properties)
+ for (var i in symbols) {
+ assertEquals(i % 2 === 0, symbols[i] in o)
+ }
+}
+TestCreate()
+
+
function TestCachedKeyAfterScavenge() {
gc();
// Keyed property lookup are cached. Hereby we assume that the keys are
@@ -412,8 +445,9 @@ TestGetOwnPropertySymbolsWithProto()
function TestWellKnown() {
var symbols = [
- "create", "hasInstance", "isConcatSpreadable", "isRegExp",
- "iterator", "toStringTag", "unscopables"
+ // TODO(rossberg): reactivate once implemented.
+ // "hasInstance", "isConcatSpreadable", "isRegExp",
+ "iterator", /* "toStringTag", */ "unscopables"
]
for (var i in symbols) {
diff --git a/deps/v8/test/mjsunit/es6/typed-array-iterator.js b/deps/v8/test/mjsunit/es6/typed-array-iterator.js
new file mode 100644
index 000000000..a2e4906c1
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/typed-array-iterator.js
@@ -0,0 +1,39 @@
+// 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.
+
+
+var constructors = [Uint8Array, Int8Array,
+ Uint16Array, Int16Array,
+ Uint32Array, Int32Array,
+ Float32Array, Float64Array,
+ Uint8ClampedArray];
+
+function TestTypedArrayPrototype(constructor) {
+ assertTrue(constructor.prototype.hasOwnProperty('entries'));
+ assertTrue(constructor.prototype.hasOwnProperty('values'));
+ assertTrue(constructor.prototype.hasOwnProperty('keys'));
+ assertTrue(constructor.prototype.hasOwnProperty(Symbol.iterator));
+
+ assertFalse(constructor.prototype.propertyIsEnumerable('entries'));
+ assertFalse(constructor.prototype.propertyIsEnumerable('values'));
+ assertFalse(constructor.prototype.propertyIsEnumerable('keys'));
+ assertFalse(constructor.prototype.propertyIsEnumerable(Symbol.iterator));
+
+ assertEquals(Array.prototype.entries, constructor.prototype.entries);
+ assertEquals(Array.prototype.values, constructor.prototype.values);
+ assertEquals(Array.prototype.keys, constructor.prototype.keys);
+ assertEquals(Array.prototype.values, constructor.prototype[Symbol.iterator]);
+}
+constructors.forEach(TestTypedArrayPrototype);
+
+
+function TestTypedArrayValues(constructor) {
+ var array = [1, 2, 3];
+ var i = 0;
+ for (var value of new constructor(array)) {
+ assertEquals(array[i++], value);
+ }
+ assertEquals(i, array.length);
+}
+constructors.forEach(TestTypedArrayValues);
diff --git a/deps/v8/test/mjsunit/es6/unscopables.js b/deps/v8/test/mjsunit/es6/unscopables.js
new file mode 100644
index 000000000..678536dba
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/unscopables.js
@@ -0,0 +1,664 @@
+// 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.
+
+// Flags: --harmony-unscopables
+// Flags: --harmony-collections
+
+var global = this;
+var globalProto = Object.getPrototypeOf(global);
+
+// Number of objects being tested. There is an assert ensuring this is correct.
+var objectCount = 21;
+
+
+function runTest(f) {
+ function restore(object, oldProto) {
+ delete object[Symbol.unscopables];
+ delete object.x;
+ delete object.x_;
+ delete object.y;
+ delete object.z;
+ Object.setPrototypeOf(object, oldProto);
+ }
+
+ function getObject(i) {
+ var objects = [
+ {},
+ [],
+ function() {},
+ function() {
+ return arguments;
+ }(),
+ function() {
+ 'use strict';
+ return arguments;
+ }(),
+ Object(1),
+ Object(true),
+ Object('bla'),
+ new Date,
+ new RegExp,
+ new Set,
+ new Map,
+ new WeakMap,
+ new WeakSet,
+ new ArrayBuffer(10),
+ new Int32Array(5),
+ Object,
+ Function,
+ Date,
+ RegExp,
+ global
+ ];
+
+ assertEquals(objectCount, objects.length);
+ return objects[i];
+ }
+
+ // Tests depends on this not being there to start with.
+ delete Array.prototype[Symbol.unscopables];
+
+ if (f.length === 1) {
+ for (var i = 0; i < objectCount; i++) {
+ var object = getObject(i);
+ var oldObjectProto = Object.getPrototypeOf(object);
+ f(object);
+ restore(object, oldObjectProto);
+ }
+ } else {
+ for (var i = 0; i < objectCount; i++) {
+ for (var j = 0; j < objectCount; j++) {
+ var object = getObject(i);
+ var proto = getObject(j);
+ if (object === proto) {
+ continue;
+ }
+ var oldObjectProto = Object.getPrototypeOf(object);
+ var oldProtoProto = Object.getPrototypeOf(proto);
+ f(object, proto);
+ restore(object, oldObjectProto);
+ restore(proto, oldProtoProto);
+ }
+ }
+ }
+}
+
+// Test array first, since other tests are changing
+// Array.prototype[Symbol.unscopables].
+function TestArrayPrototypeUnscopables() {
+ var descr = Object.getOwnPropertyDescriptor(Array.prototype,
+ Symbol.unscopables);
+ assertFalse(descr.enumerable);
+ assertFalse(descr.writable);
+ assertTrue(descr.configurable);
+ assertEquals(null, Object.getPrototypeOf(descr.value));
+
+ var copyWithin = 'local copyWithin';
+ var entries = 'local entries';
+ var fill = 'local fill';
+ var find = 'local find';
+ var findIndex = 'local findIndex';
+ var keys = 'local keys';
+ var values = 'local values';
+
+ var array = [];
+ array.toString = 42;
+
+ with (array) {
+ assertEquals('local copyWithin', copyWithin);
+ assertEquals('local entries', entries);
+ assertEquals('local fill', fill);
+ assertEquals('local find', find);
+ assertEquals('local findIndex', findIndex);
+ assertEquals('local keys', keys);
+ assertEquals('local values', values);
+ assertEquals(42, toString);
+ }
+}
+TestArrayPrototypeUnscopables();
+
+
+
+function TestBasics(object) {
+ var x = 1;
+ var y = 2;
+ var z = 3;
+ object.x = 4;
+ object.y = 5;
+
+ with (object) {
+ assertEquals(4, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(1, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+
+ object[Symbol.unscopables] = {x: 0, y: true};
+ with (object) {
+ assertEquals(1, x);
+ assertEquals(2, y);
+ assertEquals(3, z);
+ }
+}
+runTest(TestBasics);
+
+
+function TestUnscopableChain(object) {
+ var x = 1;
+ object.x = 2;
+
+ with (object) {
+ assertEquals(2, x);
+ }
+
+ object[Symbol.unscopables] = {
+ __proto__: {x: true}
+ };
+ with (object) {
+ assertEquals(1, x);
+ }
+}
+runTest(TestUnscopableChain);
+
+
+function TestBasicsSet(object) {
+ var x = 1;
+ object.x = 2;
+
+ with (object) {
+ assertEquals(2, x);
+ }
+
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(1, x);
+ x = 3;
+ assertEquals(3, x);
+ }
+
+ assertEquals(3, x);
+ assertEquals(2, object.x);
+}
+runTest(TestBasicsSet);
+
+
+function TestOnProto(object, proto) {
+ var x = 1;
+ var y = 2;
+ var z = 3;
+ proto.x = 4;
+
+ Object.setPrototypeOf(object, proto);
+ object.y = 5;
+
+ with (object) {
+ assertEquals(4, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+
+ proto[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(1, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+
+ object[Symbol.unscopables] = {y: true};
+ with (object) {
+ assertEquals(4, x);
+ assertEquals(2, y);
+ assertEquals(3, z);
+ }
+
+ proto[Symbol.unscopables] = {y: true};
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(1, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+}
+runTest(TestOnProto);
+
+
+function TestSetBlockedOnProto(object, proto) {
+ var x = 1;
+ object.x = 2;
+
+ with (object) {
+ assertEquals(2, x);
+ }
+
+ Object.setPrototypeOf(object, proto);
+ proto[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(1, x);
+ x = 3;
+ assertEquals(3, x);
+ }
+
+ assertEquals(3, x);
+ assertEquals(2, object.x);
+}
+runTest(TestSetBlockedOnProto);
+
+
+function TestNonObject(object) {
+ var x = 1;
+ var y = 2;
+ object.x = 3;
+ object.y = 4;
+
+ object[Symbol.unscopables] = 'xy';
+ with (object) {
+ assertEquals(3, x);
+ assertEquals(4, y);
+ }
+
+ object[Symbol.unscopables] = null;
+ with (object) {
+ assertEquals(3, x);
+ assertEquals(4, y);
+ }
+}
+runTest(TestNonObject);
+
+
+function TestChangeDuringWith(object) {
+ var x = 1;
+ var y = 2;
+ object.x = 3;
+ object.y = 4;
+
+ with (object) {
+ assertEquals(3, x);
+ assertEquals(4, y);
+ object[Symbol.unscopables] = {x: true};
+ assertEquals(1, x);
+ assertEquals(4, y);
+ }
+}
+runTest(TestChangeDuringWith);
+
+
+function TestChangeDuringWithWithPossibleOptimization(object) {
+ var x = 1;
+ object.x = 2;
+ with (object) {
+ for (var i = 0; i < 1000; i++) {
+ if (i === 500) object[Symbol.unscopables] = {x: true};
+ assertEquals(i < 500 ? 2: 1, x);
+ }
+ }
+}
+TestChangeDuringWithWithPossibleOptimization({});
+
+
+function TestChangeDuringWithWithPossibleOptimization2(object) {
+ var x = 1;
+ object.x = 2;
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ for (var i = 0; i < 1000; i++) {
+ if (i === 500) delete object[Symbol.unscopables];
+ assertEquals(i < 500 ? 1 : 2, x);
+ }
+ }
+}
+TestChangeDuringWithWithPossibleOptimization2({});
+
+
+function TestChangeDuringWithWithPossibleOptimization3(object) {
+ var x = 1;
+ object.x = 2;
+ object[Symbol.unscopables] = {};
+ with (object) {
+ for (var i = 0; i < 1000; i++) {
+ if (i === 500) object[Symbol.unscopables].x = true;
+ assertEquals(i < 500 ? 2 : 1, x);
+ }
+ }
+}
+TestChangeDuringWithWithPossibleOptimization3({});
+
+
+function TestChangeDuringWithWithPossibleOptimization4(object) {
+ var x = 1;
+ object.x = 2;
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ for (var i = 0; i < 1000; i++) {
+ if (i === 500) delete object[Symbol.unscopables].x;
+ assertEquals(i < 500 ? 1 : 2, x);
+ }
+ }
+}
+TestChangeDuringWithWithPossibleOptimization4({});
+
+
+function TestAccessorReceiver(object, proto) {
+ var x = 'local';
+
+ Object.defineProperty(proto, 'x', {
+ get: function() {
+ assertEquals(object, this);
+ return this.x_;
+ },
+ configurable: true
+ });
+ proto.x_ = 'proto';
+
+ Object.setPrototypeOf(object, proto);
+ proto.x_ = 'object';
+
+ with (object) {
+ assertEquals('object', x);
+ }
+}
+runTest(TestAccessorReceiver);
+
+
+function TestUnscopablesGetter(object) {
+ // This test gets really messy when object is the global since the assert
+ // functions are properties on the global object and the call count gets
+ // completely different.
+ if (object === global) return;
+
+ var x = 'local';
+ object.x = 'object';
+
+ var callCount = 0;
+ Object.defineProperty(object, Symbol.unscopables, {
+ get: function() {
+ callCount++;
+ return {};
+ },
+ configurable: true
+ });
+ with (object) {
+ assertEquals('object', x);
+ }
+ // Once for HasBinding
+ assertEquals(1, callCount);
+
+ callCount = 0;
+ Object.defineProperty(object, Symbol.unscopables, {
+ get: function() {
+ callCount++;
+ return {x: true};
+ },
+ configurable: true
+ });
+ with (object) {
+ assertEquals('local', x);
+ }
+ // Once for HasBinding
+ assertEquals(1, callCount);
+
+ callCount = 0;
+ Object.defineProperty(object, Symbol.unscopables, {
+ get: function() {
+ callCount++;
+ return callCount == 1 ? {} : {x: true};
+ },
+ configurable: true
+ });
+ with (object) {
+ x = 1;
+ }
+ // Once for HasBinding
+ assertEquals(1, callCount);
+ assertEquals(1, object.x);
+ assertEquals('local', x);
+ with (object) {
+ x = 2;
+ }
+ // One more HasBinding.
+ assertEquals(2, callCount);
+ assertEquals(1, object.x);
+ assertEquals(2, x);
+}
+runTest(TestUnscopablesGetter);
+
+
+var global = this;
+function TestUnscopablesGetter2() {
+ var x = 'local';
+
+ var globalProto = Object.getPrototypeOf(global);
+ var protos = [{}, [], function() {}, global];
+ var objects = [{}, [], function() {}];
+
+ protos.forEach(function(proto) {
+ objects.forEach(function(object) {
+ Object.defineProperty(proto, 'x', {
+ get: function() {
+ assertEquals(object, this);
+ return 'proto';
+ },
+ configurable: true
+ });
+
+ object.__proto__ = proto;
+ Object.defineProperty(object, 'x', {
+ get: function() {
+ assertEquals(object, this);
+ return 'object';
+ },
+ configurable: true
+ });
+
+ with (object) {
+ assertEquals('object', x);
+ }
+
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals('local', x);
+ }
+
+ delete proto[Symbol.unscopables];
+ delete object[Symbol.unscopables];
+ });
+ });
+
+ delete global.x;
+ Object.setPrototypeOf(global, globalProto);
+}
+TestUnscopablesGetter2();
+
+
+function TestSetterOnBlacklisted(object, proto) {
+ var x = 'local';
+ Object.defineProperty(proto, 'x', {
+ set: function(x) {
+ assertUnreachable();
+ },
+ get: function() {
+ return 'proto';
+ },
+ configurable: true
+ });
+ Object.setPrototypeOf(object, proto);
+ Object.defineProperty(object, 'x', {
+ get: function() {
+ return this.x_;
+ },
+ set: function(x) {
+ this.x_ = x;
+ },
+ configurable: true
+ });
+ object.x_ = 1;
+
+ with (object) {
+ x = 2;
+ assertEquals(2, x);
+ }
+
+ assertEquals(2, object.x);
+
+ object[Symbol.unscopables] = {x: true};
+
+ with (object) {
+ x = 3;
+ assertEquals(3, x);
+ }
+
+ assertEquals(2, object.x);
+}
+runTest(TestSetterOnBlacklisted);
+
+
+function TestObjectsAsUnscopables(object, unscopables) {
+ var x = 1;
+ object.x = 2;
+
+ with (object) {
+ assertEquals(2, x);
+ object[Symbol.unscopables] = unscopables;
+ assertEquals(2, x);
+ }
+}
+runTest(TestObjectsAsUnscopables);
+
+
+function TestAccessorOnUnscopables(object) {
+ var x = 1;
+ object.x = 2;
+
+ var unscopables = {
+ get x() {
+ assertUnreachable();
+ }
+ };
+
+ with (object) {
+ assertEquals(2, x);
+ object[Symbol.unscopables] = unscopables;
+ assertEquals(1, x);
+ }
+}
+runTest(TestAccessorOnUnscopables);
+
+
+function TestLengthUnscopables(object, proto) {
+ var length = 2;
+ with (object) {
+ assertEquals(1, length);
+ object[Symbol.unscopables] = {length: true};
+ assertEquals(2, length);
+ delete object[Symbol.unscopables];
+ assertEquals(1, length);
+ }
+}
+TestLengthUnscopables([1], Array.prototype);
+TestLengthUnscopables(function(x) {}, Function.prototype);
+TestLengthUnscopables(new String('x'), String.prototype);
+
+
+function TestFunctionNameUnscopables(object) {
+ var name = 'local';
+ with (object) {
+ assertEquals('f', name);
+ object[Symbol.unscopables] = {name: true};
+ assertEquals('local', name);
+ delete object[Symbol.unscopables];
+ assertEquals('f', name);
+ }
+}
+TestFunctionNameUnscopables(function f() {});
+
+
+function TestFunctionPrototypeUnscopables() {
+ var prototype = 'local';
+ var f = function() {};
+ var g = function() {};
+ Object.setPrototypeOf(f, g);
+ var fp = f.prototype;
+ var gp = g.prototype;
+ with (f) {
+ assertEquals(fp, prototype);
+ f[Symbol.unscopables] = {prototype: true};
+ assertEquals('local', prototype);
+ delete f[Symbol.unscopables];
+ assertEquals(fp, prototype);
+ }
+}
+TestFunctionPrototypeUnscopables(function() {});
+
+
+function TestFunctionArgumentsUnscopables() {
+ var func = function() {
+ var arguments = 'local';
+ var args = func.arguments;
+ with (func) {
+ assertEquals(args, arguments);
+ func[Symbol.unscopables] = {arguments: true};
+ assertEquals('local', arguments);
+ delete func[Symbol.unscopables];
+ assertEquals(args, arguments);
+ }
+ }
+ func(1);
+}
+TestFunctionArgumentsUnscopables();
+
+
+function TestArgumentsLengthUnscopables() {
+ var func = function() {
+ var length = 'local';
+ with (arguments) {
+ assertEquals(1, length);
+ arguments[Symbol.unscopables] = {length: true};
+ assertEquals('local', length);
+ }
+ }
+ func(1);
+}
+TestArgumentsLengthUnscopables();
+
+
+function TestFunctionCallerUnscopables() {
+ var func = function() {
+ var caller = 'local';
+ with (func) {
+ assertEquals(TestFunctionCallerUnscopables, caller);
+ func[Symbol.unscopables] = {caller: true};
+ assertEquals('local', caller);
+ delete func[Symbol.unscopables];
+ assertEquals(TestFunctionCallerUnscopables, caller);
+ }
+ }
+ func(1);
+}
+TestFunctionCallerUnscopables();
+
+
+function TestGetUnscopablesGetterThrows() {
+ var object = {
+ get x() {
+ assertUnreachable();
+ }
+ };
+ function CustomError() {}
+ Object.defineProperty(object, Symbol.unscopables, {
+ get: function() {
+ throw new CustomError();
+ }
+ });
+ assertThrows(function() {
+ with (object) {
+ x;
+ }
+ }, CustomError);
+}
+TestGetUnscopablesGetterThrows();
diff --git a/deps/v8/test/mjsunit/es6/weak_collections.js b/deps/v8/test/mjsunit/es6/weak_collections.js
deleted file mode 100644
index 74235e7d2..000000000
--- a/deps/v8/test/mjsunit/es6/weak_collections.js
+++ /dev/null
@@ -1,333 +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.
-
-// Flags: --expose-gc --allow-natives-syntax
-
-
-// Note: this test is superseded by harmony/collections.js.
-// IF YOU CHANGE THIS FILE, apply the same changes to harmony/collections.js!
-// TODO(rossberg): Remove once non-weak collections have caught up.
-
-// Test valid getter and setter calls on WeakSets.
-function TestValidSetCalls(m) {
- assertDoesNotThrow(function () { m.add(new Object) });
- assertDoesNotThrow(function () { m.has(new Object) });
- assertDoesNotThrow(function () { m.delete(new Object) });
-}
-TestValidSetCalls(new WeakSet);
-
-
-// Test valid getter and setter calls on WeakMaps
-function TestValidMapCalls(m) {
- assertDoesNotThrow(function () { m.get(new Object) });
- assertDoesNotThrow(function () { m.set(new Object) });
- assertDoesNotThrow(function () { m.has(new Object) });
- assertDoesNotThrow(function () { m.delete(new Object) });
-}
-TestValidMapCalls(new WeakMap);
-
-
-// Test invalid getter and setter calls for WeakMap
-function TestInvalidCalls(m) {
- assertThrows(function () { m.get(undefined) }, TypeError);
- assertThrows(function () { m.set(undefined, 0) }, TypeError);
- assertThrows(function () { m.get(null) }, TypeError);
- assertThrows(function () { m.set(null, 0) }, TypeError);
- assertThrows(function () { m.get(0) }, TypeError);
- assertThrows(function () { m.set(0, 0) }, TypeError);
- assertThrows(function () { m.get('a-key') }, TypeError);
- assertThrows(function () { m.set('a-key', 0) }, TypeError);
-}
-TestInvalidCalls(new WeakMap);
-
-
-// Test expected behavior for WeakSets
-function TestSet(set, key) {
- assertFalse(set.has(key));
- assertSame(undefined, set.add(key));
- assertTrue(set.has(key));
- assertTrue(set.delete(key));
- assertFalse(set.has(key));
- assertFalse(set.delete(key));
- assertFalse(set.has(key));
-}
-function TestSetBehavior(set) {
- for (var i = 0; i < 20; i++) {
- TestSet(set, new Object);
- TestSet(set, i);
- TestSet(set, i / 100);
- TestSet(set, 'key-' + i);
- }
- var keys = [ +0, -0, +Infinity, -Infinity, true, false, null, undefined ];
- for (var i = 0; i < keys.length; i++) {
- TestSet(set, keys[i]);
- }
-}
-TestSet(new WeakSet, new Object);
-
-
-// Test expected mapping behavior for WeakMaps
-function TestMapping(map, key, value) {
- assertSame(undefined, map.set(key, value));
- assertSame(value, map.get(key));
-}
-function TestMapBehavior1(m) {
- TestMapping(m, new Object, 23);
- TestMapping(m, new Object, 'the-value');
- TestMapping(m, new Object, new Object);
-}
-TestMapBehavior1(new WeakMap);
-
-
-// Test expected querying behavior of WeakMaps
-function TestQuery(m) {
- var key = new Object;
- var values = [ 'x', 0, +Infinity, -Infinity, true, false, null, undefined ];
- for (var i = 0; i < values.length; i++) {
- TestMapping(m, key, values[i]);
- assertTrue(m.has(key));
- assertFalse(m.has(new Object));
- }
-}
-TestQuery(new WeakMap);
-
-
-// Test expected deletion behavior of WeakMaps
-function TestDelete(m) {
- var key = new Object;
- TestMapping(m, key, 'to-be-deleted');
- assertTrue(m.delete(key));
- assertFalse(m.delete(key));
- assertFalse(m.delete(new Object));
- assertSame(m.get(key), undefined);
-}
-TestDelete(new WeakMap);
-
-
-// Test GC of WeakMaps with entry
-function TestGC1(m) {
- var key = new Object;
- m.set(key, 'not-collected');
- gc();
- assertSame('not-collected', m.get(key));
-}
-TestGC1(new WeakMap);
-
-
-// Test GC of WeakMaps with chained entries
-function TestGC2(m) {
- var head = new Object;
- for (key = head, i = 0; i < 10; i++, key = m.get(key)) {
- m.set(key, new Object);
- }
- gc();
- var count = 0;
- for (key = head; key != undefined; key = m.get(key)) {
- count++;
- }
- assertEquals(11, count);
-}
-TestGC2(new WeakMap);
-
-
-// Test property attribute [[Enumerable]]
-function TestEnumerable(func) {
- function props(x) {
- var array = [];
- for (var p in x) array.push(p);
- return array.sort();
- }
- assertArrayEquals([], props(func));
- assertArrayEquals([], props(func.prototype));
- assertArrayEquals([], props(new func()));
-}
-TestEnumerable(WeakMap);
-TestEnumerable(WeakSet);
-
-
-// Test arbitrary properties on WeakMaps
-function TestArbitrary(m) {
- function TestProperty(map, property, value) {
- map[property] = value;
- assertEquals(value, map[property]);
- }
- for (var i = 0; i < 20; i++) {
- TestProperty(m, i, 'val' + i);
- TestProperty(m, 'foo' + i, 'bar' + i);
- }
- TestMapping(m, new Object, 'foobar');
-}
-TestArbitrary(new WeakMap);
-
-
-// Test direct constructor call
-assertThrows(function() { WeakMap(); }, TypeError);
-assertThrows(function() { WeakSet(); }, TypeError);
-
-
-// Test some common JavaScript idioms for WeakMaps
-var m = new WeakMap;
-assertTrue(m instanceof WeakMap);
-assertTrue(WeakMap.prototype.set instanceof Function)
-assertTrue(WeakMap.prototype.get instanceof Function)
-assertTrue(WeakMap.prototype.has instanceof Function)
-assertTrue(WeakMap.prototype.delete instanceof Function)
-assertTrue(WeakMap.prototype.clear instanceof Function)
-
-
-// Test some common JavaScript idioms for WeakSets
-var s = new WeakSet;
-assertTrue(s instanceof WeakSet);
-assertTrue(WeakSet.prototype.add instanceof Function)
-assertTrue(WeakSet.prototype.has instanceof Function)
-assertTrue(WeakSet.prototype.delete instanceof Function)
-assertTrue(WeakSet.prototype.clear instanceof Function)
-
-
-// Test class of instance and prototype.
-assertEquals("WeakMap", %_ClassOf(new WeakMap))
-assertEquals("Object", %_ClassOf(WeakMap.prototype))
-assertEquals("WeakSet", %_ClassOf(new WeakSet))
-assertEquals("Object", %_ClassOf(WeakMap.prototype))
-
-
-// Test name of constructor.
-assertEquals("WeakMap", WeakMap.name);
-assertEquals("WeakSet", WeakSet.name);
-
-
-// Test prototype property of WeakMap and WeakSet.
-function TestPrototype(C) {
- assertTrue(C.prototype instanceof Object);
- assertEquals({
- value: {},
- writable: false,
- enumerable: false,
- configurable: false
- }, Object.getOwnPropertyDescriptor(C, "prototype"));
-}
-TestPrototype(WeakMap);
-TestPrototype(WeakSet);
-
-
-// Test constructor property of the WeakMap and WeakSet prototype.
-function TestConstructor(C) {
- assertFalse(C === Object.prototype.constructor);
- assertSame(C, C.prototype.constructor);
- assertSame(C, (new C).__proto__.constructor);
-}
-TestConstructor(WeakMap);
-TestConstructor(WeakSet);
-
-
-// Test the WeakMap and WeakSet global properties themselves.
-function TestDescriptor(global, C) {
- assertEquals({
- value: C,
- writable: true,
- enumerable: false,
- configurable: true
- }, Object.getOwnPropertyDescriptor(global, C.name));
-}
-TestDescriptor(this, WeakMap);
-TestDescriptor(this, WeakSet);
-
-
-// Regression test for WeakMap prototype.
-assertTrue(WeakMap.prototype.constructor === WeakMap)
-assertTrue(Object.getPrototypeOf(WeakMap.prototype) === Object.prototype)
-
-
-// Regression test for issue 1617: The prototype of the WeakMap constructor
-// needs to be unique (i.e. different from the one of the Object constructor).
-assertFalse(WeakMap.prototype === Object.prototype);
-var o = Object.create({});
-assertFalse("get" in o);
-assertFalse("set" in o);
-assertEquals(undefined, o.get);
-assertEquals(undefined, o.set);
-var o = Object.create({}, { myValue: {
- value: 10,
- enumerable: false,
- configurable: true,
- writable: true
-}});
-assertEquals(10, o.myValue);
-
-
-// Regression test for issue 1884: Invoking any of the methods for Harmony
-// maps, sets, or weak maps, with a wrong type of receiver should be throwing
-// a proper TypeError.
-var alwaysBogus = [ undefined, null, true, "x", 23, {} ];
-var bogusReceiversTestSet = [
- { proto: WeakMap.prototype,
- funcs: [ 'get', 'set', 'has', 'delete' ],
- receivers: alwaysBogus.concat([ new WeakSet ]),
- },
- { proto: WeakSet.prototype,
- funcs: [ 'add', 'has', 'delete' ],
- receivers: alwaysBogus.concat([ new WeakMap ]),
- },
-];
-function TestBogusReceivers(testSet) {
- for (var i = 0; i < testSet.length; i++) {
- var proto = testSet[i].proto;
- var funcs = testSet[i].funcs;
- var receivers = testSet[i].receivers;
- for (var j = 0; j < funcs.length; j++) {
- var func = proto[funcs[j]];
- for (var k = 0; k < receivers.length; k++) {
- assertThrows(function () { func.call(receivers[k], {}) }, TypeError);
- }
- }
- }
-}
-TestBogusReceivers(bogusReceiversTestSet);
-
-
-// Test WeakMap clear
-(function() {
- var k = new Object();
- var w = new WeakMap();
- w.set(k, 23);
- assertTrue(w.has(k));
- assertEquals(23, w.get(k));
- w.clear();
- assertFalse(w.has(k));
- assertEquals(undefined, w.get(k));
-})();
-
-
-// Test WeakSet clear
-(function() {
- var k = new Object();
- var w = new WeakSet();
- w.add(k);
- assertTrue(w.has(k));
- w.clear();
- assertFalse(w.has(k));
-})();
diff --git a/deps/v8/test/mjsunit/es7/object-observe-debug-event.js b/deps/v8/test/mjsunit/es7/object-observe-debug-event.js
new file mode 100644
index 000000000..ed627642c
--- /dev/null
+++ b/deps/v8/test/mjsunit/es7/object-observe-debug-event.js
@@ -0,0 +1,51 @@
+// 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.
+
+// Flags: --expose-debug-as debug
+
+Debug = debug.Debug;
+
+var base_id = -1;
+var exception = null;
+var expected = [
+ "enqueue #1",
+ "willHandle #1",
+ "didHandle #1",
+];
+
+function assertLog(msg) {
+ print(msg);
+ assertTrue(expected.length > 0);
+ assertEquals(expected.shift(), msg);
+ if (!expected.length) {
+ Debug.setListener(null);
+ }
+}
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.AsyncTaskEvent) return;
+ try {
+ if (base_id < 0)
+ base_id = event_data.id();
+ var id = event_data.id() - base_id + 1;
+ assertEquals("Object.observe", event_data.name());
+ assertLog(event_data.type() + " #" + id);
+ } catch (e) {
+ print(e + e.stack)
+ exception = e;
+ }
+}
+
+Debug.setListener(listener);
+
+var obj = {};
+Object.observe(obj, function(changes) {
+ print(change.type + " " + change.name + " " + change.oldValue);
+});
+
+obj.foo = 1;
+obj.zoo = 2;
+obj.foo = 3;
+
+assertNull(exception);
diff --git a/deps/v8/test/mjsunit/es7/object-observe-runtime.js b/deps/v8/test/mjsunit/es7/object-observe-runtime.js
new file mode 100644
index 000000000..769cd1b29
--- /dev/null
+++ b/deps/v8/test/mjsunit/es7/object-observe-runtime.js
@@ -0,0 +1,18 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+// These tests are meant to ensure that that the Object.observe runtime
+// functions are hardened.
+
+var obj = {};
+%SetIsObserved(obj);
+assertThrows(function() {
+ %SetIsObserved(obj);
+});
+
+assertThrows(function() {
+ %SetIsObserved(this);
+});
diff --git a/deps/v8/test/mjsunit/es7/object-observe.js b/deps/v8/test/mjsunit/es7/object-observe.js
index 7bb579f0c..5af205ead 100644
--- a/deps/v8/test/mjsunit/es7/object-observe.js
+++ b/deps/v8/test/mjsunit/es7/object-observe.js
@@ -25,8 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-proxies --harmony-collections
-// Flags: --harmony-symbols --allow-natives-syntax
+// Flags: --harmony-proxies
+// Flags: --allow-natives-syntax
var allObservers = [];
function reset() {
@@ -1234,8 +1234,9 @@ observer2.assertCallbackRecords([
// Updating length on large (slow) array
reset();
-var slow_arr = new Array(1000000000);
+var slow_arr = %NormalizeElements([]);
slow_arr[500000000] = 'hello';
+slow_arr.length = 1000000000;
Object.observe(slow_arr, observer.callback);
var spliceRecords;
function slowSpliceCallback(records) {
@@ -1685,8 +1686,10 @@ var obj = { __proto__: fun };
Object.observe(obj, observer.callback);
obj.prototype = 7;
Object.deliverChangeRecords(observer.callback);
-observer.assertNotCalled();
-
+observer.assertRecordCount(1);
+observer.assertCallbackRecords([
+ { object: obj, name: 'prototype', type: 'add' },
+]);
// Check that changes in observation status are detected in all IC states and
// in optimized code, especially in cases usually using fast elements.
diff --git a/deps/v8/test/mjsunit/fast-non-keyed.js b/deps/v8/test/mjsunit/fast-non-keyed.js
index c2f7fc7f9..6a300ab1e 100644
--- a/deps/v8/test/mjsunit/fast-non-keyed.js
+++ b/deps/v8/test/mjsunit/fast-non-keyed.js
@@ -108,6 +108,6 @@ var obj3 = {};
AddProps3(obj3);
assertTrue(%HasFastProperties(obj3));
-var bad_name = {};
-bad_name[".foo"] = 0;
-assertFalse(%HasFastProperties(bad_name));
+var funny_name = {};
+funny_name[".foo"] = 0;
+assertTrue(%HasFastProperties(funny_name));
diff --git a/deps/v8/test/mjsunit/fast-prototype.js b/deps/v8/test/mjsunit/fast-prototype.js
index cdcc1a9ed..98647612f 100644
--- a/deps/v8/test/mjsunit/fast-prototype.js
+++ b/deps/v8/test/mjsunit/fast-prototype.js
@@ -50,6 +50,8 @@ function DoProtoMagic(proto, set__proto__) {
(new Sub()).__proto__ = proto;
} else {
Sub.prototype = proto;
+ // Need to instantiate Sub to mark .prototype as prototype.
+ new Sub();
}
}
@@ -72,10 +74,15 @@ function test(use_new, add_first, set__proto__, same_map_as) {
// Still fast
assertTrue(%HasFastProperties(proto));
AddProps(proto);
- // After we add all those properties it went slow mode again :-(
- assertFalse(%HasFastProperties(proto));
+ if (set__proto__) {
+ // After we add all those properties it went slow mode again :-(
+ assertFalse(%HasFastProperties(proto));
+ } else {
+ // .prototype keeps it fast.
+ assertTrue(%HasFastProperties(proto));
+ }
}
- if (same_map_as && !add_first) {
+ if (same_map_as && !add_first && set__proto__) {
assertTrue(%HaveSameMap(same_map_as, proto));
}
return proto;
diff --git a/deps/v8/test/mjsunit/global-const-var-conflicts.js b/deps/v8/test/mjsunit/global-const-var-conflicts.js
index 2fca96f9f..3b87e3d7b 100644
--- a/deps/v8/test/mjsunit/global-const-var-conflicts.js
+++ b/deps/v8/test/mjsunit/global-const-var-conflicts.js
@@ -41,17 +41,20 @@ try { eval("var b"); } catch (e) { caught++; assertTrue(e instanceof TypeError);
assertEquals(0, b);
try { eval("var b = 1"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
assertEquals(0, b);
+assertEquals(0, caught);
eval("var c");
try { eval("const c"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
assertTrue(typeof c == 'undefined');
+assertEquals(1, caught);
try { eval("const c = 1"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
-assertEquals(1, c);
+assertEquals(undefined, c);
+assertEquals(2, caught);
eval("var d = 0");
try { eval("const d"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
-assertEquals(undefined, d);
+assertEquals(0, d);
+assertEquals(3, caught);
try { eval("const d = 1"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
-assertEquals(1, d);
-
-assertEquals(0, caught);
+assertEquals(0, d);
+assertEquals(4, caught);
diff --git a/deps/v8/test/mjsunit/harmony/array-fill.js b/deps/v8/test/mjsunit/harmony/array-fill.js
index 571233f6f..eae18d113 100644
--- a/deps/v8/test/mjsunit/harmony/array-fill.js
+++ b/deps/v8/test/mjsunit/harmony/array-fill.js
@@ -4,7 +4,7 @@
// Flags: --harmony-arrays
-assertEquals(1, Array.prototype.find.length);
+assertEquals(1, Array.prototype.fill.length);
assertArrayEquals([].fill(8), []);
assertArrayEquals([0, 0, 0, 0, 0].fill(), [undefined, undefined, undefined, undefined, undefined]);
@@ -22,7 +22,7 @@ assertArrayEquals([0, 0, 0, 0, 0].fill(8, -1, -3), [0, 0, 0, 0, 0]);
assertArrayEquals([0, 0, 0, 0, 0].fill(8, undefined, 4), [8, 8, 8, 8, 0]);
assertArrayEquals([ , , , , 0].fill(8, 1, 3), [, 8, 8, , 0]);
-// If the range if empty, the array is not actually modified and
+// If the range is empty, the array is not actually modified and
// should not throw, even when applied to a frozen object.
assertArrayEquals(Object.freeze([1, 2, 3]).fill(0, 0, 0), [1, 2, 3]);
diff --git a/deps/v8/test/mjsunit/harmony/arrow-functions.js b/deps/v8/test/mjsunit/harmony/arrow-functions.js
new file mode 100644
index 000000000..22b1c94f7
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/arrow-functions.js
@@ -0,0 +1,48 @@
+// 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.
+
+// Flags: --harmony-arrow-functions
+
+// Arrow functions are like functions, except they throw when using the
+// "new" operator on them.
+assertEquals("function", typeof (() => {}));
+assertEquals(Function.prototype, Object.getPrototypeOf(() => {}));
+assertThrows("new (() => {})", TypeError);
+
+// Check the different syntax variations
+assertEquals(1, (() => 1)());
+assertEquals(2, (a => a + 1)(1));
+assertEquals(3, (() => { return 3; })());
+assertEquals(4, (a => { return a + 3; })(1));
+assertEquals(5, ((a, b) => a + b)(1, 4));
+assertEquals(6, ((a, b) => { return a + b; })(1, 5));
+
+// The following are tests from:
+// http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax
+
+// Empty arrow function returns undefined
+var empty = () => {};
+assertEquals(undefined, empty());
+
+// Single parameter case needs no parentheses around parameter list
+var identity = x => x;
+assertEquals(empty, identity(empty));
+
+// No need for parentheses even for lower-precedence expression body
+var square = x => x * x;
+assertEquals(9, square(3));
+
+// Parenthesize the body to return an object literal expression
+var key_maker = val => ({key: val});
+assertEquals(empty, key_maker(empty).key);
+
+// Statement body needs braces, must use 'return' explicitly if not void
+var evens = [0, 2, 4, 6, 8];
+assertEquals([1, 3, 5, 7, 9], evens.map(v => v + 1));
+
+var fives = [];
+[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].forEach(v => {
+ if (v % 5 === 0) fives.push(v);
+});
+assertEquals([5, 10], fives);
diff --git a/deps/v8/test/mjsunit/harmony/block-conflicts.js b/deps/v8/test/mjsunit/harmony/block-conflicts.js
index 3aa9d2222..1eedb682a 100644
--- a/deps/v8/test/mjsunit/harmony/block-conflicts.js
+++ b/deps/v8/test/mjsunit/harmony/block-conflicts.js
@@ -29,7 +29,6 @@
// Test for conflicting variable bindings.
-// TODO(ES6): properly activate extended mode
"use strict";
function CheckException(e) {
@@ -40,9 +39,18 @@ function CheckException(e) {
}
+function TestGlobal(s,e) {
+ try {
+ return eval(s + e);
+ } catch (x) {
+ return CheckException(x);
+ }
+}
+
+
function TestFunction(s,e) {
try {
- return eval("(function(){" + s + ";return " + e + "})")();
+ return eval("(function(){" + s + " return " + e + "})")();
} catch (x) {
return CheckException(x);
}
@@ -51,7 +59,7 @@ function TestFunction(s,e) {
function TestBlock(s,e) {
try {
- return eval("(function(){ if (true) { " + s + "; }; return " + e + "})")();
+ return eval("(function(){ {" + s + "} return " + e + "})")();
} catch (x) {
return CheckException(x);
}
@@ -60,76 +68,123 @@ function TestBlock(s,e) {
function TestAll(expected,s,opt_e) {
var e = "";
var msg = s;
- if (opt_e) { e = opt_e; msg += "; " + opt_e; }
- assertEquals(expected, TestFunction(s,e), "function:'" + msg + "'");
- assertEquals(expected, TestBlock(s,e), "block:'" + msg + "'");
+ if (opt_e) { e = opt_e; msg += opt_e; }
+ assertEquals(expected === 'LocalConflict' ? 'NoConflict' : expected,
+ TestGlobal(s,e), "global:'" + msg + "'");
+ assertEquals(expected === 'LocalConflict' ? 'NoConflict' : expected,
+ TestFunction(s,e), "function:'" + msg + "'");
+ assertEquals(expected === 'LocalConflict' ? 'Conflict' : expected,
+ TestBlock(s,e), "block:'" + msg + "'");
}
function TestConflict(s) {
TestAll('Conflict', s);
- TestAll('Conflict', 'eval("' + s + '")');
+ TestAll('Conflict', 'eval("' + s + '");');
}
-
function TestNoConflict(s) {
TestAll('NoConflict', s, "'NoConflict'");
- TestAll('NoConflict', 'eval("' + s + '")', "'NoConflict'");
+ TestAll('NoConflict', 'eval("' + s + '");', "'NoConflict'");
}
-var letbinds = [ "let x",
- "let x = 0",
- "let x = undefined",
- "function x() { }",
- "let x = function() {}",
- "let x, y",
- "let y, x",
- "const x = 0",
- "const x = undefined",
- "const x = function() {}",
- "const x = 2, y = 3",
- "const y = 4, x = 5",
+function TestLocalConflict(s) {
+ TestAll('LocalConflict', s, "'NoConflict'");
+ TestAll('NoConflict', 'eval("' + s + '");', "'NoConflict'");
+}
+
+var letbinds = [ "let x;",
+ "let x = 0;",
+ "let x = undefined;",
+ "let x = function() {};",
+ "let x, y;",
+ "let y, x;",
+ "const x = 0;",
+ "const x = undefined;",
+ "const x = function() {};",
+ "const x = 2, y = 3;",
+ "const y = 4, x = 5;",
];
-var varbinds = [ "var x",
- "var x = 0",
- "var x = undefined",
- "var x = function() {}",
- "var x, y",
- "var y, x",
+var varbinds = [ "var x;",
+ "var x = 0;",
+ "var x = undefined;",
+ "var x = function() {};",
+ "var x, y;",
+ "var y, x;",
];
-
+var funbind = "function x() {}";
for (var l = 0; l < letbinds.length; ++l) {
// Test conflicting let/var bindings.
for (var v = 0; v < varbinds.length; ++v) {
// Same level.
- TestConflict(letbinds[l] +'; ' + varbinds[v]);
- TestConflict(varbinds[v] +'; ' + letbinds[l]);
+ TestConflict(letbinds[l] + varbinds[v]);
+ TestConflict(varbinds[v] + letbinds[l]);
// Different level.
- TestConflict(letbinds[l] +'; {' + varbinds[v] + '; }');
- TestConflict('{ ' + varbinds[v] +'; }' + letbinds[l]);
+ TestConflict(letbinds[l] + '{' + varbinds[v] + '}');
+ TestConflict('{' + varbinds[v] +'}' + letbinds[l]);
+ TestNoConflict(varbinds[v] + '{' + letbinds[l] + '}');
+ TestNoConflict('{' + letbinds[l] + '}' + varbinds[v]);
+ // For loop.
+ TestConflict('for (' + letbinds[l] + '0;) {' + varbinds[v] + '}');
+ TestNoConflict('for (' + varbinds[v] + '0;) {' + letbinds[l] + '}');
}
// Test conflicting let/let bindings.
for (var k = 0; k < letbinds.length; ++k) {
// Same level.
- TestConflict(letbinds[l] +'; ' + letbinds[k]);
- TestConflict(letbinds[k] +'; ' + letbinds[l]);
+ TestConflict(letbinds[l] + letbinds[k]);
+ TestConflict(letbinds[k] + letbinds[l]);
// Different level.
- TestNoConflict(letbinds[l] +'; { ' + letbinds[k] + '; }');
- TestNoConflict('{ ' + letbinds[k] +'; } ' + letbinds[l]);
+ TestNoConflict(letbinds[l] + '{ ' + letbinds[k] + '}');
+ TestNoConflict('{' + letbinds[k] +'} ' + letbinds[l]);
+ // For loop.
+ TestNoConflict('for (' + letbinds[l] + '0;) {' + letbinds[k] + '}');
+ TestNoConflict('for (' + letbinds[k] + '0;) {' + letbinds[l] + '}');
}
+ // Test conflicting function/let bindings.
+ // Same level.
+ TestConflict(letbinds[l] + funbind);
+ TestConflict(funbind + letbinds[l]);
+ // Different level.
+ TestNoConflict(letbinds[l] + '{' + funbind + '}');
+ TestNoConflict('{' + funbind + '}' + letbinds[l]);
+ TestNoConflict(funbind + '{' + letbinds[l] + '}');
+ TestNoConflict('{' + letbinds[l] + '}' + funbind);
+ // For loop.
+ TestNoConflict('for (' + letbinds[l] + '0;) {' + funbind + '}');
+
// Test conflicting parameter/let bindings.
- TestConflict('(function (x) { ' + letbinds[l] + '; })()');
+ TestConflict('(function(x) {' + letbinds[l] + '})();');
+}
+
+// Test conflicting function/var bindings.
+for (var v = 0; v < varbinds.length; ++v) {
+ // Same level.
+ TestLocalConflict(varbinds[v] + funbind);
+ TestLocalConflict(funbind + varbinds[v]);
+ // Different level.
+ TestLocalConflict(funbind + '{' + varbinds[v] + '}');
+ TestLocalConflict('{' + varbinds[v] +'}' + funbind);
+ TestNoConflict(varbinds[v] + '{' + funbind + '}');
+ TestNoConflict('{' + funbind + '}' + varbinds[v]);
+ // For loop.
+ TestNoConflict('for (' + varbinds[v] + '0;) {' + funbind + '}');
}
// Test conflicting catch/var bindings.
for (var v = 0; v < varbinds.length; ++v) {
- TestConflict('try {} catch (x) { ' + varbinds[v] + '; }');
+ TestConflict('try {} catch(x) {' + varbinds[v] + '}');
}
// Test conflicting parameter/var bindings.
for (var v = 0; v < varbinds.length; ++v) {
- TestNoConflict('(function (x) { ' + varbinds[v] + '; })()');
+ TestNoConflict('(function (x) {' + varbinds[v] + '})();');
}
+
+// Test conflicting catch/function bindings.
+TestNoConflict('try {} catch(x) {' + funbind + '}');
+
+// Test conflicting parameter/function bindings.
+TestNoConflict('(function (x) {' + funbind + '})();');
diff --git a/deps/v8/test/mjsunit/harmony/block-const-assign.js b/deps/v8/test/mjsunit/harmony/block-const-assign.js
index 8297a558a..b71729e8a 100644
--- a/deps/v8/test/mjsunit/harmony/block-const-assign.js
+++ b/deps/v8/test/mjsunit/harmony/block-const-assign.js
@@ -30,9 +30,8 @@
// Test that we throw early syntax errors in harmony mode
// when using an immutable binding in an assigment or with
// prefix/postfix decrement/increment operators.
-// TODO(ES6): properly activate extended mode
-"use strict";
+"use strict";
// Function local const.
function constDecl0(use) {
diff --git a/deps/v8/test/mjsunit/harmony/block-early-errors.js b/deps/v8/test/mjsunit/harmony/block-early-errors.js
index 791f001af..8ed5ea84e 100644
--- a/deps/v8/test/mjsunit/harmony/block-early-errors.js
+++ b/deps/v8/test/mjsunit/harmony/block-early-errors.js
@@ -30,7 +30,6 @@
function CheckException(e) {
var string = e.toString();
assertInstanceof(e, SyntaxError);
- assertTrue(string.indexOf("Illegal let") >= 0);
}
function Check(str) {
@@ -49,7 +48,7 @@ function Check(str) {
}
// Check for early syntax errors when using let
-// declarations outside of extended mode.
+// declarations outside of strict mode.
Check("let x;");
Check("let x = 1;");
Check("let x, y;");
diff --git a/deps/v8/test/mjsunit/harmony/block-for.js b/deps/v8/test/mjsunit/harmony/block-for.js
index e84f0d2fe..110f1ccf4 100644
--- a/deps/v8/test/mjsunit/harmony/block-for.js
+++ b/deps/v8/test/mjsunit/harmony/block-for.js
@@ -27,7 +27,6 @@
// Flags: --harmony-scoping
-// TODO(ES6): properly activate extended mode
"use strict";
function props(x) {
@@ -93,7 +92,6 @@ assertEquals('ab', result);
// Check that there is exactly one variable without initializer
// in a for-in statement with let variables.
-// TODO(ES6): properly activate extended mode
assertThrows("function foo() { 'use strict'; for (let in {}) { } }", SyntaxError);
assertThrows("function foo() { 'use strict'; for (let x = 3 in {}) { } }", SyntaxError);
assertThrows("function foo() { 'use strict'; for (let x, y in {}) { } }", SyntaxError);
@@ -102,7 +100,7 @@ assertThrows("function foo() { 'use strict'; for (let x, y = 4 in {}) { } }", Sy
assertThrows("function foo() { 'use strict'; for (let x = 3, y = 4 in {}) { } }", SyntaxError);
-// In a normal for statement the iteration variable is not
+// In a normal for statement the iteration variable is
// freshly allocated for each iteration.
function closures1() {
let a = [];
@@ -110,7 +108,7 @@ function closures1() {
a.push(function () { return i; });
}
for (let j = 0; j < 5; ++j) {
- assertEquals(5, a[j]());
+ assertEquals(j, a[j]());
}
}
closures1();
@@ -123,13 +121,45 @@ function closures2() {
b.push(function () { return j; });
}
for (let k = 0; k < 5; ++k) {
- assertEquals(5, a[k]());
- assertEquals(15, b[k]());
+ assertEquals(k, a[k]());
+ assertEquals(k + 10, b[k]());
}
}
closures2();
+function closure_in_for_init() {
+ let a = [];
+ for (let i = 0, f = function() { return i }; i < 5; ++i) {
+ a.push(f);
+ }
+ for (let k = 0; k < 5; ++k) {
+ assertEquals(0, a[k]());
+ }
+}
+closure_in_for_init();
+
+
+function closure_in_for_cond() {
+ let a = [];
+ for (let i = 0; a.push(function () { return i; }), i < 5; ++i) { }
+ for (let k = 0; k < 5; ++k) {
+ assertEquals(k, a[k]());
+ }
+}
+closure_in_for_next();
+
+
+function closure_in_for_next() {
+ let a = [];
+ for (let i = 0; i < 5; a.push(function () { return i; }), ++i) { }
+ for (let k = 0; k < 5; ++k) {
+ assertEquals(k + 1, a[k]());
+ }
+}
+closure_in_for_next();
+
+
// In a for-in statement the iteration variable is fresh
// for earch iteration.
function closures3(x) {
diff --git a/deps/v8/test/mjsunit/harmony/block-leave.js b/deps/v8/test/mjsunit/harmony/block-leave.js
index a7f6b6947..87d35b396 100644
--- a/deps/v8/test/mjsunit/harmony/block-leave.js
+++ b/deps/v8/test/mjsunit/harmony/block-leave.js
@@ -27,7 +27,6 @@
// Flags: --harmony-scoping
-// TODO(ES6): properly activate extended mode
"use strict";
// We want to test the context chain shape. In each of the tests cases
diff --git a/deps/v8/test/mjsunit/harmony/block-let-crankshaft.js b/deps/v8/test/mjsunit/harmony/block-let-crankshaft.js
index 5888fd24f..e8e00b200 100644
--- a/deps/v8/test/mjsunit/harmony/block-let-crankshaft.js
+++ b/deps/v8/test/mjsunit/harmony/block-let-crankshaft.js
@@ -27,12 +27,12 @@
// Flags: --harmony-scoping --allow-natives-syntax
-// TODO(ES6): properly activate extended mode
"use strict";
// Check that the following functions are optimizable.
var functions = [ f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14,
- f15, f16, f17, f18, f19, f20, f21, f22, f23 ];
+ f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26,
+ f27, f28, f29, f30, f31, f32, f33];
for (var i = 0; i < functions.length; ++i) {
var func = functions[i];
@@ -156,6 +156,184 @@ function f23() {
(function() { x; });
}
+function f24() {
+ let x = 1;
+ {
+ let x = 2;
+ {
+ let x = 3;
+ assertEquals(3, x);
+ }
+ assertEquals(2, x);
+ }
+ assertEquals(1, x);
+}
+
+function f25() {
+ {
+ let x = 2;
+ L: {
+ let x = 3;
+ assertEquals(3, x);
+ break L;
+ assertTrue(false);
+ }
+ assertEquals(2, x);
+ }
+ assertTrue(true);
+}
+
+function f26() {
+ {
+ let x = 1;
+ L: {
+ let x = 2;
+ {
+ let x = 3;
+ assertEquals(3, x);
+ break L;
+ assertTrue(false);
+ }
+ assertTrue(false);
+ }
+ assertEquals(1, x);
+ }
+}
+
+
+function f27() {
+ do {
+ let x = 4;
+ assertEquals(4,x);
+ {
+ let x = 5;
+ assertEquals(5, x);
+ continue;
+ assertTrue(false);
+ }
+ } while (false);
+}
+
+function f28() {
+ label: for (var i = 0; i < 10; ++i) {
+ let x = 'middle' + i;
+ for (var j = 0; j < 10; ++j) {
+ let x = 'inner' + j;
+ continue label;
+ }
+ }
+}
+
+function f29() {
+ // Verify that the context is correctly set in the stack frame after exiting
+ // from with.
+
+ let x = 'outer';
+ label: {
+ let x = 'inner';
+ break label;
+ }
+ f(); // The context could be restored from the stack after the call.
+ assertEquals('outer', x);
+
+ function f() {
+ assertEquals('outer', x);
+ };
+}
+
+function f30() {
+ let x = 'outer';
+ for (var i = 0; i < 10; ++i) {
+ let x = 'inner';
+ continue;
+ }
+ f();
+ assertEquals('outer', x);
+
+ function f() {
+ assertEquals('outer', x);
+ };
+}
+
+function f31() {
+ {
+ let x = 'outer';
+ label: for (var i = 0; assertEquals('outer', x), i < 10; ++i) {
+ let x = 'middle' + i;
+ {
+ let x = 'inner' + j;
+ continue label;
+ }
+ }
+ assertEquals('outer', x);
+ }
+}
+
+var c = true;
+
+function f32() {
+ {
+ let x = 'outer';
+ L: {
+ {
+ let x = 'inner';
+ if (c) {
+ break L;
+ }
+ }
+ foo();
+ }
+ }
+
+ function foo() {
+ return 'bar';
+ }
+}
+
+function f33() {
+ {
+ let x = 'outer';
+ L: {
+ {
+ let x = 'inner';
+ if (c) {
+ break L;
+ }
+ foo();
+ }
+ }
+ }
+
+ function foo() {
+ return 'bar';
+ }
+}
+
+function TestThrow() {
+ function f() {
+ let x = 'outer';
+ {
+ let x = 'inner';
+ throw x;
+ }
+ }
+ for (var i = 0; i < 5; i++) {
+ try {
+ f();
+ } catch (e) {
+ assertEquals('inner', e);
+ }
+ }
+ %OptimizeFunctionOnNextCall(f);
+ try {
+ f();
+ } catch (e) {
+ assertEquals('inner', e);
+ }
+ assertOptimized(f);
+}
+
+TestThrow();
// Test that temporal dead zone semantics for function and block scoped
// let bindings are handled by the optimizing compiler.
@@ -208,9 +386,59 @@ function TestFunctionContext(s) {
}
}
+function TestBlockLocal(s) {
+ 'use strict';
+ var func = eval("(function baz(){ { " + s + "; } })");
+ print("Testing:");
+ print(func);
+ for (var i = 0; i < 5; ++i) {
+ try {
+ func();
+ assertUnreachable();
+ } catch (e) {
+ assertInstanceof(e, ReferenceError);
+ }
+ }
+ %OptimizeFunctionOnNextCall(func);
+ try {
+ func();
+ assertUnreachable();
+ } catch (e) {
+ assertInstanceof(e, ReferenceError);
+ }
+}
+
+function TestBlockContext(s) {
+ 'use strict';
+ var func = eval("(function baz(){ { " + s + "; (function() { x; }); } })");
+ print("Testing:");
+ print(func);
+ for (var i = 0; i < 5; ++i) {
+ print(i);
+ try {
+ func();
+ assertUnreachable();
+ } catch (e) {
+ assertInstanceof(e, ReferenceError);
+ }
+ }
+ print("optimize");
+ %OptimizeFunctionOnNextCall(func);
+ try {
+ print("call");
+ func();
+ assertUnreachable();
+ } catch (e) {
+ print("catch");
+ assertInstanceof(e, ReferenceError);
+ }
+}
+
function TestAll(s) {
TestFunctionLocal(s);
TestFunctionContext(s);
+ TestBlockLocal(s);
+ TestBlockContext(s);
}
// Use before initialization in declaration statement.
@@ -229,34 +457,28 @@ TestAll('x++; let x;');
TestAll('let y = x; const x = 1;');
-function f(x, b) {
- let y = (b ? y : x) + 42;
+function f(x) {
+ let y = x + 42;
return y;
}
-function g(x, b) {
+function g(x) {
{
- let y = (b ? y : x) + 42;
+ let y = x + 42;
return y;
}
}
for (var i=0; i<10; i++) {
- f(i, false);
- g(i, false);
+ f(i);
+ g(i);
}
%OptimizeFunctionOnNextCall(f);
%OptimizeFunctionOnNextCall(g);
-try {
- f(42, true);
-} catch (e) {
- assertInstanceof(e, ReferenceError);
-}
+f(12);
+g(12);
-try {
- g(42, true);
-} catch (e) {
- assertInstanceof(e, ReferenceError);
-}
+assertTrue(%GetOptimizationStatus(f) != 2);
+assertTrue(%GetOptimizationStatus(g) != 2);
diff --git a/deps/v8/test/mjsunit/harmony/block-let-declaration.js b/deps/v8/test/mjsunit/harmony/block-let-declaration.js
index 4ddeefdba..44a0049a4 100644
--- a/deps/v8/test/mjsunit/harmony/block-let-declaration.js
+++ b/deps/v8/test/mjsunit/harmony/block-let-declaration.js
@@ -28,7 +28,7 @@
// Flags: --harmony-scoping
// Test let declarations in various settings.
-// TODO(ES6): properly activate extended mode
+
"use strict";
// Global
@@ -56,11 +56,11 @@ if (true) {
// an exception in eval code during parsing, before even compiling or executing
// the code. Thus the generated function is not called here.
function TestLocalThrows(str, expect) {
- assertThrows("(function(){ 'use strict'; " + str + "})", expect);
+ assertThrows("(function(arg){ 'use strict'; " + str + "})", expect);
}
function TestLocalDoesNotThrow(str) {
- assertDoesNotThrow("(function(){ 'use strict'; " + str + "})()");
+ assertDoesNotThrow("(function(arg){ 'use strict'; " + str + "})()");
}
// Test let declarations in statement positions.
@@ -108,6 +108,28 @@ TestLocalDoesNotThrow("for (;false;) var x;");
TestLocalDoesNotThrow("switch (true) { case true: var x; }");
TestLocalDoesNotThrow("switch (true) { default: var x; }");
+// Test that redeclarations of functions are only allowed in outermost scope.
+TestLocalThrows("{ let f; var f; }");
+TestLocalThrows("{ var f; let f; }");
+TestLocalThrows("{ function f() {} let f; }");
+TestLocalThrows("{ let f; function f() {} }");
+TestLocalThrows("{ function f() {} var f; }");
+TestLocalThrows("{ var f; function f() {} }");
+TestLocalThrows("{ function f() {} function f() {} }");
+TestLocalThrows("function f() {} let f;");
+TestLocalThrows("let f; function f() {}");
+TestLocalDoesNotThrow("function arg() {}");
+TestLocalDoesNotThrow("function f() {} var f;");
+TestLocalDoesNotThrow("var f; function f() {}");
+TestLocalDoesNotThrow("function f() {} function f() {}");
+
+function g(f) {
+ function f() { return 1 }
+ return f()
+}
+assertEquals(1, g(function() { return 2 }))
+
+
// Test function declarations in source element and
// sloppy statement positions.
function f() {
diff --git a/deps/v8/test/mjsunit/harmony/block-let-semantics.js b/deps/v8/test/mjsunit/harmony/block-let-semantics.js
index d14e7cd36..a37b795b0 100644
--- a/deps/v8/test/mjsunit/harmony/block-let-semantics.js
+++ b/deps/v8/test/mjsunit/harmony/block-let-semantics.js
@@ -27,7 +27,6 @@
// Flags: --harmony-scoping
-// TODO(ES6): properly activate extended mode
"use strict";
// Test temporal dead zone semantics of let bound variables in
diff --git a/deps/v8/test/mjsunit/harmony/block-scoping.js b/deps/v8/test/mjsunit/harmony/block-scoping.js
index 31194d99f..001d9fbfd 100644
--- a/deps/v8/test/mjsunit/harmony/block-scoping.js
+++ b/deps/v8/test/mjsunit/harmony/block-scoping.js
@@ -28,7 +28,6 @@
// Flags: --allow-natives-syntax --harmony-scoping
// Test functionality of block scopes.
-// TODO(ES6): properly activate extended mode
"use strict";
// Hoisting of var declarations.
@@ -40,8 +39,10 @@ function f1() {
assertEquals(1, x)
assertEquals(undefined, y)
}
+for (var j = 0; j < 5; ++j) f1();
+%OptimizeFunctionOnNextCall(f1);
f1();
-
+assertTrue(%GetOptimizationStatus(f1) != 2);
// Dynamic lookup in and through block contexts.
function f2(one) {
@@ -59,8 +60,8 @@ function f2(one) {
assertEquals(6, eval('v'));
}
}
-f2(1);
+f2(1);
// Lookup in and through block contexts.
function f3(one) {
@@ -76,10 +77,13 @@ function f3(one) {
assertEquals(4, z);
assertEquals(5, u);
assertEquals(6, v);
-
}
}
+for (var j = 0; j < 5; ++j) f3(1);
+%OptimizeFunctionOnNextCall(f3);
f3(1);
+assertTrue(%GetOptimizationStatus(f3) != 2);
+
// Dynamic lookup from closure.
diff --git a/deps/v8/test/mjsunit/harmony/debug-blockscopes.js b/deps/v8/test/mjsunit/harmony/debug-blockscopes.js
index f56a306b6..2db49427c 100644
--- a/deps/v8/test/mjsunit/harmony/debug-blockscopes.js
+++ b/deps/v8/test/mjsunit/harmony/debug-blockscopes.js
@@ -29,7 +29,6 @@
// The functions used for testing backtraces. They are at the top to make the
// testing of source line/column easier.
-// TODO(ES6): properly activate extended mode
"use strict";
// Get the Debug object exposed from the debug context global object.
@@ -412,10 +411,12 @@ function for_loop_3() {
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Block,
+ debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x:3}, 0, exec_state);
- CheckScopeContent({}, 1, exec_state);
+ CheckScopeContent({x:3}, 1, exec_state);
+ CheckScopeContent({}, 2, exec_state);
};
for_loop_3();
EndTest();
@@ -434,11 +435,13 @@ function for_loop_4() {
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Block,
debug.ScopeType.Block,
+ debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x:5}, 0, exec_state);
CheckScopeContent({x:3}, 1, exec_state);
- CheckScopeContent({}, 2, exec_state);
+ CheckScopeContent({x:3}, 2, exec_state);
+ CheckScopeContent({}, 3, exec_state);
};
for_loop_4();
EndTest();
@@ -455,10 +458,12 @@ function for_loop_5() {
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Block,
+ debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x:3,y:5}, 0, exec_state);
- CheckScopeContent({}, 1, exec_state);
+ CheckScopeContent({x:3,y:5}, 1, exec_state);
+ CheckScopeContent({}, 2, exec_state);
};
for_loop_5();
EndTest();
diff --git a/deps/v8/test/mjsunit/harmony/debug-evaluate-blockscopes.js b/deps/v8/test/mjsunit/harmony/debug-evaluate-blockscopes.js
index d6ce8b2b6..16885d009 100644
--- a/deps/v8/test/mjsunit/harmony/debug-evaluate-blockscopes.js
+++ b/deps/v8/test/mjsunit/harmony/debug-evaluate-blockscopes.js
@@ -30,7 +30,6 @@
// Test debug evaluation for functions without local context, but with
// nested catch contexts.
-// TODO(ES6): properly activate extended mode
"use strict";
var x;
diff --git a/deps/v8/test/mjsunit/regress/regress-2336.js b/deps/v8/test/mjsunit/harmony/empty-for.js
index edfff6021..02211260f 100644
--- a/deps/v8/test/mjsunit/regress/regress-2336.js
+++ b/deps/v8/test/mjsunit/harmony/empty-for.js
@@ -1,4 +1,4 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
+// 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:
@@ -25,29 +25,48 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --expose-debug-as debug --expose-gc
+// Flags: --harmony-scoping
-// Check that we can cope with a debug listener that runs in the
-// GC epilogue and causes enough allocation to trigger a new GC during
-// the epilogue.
+"use strict";
-var f = eval("(function f() { return 42; })");
+function for_const() {
+ for (const x = 1;;) {
+ if (x == 1) break;
+ }
+ for (const x = 1; x < 2;) {
+ if (x == 1) break;
+ }
+ for (const x = 1;; 0) {
+ if (x == 1) break;
+ }
+}
-Debug = debug.Debug;
+for_const();
-var called = false;
+function for_let() {
+ for (let x;;) {
+ if (!x) break;
+ }
+ for (let x; x < 2;) {
+ if (!x) break;
+ }
+ for (let x = 1;; x++) {
+ if (x == 2) break;
+ }
+}
+
+for_let();
-function listener(event, exec_state, event_data, data) {
- if (event == Debug.DebugEvent.ScriptCollected) {
- if (!called) {
- called = true;
- gc();
- }
+function for_var() {
+ for (var x;;) {
+ if (!x) break;
+ }
+ for (var x; x < 2;) {
+ if (!x) break;
+ }
+ for (var x = 1;; x++) {
+ if (x == 2) break;
}
-};
+}
-Debug.scripts();
-Debug.setListener(listener);
-f = void 0;
-gc();
-assertTrue(called);
+for_var();
diff --git a/deps/v8/test/mjsunit/harmony/generators-debug-liveedit.js b/deps/v8/test/mjsunit/harmony/generators-debug-liveedit.js
new file mode 100644
index 000000000..341ef483c
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/generators-debug-liveedit.js
@@ -0,0 +1,119 @@
+// 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.
+
+// Flags: --expose-debug-as debug --harmony-generators
+
+var Debug = debug.Debug;
+var LiveEdit = Debug.LiveEdit;
+
+unique_id = 0;
+
+var Generator = (function*(){}).constructor;
+
+function assertIteratorResult(value, done, result) {
+ assertEquals({value: value, done: done}, result);
+}
+
+function MakeGenerator() {
+ // Prevents eval script caching.
+ unique_id++;
+ return Generator('callback',
+ "/* " + unique_id + "*/\n" +
+ "yield callback();\n" +
+ "return 'Cat';\n");
+}
+
+function MakeFunction() {
+ // Prevents eval script caching.
+ unique_id++;
+ return Function('callback',
+ "/* " + unique_id + "*/\n" +
+ "callback();\n" +
+ "return 'Cat';\n");
+}
+
+// First, try MakeGenerator with no perturbations.
+(function(){
+ var generator = MakeGenerator();
+ function callback() {};
+ var iter = generator(callback);
+ assertIteratorResult(undefined, false, iter.next());
+ assertIteratorResult("Cat", true, iter.next());
+})();
+
+function patch(fun, from, to) {
+ function debug() {
+ var log = new Array();
+ var script = Debug.findScript(fun);
+ var pos = script.source.indexOf(from);
+ try {
+ LiveEdit.TestApi.ApplySingleChunkPatch(script, pos, from.length, to,
+ log);
+ } finally {
+ print("Change log: " + JSON.stringify(log) + "\n");
+ }
+ }
+ Debug.ExecuteInDebugContext(debug, false);
+}
+
+// Try to edit a MakeGenerator while it's running, then again while it's
+// stopped.
+(function(){
+ var generator = MakeGenerator();
+
+ var gen_patch_attempted = false;
+ function attempt_gen_patch() {
+ assertFalse(gen_patch_attempted);
+ gen_patch_attempted = true;
+ assertThrows(function() { patch(generator, "'Cat'", "'Capybara'") },
+ LiveEdit.Failure);
+ };
+ var iter = generator(attempt_gen_patch);
+ assertIteratorResult(undefined, false, iter.next());
+ // Patch should not succeed because there is a live generator activation on
+ // the stack.
+ assertIteratorResult("Cat", true, iter.next());
+ assertTrue(gen_patch_attempted);
+
+ // At this point one iterator is live, but closed, so the patch will succeed.
+ patch(generator, "'Cat'", "'Capybara'");
+ iter = generator(function(){});
+ assertIteratorResult(undefined, false, iter.next());
+ // Patch successful.
+ assertIteratorResult("Capybara", true, iter.next());
+
+ // Patching will fail however when a live iterator is suspended.
+ iter = generator(function(){});
+ assertIteratorResult(undefined, false, iter.next());
+ assertThrows(function() { patch(generator, "'Capybara'", "'Tapir'") },
+ LiveEdit.Failure);
+ assertIteratorResult("Capybara", true, iter.next());
+
+ // Try to patch functions with activations inside and outside generator
+ // function activations. We should succeed in the former case, but not in the
+ // latter.
+ var fun_outside = MakeFunction();
+ var fun_inside = MakeFunction();
+ var fun_patch_attempted = false;
+ var fun_patch_restarted = false;
+ function attempt_fun_patches() {
+ if (fun_patch_attempted) {
+ assertFalse(fun_patch_restarted);
+ fun_patch_restarted = true;
+ return;
+ }
+ fun_patch_attempted = true;
+ // Patching outside a generator activation must fail.
+ assertThrows(function() { patch(fun_outside, "'Cat'", "'Cobra'") },
+ LiveEdit.Failure);
+ // Patching inside a generator activation may succeed.
+ patch(fun_inside, "'Cat'", "'Koala'");
+ }
+ iter = generator(function() { return fun_inside(attempt_fun_patches) });
+ assertEquals('Cat',
+ fun_outside(function () {
+ assertIteratorResult('Koala', false, iter.next());
+ assertTrue(fun_patch_restarted);
+ }));
+})();
diff --git a/deps/v8/test/mjsunit/harmony/generators-iteration.js b/deps/v8/test/mjsunit/harmony/generators-iteration.js
index d86a20f9e..1a793678d 100644
--- a/deps/v8/test/mjsunit/harmony/generators-iteration.js
+++ b/deps/v8/test/mjsunit/harmony/generators-iteration.js
@@ -337,6 +337,50 @@ TestGenerator(
"foo",
[2, "1foo3", 5, "4foo6", "foofoo"]);
+// Yield with no arguments yields undefined.
+TestGenerator(
+ function* g26() { return yield yield },
+ [undefined, undefined, undefined],
+ "foo",
+ [undefined, "foo", "foo"]);
+
+// A newline causes the parser to stop looking for an argument to yield.
+TestGenerator(
+ function* g27() {
+ yield
+ 3
+ return
+ },
+ [undefined, undefined],
+ "foo",
+ [undefined, undefined]);
+
+// TODO(wingo): We should use TestGenerator for these, except that
+// currently yield* will unconditionally propagate a throw() to the
+// delegate iterator, which fails for these iterators that don't have
+// throw(). See http://code.google.com/p/v8/issues/detail?id=3484.
+(function() {
+ function* g28() {
+ yield* [1, 2, 3];
+ }
+ var iter = g28();
+ assertIteratorResult(1, false, iter.next());
+ assertIteratorResult(2, false, iter.next());
+ assertIteratorResult(3, false, iter.next());
+ assertIteratorResult(undefined, true, iter.next());
+})();
+
+(function() {
+ function* g29() {
+ yield* "abc";
+ }
+ var iter = g29();
+ assertIteratorResult("a", false, iter.next());
+ assertIteratorResult("b", false, iter.next());
+ assertIteratorResult("c", false, iter.next());
+ assertIteratorResult(undefined, true, iter.next());
+})();
+
// Generator function instances.
TestGenerator(GeneratorFunction(),
[undefined],
@@ -375,12 +419,16 @@ function TestDelegatingYield() {
function next() {
return results[i++];
}
- return { next: next }
+ var iter = { next: next };
+ var ret = {};
+ ret[Symbol.iterator] = function() { return iter; };
+ return ret;
}
function* yield_results(expected) {
return yield* results(expected);
}
- function collect_results(iter) {
+ function collect_results(iterable) {
+ var iter = iterable[Symbol.iterator]();
var ret = [];
var result;
do {
diff --git a/deps/v8/test/mjsunit/harmony/generators-parsing.js b/deps/v8/test/mjsunit/harmony/generators-parsing.js
index 2a4a68c37..21790b0e1 100644
--- a/deps/v8/test/mjsunit/harmony/generators-parsing.js
+++ b/deps/v8/test/mjsunit/harmony/generators-parsing.js
@@ -35,6 +35,40 @@ function* g() { yield 3; yield 4; }
// Yield expressions.
function* g() { (yield 3) + (yield 4); }
+// Yield without a RHS.
+function* g() { yield; }
+function* g() { yield }
+function* g() {
+ yield
+}
+function* g() { (yield) }
+function* g() { [yield] }
+function* g() { {yield} }
+function* g() { yield, yield }
+function* g() { yield; yield }
+function* g() { (yield) ? yield : yield }
+function* g() {
+ (yield)
+ ? yield
+ : yield
+}
+
+// If yield has a RHS, it needs to start on the same line. The * in a
+// yield* counts as starting the RHS.
+function* g() {
+ yield *
+ foo
+}
+assertThrows("function* g() { yield\n* foo }", SyntaxError);
+assertEquals(undefined,
+ (function*(){
+ yield
+ 3
+ })().next().value);
+
+// A YieldExpression is not a LogicalORExpression.
+assertThrows("function* g() { yield ? yield : yield }", SyntaxError);
+
// You can have a generator in strict mode.
function* g() { "use strict"; yield 3; yield 4; }
@@ -50,14 +84,10 @@ function* g() { yield 1; return 2; yield "dead"; }
// Named generator expression.
(function* g() { yield 3; });
-// A generator without a yield is specified as causing an early error. This
-// behavior is currently unimplemented. See
-// https://bugs.ecmascript.org/show_bug.cgi?id=1283.
+// You can have a generator without a yield.
function* g() { }
-// A YieldExpression in the RHS of a YieldExpression is currently specified as
-// causing an early error. This behavior is currently unimplemented. See
-// https://bugs.ecmascript.org/show_bug.cgi?id=1283.
+// A YieldExpression is valid as the RHS of a YieldExpression.
function* g() { yield yield 1; }
function* g() { yield 3 + (yield 4); }
@@ -86,9 +116,6 @@ assertThrows("function* g() { yield: 1 }", SyntaxError)
// functions.
function* g() { function f() { yield (yield + yield (0)); } }
-// Yield needs a RHS.
-assertThrows("function* g() { yield; }", SyntaxError);
-
// Yield in a generator is not an identifier.
assertThrows("function* g() { yield = 10; }", SyntaxError);
diff --git a/deps/v8/test/mjsunit/harmony/generators-poisoned-properties.js b/deps/v8/test/mjsunit/harmony/generators-poisoned-properties.js
new file mode 100644
index 000000000..39a583ec9
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/generators-poisoned-properties.js
@@ -0,0 +1,42 @@
+// 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.
+
+// Flags: --harmony-generators
+
+function assertIteratorResult(value, done, result) {
+ assertEquals({value: value, done: done}, result);
+}
+
+function test(f) {
+ var cdesc = Object.getOwnPropertyDescriptor(f, "caller");
+ var adesc = Object.getOwnPropertyDescriptor(f, "arguments");
+
+ assertFalse(cdesc.enumerable);
+ assertFalse(cdesc.configurable);
+
+ assertFalse(adesc.enumerable);
+ assertFalse(adesc.configurable);
+
+ assertSame(cdesc.get, cdesc.set);
+ assertSame(cdesc.get, adesc.get);
+ assertSame(cdesc.get, adesc.set);
+
+ assertTrue(cdesc.get instanceof Function);
+ assertEquals(0, cdesc.get.length);
+ assertThrows(cdesc.get, TypeError);
+
+ assertThrows(function() { return f.caller; }, TypeError);
+ assertThrows(function() { f.caller = 42; }, TypeError);
+ assertThrows(function() { return f.arguments; }, TypeError);
+ assertThrows(function() { f.arguments = 42; }, TypeError);
+}
+
+function *sloppy() { test(sloppy); }
+function *strict() { "use strict"; test(strict); }
+
+test(sloppy);
+test(strict);
+
+assertIteratorResult(undefined, true, sloppy().next());
+assertIteratorResult(undefined, true, strict().next());
diff --git a/deps/v8/test/mjsunit/harmony/generators-runtime.js b/deps/v8/test/mjsunit/harmony/generators-runtime.js
index aef063b6c..9fb707549 100644
--- a/deps/v8/test/mjsunit/harmony/generators-runtime.js
+++ b/deps/v8/test/mjsunit/harmony/generators-runtime.js
@@ -29,9 +29,8 @@
// Test aspects of the generator runtime.
-// FIXME(wingo): Replace this reference with a more official link.
// See:
-// http://wiki.ecmascript.org/lib/exe/fetch.php?cache=cache&media=harmony:es6_generator_object_model_3-29-13.png
+// http://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorfunction-objects
function f() { }
function* g() { yield 1; }
@@ -55,7 +54,16 @@ function TestGeneratorFunctionInstance() {
var f_desc = Object.getOwnPropertyDescriptor(f, prop);
var g_desc = Object.getOwnPropertyDescriptor(g, prop);
assertEquals(f_desc.configurable, g_desc.configurable, prop);
- assertEquals(f_desc.writable, g_desc.writable, prop);
+ if (prop === 'arguments' || prop === 'caller') {
+ // Unlike sloppy functions, which have read-only data arguments and caller
+ // properties, sloppy generators have a poison pill implemented via
+ // accessors
+ assertFalse('writable' in g_desc, prop);
+ assertTrue(g_desc.get instanceof Function, prop);
+ assertEquals(g_desc.get, g_desc.set, prop);
+ } else {
+ assertEquals(f_desc.writable, g_desc.writable, prop);
+ }
assertEquals(f_desc.enumerable, g_desc.enumerable, prop);
}
}
@@ -92,6 +100,16 @@ function TestGeneratorObjectPrototype() {
found_property_names.sort();
assertArrayEquals(expected_property_names, found_property_names);
+
+ iterator_desc = Object.getOwnPropertyDescriptor(GeneratorObjectPrototype,
+ Symbol.iterator);
+ assertTrue(iterator_desc !== undefined);
+ assertFalse(iterator_desc.writable);
+ assertFalse(iterator_desc.enumerable);
+ assertFalse(iterator_desc.configurable);
+
+ // The generator object's "iterator" function is just the identity.
+ assertSame(iterator_desc.value.call(42), 42);
}
TestGeneratorObjectPrototype();
diff --git a/deps/v8/test/mjsunit/harmony/private.js b/deps/v8/test/mjsunit/harmony/private.js
index 225799831..4b29fd863 100644
--- a/deps/v8/test/mjsunit/harmony/private.js
+++ b/deps/v8/test/mjsunit/harmony/private.js
@@ -25,7 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-symbols --harmony-collections
// Flags: --expose-gc --allow-natives-syntax
var symbols = []
@@ -115,8 +114,8 @@ TestToBoolean()
function TestToNumber() {
for (var i in symbols) {
- assertSame(NaN, Number(symbols[i]).valueOf())
- assertSame(NaN, symbols[i] + 0)
+ assertThrows(function() { Number(symbols[i]); }, TypeError);
+ assertThrows(function() { symbols[i] + 0; }, TypeError);
}
}
TestToNumber()
@@ -342,3 +341,18 @@ function TestGetOwnPropertySymbols() {
assertEquals(syms, [publicSymbol, publicSymbol2])
}
TestGetOwnPropertySymbols()
+
+
+function TestSealAndFreeze(freeze) {
+ var sym = %CreatePrivateSymbol("private")
+ var obj = {}
+ obj[sym] = 1
+ freeze(obj)
+ obj[sym] = 2
+ assertEquals(2, obj[sym])
+ assertTrue(delete obj[sym])
+ assertEquals(undefined, obj[sym])
+}
+TestSealAndFreeze(Object.seal)
+TestSealAndFreeze(Object.freeze)
+TestSealAndFreeze(Object.preventExtensions)
diff --git a/deps/v8/test/mjsunit/harmony/proxies-example-membrane.js b/deps/v8/test/mjsunit/harmony/proxies-example-membrane.js
index a645a6603..7b2af722f 100644
--- a/deps/v8/test/mjsunit/harmony/proxies-example-membrane.js
+++ b/deps/v8/test/mjsunit/harmony/proxies-example-membrane.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony
+// Flags: --harmony --harmony-proxies
// A simple no-op handler. Adapted from:
diff --git a/deps/v8/test/mjsunit/harmony/proxies-hash.js b/deps/v8/test/mjsunit/harmony/proxies-hash.js
index 789de35f6..65d2d3c56 100644
--- a/deps/v8/test/mjsunit/harmony/proxies-hash.js
+++ b/deps/v8/test/mjsunit/harmony/proxies-hash.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-proxies --harmony-collections
+// Flags: --harmony-proxies
// Helper.
diff --git a/deps/v8/test/mjsunit/harmony/proxies-json.js b/deps/v8/test/mjsunit/harmony/proxies-json.js
index 539c5a84c..eba10a145 100644
--- a/deps/v8/test/mjsunit/harmony/proxies-json.js
+++ b/deps/v8/test/mjsunit/harmony/proxies-json.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony
+// Flags: --harmony-proxies
function testStringify(expected, object) {
// Test fast case that bails out to slow case.
diff --git a/deps/v8/test/mjsunit/harmony/proxies-symbols.js b/deps/v8/test/mjsunit/harmony/proxies-symbols.js
index 8920e3996..52353c036 100644
--- a/deps/v8/test/mjsunit/harmony/proxies-symbols.js
+++ b/deps/v8/test/mjsunit/harmony/proxies-symbols.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-proxies --harmony-symbols
+// Flags: --harmony-proxies
// Helper.
diff --git a/deps/v8/test/mjsunit/harmony/proxies-with-unscopables.js b/deps/v8/test/mjsunit/harmony/proxies-with-unscopables.js
new file mode 100644
index 000000000..b982480fe
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/proxies-with-unscopables.js
@@ -0,0 +1,153 @@
+// 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.
+
+// Flags: --harmony-unscopables
+// Flags: --harmony-proxies
+
+
+// TODO(arv): Once proxies can intercept symbols, add more tests.
+
+
+function TestBasics() {
+ var log = [];
+
+ var proxy = Proxy.create({
+ getPropertyDescriptor: function(key) {
+ log.push(key);
+ if (key === 'x') {
+ return {
+ value: 1,
+ configurable: true
+ };
+ }
+ return undefined;
+ }
+ });
+
+ var x = 'local';
+
+ with (proxy) {
+ assertEquals(1, x);
+ }
+
+ // One 'x' for HasBinding and one for GetBindingValue
+ assertEquals(['assertEquals', 'x', 'x'], log);
+}
+TestBasics();
+
+
+function TestInconsistent() {
+ var log = [];
+ var calls = 0;
+
+ var proxy = Proxy.create({
+ getPropertyDescriptor: function(key) {
+ log.push(key);
+ if (key === 'x' && calls < 1) {
+ calls++;
+ return {
+ value: 1,
+ configurable: true
+ };
+ }
+ return undefined;
+ }
+ });
+
+ var x = 'local';
+
+ with (proxy) {
+ assertEquals(void 0, x);
+ }
+
+ // One 'x' for HasBinding and one for GetBindingValue
+ assertEquals(['assertEquals', 'x', 'x'], log);
+}
+TestInconsistent();
+
+
+function TestUseProxyAsUnscopables() {
+ var x = 1;
+ var object = {
+ x: 2
+ };
+ var calls = 0;
+ var proxy = Proxy.create({
+ has: function(key) {
+ calls++;
+ assertEquals('x', key);
+ return calls === 2;
+ },
+ getPropertyDescriptor: function(key) {
+ assertUnreachable();
+ }
+ });
+
+ object[Symbol.unscopables] = proxy;
+
+ with (object) {
+ assertEquals(2, x);
+ assertEquals(1, x);
+ }
+
+ // HasBinding, HasBinding
+ assertEquals(2, calls);
+}
+TestUseProxyAsUnscopables();
+
+
+function TestThrowInHasUnscopables() {
+ var x = 1;
+ var object = {
+ x: 2
+ };
+
+ function CustomError() {}
+
+ var calls = 0;
+ var proxy = Proxy.create({
+ has: function(key) {
+ if (calls++ === 0) {
+ throw new CustomError();
+ }
+ assertUnreachable();
+ },
+ getPropertyDescriptor: function(key) {
+ assertUnreachable();
+ }
+ });
+
+ object[Symbol.unscopables] = proxy;
+
+ assertThrows(function() {
+ with (object) {
+ x;
+ }
+ }, CustomError);
+}
+TestThrowInHasUnscopables();
+
+
+var global = this;
+function TestGlobalShouldIgnoreUnscopables() {
+ global.x = 1;
+ var proxy = Proxy.create({
+ getPropertyDescriptor: function() {
+ assertUnreachable();
+ }
+ });
+ global[Symbol.unscopables] = proxy;
+
+ assertEquals(1, global.x);
+ assertEquals(1, x);
+
+ global.x = 2;
+ assertEquals(2, global.x);
+ assertEquals(2, x);
+
+ x = 3;
+ assertEquals(3, global.x);
+ assertEquals(3, x);
+}
+TestGlobalShouldIgnoreUnscopables();
diff --git a/deps/v8/test/mjsunit/harmony/proxies.js b/deps/v8/test/mjsunit/harmony/proxies.js
index 00e605f8d..b082c0669 100644
--- a/deps/v8/test/mjsunit/harmony/proxies.js
+++ b/deps/v8/test/mjsunit/harmony/proxies.js
@@ -1807,7 +1807,7 @@ TestKeysThrow({
},
})
-TestKeysThrow([], {
+TestKeysThrow({
get getOwnPropertyNames() {
return function() { return [1, 2] }
},
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-3426.js b/deps/v8/test/mjsunit/harmony/regress/regress-3426.js
new file mode 100644
index 000000000..c3b11a179
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/regress/regress-3426.js
@@ -0,0 +1,7 @@
+// 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.
+
+// Flags: --harmony-scoping
+
+assertThrows("(function() { 'use strict'; { let f; var f; } })", SyntaxError);
diff --git a/deps/v8/test/mjsunit/harmony/set-prototype-of.js b/deps/v8/test/mjsunit/harmony/set-prototype-of.js
index 02bd5e2ee..810220d1a 100644
--- a/deps/v8/test/mjsunit/harmony/set-prototype-of.js
+++ b/deps/v8/test/mjsunit/harmony/set-prototype-of.js
@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-symbols
-
function getObjects() {
function func() {}
diff --git a/deps/v8/test/mjsunit/harmony/string-codepointat.js b/deps/v8/test/mjsunit/harmony/string-codepointat.js
new file mode 100644
index 000000000..411b0f23c
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/string-codepointat.js
@@ -0,0 +1,91 @@
+// 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.
+
+// Flags: --harmony-strings
+
+// Tests taken from:
+// https://github.com/mathiasbynens/String.prototype.codePointAt
+
+assertEquals(String.prototype.codePointAt.length, 1);
+assertEquals(String.prototype.propertyIsEnumerable("codePointAt"), false);
+
+// String that starts with a BMP symbol
+assertEquals("abc\uD834\uDF06def".codePointAt(""), 0x61);
+assertEquals("abc\uD834\uDF06def".codePointAt("_"), 0x61);
+assertEquals("abc\uD834\uDF06def".codePointAt(), 0x61);
+assertEquals("abc\uD834\uDF06def".codePointAt(-Infinity), undefined);
+assertEquals("abc\uD834\uDF06def".codePointAt(-1), undefined);
+assertEquals("abc\uD834\uDF06def".codePointAt(-0), 0x61);
+assertEquals("abc\uD834\uDF06def".codePointAt(0), 0x61);
+assertEquals("abc\uD834\uDF06def".codePointAt(3), 0x1D306);
+assertEquals("abc\uD834\uDF06def".codePointAt(4), 0xDF06);
+assertEquals("abc\uD834\uDF06def".codePointAt(5), 0x64);
+assertEquals("abc\uD834\uDF06def".codePointAt(42), undefined);
+assertEquals("abc\uD834\uDF06def".codePointAt(Infinity), undefined);
+assertEquals("abc\uD834\uDF06def".codePointAt(Infinity), undefined);
+assertEquals("abc\uD834\uDF06def".codePointAt(NaN), 0x61);
+assertEquals("abc\uD834\uDF06def".codePointAt(false), 0x61);
+assertEquals("abc\uD834\uDF06def".codePointAt(null), 0x61);
+assertEquals("abc\uD834\uDF06def".codePointAt(undefined), 0x61);
+
+// String that starts with an astral symbol
+assertEquals("\uD834\uDF06def".codePointAt(""), 0x1D306);
+assertEquals("\uD834\uDF06def".codePointAt("1"), 0xDF06);
+assertEquals("\uD834\uDF06def".codePointAt("_"), 0x1D306);
+assertEquals("\uD834\uDF06def".codePointAt(), 0x1D306);
+assertEquals("\uD834\uDF06def".codePointAt(-1), undefined);
+assertEquals("\uD834\uDF06def".codePointAt(-0), 0x1D306);
+assertEquals("\uD834\uDF06def".codePointAt(0), 0x1D306);
+assertEquals("\uD834\uDF06def".codePointAt(1), 0xDF06);
+assertEquals("\uD834\uDF06def".codePointAt(42), undefined);
+assertEquals("\uD834\uDF06def".codePointAt(false), 0x1D306);
+assertEquals("\uD834\uDF06def".codePointAt(null), 0x1D306);
+assertEquals("\uD834\uDF06def".codePointAt(undefined), 0x1D306);
+
+// Lone high surrogates
+assertEquals("\uD834abc".codePointAt(""), 0xD834);
+assertEquals("\uD834abc".codePointAt("_"), 0xD834);
+assertEquals("\uD834abc".codePointAt(), 0xD834);
+assertEquals("\uD834abc".codePointAt(-1), undefined);
+assertEquals("\uD834abc".codePointAt(-0), 0xD834);
+assertEquals("\uD834abc".codePointAt(0), 0xD834);
+assertEquals("\uD834abc".codePointAt(false), 0xD834);
+assertEquals("\uD834abc".codePointAt(NaN), 0xD834);
+assertEquals("\uD834abc".codePointAt(null), 0xD834);
+assertEquals("\uD834abc".codePointAt(undefined), 0xD834);
+
+// Lone low surrogates
+assertEquals("\uDF06abc".codePointAt(""), 0xDF06);
+assertEquals("\uDF06abc".codePointAt("_"), 0xDF06);
+assertEquals("\uDF06abc".codePointAt(), 0xDF06);
+assertEquals("\uDF06abc".codePointAt(-1), undefined);
+assertEquals("\uDF06abc".codePointAt(-0), 0xDF06);
+assertEquals("\uDF06abc".codePointAt(0), 0xDF06);
+assertEquals("\uDF06abc".codePointAt(false), 0xDF06);
+assertEquals("\uDF06abc".codePointAt(NaN), 0xDF06);
+assertEquals("\uDF06abc".codePointAt(null), 0xDF06);
+assertEquals("\uDF06abc".codePointAt(undefined), 0xDF06);
+
+assertThrows(function() {
+ String.prototype.codePointAt.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.codePointAt.call(undefined, 4);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.codePointAt.call(null);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.codePointAt.call(null, 4);
+}, TypeError);
+assertEquals(String.prototype.codePointAt.call(42, 0), 0x34);
+assertEquals(String.prototype.codePointAt.call(42, 1), 0x32);
+assertEquals(String.prototype.codePointAt.call({
+ toString: function() { return "abc"; }
+}, 2), 0x63);
+var tmp = 0;
+assertEquals(String.prototype.codePointAt.call({
+ toString: function() { ++tmp; return String(tmp); }
+}, 0), 0x31);
+assertEquals(tmp, 1);
diff --git a/deps/v8/test/mjsunit/harmony/string-fromcodepoint.js b/deps/v8/test/mjsunit/harmony/string-fromcodepoint.js
new file mode 100644
index 000000000..97ecf0eec
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/string-fromcodepoint.js
@@ -0,0 +1,62 @@
+// 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.
+
+// Flags: --harmony-strings
+
+// Tests taken from:
+// https://github.com/mathiasbynens/String.fromCodePoint
+
+assertEquals(String.fromCodePoint.length, 1);
+assertEquals(String.propertyIsEnumerable("fromCodePoint"), false);
+
+assertEquals(String.fromCodePoint(""), "\0");
+assertEquals(String.fromCodePoint(), "");
+assertEquals(String.fromCodePoint(-0), "\0");
+assertEquals(String.fromCodePoint(0), "\0");
+assertEquals(String.fromCodePoint(0x1D306), "\uD834\uDF06");
+assertEquals(
+ String.fromCodePoint(0x1D306, 0x61, 0x1D307),
+ "\uD834\uDF06a\uD834\uDF07");
+assertEquals(String.fromCodePoint(0x61, 0x62, 0x1D307), "ab\uD834\uDF07");
+assertEquals(String.fromCodePoint(false), "\0");
+assertEquals(String.fromCodePoint(null), "\0");
+
+assertThrows(function() { String.fromCodePoint("_"); }, RangeError);
+assertThrows(function() { String.fromCodePoint("+Infinity"); }, RangeError);
+assertThrows(function() { String.fromCodePoint("-Infinity"); }, RangeError);
+assertThrows(function() { String.fromCodePoint(-1); }, RangeError);
+assertThrows(function() { String.fromCodePoint(0x10FFFF + 1); }, RangeError);
+assertThrows(function() { String.fromCodePoint(3.14); }, RangeError);
+assertThrows(function() { String.fromCodePoint(3e-2); }, RangeError);
+assertThrows(function() { String.fromCodePoint(-Infinity); }, RangeError);
+assertThrows(function() { String.fromCodePoint(+Infinity); }, RangeError);
+assertThrows(function() { String.fromCodePoint(NaN); }, RangeError);
+assertThrows(function() { String.fromCodePoint(undefined); }, RangeError);
+assertThrows(function() { String.fromCodePoint({}); }, RangeError);
+assertThrows(function() { String.fromCodePoint(/./); }, RangeError);
+assertThrows(function() { String.fromCodePoint({
+ valueOf: function() { throw Error(); } });
+}, Error);
+assertThrows(function() { String.fromCodePoint({
+ valueOf: function() { throw Error(); } });
+}, Error);
+var tmp = 0x60;
+assertEquals(String.fromCodePoint({
+ valueOf: function() { ++tmp; return tmp; }
+}), "a");
+assertEquals(tmp, 0x61);
+
+var counter = Math.pow(2, 15) * 3 / 2;
+var result = [];
+while (--counter >= 0) {
+ result.push(0); // one code unit per symbol
+}
+String.fromCodePoint.apply(null, result); // must not throw
+
+var counter = Math.pow(2, 15) * 3 / 2;
+var result = [];
+while (--counter >= 0) {
+ result.push(0xFFFF + 1); // two code units per symbol
+}
+String.fromCodePoint.apply(null, result); // must not throw
diff --git a/deps/v8/test/mjsunit/harmony/typeof.js b/deps/v8/test/mjsunit/harmony/typeof.js
deleted file mode 100644
index acde97785..000000000
--- a/deps/v8/test/mjsunit/harmony/typeof.js
+++ /dev/null
@@ -1,35 +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.
-
-// Flags: --harmony-typeof
-
-assertFalse(typeof null == 'object')
-assertFalse(typeof null === 'object')
-assertTrue(typeof null == 'null')
-assertTrue(typeof null === 'null')
-assertEquals("null", typeof null)
-assertSame("null", typeof null)
diff --git a/deps/v8/test/mjsunit/json-stringify-recursive.js b/deps/v8/test/mjsunit/json-stringify-recursive.js
index 31aa0027c..d2788a5f0 100644
--- a/deps/v8/test/mjsunit/json-stringify-recursive.js
+++ b/deps/v8/test/mjsunit/json-stringify-recursive.js
@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --stack-size=100
+
var a = {};
for (i = 0; i < 10000; i++) {
var current = {};
diff --git a/deps/v8/test/mjsunit/keyed-load-dictionary-stub.js b/deps/v8/test/mjsunit/keyed-load-dictionary-stub.js
new file mode 100644
index 000000000..733fd6d9c
--- /dev/null
+++ b/deps/v8/test/mjsunit/keyed-load-dictionary-stub.js
@@ -0,0 +1,20 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function generate_dictionary_array() {
+ var result = [0, 1, 2, 3, 4];
+ result[256 * 1024] = 5;
+ return result;
+}
+
+function get_accessor(a, i) {
+ return a[i];
+}
+
+var array1 = generate_dictionary_array();
+get_accessor(array1, 1);
+get_accessor(array1, 2);
+get_accessor(12345, 2);
diff --git a/deps/v8/test/mjsunit/math-abs.js b/deps/v8/test/mjsunit/math-abs.js
index 09b9c88f7..b90ae0917 100644
--- a/deps/v8/test/mjsunit/math-abs.js
+++ b/deps/v8/test/mjsunit/math-abs.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --max-new-space-size=2 --allow-natives-syntax
+// Flags: --max-semi-space-size=1 --allow-natives-syntax
function zero() {
var x = 0.5;
diff --git a/deps/v8/test/mjsunit/math-floor-part1.js b/deps/v8/test/mjsunit/math-floor-part1.js
index bae47dc3c..65ae3c68e 100644
--- a/deps/v8/test/mjsunit/math-floor-part1.js
+++ b/deps/v8/test/mjsunit/math-floor-part1.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --max-new-space-size=2 --allow-natives-syntax
+// Flags: --max-semi-space-size=1 --allow-natives-syntax
var test_id = 0;
diff --git a/deps/v8/test/mjsunit/math-floor-part2.js b/deps/v8/test/mjsunit/math-floor-part2.js
index ad60fba45..60045705c 100644
--- a/deps/v8/test/mjsunit/math-floor-part2.js
+++ b/deps/v8/test/mjsunit/math-floor-part2.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --max-new-space-size=2 --allow-natives-syntax
+// Flags: --max-semi-space-size=1 --allow-natives-syntax
var test_id = 0;
diff --git a/deps/v8/test/mjsunit/math-floor-part3.js b/deps/v8/test/mjsunit/math-floor-part3.js
index a6d1c5e85..9225c388b 100644
--- a/deps/v8/test/mjsunit/math-floor-part3.js
+++ b/deps/v8/test/mjsunit/math-floor-part3.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --max-new-space-size=2 --allow-natives-syntax
+// Flags: --max-semi-space-size=1 --allow-natives-syntax
var test_id = 0;
diff --git a/deps/v8/test/mjsunit/math-floor-part4.js b/deps/v8/test/mjsunit/math-floor-part4.js
index 58212b4c5..ade36a9c3 100644
--- a/deps/v8/test/mjsunit/math-floor-part4.js
+++ b/deps/v8/test/mjsunit/math-floor-part4.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --max-new-space-size=2 --allow-natives-syntax
+// Flags: --max-semi-space-size=1 --allow-natives-syntax
var test_id = 0;
diff --git a/deps/v8/test/mjsunit/migrations.js b/deps/v8/test/mjsunit/migrations.js
new file mode 100644
index 000000000..6a2ea64a7
--- /dev/null
+++ b/deps/v8/test/mjsunit/migrations.js
@@ -0,0 +1,311 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-ayle license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --track-fields --expose-gc
+
+var global = Function('return this')();
+var verbose = 0;
+
+function test(ctor_desc, use_desc, migr_desc) {
+ var n = 5;
+ var objects = [];
+ var results = [];
+
+ if (verbose) {
+ print();
+ print("===========================================================");
+ print("=== " + ctor_desc.name +
+ " | " + use_desc.name + " |--> " + migr_desc.name);
+ print("===========================================================");
+ }
+
+ // Clean ICs and transitions.
+ %NotifyContextDisposed();
+ gc(); gc(); gc();
+
+
+ // create objects
+ if (verbose) {
+ print("-----------------------------");
+ print("--- construct");
+ print();
+ }
+ for (var i = 0; i < n; i++) {
+ objects[i] = ctor_desc.ctor.apply(ctor_desc, ctor_desc.args(i));
+ }
+
+ try {
+ // use them
+ if (verbose) {
+ print("-----------------------------");
+ print("--- use 1");
+ print();
+ }
+ var use = use_desc.use1;
+ for (var i = 0; i < n; i++) {
+ if (i == 3) %OptimizeFunctionOnNextCall(use);
+ results[i] = use(objects[i], i);
+ }
+
+ // trigger migrations
+ if (verbose) {
+ print("-----------------------------");
+ print("--- trigger migration");
+ print();
+ }
+ var migr = migr_desc.migr;
+ for (var i = 0; i < n; i++) {
+ if (i == 3) %OptimizeFunctionOnNextCall(migr);
+ migr(objects[i], i);
+ }
+
+ // use again
+ if (verbose) {
+ print("-----------------------------");
+ print("--- use 2");
+ print();
+ }
+ var use = use_desc.use2 !== undefined ? use_desc.use2 : use_desc.use1;
+ for (var i = 0; i < n; i++) {
+ if (i == 3) %OptimizeFunctionOnNextCall(use);
+ results[i] = use(objects[i], i);
+ if (verbose >= 2) print(results[i]);
+ }
+
+ } catch (e) {
+ if (verbose) print("--- incompatible use: " + e);
+ }
+ return results;
+}
+
+
+var ctors = [
+ {
+ name: "none-to-double",
+ ctor: function(v) { return {a: v}; },
+ args: function(i) { return [1.5 + i]; },
+ },
+ {
+ name: "double",
+ ctor: function(v) { var o = {}; o.a = v; return o; },
+ args: function(i) { return [1.5 + i]; },
+ },
+ {
+ name: "none-to-smi",
+ ctor: function(v) { return {a: v}; },
+ args: function(i) { return [i]; },
+ },
+ {
+ name: "smi",
+ ctor: function(v) { var o = {}; o.a = v; return o; },
+ args: function(i) { return [i]; },
+ },
+ {
+ name: "none-to-object",
+ ctor: function(v) { return {a: v}; },
+ args: function(i) { return ["s"]; },
+ },
+ {
+ name: "object",
+ ctor: function(v) { var o = {}; o.a = v; return o; },
+ args: function(i) { return ["s"]; },
+ },
+ {
+ name: "{a:, b:, c:}",
+ ctor: function(v1, v2, v3) { return {a: v1, b: v2, c: v3}; },
+ args: function(i) { return [1.5 + i, 1.6, 1.7]; },
+ },
+ {
+ name: "{a..h:}",
+ ctor: function(v) { var o = {}; o.h=o.g=o.f=o.e=o.d=o.c=o.b=o.a=v; return o; },
+ args: function(i) { return [1.5 + i]; },
+ },
+ {
+ name: "1",
+ ctor: function(v) { var o = 1; o.a = v; return o; },
+ args: function(i) { return [1.5 + i]; },
+ },
+ {
+ name: "f()",
+ ctor: function(v) { var o = function() { return v;}; o.a = v; return o; },
+ args: function(i) { return [1.5 + i]; },
+ },
+ {
+ name: "f().bind",
+ ctor: function(v) { var o = function(a,b,c) { return a+b+c; }; o = o.bind(o, v, v+1, v+2.2); return o; },
+ args: function(i) { return [1.5 + i]; },
+ },
+ {
+ name: "dictionary elements",
+ ctor: function(v) { var o = []; o[1] = v; o[200000] = v; return o; },
+ args: function(i) { return [1.5 + i]; },
+ },
+ {
+ name: "json",
+ ctor: function(v) { var json = '{"a":' + v + ',"b":' + v + '}'; return JSON.parse(json); },
+ args: function(i) { return [1.5 + i]; },
+ },
+ {
+ name: "fast accessors",
+ accessor: {
+ get: function() { return this.a_; },
+ set: function(value) {this.a_ = value; },
+ configurable: true,
+ },
+ ctor: function(v) {
+ var o = {a_:v};
+ Object.defineProperty(o, "a", this.accessor);
+ return o;
+ },
+ args: function(i) { return [1.5 + i]; },
+ },
+ {
+ name: "slow accessor",
+ accessor1: { value: this.a_, configurable: true },
+ accessor2: {
+ get: function() { return this.a_; },
+ set: function(value) {this.a_ = value; },
+ configurable: true,
+ },
+ ctor: function(v) {
+ var o = {a_:v};
+ Object.defineProperty(o, "a", this.accessor1);
+ Object.defineProperty(o, "a", this.accessor2);
+ return o;
+ },
+ args: function(i) { return [1.5 + i]; },
+ },
+ {
+ name: "slow",
+ proto: {},
+ ctor: function(v) {
+ var o = {__proto__: this.proto};
+ o.a = v;
+ for (var i = 0; %HasFastProperties(o); i++) o["f"+i] = v;
+ return o;
+ },
+ args: function(i) { return [1.5 + i]; },
+ },
+ {
+ name: "global",
+ ctor: function(v) { return global; },
+ args: function(i) { return [i]; },
+ },
+];
+
+
+
+var uses = [
+ {
+ name: "o.a+1.0",
+ use1: function(o, i) { return o.a + 1.0; },
+ use2: function(o, i) { return o.a + 1.1; },
+ },
+ {
+ name: "o.b+1.0",
+ use1: function(o, i) { return o.b + 1.0; },
+ use2: function(o, i) { return o.b + 1.1; },
+ },
+ {
+ name: "o[1]+1.0",
+ use1: function(o, i) { return o[1] + 1.0; },
+ use2: function(o, i) { return o[1] + 1.1; },
+ },
+ {
+ name: "o[-1]+1.0",
+ use1: function(o, i) { return o[-1] + 1.0; },
+ use2: function(o, i) { return o[-1] + 1.1; },
+ },
+ {
+ name: "()",
+ use1: function(o, i) { return o() + 1.0; },
+ use2: function(o, i) { return o() + 1.1; },
+ },
+];
+
+
+
+var migrations = [
+ {
+ name: "to smi",
+ migr: function(o, i) { if (i == 0) o.a = 1; },
+ },
+ {
+ name: "to double",
+ migr: function(o, i) { if (i == 0) o.a = 1.1; },
+ },
+ {
+ name: "to object",
+ migr: function(o, i) { if (i == 0) o.a = {}; },
+ },
+ {
+ name: "set prototype {}",
+ migr: function(o, i) { o.__proto__ = {}; },
+ },
+ {
+ name: "%FunctionSetPrototype",
+ migr: function(o, i) { %FunctionSetPrototype(o, null); },
+ },
+ {
+ name: "modify prototype",
+ migr: function(o, i) { if (i == 0) o.__proto__.__proto1__ = [,,,5,,,]; },
+ },
+ {
+ name: "freeze prototype",
+ migr: function(o, i) { if (i == 0) Object.freeze(o.__proto__); },
+ },
+ {
+ name: "delete and re-add property",
+ migr: function(o, i) { var v = o.a; delete o.a; o.a = v; },
+ },
+ {
+ name: "modify prototype",
+ migr: function(o, i) { if (i >= 0) o.__proto__ = {}; },
+ },
+ {
+ name: "set property callback",
+ migr: function(o, i) {
+ Object.defineProperty(o, "a", {
+ get: function() { return 1.5 + i; },
+ set: function(value) {},
+ configurable: true,
+ });
+ },
+ },
+ {
+ name: "observe",
+ migr: function(o, i) { Object.observe(o, function(){}); },
+ },
+ {
+ name: "%EnableAccessChecks",
+ migr: function(o, i) {
+ if (typeof (o) !== 'function') %EnableAccessChecks(o);
+ },
+ },
+ {
+ name: "%DisableAccessChecks",
+ migr: function(o, i) {
+ if ((typeof (o) !== 'function') && (o !== global)) %DisableAccessChecks(o);
+ },
+ },
+ {
+ name: "seal",
+ migr: function(o, i) { Object.seal(o); },
+ },
+ { // Must be the last in the sequence, because after the global object freeze
+ // the other modifications does not make sence.
+ name: "freeze",
+ migr: function(o, i) { Object.freeze(o); },
+ },
+];
+
+
+
+migrations.forEach(function(migr) {
+ uses.forEach(function(use) {
+ ctors.forEach(function(ctor) {
+ test(ctor, use, migr);
+ });
+ });
+});
diff --git a/deps/v8/test/mjsunit/mirror-object.js b/deps/v8/test/mjsunit/mirror-object.js
index 8bf8a2d4f..7020338ca 100644
--- a/deps/v8/test/mjsunit/mirror-object.js
+++ b/deps/v8/test/mjsunit/mirror-object.js
@@ -111,12 +111,14 @@ function testObjectMirror(obj, cls_name, ctor_name, hasSpecialProperties) {
// Check that the serialization contains all properties.
assertEquals(names.length, fromJSON.properties.length, 'Some properties missing in JSON');
- for (var i = 0; i < fromJSON.properties.length; i++) {
- var name = fromJSON.properties[i].name;
- if (typeof name == 'undefined') name = fromJSON.properties[i].index;
+ for (var j = 0; j < names.length; j++) {
+ var name = names[j];
+ // Serialization of symbol-named properties to JSON doesn't really
+ // work currently, as they don't get a {name: ...} entry.
+ if (typeof name === 'symbol') continue;
var found = false;
- for (var j = 0; j < names.length; j++) {
- if (names[j] == name) {
+ for (var i = 0; i < fromJSON.properties.length; i++) {
+ if (fromJSON.properties[i].name == name) {
// Check that serialized handle is correct.
assertEquals(properties[i].value().handle(), fromJSON.properties[i].ref, 'Unexpected serialized handle');
@@ -170,6 +172,9 @@ function Point(x,y) {
this.y_ = y;
}
+var object_with_symbol = {};
+object_with_symbol[Symbol.iterator] = 42;
+
// Test a number of different objects.
testObjectMirror({}, 'Object', 'Object');
testObjectMirror({'a':1,'b':2}, 'Object', 'Object');
@@ -180,6 +185,7 @@ testObjectMirror(this.__proto__, 'Object', '');
testObjectMirror([], 'Array', 'Array');
testObjectMirror([1,2], 'Array', 'Array');
testObjectMirror(Object(17), 'Number', 'Number');
+testObjectMirror(object_with_symbol, 'Object', 'Object');
// Test circular references.
o = {};
diff --git a/deps/v8/test/mjsunit/mirror-script.js b/deps/v8/test/mjsunit/mirror-script.js
index 1d64ac26b..e545a6163 100644
--- a/deps/v8/test/mjsunit/mirror-script.js
+++ b/deps/v8/test/mjsunit/mirror-script.js
@@ -84,7 +84,7 @@ function testScriptMirror(f, file_name, file_lines, type, compilation_type,
// Test the script mirror for different functions.
testScriptMirror(function(){}, 'mirror-script.js', 98, 2, 0);
-testScriptMirror(Math.sin, 'native math.js', -1, 0, 0);
+testScriptMirror(Math.round, 'native math.js', -1, 0, 0);
testScriptMirror(eval('(function(){})'), null, 1, 2, 1, '(function(){})', 87);
testScriptMirror(eval('(function(){\n })'), null, 2, 2, 1, '(function(){\n })', 88);
diff --git a/deps/v8/test/mjsunit/mjsunit.js b/deps/v8/test/mjsunit/mjsunit.js
index 5f03774d7..043027908 100644
--- a/deps/v8/test/mjsunit/mjsunit.js
+++ b/deps/v8/test/mjsunit/mjsunit.js
@@ -231,8 +231,16 @@ var assertUnoptimized;
return deepObjectEquals(a, b);
}
+ function checkArity(args, arity, name) {
+ if (args.length < arity) {
+ fail(PrettyPrint(arity), args.length,
+ name + " requires " + arity + " or more arguments");
+ }
+ }
assertSame = function assertSame(expected, found, name_opt) {
+ checkArity(arguments, 2, "assertSame");
+
// TODO(mstarzinger): We should think about using Harmony's egal operator
// or the function equivalent Object.is() here.
if (found === expected) {
@@ -245,6 +253,8 @@ var assertUnoptimized;
assertEquals = function assertEquals(expected, found, name_opt) {
+ checkArity(arguments, 2, "assertEquals");
+
if (!deepEquals(found, expected)) {
fail(PrettyPrint(expected), found, name_opt);
}
@@ -371,15 +381,18 @@ var assertUnoptimized;
throw new MjsUnitAssertionError(message);
};
+ var OptimizationStatusImpl = undefined;
- var OptimizationStatus;
- try {
- OptimizationStatus =
- new Function("fun", "sync", "return %GetOptimizationStatus(fun, sync);");
- } catch (e) {
- OptimizationStatus = function() {
- throw new Error("natives syntax not allowed");
+ var OptimizationStatus = function(fun, sync_opt) {
+ if (OptimizationStatusImpl === undefined) {
+ try {
+ OptimizationStatusImpl = new Function(
+ "fun", "sync", "return %GetOptimizationStatus(fun, sync);");
+ } catch (e) {
+ throw new Error("natives syntax not allowed");
+ }
}
+ return OptimizationStatusImpl(fun, sync_opt);
}
assertUnoptimized = function assertUnoptimized(fun, sync_opt, name_opt) {
diff --git a/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status
index 117a0e6f7..228d24364 100644
--- a/deps/v8/test/mjsunit/mjsunit.status
+++ b/deps/v8/test/mjsunit/mjsunit.status
@@ -48,6 +48,116 @@
# This test non-deterministically runs out of memory on Windows ia32.
'regress/regress-crbug-160010': [SKIP],
+ # Issue 3389: deopt_every_n_garbage_collections is unsafe
+ 'regress/regress-2653': [SKIP],
+
+ ##############################################################################
+ # TurboFan compiler failures.
+
+ # TODO(mstarzinger): An arguments object materialized in the prologue can't
+ # be accessed indirectly. Either we drop that requirement or wait for support
+ # from the deoptimizer to do that.
+ 'arguments-indirect': [PASS, NO_VARIANTS],
+
+ # TODO(mstarzinger): Sometimes the try-catch blacklist fails.
+ 'debug-references': [PASS, NO_VARIANTS],
+ 'regress/regress-263': [PASS, NO_VARIANTS],
+
+ # Some tests are over-restrictive about object layout.
+ 'array-constructor-feedback': [PASS, NO_VARIANTS],
+ 'array-feedback': [PASS, NO_VARIANTS],
+
+ # Some tests are just too slow to run for now.
+ 'big-object-literal': [PASS, NO_VARIANTS],
+ 'bit-not': [PASS, NO_VARIANTS],
+ 'json2': [PASS, NO_VARIANTS],
+ 'packed-elements': [PASS, NO_VARIANTS],
+ 'unbox-double-arrays': [PASS, NO_VARIANTS],
+ 'whitespaces': [PASS, NO_VARIANTS],
+ 'compiler/optimized-for-in': [PASS, NO_VARIANTS],
+ 'compiler/osr-assert': [PASS, NO_VARIANTS],
+ 'compiler/osr-regress-max-locals': [PASS, NO_VARIANTS],
+ 'es7/object-observe': [PASS, NO_VARIANTS],
+ 'regress/regress-2185-2': [PASS, NO_VARIANTS],
+ 'regress/regress-284': [PASS, NO_VARIANTS],
+ 'regress/string-set-char-deopt': [PASS, NO_VARIANTS],
+ 'tools/profviz': [PASS, NO_VARIANTS],
+
+ # Support for breakpoints requires special relocation info for DebugBreak.
+ 'debug-clearbreakpointgroup': [PASS, NO_VARIANTS],
+ 'debug-step-2': [PASS, NO_VARIANTS],
+ 'regress/regress-debug-deopt-while-recompile': [PASS, NO_VARIANTS],
+ 'regress/regress-opt-after-debug-deopt': [PASS, NO_VARIANTS],
+
+ # Support for %GetFrameDetails is missing and requires checkpoints.
+ 'debug-backtrace-text': [PASS, NO_VARIANTS],
+ 'debug-break-inline': [PASS, NO_VARIANTS],
+ 'debug-evaluate-arguments': [PASS, NO_VARIANTS],
+ 'debug-evaluate-bool-constructor': [PASS, NO_VARIANTS],
+ 'debug-evaluate-closure': [PASS, NO_VARIANTS],
+ 'debug-evaluate-const': [PASS, NO_VARIANTS],
+ 'debug-evaluate-locals-optimized-double': [PASS, NO_VARIANTS],
+ 'debug-evaluate-locals-optimized': [PASS, NO_VARIANTS],
+ 'debug-evaluate-locals': [PASS, NO_VARIANTS],
+ 'debug-evaluate-with-context': [PASS, NO_VARIANTS],
+ 'debug-evaluate-with': [PASS, NO_VARIANTS],
+ 'debug-liveedit-double-call': [PASS, NO_VARIANTS],
+ 'debug-liveedit-restart-frame': [PASS, NO_VARIANTS],
+ 'debug-receiver': [PASS, NO_VARIANTS],
+ 'debug-return-value': [PASS, NO_VARIANTS],
+ 'debug-scopes': [PASS, NO_VARIANTS],
+ 'debug-set-variable-value': [PASS, NO_VARIANTS],
+ 'debug-step-stub-callfunction': [PASS, NO_VARIANTS],
+ 'debug-stepin-accessor': [PASS, NO_VARIANTS],
+ 'debug-stepin-builtin': [PASS, NO_VARIANTS],
+ 'debug-stepin-constructor': [PASS, NO_VARIANTS],
+ 'debug-stepin-function-call': [PASS, NO_VARIANTS],
+ 'debug-stepnext-do-while': [PASS, NO_VARIANTS],
+ 'debug-stepout-recursive-function': [PASS, NO_VARIANTS],
+ 'debug-stepout-scope-part1': [PASS, NO_VARIANTS],
+ 'debug-stepout-scope-part2': [PASS, NO_VARIANTS],
+ 'debug-stepout-scope-part3': [PASS, NO_VARIANTS],
+ 'debug-stepout-scope-part7': [PASS, NO_VARIANTS],
+ 'debug-stepout-to-builtin': [PASS, NO_VARIANTS],
+ 'es6/debug-promises/throw-in-constructor': [PASS, NO_VARIANTS],
+ 'es6/debug-promises/reject-in-constructor': [PASS, NO_VARIANTS],
+ 'es6/debug-promises/throw-with-undefined-reject': [PASS, NO_VARIANTS],
+ 'es6/debug-promises/throw-with-throw-in-reject': [PASS, NO_VARIANTS],
+ 'es6/debug-promises/reject-with-throw-in-reject': [PASS, NO_VARIANTS],
+ 'es6/debug-promises/throw-uncaught-all': [PASS, NO_VARIANTS],
+ 'es6/debug-promises/throw-uncaught-uncaught': [PASS, NO_VARIANTS],
+ 'es6/debug-promises/reject-uncaught-late': [PASS, NO_VARIANTS],
+ 'harmony/debug-blockscopes': [PASS, NO_VARIANTS],
+ 'harmony/generators-debug-scopes': [PASS, NO_VARIANTS],
+ 'regress/regress-1081309': [PASS, NO_VARIANTS],
+ 'regress/regress-1170187': [PASS, NO_VARIANTS],
+ 'regress/regress-119609': [PASS, NO_VARIANTS],
+ 'regress/regress-131994': [PASS, NO_VARIANTS],
+ 'regress/regress-269': [PASS, NO_VARIANTS],
+ 'regress/regress-325676': [PASS, NO_VARIANTS],
+ 'regress/regress-crbug-107996': [PASS, NO_VARIANTS],
+ 'regress/regress-crbug-171715': [PASS, NO_VARIANTS],
+ 'regress/regress-crbug-222893': [PASS, NO_VARIANTS],
+ 'regress/regress-crbug-259300': [PASS, NO_VARIANTS],
+ 'regress/regress-frame-details-null-receiver': [PASS, NO_VARIANTS],
+
+ # Support for ES6 generators is missing.
+ 'regress-3225': [PASS, NO_VARIANTS],
+ 'harmony/generators-debug-liveedit': [PASS, NO_VARIANTS],
+ 'harmony/generators-iteration': [PASS, NO_VARIANTS],
+ 'harmony/generators-parsing': [PASS, NO_VARIANTS],
+ 'harmony/generators-poisoned-properties': [PASS, NO_VARIANTS],
+ 'harmony/generators-relocation': [PASS, NO_VARIANTS],
+ 'harmony/regress/regress-2681': [PASS, NO_VARIANTS],
+ 'harmony/regress/regress-2691': [PASS, NO_VARIANTS],
+ 'harmony/regress/regress-3280': [PASS, NO_VARIANTS],
+
+ # Support for ES6 for-of iteration is missing.
+ 'es6/array-iterator': [PASS, NO_VARIANTS],
+ 'es6/iteration-semantics': [PASS, NO_VARIANTS],
+ 'es6/string-iterator': [PASS, NO_VARIANTS],
+ 'es6/typed-array-iterator': [PASS, NO_VARIANTS],
+
##############################################################################
# Too slow in debug mode with --stress-opt mode.
'compiler/regress-stacktrace-methods': [PASS, ['mode == debug', SKIP]],
@@ -67,14 +177,11 @@
# No need to waste time for this test.
'd8-performance-now': [PASS, NO_VARIANTS],
- ##############################################################################
- 'big-object-literal': [PASS, ['arch == arm or arch == android_arm or arch == android_arm64', SKIP]],
-
# Issue 488: this test sometimes times out.
'array-constructor': [PASS, TIMEOUT],
# Very slow on ARM and MIPS, contains no architecture dependent code.
- 'unicode-case-overoptimization': [PASS, NO_VARIANTS, ['arch == arm or arch == android_arm or arch == android_arm64 or arch == mipsel or arch == mips', TIMEOUT]],
+ 'unicode-case-overoptimization': [PASS, NO_VARIANTS, ['arch == arm or arch == android_arm or arch == android_arm64 or arch == mipsel or arch == mips64el or arch == mips', TIMEOUT]],
##############################################################################
# This test expects to reach a certain recursion depth, which may not work
@@ -84,6 +191,8 @@
##############################################################################
# Skip long running tests that time out in debug mode.
'generated-transition-stub': [PASS, ['mode == debug', SKIP]],
+ 'migrations': [SKIP],
+ 'array-functions-prototype-misc': [PASS, ['mode == debug', SKIP]],
##############################################################################
# This test sets the umask on a per-process basis and hence cannot be
@@ -94,7 +203,7 @@
# get the same random seed and would generate the same directory name. Besides
# that, it doesn't make sense to run several variants of d8-os anyways.
'd8-os': [PASS, NO_VARIANTS, ['isolates or arch == android_arm or arch == android_arm64 or arch == android_ia32', SKIP]],
- 'tools/tickprocessor': [PASS, ['arch == android_arm or arch == android_arm64 or arch == android_ia32', SKIP]],
+ 'tools/tickprocessor': [PASS, NO_VARIANTS, ['arch == android_arm or arch == android_arm64 or arch == android_ia32', SKIP]],
##############################################################################
# Long running test that reproduces memory leak and should be run manually.
@@ -117,7 +226,7 @@
# BUG(v8:2989). PASS/FAIL on linux32 because crankshaft is turned off for
# nosse2. Also for arm novfp3.
- 'regress/regress-2989': [FAIL, NO_VARIANTS, ['system == linux and arch == ia32 or arch == arm and simulator == True', PASS]],
+ 'regress/regress-2989': [FAIL, NO_VARIANTS, ['system == linux and arch == x87 or arch == arm and simulator == True', PASS]],
# Skip endain dependent test for mips due to different typed views of the same
# array buffer.
@@ -133,18 +242,66 @@
'array-feedback': [SKIP],
'array-literal-feedback': [SKIP],
'd8-performance-now': [SKIP],
+ 'debug-stepout-scope-part8': [PASS, ['arch == arm ', FAIL]],
'elements-kind': [SKIP],
+ 'elements-transition-hoisting': [SKIP],
'fast-prototype': [SKIP],
+ 'getters-on-elements': [SKIP],
+ 'harmony/block-let-crankshaft': [SKIP],
'opt-elements-kind': [SKIP],
'osr-elements-kind': [SKIP],
'regress/regress-165637': [SKIP],
'regress/regress-2249': [SKIP],
- 'debug-stepout-scope-part8': [PASS, ['arch == arm ', FAIL]],
+ # Tests taking too long
+ 'debug-stepout-scope-part8': [SKIP],
+ 'mirror-object': [SKIP],
+ 'packed-elements': [SKIP],
+ 'regress/regress-1122': [SKIP],
+ 'regress/regress-331444': [SKIP],
+ 'regress/regress-353551': [SKIP],
+ 'regress/regress-crbug-119926': [SKIP],
+ 'regress/short-circuit': [SKIP],
+ 'stack-traces-overflow': [SKIP],
+ 'unicode-test': [SKIP],
+ 'whitespaces': [SKIP],
+
+ # TODO(mstarzinger): Takes too long with TF.
+ 'array-sort': [PASS, NO_VARIANTS],
}], # 'gc_stress == True'
##############################################################################
+['no_i18n', {
+ # Don't call runtime functions that don't exist without i18n support.
+ 'runtime-gen/availablelocalesof': [SKIP],
+ 'runtime-gen/breakiteratoradopttext': [SKIP],
+ 'runtime-gen/breakiteratorbreaktype': [SKIP],
+ 'runtime-gen/breakiteratorbreaktype': [SKIP],
+ 'runtime-gen/breakiteratorcurrent': [SKIP],
+ 'runtime-gen/breakiteratorfirst': [SKIP],
+ 'runtime-gen/breakiteratornext': [SKIP],
+ 'runtime-gen/canonicalizelanguagetag': [SKIP],
+ 'runtime-gen/createbreakiterator': [SKIP],
+ 'runtime-gen/createcollator': [SKIP],
+ 'runtime-gen/getdefaulticulocale': [SKIP],
+ 'runtime-gen/getimplfrominitializedintlobject': [SKIP],
+ 'runtime-gen/getlanguagetagvariants': [SKIP],
+ 'runtime-gen/internalcompare': [SKIP],
+ 'runtime-gen/internaldateformat': [SKIP],
+ 'runtime-gen/internaldateparse': [SKIP],
+ 'runtime-gen/internalnumberformat': [SKIP],
+ 'runtime-gen/internalnumberparse': [SKIP],
+ 'runtime-gen/isinitializedintlobject': [SKIP],
+ 'runtime-gen/isinitializedintlobjectoftype': [SKIP],
+ 'runtime-gen/markasinitializedintlobjectoftype': [SKIP],
+ 'runtime-gen/stringnormalize': [SKIP],
+}],
+
+##############################################################################
['arch == arm64 or arch == android_arm64', {
+ # arm64 TF timeout.
+ 'regress/regress-1257': [PASS, TIMEOUT],
+
# Requires bigger stack size in the Genesis and if stack size is increased,
# the test requires too much time to run. However, the problem test covers
# should be platform-independent.
@@ -153,6 +310,7 @@
# Pass but take too long to run. Skip.
# Some similar tests (with fewer iterations) may be included in arm64-js
# tests.
+ 'big-object-literal': [SKIP],
'compiler/regress-arguments': [SKIP],
'compiler/regress-gvn': [SKIP],
'compiler/regress-max-locals-for-osr': [SKIP],
@@ -174,15 +332,12 @@
'regress/regress-2185-2': [PASS, TIMEOUT],
'whitespaces': [PASS, TIMEOUT, SLOW],
- # Stack manipulations in LiveEdit is not implemented for this arch.
- 'debug-liveedit-check-stack': [SKIP],
- 'debug-liveedit-stack-padding': [SKIP],
- 'debug-liveedit-restart-frame': [SKIP],
- 'debug-liveedit-double-call': [SKIP],
-
# BUG(v8:3147). It works on other architectures by accident.
'regress/regress-conditional-position': [FAIL],
+ # BUG(v8:3457).
+ 'deserialize-reference': [PASS, FAIL],
+
# Slow tests.
'array-concat': [PASS, SLOW],
'array-constructor': [PASS, SLOW],
@@ -193,7 +348,7 @@
'bit-not': [PASS, SLOW],
'compiler/alloc-number': [PASS, SLOW],
'compiler/osr-assert': [PASS, SLOW],
- 'compiler/osr-warm': [PASS, SLOW],
+ 'compiler/osr-warm': [PASS, TIMEOUT, SLOW],
'compiler/osr-with-args': [PASS, SLOW],
'debug-scopes': [PASS, SLOW],
'generated-transition-stub': [PASS, SLOW],
@@ -259,6 +414,7 @@
# Long running tests. Skipping because having them timeout takes too long on
# the buildbot.
+ 'big-object-literal': [SKIP],
'compiler/alloc-number': [SKIP],
'regress/regress-490': [SKIP],
'regress/regress-634': [SKIP],
@@ -270,12 +426,6 @@
# should be platform-independent.
'regress/regress-1132': [SKIP],
- # Stack manipulations in LiveEdit is not implemented for this arch.
- 'debug-liveedit-check-stack': [SKIP],
- 'debug-liveedit-stack-padding': [SKIP],
- 'debug-liveedit-restart-frame': [SKIP],
- 'debug-liveedit-double-call': [SKIP],
-
# Currently always deopt on minus zero
'math-floor-of-div-minus-zero': [SKIP],
@@ -321,17 +471,78 @@
# should be platform-independent.
'regress/regress-1132': [SKIP],
- # Stack manipulations in LiveEdit is not implemented for this arch.
- 'debug-liveedit-check-stack': [SKIP],
- 'debug-liveedit-stack-padding': [SKIP],
- 'debug-liveedit-restart-frame': [SKIP],
- 'debug-liveedit-double-call': [SKIP],
-
# Currently always deopt on minus zero
'math-floor-of-div-minus-zero': [SKIP],
+
+ # BUG(v8:3457).
+ 'deserialize-reference': [SKIP],
}], # 'arch == mipsel or arch == mips'
##############################################################################
+['arch == mips64el', {
+
+ # Slow tests which times out in debug mode.
+ 'try': [PASS, ['mode == debug', SKIP]],
+ 'debug-scripts-request': [PASS, ['mode == debug', SKIP]],
+ 'array-constructor': [PASS, ['mode == debug', SKIP]],
+
+ # Times out often in release mode on MIPS.
+ 'compiler/regress-stacktrace-methods': [PASS, PASS, ['mode == release', TIMEOUT]],
+ 'array-splice': [PASS, TIMEOUT],
+
+ # Long running test.
+ 'mirror-object': [PASS, TIMEOUT],
+ 'string-indexof-2': [PASS, TIMEOUT],
+
+ # BUG(3251035): Timeouts in long looping crankshaft optimization
+ # tests. Skipping because having them timeout takes too long on the
+ # buildbot.
+ 'compiler/alloc-number': [PASS, SLOW],
+ 'compiler/array-length': [PASS, SLOW],
+ 'compiler/assignment-deopt': [PASS, SLOW],
+ 'compiler/deopt-args': [PASS, SLOW],
+ 'compiler/inline-compare': [PASS, SLOW],
+ 'compiler/inline-global-access': [PASS, SLOW],
+ 'compiler/optimized-function-calls': [PASS, SLOW],
+ 'compiler/pic': [PASS, SLOW],
+ 'compiler/property-calls': [PASS, SLOW],
+ 'compiler/recursive-deopt': [PASS, SLOW],
+ 'compiler/regress-4': [PASS, SLOW],
+ 'compiler/regress-funcaller': [PASS, SLOW],
+ 'compiler/regress-rep-change': [PASS, SLOW],
+ 'compiler/regress-arguments': [PASS, SLOW],
+ 'compiler/regress-funarguments': [PASS, SLOW],
+ 'compiler/regress-3249650': [PASS, SLOW],
+ 'compiler/simple-deopt': [PASS, SLOW],
+ 'regress/regress-490': [PASS, SLOW],
+ 'regress/regress-634': [PASS, SLOW],
+ 'regress/regress-create-exception': [PASS, SLOW],
+ 'regress/regress-3218915': [PASS, SLOW],
+ 'regress/regress-3247124': [PASS, SLOW],
+
+ # Requires bigger stack size in the Genesis and if stack size is increased,
+ # the test requires too much time to run. However, the problem test covers
+ # should be platform-independent.
+ 'regress/regress-1132': [SKIP],
+
+ # Currently always deopt on minus zero
+ 'math-floor-of-div-minus-zero': [SKIP],
+
+ # BUG(v8:3457).
+ 'deserialize-reference': [SKIP],
+}], # 'arch == mips64el'
+
+['arch == mips64el and simulator_run == False', {
+ # Random failures on HW, need investigation.
+ 'debug-*': [SKIP],
+}],
+##############################################################################
+['system == windows', {
+ # BUG(v8:3435)
+ 'debug-script-breakpoints': [PASS, FAIL],
+}], # 'system == windows'
+
+##############################################################################
# Native Client uses the ARM simulator so will behave similarly to arm
# on mjsunit tests.
# TODO(bradchen): enable more tests for NaCl V8 when it stops using
@@ -346,6 +557,7 @@
'debug-liveedit-stack-padding': [SKIP],
'debug-liveedit-restart-frame': [SKIP],
'debug-liveedit-double-call': [SKIP],
+ 'harmony/generators-debug-liveedit': [SKIP],
# NaCl builds have problems with this test since Pepper_28.
# V8 Issue 2786
diff --git a/deps/v8/test/mjsunit/object-define-property.js b/deps/v8/test/mjsunit/object-define-property.js
index cbb2d211f..4c495c682 100644
--- a/deps/v8/test/mjsunit/object-define-property.js
+++ b/deps/v8/test/mjsunit/object-define-property.js
@@ -27,7 +27,7 @@
// Tests the object.defineProperty method - ES 15.2.3.6
-// Flags: --allow-natives-syntax --es5-readonly
+// Flags: --allow-natives-syntax
// Check that an exception is thrown when null is passed as object.
var exception = false;
@@ -467,35 +467,35 @@ try {
}
-// Test runtime calls to DefineOrRedefineDataProperty and
-// DefineOrRedefineAccessorProperty - make sure we don't
+// Test runtime calls to DefineDataPropertyUnchecked and
+// DefineAccessorPropertyUnchecked - make sure we don't
// crash.
try {
- %DefineOrRedefineAccessorProperty(0, 0, 0, 0, 0);
+ %DefineAccessorPropertyUnchecked(0, 0, 0, 0, 0);
} catch (e) {
assertTrue(/illegal access/.test(e));
}
try {
- %DefineOrRedefineDataProperty(0, 0, 0, 0);
+ %DefineDataPropertyUnchecked(0, 0, 0, 0);
} catch (e) {
assertTrue(/illegal access/.test(e));
}
try {
- %DefineOrRedefineDataProperty(null, null, null, null);
+ %DefineDataPropertyUnchecked(null, null, null, null);
} catch (e) {
assertTrue(/illegal access/.test(e));
}
try {
- %DefineOrRedefineAccessorProperty(null, null, null, null, null);
+ %DefineAccessorPropertyUnchecked(null, null, null, null, null);
} catch (e) {
assertTrue(/illegal access/.test(e));
}
try {
- %DefineOrRedefineDataProperty({}, null, null, null);
+ %DefineDataPropertyUnchecked({}, null, null, null);
} catch (e) {
assertTrue(/illegal access/.test(e));
}
@@ -503,13 +503,13 @@ try {
// Defining properties null should fail even when we have
// other allowed values
try {
- %DefineOrRedefineAccessorProperty(null, 'foo', func, null, 0);
+ %DefineAccessorPropertyUnchecked(null, 'foo', func, null, 0);
} catch (e) {
assertTrue(/illegal access/.test(e));
}
try {
- %DefineOrRedefineDataProperty(null, 'foo', 0, 0);
+ %DefineDataPropertyUnchecked(null, 'foo', 0, 0);
} catch (e) {
assertTrue(/illegal access/.test(e));
}
diff --git a/deps/v8/test/mjsunit/object-toprimitive.js b/deps/v8/test/mjsunit/object-toprimitive.js
index 3a67ced47..34803ec93 100644
--- a/deps/v8/test/mjsunit/object-toprimitive.js
+++ b/deps/v8/test/mjsunit/object-toprimitive.js
@@ -102,3 +102,5 @@ trace = [];
var nt = Number(ot);
assertEquals(87, nt);
assertEquals(["gvo", "gts", "ts"], trace);
+
+assertThrows('Number(Symbol())', TypeError);
diff --git a/deps/v8/test/mjsunit/opt-elements-kind.js b/deps/v8/test/mjsunit/opt-elements-kind.js
index f26bb4206..be7303b04 100644
--- a/deps/v8/test/mjsunit/opt-elements-kind.js
+++ b/deps/v8/test/mjsunit/opt-elements-kind.js
@@ -25,28 +25,13 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+// Flags: --allow-natives-syntax --expose-gc
// Limit the number of stress runs to reduce polymorphism it defeats some of the
// assumptions made about how elements transitions work because transition stubs
// end up going generic.
// Flags: --stress-runs=2
-// Test element kind of objects.
-// Since --smi-only-arrays affects builtins, its default setting at compile
-// time sticks if built with snapshot. If --smi-only-arrays is deactivated
-// by default, only a no-snapshot build actually has smi-only arrays enabled
-// in this test case. Depending on whether smi-only arrays are actually
-// enabled, this test takes the appropriate code path to check smi-only arrays.
-
-support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
-
-if (support_smi_only_arrays) {
- print("Tests include smi-only arrays.");
-} else {
- print("Tests do NOT include smi-only arrays.");
-}
-
var elements_kind = {
fast_smi_only : 'fast smi only elements',
fast : 'fast elements',
@@ -100,10 +85,6 @@ function getKind(obj) {
}
function assertKind(expected, obj, name_opt) {
- if (!support_smi_only_arrays &&
- expected == elements_kind.fast_smi_only) {
- expected = elements_kind.fast;
- }
assertEquals(expected, getKind(obj), name_opt);
}
@@ -143,8 +124,6 @@ function convert_mixed(array, value, kind) {
}
function test1() {
- if (!support_smi_only_arrays) return;
-
// Test transition chain SMI->DOUBLE->FAST (crankshafted function will
// transition to FAST directly).
var smis = construct_smis();
diff --git a/deps/v8/test/mjsunit/osr-elements-kind.js b/deps/v8/test/mjsunit/osr-elements-kind.js
index 2ad3c4348..518b98474 100644
--- a/deps/v8/test/mjsunit/osr-elements-kind.js
+++ b/deps/v8/test/mjsunit/osr-elements-kind.js
@@ -25,28 +25,13 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+// Flags: --allow-natives-syntax --expose-gc
// Limit the number of stress runs to reduce polymorphism it defeats some of the
// assumptions made about how elements transitions work because transition stubs
// end up going generic.
// Flags: --stress-runs=2
-// Test element kind of objects.
-// Since --smi-only-arrays affects builtins, its default setting at compile
-// time sticks if built with snapshot. If --smi-only-arrays is deactivated
-// by default, only a no-snapshot build actually has smi-only arrays enabled
-// in this test case. Depending on whether smi-only arrays are actually
-// enabled, this test takes the appropriate code path to check smi-only arrays.
-
-support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
-
-if (support_smi_only_arrays) {
- print("Tests include smi-only arrays.");
-} else {
- print("Tests do NOT include smi-only arrays.");
-}
-
var elements_kind = {
fast_smi_only : 'fast smi only elements',
fast : 'fast elements',
@@ -100,10 +85,6 @@ function getKind(obj) {
}
function assertKind(expected, obj, name_opt) {
- if (!support_smi_only_arrays &&
- expected == elements_kind.fast_smi_only) {
- expected = elements_kind.fast;
- }
assertEquals(expected, getKind(obj), name_opt);
}
@@ -113,53 +94,51 @@ function assertKind(expected, obj, name_opt) {
%NeverOptimizeFunction(convert_mixed);
for (var i = 0; i < 1000000; i++) { }
-if (support_smi_only_arrays) {
- // This code exists to eliminate the learning influence of AllocationSites
- // on the following tests.
- var __sequence = 0;
- function make_array_string() {
- this.__sequence = this.__sequence + 1;
- return "/* " + this.__sequence + " */ [0, 0, 0];"
- }
- function make_array() {
- return eval(make_array_string());
- }
+// This code exists to eliminate the learning influence of AllocationSites
+// on the following tests.
+var __sequence = 0;
+function make_array_string() {
+ this.__sequence = this.__sequence + 1;
+ return "/* " + this.__sequence + " */ [0, 0, 0];"
+}
+function make_array() {
+ return eval(make_array_string());
+}
- function construct_smis() {
- var a = make_array();
- a[0] = 0; // Send the COW array map to the steak house.
- assertKind(elements_kind.fast_smi_only, a);
- return a;
- }
- function construct_doubles() {
- var a = construct_smis();
- a[0] = 1.5;
- assertKind(elements_kind.fast_double, a);
- return a;
- }
+function construct_smis() {
+ var a = make_array();
+ a[0] = 0; // Send the COW array map to the steak house.
+ assertKind(elements_kind.fast_smi_only, a);
+ return a;
+}
+function construct_doubles() {
+ var a = construct_smis();
+ a[0] = 1.5;
+ assertKind(elements_kind.fast_double, a);
+ return a;
+}
- // Test transition chain SMI->DOUBLE->FAST (crankshafted function will
- // transition to FAST directly).
- function convert_mixed(array, value, kind) {
- array[1] = value;
- assertKind(kind, array);
- assertEquals(value, array[1]);
- }
- smis = construct_smis();
- convert_mixed(smis, 1.5, elements_kind.fast_double);
+// Test transition chain SMI->DOUBLE->FAST (crankshafted function will
+// transition to FAST directly).
+function convert_mixed(array, value, kind) {
+ array[1] = value;
+ assertKind(kind, array);
+ assertEquals(value, array[1]);
+}
+smis = construct_smis();
+convert_mixed(smis, 1.5, elements_kind.fast_double);
- doubles = construct_doubles();
- convert_mixed(doubles, "three", elements_kind.fast);
+doubles = construct_doubles();
+convert_mixed(doubles, "three", elements_kind.fast);
- convert_mixed(construct_smis(), "three", elements_kind.fast);
- convert_mixed(construct_doubles(), "three", elements_kind.fast);
+convert_mixed(construct_smis(), "three", elements_kind.fast);
+convert_mixed(construct_doubles(), "three", elements_kind.fast);
- smis = construct_smis();
- doubles = construct_doubles();
- convert_mixed(smis, 1, elements_kind.fast);
- convert_mixed(doubles, 1, elements_kind.fast);
- assertTrue(%HaveSameMap(smis, doubles));
-}
+smis = construct_smis();
+doubles = construct_doubles();
+convert_mixed(smis, 1, elements_kind.fast);
+convert_mixed(doubles, 1, elements_kind.fast);
+assertTrue(%HaveSameMap(smis, doubles));
// Throw away type information in the ICs for next stress run.
gc();
diff --git a/deps/v8/test/mjsunit/outobject-double-for-in.js b/deps/v8/test/mjsunit/outobject-double-for-in.js
new file mode 100644
index 000000000..eb8ac940a
--- /dev/null
+++ b/deps/v8/test/mjsunit/outobject-double-for-in.js
@@ -0,0 +1,66 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function DoubleContainer() {
+ this.x0 = 0.5;
+ this.x1 = undefined;
+ this.x2 = undefined;
+ this.x3 = undefined;
+ this.x4 = undefined;
+ this.x5 = undefined;
+ this.x6 = undefined;
+ this.x7 = 5;
+ this.x8 = undefined;
+ this.x9 = undefined;
+ this.x10 = undefined;
+ this.x11 = undefined;
+ this.x12 = undefined;
+ this.x13 = undefined;
+ this.x14 = undefined;
+ this.x15 = undefined;
+ this.x16 = true;
+ this.y = 2.5;
+}
+
+var z = new DoubleContainer();
+
+function test_props(a) {
+ for (var i in a) {
+ assertTrue(i !== "x0" || a[i] === 0.5);
+ assertTrue(i !== "y" || a[i] === 2.5);
+ assertTrue(i !== "x12" || a[i] === undefined);
+ assertTrue(i !== "x16" || a[i] === true);
+ assertTrue(i !== "x7" || a[i] === 5);
+ }
+}
+
+test_props(z);
+test_props(z);
+%OptimizeFunctionOnNextCall(test_props);
+test_props(z);
diff --git a/deps/v8/test/mjsunit/override-read-only-property.js b/deps/v8/test/mjsunit/override-read-only-property.js
index 2876ae1f8..f8114a660 100644
--- a/deps/v8/test/mjsunit/override-read-only-property.js
+++ b/deps/v8/test/mjsunit/override-read-only-property.js
@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --es5_readonly
-
// According to ECMA-262, sections 8.6.2.2 and 8.6.2.3 you're not
// allowed to override read-only properties, not even if the read-only
// property is in the prototype chain.
diff --git a/deps/v8/test/mjsunit/own-symbols.js b/deps/v8/test/mjsunit/own-symbols.js
new file mode 100644
index 000000000..588a032aa
--- /dev/null
+++ b/deps/v8/test/mjsunit/own-symbols.js
@@ -0,0 +1,55 @@
+// 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.
+//
+// Flags: --allow-natives-syntax
+
+var s = %CreatePrivateOwnSymbol("s");
+var s1 = %CreatePrivateOwnSymbol("s1");
+
+function TestSimple() {
+ var p = {}
+ p[s] = "moo";
+
+ var o = Object.create(p);
+
+ assertEquals(undefined, o[s]);
+ assertEquals("moo", p[s]);
+
+ o[s] = "bow-wow";
+ assertEquals("bow-wow", o[s]);
+ assertEquals("moo", p[s]);
+}
+
+TestSimple();
+
+
+function TestICs() {
+ var p = {}
+ p[s] = "moo";
+
+
+ var o = Object.create(p);
+ o[s1] = "bow-wow";
+ function checkNonOwn(o) {
+ assertEquals(undefined, o[s]);
+ assertEquals("bow-wow", o[s1]);
+ }
+
+ checkNonOwn(o);
+
+ // Test monomorphic/optimized.
+ for (var i = 0; i < 1000; i++) {
+ checkNonOwn(o);
+ }
+
+ // Test non-monomorphic.
+ for (var i = 0; i < 1000; i++) {
+ var oNew = Object.create(p);
+ oNew["s" + i] = i;
+ oNew[s1] = "bow-wow";
+ checkNonOwn(oNew);
+ }
+}
+
+TestICs();
diff --git a/deps/v8/test/mjsunit/packed-elements.js b/deps/v8/test/mjsunit/packed-elements.js
index 4a8737306..3ce92d118 100644
--- a/deps/v8/test/mjsunit/packed-elements.js
+++ b/deps/v8/test/mjsunit/packed-elements.js
@@ -25,9 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays --packed-arrays
-
-var has_packed_elements = !%HasFastHoleyElements(Array());
+// Flags: --allow-natives-syntax
function test1() {
var a = Array(8);
@@ -101,11 +99,9 @@ function test_with_optimization(f) {
for (i = 0; i < 25000; ++i) f(); // Make sure GC happens
}
-if (has_packed_elements) {
- test_with_optimization(test1);
- test_with_optimization(test2);
- test_with_optimization(test3);
- test_with_optimization(test4);
- test_with_optimization(test5);
- test_with_optimization(test6);
-}
+test_with_optimization(test1);
+test_with_optimization(test2);
+test_with_optimization(test3);
+test_with_optimization(test4);
+test_with_optimization(test5);
+test_with_optimization(test6);
diff --git a/deps/v8/test/mjsunit/polymorph-arrays.js b/deps/v8/test/mjsunit/polymorph-arrays.js
index ff0c433bd..2bb043321 100644
--- a/deps/v8/test/mjsunit/polymorph-arrays.js
+++ b/deps/v8/test/mjsunit/polymorph-arrays.js
@@ -37,7 +37,7 @@ function init_sparse_array(a) {
a[i] = i;
}
a[5000000] = 256;
- assertTrue(%HasDictionaryElements(a));
+ return %NormalizeElements(a);
}
function testPolymorphicLoads() {
@@ -49,7 +49,7 @@ function testPolymorphicLoads() {
var object_array = new Object;
var sparse_object_array = new Object;
var js_array = new Array(10);
- var sparse_js_array = new Array(5000001);
+ var sparse_js_array = %NormalizeElements([]);
init_array(object_array);
init_array(js_array);
@@ -67,7 +67,7 @@ function testPolymorphicLoads() {
var object_array = new Object;
var sparse_object_array = new Object;
var js_array = new Array(10);
- var sparse_js_array = new Array(5000001);
+ var sparse_js_array = %NormalizeElements([]);
init_array(object_array);
init_array(js_array);
@@ -114,7 +114,8 @@ function testPolymorphicStores() {
var object_array = new Object;
var sparse_object_array = new Object;
var js_array = new Array(10);
- var sparse_js_array = new Array(5000001);
+ var sparse_js_array = [];
+ sparse_js_array.length = 5000001;
init_array(object_array);
init_array(js_array);
@@ -132,7 +133,8 @@ function testPolymorphicStores() {
var object_array = new Object;
var sparse_object_array = new Object;
var js_array = new Array(10);
- var sparse_js_array = new Array(5000001);
+ var sparse_js_array = %NormalizeElements([]);
+ sparse_js_array.length = 5000001;
init_array(object_array);
init_array(js_array);
diff --git a/deps/v8/test/mjsunit/proto-accessor.js b/deps/v8/test/mjsunit/proto-accessor.js
index b2e7d3466..513a04402 100644
--- a/deps/v8/test/mjsunit/proto-accessor.js
+++ b/deps/v8/test/mjsunit/proto-accessor.js
@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-symbols
-
// Fake Symbol if undefined, allowing test to run in non-Harmony mode as well.
this.Symbol = typeof Symbol != 'undefined' ? Symbol : String;
diff --git a/deps/v8/test/mjsunit/readonly.js b/deps/v8/test/mjsunit/readonly.js
index 050e25627..084e9ffe2 100644
--- a/deps/v8/test/mjsunit/readonly.js
+++ b/deps/v8/test/mjsunit/readonly.js
@@ -25,8 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --es5_readonly
-// Flags: --harmony-proxies
+// Flags: --allow-natives-syntax --harmony-proxies
// Different ways to create an object.
diff --git a/deps/v8/test/mjsunit/regress-3456.js b/deps/v8/test/mjsunit/regress-3456.js
new file mode 100644
index 000000000..498953b80
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress-3456.js
@@ -0,0 +1,13 @@
+// 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.
+
+// Flags: --min-preparse-length 1
+
+// Arrow function parsing (commit r22366) changed the flags stored in
+// PreParserExpression, and IsValidReferenceExpression() would return
+// false for certain valid expressions. This case is the minimum amount
+// of code needed to validate that IsValidReferenceExpression() works
+// properly. If it does not, a ReferenceError is thrown during parsing.
+
+function f() { ++(this.foo) }
diff --git a/deps/v8/test/mjsunit/regress/debug-prepare-step-in.js b/deps/v8/test/mjsunit/regress/debug-prepare-step-in.js
index b8c211640..60b47f7a5 100644
--- a/deps/v8/test/mjsunit/regress/debug-prepare-step-in.js
+++ b/deps/v8/test/mjsunit/regress/debug-prepare-step-in.js
@@ -52,3 +52,5 @@ function g() {
}
g();
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/regress/regress-1170.js b/deps/v8/test/mjsunit/regress/regress-1170.js
index 8c5f6f8ab..5d5800ee3 100644
--- a/deps/v8/test/mjsunit/regress/regress-1170.js
+++ b/deps/v8/test/mjsunit/regress/regress-1170.js
@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --es52_globals
-
var setter_value = 0;
this.__defineSetter__("a", function(v) { setter_value = v; });
@@ -35,8 +33,9 @@ assertEquals(1, setter_value);
assertFalse("value" in Object.getOwnPropertyDescriptor(this, "a"));
eval("with({}) { eval('var a = 2') }");
-assertEquals(2, setter_value);
+assertTrue("get" in Object.getOwnPropertyDescriptor(this, "a"));
assertFalse("value" in Object.getOwnPropertyDescriptor(this, "a"));
+assertEquals(2, setter_value);
// Function declarations are treated specially to match Safari. We do
// not call setters for them.
@@ -47,10 +46,8 @@ assertTrue("value" in Object.getOwnPropertyDescriptor(this, "a"));
this.__defineSetter__("b", function(v) { setter_value = v; });
try {
eval("const b = 3");
-} catch(e) {
- assertUnreachable();
-}
-assertEquals(3, setter_value);
+} catch(e) { }
+assertEquals(2, setter_value);
try {
eval("with({}) { eval('const b = 23') }");
diff --git a/deps/v8/test/mjsunit/regress/regress-1199637.js b/deps/v8/test/mjsunit/regress/regress-1199637.js
index 8b02a6559..397aeb876 100644
--- a/deps/v8/test/mjsunit/regress/regress-1199637.js
+++ b/deps/v8/test/mjsunit/regress/regress-1199637.js
@@ -34,43 +34,43 @@ const NONE = 0;
const READ_ONLY = 1;
// Use DeclareGlobal...
-%SetProperty(this.__proto__, "a", 1234, NONE);
+%AddNamedProperty(this.__proto__, "a", 1234, NONE);
assertEquals(1234, a);
eval("var a = 5678;");
assertEquals(5678, a);
-%SetProperty(this.__proto__, "b", 1234, NONE);
+%AddNamedProperty(this.__proto__, "b", 1234, NONE);
assertEquals(1234, b);
eval("const b = 5678;");
assertEquals(5678, b);
-%SetProperty(this.__proto__, "c", 1234, READ_ONLY);
+%AddNamedProperty(this.__proto__, "c", 1234, READ_ONLY);
assertEquals(1234, c);
eval("var c = 5678;");
assertEquals(5678, c);
-%SetProperty(this.__proto__, "d", 1234, READ_ONLY);
+%AddNamedProperty(this.__proto__, "d", 1234, READ_ONLY);
assertEquals(1234, d);
eval("const d = 5678;");
assertEquals(5678, d);
// Use DeclareContextSlot...
-%SetProperty(this.__proto__, "x", 1234, NONE);
+%AddNamedProperty(this.__proto__, "x", 1234, NONE);
assertEquals(1234, x);
eval("with({}) { var x = 5678; }");
assertEquals(5678, x);
-%SetProperty(this.__proto__, "y", 1234, NONE);
+%AddNamedProperty(this.__proto__, "y", 1234, NONE);
assertEquals(1234, y);
eval("with({}) { const y = 5678; }");
assertEquals(5678, y);
-%SetProperty(this.__proto__, "z", 1234, READ_ONLY);
+%AddNamedProperty(this.__proto__, "z", 1234, READ_ONLY);
assertEquals(1234, z);
eval("with({}) { var z = 5678; }");
assertEquals(5678, z);
-%SetProperty(this.__proto__, "w", 1234, READ_ONLY);
+%AddNamedProperty(this.__proto__, "w", 1234, READ_ONLY);
assertEquals(1234, w);
eval("with({}) { const w = 5678; }");
assertEquals(5678, w);
diff --git a/deps/v8/test/mjsunit/regress/regress-1213575.js b/deps/v8/test/mjsunit/regress/regress-1213575.js
index f3a11dbaa..8c197bcf8 100644
--- a/deps/v8/test/mjsunit/regress/regress-1213575.js
+++ b/deps/v8/test/mjsunit/regress/regress-1213575.js
@@ -37,4 +37,4 @@ try {
assertTrue(e instanceof TypeError);
caught = true;
}
-assertFalse(caught);
+assertTrue(caught);
diff --git a/deps/v8/test/mjsunit/regress/regress-1530.js b/deps/v8/test/mjsunit/regress/regress-1530.js
index db2114450..20d1f265c 100644
--- a/deps/v8/test/mjsunit/regress/regress-1530.js
+++ b/deps/v8/test/mjsunit/regress/regress-1530.js
@@ -33,34 +33,52 @@ var f = function() {};
// Verify that normal assignment of 'prototype' property works properly
// and updates the internal value.
-var x = { foo: 'bar' };
-f.prototype = x;
-assertSame(f.prototype, x);
+var a = { foo: 'bar' };
+f.prototype = a;
+assertSame(f.prototype, a);
assertSame(f.prototype.foo, 'bar');
assertSame(new f().foo, 'bar');
-assertSame(Object.getPrototypeOf(new f()), x);
-assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, x);
+assertSame(Object.getPrototypeOf(new f()), a);
+assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, a);
+assertTrue(Object.getOwnPropertyDescriptor(f, 'prototype').writable);
// Verify that 'prototype' behaves like a data property when it comes to
// redefining with Object.defineProperty() and the internal value gets
// updated.
-var y = { foo: 'baz' };
-Object.defineProperty(f, 'prototype', { value: y, writable: true });
-assertSame(f.prototype, y);
+var b = { foo: 'baz' };
+Object.defineProperty(f, 'prototype', { value: b, writable: true });
+assertSame(f.prototype, b);
assertSame(f.prototype.foo, 'baz');
assertSame(new f().foo, 'baz');
-assertSame(Object.getPrototypeOf(new f()), y);
-assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, y);
+assertSame(Object.getPrototypeOf(new f()), b);
+assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, b);
+assertTrue(Object.getOwnPropertyDescriptor(f, 'prototype').writable);
// Verify that the previous redefinition didn't screw up callbacks and
// the internal value still gets updated.
-var z = { foo: 'other' };
-f.prototype = z;
-assertSame(f.prototype, z);
+var c = { foo: 'other' };
+f.prototype = c;
+assertSame(f.prototype, c);
assertSame(f.prototype.foo, 'other');
assertSame(new f().foo, 'other');
-assertSame(Object.getPrototypeOf(new f()), z);
-assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, z);
+assertSame(Object.getPrototypeOf(new f()), c);
+assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, c);
+assertTrue(Object.getOwnPropertyDescriptor(f, 'prototype').writable);
+
+// Verify that 'prototype' can be redefined to contain a different value
+// and have a different writability attribute at the same time.
+var d = { foo: 'final' };
+Object.defineProperty(f, 'prototype', { value: d, writable: false });
+assertSame(f.prototype, d);
+assertSame(f.prototype.foo, 'final');
+assertSame(new f().foo, 'final');
+assertSame(Object.getPrototypeOf(new f()), d);
+assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, d);
+assertFalse(Object.getOwnPropertyDescriptor(f, 'prototype').writable);
+
+// Verify that non-writability of redefined 'prototype' is respected.
+assertThrows("'use strict'; f.prototype = {}");
+assertThrows("Object.defineProperty(f, 'prototype', { value: {} })");
// Verify that non-writability of other properties is respected.
assertThrows("Object.defineProperty(f, 'name', { value: {} })");
diff --git a/deps/v8/test/mjsunit/regress/regress-1708.js b/deps/v8/test/mjsunit/regress/regress-1708.js
index 48ee79c77..ed2ddb145 100644
--- a/deps/v8/test/mjsunit/regress/regress-1708.js
+++ b/deps/v8/test/mjsunit/regress/regress-1708.js
@@ -32,7 +32,7 @@
// sure that concurrent sweeping, which relies on similar assumptions
// as lazy sweeping works correctly.
-// Flags: --expose-gc --noincremental-marking --max-new-space-size=2
+// Flags: --expose-gc --noincremental-marking --max-semi-space-size=1
(function() {
var head = new Array(1);
diff --git a/deps/v8/test/mjsunit/regress/regress-2790.js b/deps/v8/test/mjsunit/regress/regress-2790.js
index 927f2607c..ac79e6404 100644
--- a/deps/v8/test/mjsunit/regress/regress-2790.js
+++ b/deps/v8/test/mjsunit/regress/regress-2790.js
@@ -26,6 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Test that we can create arrays of any size.
-for (var i = 1000; i < 1000000; i += 197) {
+for (var i = 1000; i < 1000000; i += 19703) {
new Array(i);
}
diff --git a/deps/v8/test/mjsunit/regress/regress-320532.js b/deps/v8/test/mjsunit/regress/regress-320532.js
index 6ec4b9729..0c3198f79 100644
--- a/deps/v8/test/mjsunit/regress/regress-320532.js
+++ b/deps/v8/test/mjsunit/regress/regress-320532.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+// Flags: --allow-natives-syntax --expose-gc
// Flags: --noalways-opt
// Flags: --stress-runs=8 --send-idle-notification --gc-global
diff --git a/deps/v8/test/mjsunit/regress/regress-3281.js b/deps/v8/test/mjsunit/regress/regress-3281.js
index ebb25991d..7d42c026b 100644
--- a/deps/v8/test/mjsunit/regress/regress-3281.js
+++ b/deps/v8/test/mjsunit/regress/regress-3281.js
@@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --harmony-collections
-
+// Flags: --expose-natives-as=builtins
// Should not crash or raise an exception.
var s = new Set();
-var setIterator = %SetCreateIterator(s, 2);
+var setIterator = new builtins.SetIterator(s, 2);
var m = new Map();
-var mapIterator = %MapCreateIterator(m, 2);
+var mapIterator = new builtins.MapIterator(m, 2);
diff --git a/deps/v8/test/mjsunit/regress/regress-3307.js b/deps/v8/test/mjsunit/regress/regress-3307.js
new file mode 100644
index 000000000..1fc770d20
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-3307.js
@@ -0,0 +1,24 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function p(x) {
+ this.x = x;
+}
+
+function f() {
+ var a = new p(1), b = new p(2);
+ for (var i = 0; i < 1; i++) {
+ a.x += b.x;
+ }
+ return a.x;
+}
+
+new p(0.1); // make 'x' mutable box double field in p.
+
+assertEquals(3, f());
+assertEquals(3, f());
+%OptimizeFunctionOnNextCall(f);
+assertEquals(3, f());
diff --git a/deps/v8/test/mjsunit/regress/regress-3315.js b/deps/v8/test/mjsunit/regress/regress-3315.js
new file mode 100644
index 000000000..a1105e284
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-3315.js
@@ -0,0 +1,26 @@
+// 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.
+
+var indexZeroCallCount = 0;
+var indexOneCallCount = 0;
+var lengthCallCount = 0;
+var acceptList = {
+ get 0() {
+ indexZeroCallCount++;
+ return 'foo';
+ },
+ get 1() {
+ indexOneCallCount++;
+ return 'bar';
+ },
+ get length() {
+ lengthCallCount++;
+ return 1;
+ }
+};
+
+Object.observe({}, function(){}, acceptList);
+assertEquals(1, lengthCallCount);
+assertEquals(1, indexZeroCallCount);
+assertEquals(0, indexOneCallCount);
diff --git a/deps/v8/test/mjsunit/regress/regress-3334.js b/deps/v8/test/mjsunit/regress/regress-3334.js
new file mode 100644
index 000000000..301155dbd
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-3334.js
@@ -0,0 +1,13 @@
+// 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.
+
+function foo(){}
+Object.defineProperty(foo, "prototype", { value: 2 });
+assertEquals(2, foo.prototype);
+
+function bar(){}
+Object.defineProperty(bar, "prototype", { value: 2, writable: false });
+assertEquals(2, bar.prototype);
+assertThrows(function() { "use strict"; bar.prototype = 10; }, TypeError);
+assertEquals(false, Object.getOwnPropertyDescriptor(bar,"prototype").writable);
diff --git a/deps/v8/test/mjsunit/regress/regress-334.js b/deps/v8/test/mjsunit/regress/regress-334.js
index 37dd299cf..c52c72aa9 100644
--- a/deps/v8/test/mjsunit/regress/regress-334.js
+++ b/deps/v8/test/mjsunit/regress/regress-334.js
@@ -37,10 +37,10 @@ function func1(){}
function func2(){}
var object = {__proto__:{}};
-%SetProperty(object, "foo", func1, DONT_ENUM | DONT_DELETE);
-%SetProperty(object, "bar", func1, DONT_ENUM | READ_ONLY);
-%SetProperty(object, "baz", func1, DONT_DELETE | READ_ONLY);
-%SetProperty(object.__proto__, "bif", func1, DONT_ENUM | DONT_DELETE);
+%AddNamedProperty(object, "foo", func1, DONT_ENUM | DONT_DELETE);
+%AddNamedProperty(object, "bar", func1, DONT_ENUM | READ_ONLY);
+%AddNamedProperty(object, "baz", func1, DONT_DELETE | READ_ONLY);
+%AddNamedProperty(object.__proto__, "bif", func1, DONT_ENUM | DONT_DELETE);
object.bif = func2;
function enumerable(obj) {
diff --git a/deps/v8/test/mjsunit/regress/regress-3359.js b/deps/v8/test/mjsunit/regress/regress-3359.js
new file mode 100644
index 000000000..0973797e7
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-3359.js
@@ -0,0 +1,12 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function f() {
+ return 1 >> Boolean.constructor + 1;
+}
+assertEquals(1, f());
+%OptimizeFunctionOnNextCall(f);
+assertEquals(1, f());
diff --git a/deps/v8/test/mjsunit/regress/regress-3380.js b/deps/v8/test/mjsunit/regress/regress-3380.js
new file mode 100644
index 000000000..2fae459b3
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-3380.js
@@ -0,0 +1,16 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function foo(a) {
+ return (a[0] >>> 0) > 0;
+}
+
+var a = new Uint32Array([4]);
+var b = new Uint32Array([0x80000000]);
+assertTrue(foo(a));
+assertTrue(foo(a));
+%OptimizeFunctionOnNextCall(foo);
+assertTrue(foo(b))
diff --git a/deps/v8/test/mjsunit/regress/regress-3392.js b/deps/v8/test/mjsunit/regress/regress-3392.js
new file mode 100644
index 000000000..375f30210
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-3392.js
@@ -0,0 +1,18 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function foo() {
+ var a = {b: -1.5};
+ for (var i = 0; i < 1; i++) {
+ a.b = 1;
+ }
+ assertTrue(0 <= a.b);
+}
+
+foo();
+foo();
+%OptimizeFunctionOnNextCall(foo);
+foo();
diff --git a/deps/v8/test/mjsunit/regress/regress-3404.js b/deps/v8/test/mjsunit/regress/regress-3404.js
new file mode 100644
index 000000000..c4d280e57
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-3404.js
@@ -0,0 +1,27 @@
+// 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.
+
+function testError(error) {
+ // Reconfigure e.stack to be non-configurable
+ var desc1 = Object.getOwnPropertyDescriptor(error, "stack");
+ Object.defineProperty(error, "stack",
+ {get: desc1.get, set: desc1.set, configurable: false});
+
+ var desc2 = Object.getOwnPropertyDescriptor(error, "stack");
+ assertFalse(desc2.configurable);
+ assertEquals(desc1.get, desc2.get);
+ assertEquals(desc2.get, desc2.get);
+}
+
+function stackOverflow() {
+ function f() { f(); }
+ try { f() } catch (e) { return e; }
+}
+
+function referenceError() {
+ try { g() } catch (e) { return e; }
+}
+
+testError(referenceError());
+testError(stackOverflow());
diff --git a/deps/v8/test/mjsunit/regress/regress-3462.js b/deps/v8/test/mjsunit/regress/regress-3462.js
new file mode 100644
index 000000000..5a3355920
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-3462.js
@@ -0,0 +1,48 @@
+// 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.
+
+
+function TestFunctionPrototypeSetter() {
+ var f = function() {};
+ var o = {__proto__: f};
+ o.prototype = 42;
+ assertEquals(42, o.prototype);
+ assertTrue(o.hasOwnProperty('prototype'));
+}
+TestFunctionPrototypeSetter();
+
+
+function TestFunctionPrototypeSetterOnValue() {
+ var f = function() {};
+ var fp = f.prototype;
+ Number.prototype.__proto__ = f;
+ var n = 42;
+ var o = {};
+ n.prototype = o;
+ assertEquals(fp, n.prototype);
+ assertEquals(fp, f.prototype);
+ assertFalse(Number.prototype.hasOwnProperty('prototype'));
+}
+TestFunctionPrototypeSetterOnValue();
+
+
+function TestArrayLengthSetter() {
+ var a = [1];
+ var o = {__proto__: a};
+ o.length = 2;
+ assertEquals(2, o.length);
+ assertEquals(1, a.length);
+ assertTrue(o.hasOwnProperty('length'));
+}
+TestArrayLengthSetter();
+
+
+function TestArrayLengthSetterOnValue() {
+ Number.prototype.__proto__ = [1];
+ var n = 42;
+ n.length = 2;
+ assertEquals(1, n.length);
+ assertFalse(Number.prototype.hasOwnProperty('length'));
+}
+TestArrayLengthSetterOnValue();
diff --git a/deps/v8/test/mjsunit/regress/regress-3476.js b/deps/v8/test/mjsunit/regress/regress-3476.js
new file mode 100644
index 000000000..f4333dbbf
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-3476.js
@@ -0,0 +1,24 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function MyWrapper(v) {
+ return { valueOf: function() { return v } };
+}
+
+function f() {
+ assertEquals("truex", true + "x");
+ assertEquals("truey", true + new String("y"));
+ assertEquals("truez", true + new MyWrapper("z"));
+
+ assertEquals("xtrue", "x" + true);
+ assertEquals("ytrue", new String("y") + true);
+ assertEquals("ztrue", new MyWrapper("z") + true);
+}
+
+f();
+f();
+%OptimizeFunctionOnNextCall(f);
+f();
diff --git a/deps/v8/test/mjsunit/regress/regress-370827.js b/deps/v8/test/mjsunit/regress/regress-370827.js
new file mode 100644
index 000000000..5536d5196
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-370827.js
@@ -0,0 +1,21 @@
+// 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.
+
+// Flags: --allow-natives-syntax --expose-gc --heap-stats
+
+function g(dummy, x) {
+ var start = "";
+ if (x) { start = x + " - "; }
+ start = start + "array length";
+};
+
+function f() {
+ gc();
+ g([0.1]);
+}
+
+f();
+%OptimizeFunctionOnNextCall(f);
+f();
+f();
diff --git a/deps/v8/test/mjsunit/regress/regress-373283.js b/deps/v8/test/mjsunit/regress/regress-373283.js
new file mode 100644
index 000000000..20cee4d80
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-373283.js
@@ -0,0 +1,18 @@
+// 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.
+
+// Flags: --allow-natives-syntax --deopt-every-n-times=1
+
+function __f_0() {
+ var x = [];
+ x[21] = 1;
+ x[21] + 0;
+}
+
+for (var i = 0; i < 3; i++) __f_0();
+%OptimizeFunctionOnNextCall(__f_0);
+for (var i = 0; i < 10; i++) __f_0();
+%OptimizeFunctionOnNextCall(__f_0);
+__f_0();
+%GetScript("foo");
diff --git a/deps/v8/test/mjsunit/regress/regress-377290.js b/deps/v8/test/mjsunit/regress/regress-377290.js
new file mode 100644
index 000000000..23e31e79d
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-377290.js
@@ -0,0 +1,17 @@
+// 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.
+
+// Flags: --expose-gc
+
+Object.prototype.__defineGetter__('constructor', function() { throw 42; });
+__v_7 = [
+ function() { [].push() },
+];
+for (var __v_6 = 0; __v_6 < 5; ++__v_6) {
+ for (var __v_8 in __v_7) {
+ print(__v_8, " -> ", __v_7[__v_8]);
+ gc();
+ try { __v_7[__v_8](); } catch (e) {};
+ }
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-379770.js b/deps/v8/test/mjsunit/regress/regress-379770.js
new file mode 100644
index 000000000..a6653c259
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-379770.js
@@ -0,0 +1,26 @@
+// 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.
+// Flags: --allow-natives-syntax --nostress-opt
+// Flags: --nouse-osr
+
+function foo(obj) {
+ var counter = 1;
+ for (var i = 0; i < obj.length; i++) {
+ %OptimizeFunctionOnNextCall(foo, "osr");
+ }
+ counter += obj;
+ return counter;
+}
+
+function bar() {
+ var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
+ for (var i = 0; i < 100; i++ ) {
+ foo(a);
+ }
+}
+
+try {
+ bar();
+} catch (e) {
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-380049.js b/deps/v8/test/mjsunit/regress/regress-380049.js
new file mode 100644
index 000000000..a78626cc5
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-380049.js
@@ -0,0 +1,9 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function foo(a,b,c) { return arguments; }
+var f = foo(false, null, 40);
+assertThrows(function() { %ObjectFreeze(f); });
diff --git a/deps/v8/test/mjsunit/regress/regress-380092.js b/deps/v8/test/mjsunit/regress/regress-380092.js
new file mode 100644
index 000000000..fe6b0b761
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-380092.js
@@ -0,0 +1,22 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function many_hoist(o, index) {
+ return o[index + 33554427];
+}
+
+var obj = {};
+many_hoist(obj, 0);
+%OptimizeFunctionOnNextCall(many_hoist);
+many_hoist(obj, 5);
+
+function constant_too_large(o, index) {
+ return o[index + 1033554433];
+}
+
+constant_too_large(obj, 0);
+%OptimizeFunctionOnNextCall(constant_too_large);
+constant_too_large(obj, 5);
diff --git a/deps/v8/test/mjsunit/regress/regress-381313.js b/deps/v8/test/mjsunit/regress/regress-381313.js
new file mode 100644
index 000000000..d2b9d7c11
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-381313.js
@@ -0,0 +1,42 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+var g = 0;
+
+function f(x, deopt) {
+ var a0 = x;
+ var a1 = 2 * x;
+ var a2 = 3 * x;
+ var a3 = 4 * x;
+ var a4 = 5 * x;
+ var a5 = 6 * x;
+ var a6 = 7 * x;
+ var a7 = 8 * x;
+ var a8 = 9 * x;
+ var a9 = 10 * x;
+ var a10 = 11 * x;
+ var a11 = 12 * x;
+ var a12 = 13 * x;
+ var a13 = 14 * x;
+ var a14 = 15 * x;
+ var a15 = 16 * x;
+ var a16 = 17 * x;
+ var a17 = 18 * x;
+ var a18 = 19 * x;
+ var a19 = 20 * x;
+
+ g = 1;
+
+ deopt + 0;
+
+ return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 +
+ a10 + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19;
+}
+
+f(0.5, 0);
+f(0.5, 0);
+%OptimizeFunctionOnNextCall(f);
+print(f(0.5, ""));
diff --git a/deps/v8/test/cctest/test-cpu.cc b/deps/v8/test/mjsunit/regress/regress-392114.js
index 06966c68c..e5cf1cde3 100644
--- a/deps/v8/test/cctest/test-cpu.cc
+++ b/deps/v8/test/mjsunit/regress/regress-392114.js
@@ -1,4 +1,4 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
+// 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:
@@ -25,31 +25,42 @@
// (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"
+// Flags: --expose-debug-as debug --allow-natives-syntax
-#include "cctest.h"
-#include "cpu.h"
+Debug = debug.Debug;
-using namespace v8::internal;
+function dummy(x) {
+ return x + 100;
+}
+function create_closure() {
+ var f = function(arg) {
+ if (arg) { %DeoptimizeFunction(f); }
+ var a = Array(10);
+ for (var i = 0; i < a.length; i++) {
+ a[i] = i;
+ }
+ }
+ return f;
+}
-TEST(FeatureImplications) {
- // Test for features implied by other features.
- CPU cpu;
+var c = create_closure();
+c();
- // ia32 and x64 features
- CHECK(!cpu.has_sse() || cpu.has_mmx());
- CHECK(!cpu.has_sse2() || cpu.has_sse());
- CHECK(!cpu.has_sse3() || cpu.has_sse2());
- CHECK(!cpu.has_ssse3() || cpu.has_sse3());
- CHECK(!cpu.has_sse41() || cpu.has_sse3());
- CHECK(!cpu.has_sse42() || cpu.has_sse41());
+// c CallIC state now has custom Array handler installed.
- // arm features
- CHECK(!cpu.has_vfp3_d32() || cpu.has_vfp3());
-}
+// Turn on the debugger.
+Debug.setListener(function () {});
+var d = create_closure();
+%OptimizeFunctionOnNextCall(d);
+// Thanks to the debugger, we recreate the full code too. We deopt and run
+// it, stomping on the unexpected AllocationSite in the type vector slot.
+d(true);
-TEST(NumberOfProcessorsOnline) {
- CHECK_GT(CPU::NumberOfProcessorsOnline(), 0);
-}
+// CallIC in c misinterprets type vector slot contents as an AllocationSite,
+// corrupting the heap.
+c();
+
+// CallIC MISS - crash due to corruption.
+dummy();
diff --git a/deps/v8/test/mjsunit/regress/regress-99167.js b/deps/v8/test/mjsunit/regress/regress-99167.js
index 777acf448..eac49d12b 100644
--- a/deps/v8/test/mjsunit/regress/regress-99167.js
+++ b/deps/v8/test/mjsunit/regress/regress-99167.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --expose-gc --max-new-space-size=2
+// Flags: --expose-gc --max-semi-space-size=1
eval("function Node() { this.a = 1; this.a = 3; }");
new Node;
diff --git a/deps/v8/test/mjsunit/regress/regress-cntl-descriptors-enum.js b/deps/v8/test/mjsunit/regress/regress-cntl-descriptors-enum.js
index ee72fafc8..fd4ac6d6c 100644
--- a/deps/v8/test/mjsunit/regress/regress-cntl-descriptors-enum.js
+++ b/deps/v8/test/mjsunit/regress/regress-cntl-descriptors-enum.js
@@ -30,10 +30,10 @@
DontEnum = 2;
var o = {};
-%SetProperty(o, "a", 0, DontEnum);
+%AddNamedProperty(o, "a", 0, DontEnum);
var o2 = {};
-%SetProperty(o2, "a", 0, DontEnum);
+%AddNamedProperty(o2, "a", 0, DontEnum);
assertTrue(%HaveSameMap(o, o2));
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-245480.js b/deps/v8/test/mjsunit/regress/regress-crbug-245480.js
index ec8850905..43fa6ba3b 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-245480.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-245480.js
@@ -25,25 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+// Flags: --allow-natives-syntax --expose-gc
// Flags: --noalways-opt
-// Test element kind of objects.
-// Since --smi-only-arrays affects builtins, its default setting at compile
-// time sticks if built with snapshot. If --smi-only-arrays is deactivated
-// by default, only a no-snapshot build actually has smi-only arrays enabled
-// in this test case. Depending on whether smi-only arrays are actually
-// enabled, this test takes the appropriate code path to check smi-only arrays.
-
-// support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
-support_smi_only_arrays = true;
-
-if (support_smi_only_arrays) {
- print("Tests include smi-only arrays.");
-} else {
- print("Tests do NOT include smi-only arrays.");
-}
-
function isHoley(obj) {
if (%HasFastHoleyElements(obj)) return true;
return false;
@@ -57,19 +41,17 @@ function assertNotHoley(obj, name_opt) {
assertEquals(false, isHoley(obj), name_opt);
}
-if (support_smi_only_arrays) {
- function create_array(arg) {
- return new Array(arg);
- }
-
- obj = create_array(0);
- assertNotHoley(obj);
- create_array(0);
- %OptimizeFunctionOnNextCall(create_array);
- obj = create_array(10);
- assertHoley(obj);
+function create_array(arg) {
+ return new Array(arg);
}
+obj = create_array(0);
+assertNotHoley(obj);
+create_array(0);
+%OptimizeFunctionOnNextCall(create_array);
+obj = create_array(10);
+assertHoley(obj);
+
// The code below would assert in debug or crash in release
function f(length) {
return new Array(length)
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-350864.js b/deps/v8/test/mjsunit/regress/regress-crbug-350864.js
index 8a793cb0a..510834be3 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-350864.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-350864.js
@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-symbols
-
var v0 = new WeakMap;
var v1 = {};
v0.set(v1, 1);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-374838.js b/deps/v8/test/mjsunit/regress/regress-crbug-374838.js
new file mode 100644
index 000000000..614b4d9a8
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-374838.js
@@ -0,0 +1,20 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function foo() {
+ var a = [0];
+ result = 0;
+ for (var i = 0; i < 4; i++) {
+ result += a.length;
+ a.shift();
+ }
+ return result;
+}
+
+assertEquals(1, foo());
+assertEquals(1, foo());
+%OptimizeFunctionOnNextCall(foo);
+assertEquals(1, foo());
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-380512.js b/deps/v8/test/mjsunit/regress/regress-crbug-380512.js
new file mode 100644
index 000000000..af78ba718
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-380512.js
@@ -0,0 +1,12 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function f() { [].lastIndexOf(42); }
+
+f();
+f();
+%OptimizeFunctionOnNextCall(f);
+f();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-381534.js b/deps/v8/test/mjsunit/regress/regress-crbug-381534.js
new file mode 100644
index 000000000..2aa392967
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-381534.js
@@ -0,0 +1,40 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+var obj = {};
+
+function f(v) {
+ var v1 = -(4/3);
+ var v2 = 1;
+ var arr = new Array(+0, true, 0, -0, false, undefined, null, "0", obj, v1, -(4/3), -1.3333333333333, "str", v2, 1, false);
+ assertEquals(10, arr.lastIndexOf(-(4/3)));
+ assertEquals(9, arr.indexOf(-(4/3)));
+
+ assertEquals(10, arr.lastIndexOf(v));
+ assertEquals(9, arr.indexOf(v));
+
+ assertEquals(8, arr.lastIndexOf(obj));
+ assertEquals(8, arr.indexOf(obj));
+}
+
+function g(v, x, index) {
+ var arr = new Array({}, x-1.1, x-2, x-3.1);
+ assertEquals(index, arr.indexOf(0));
+ assertEquals(index, arr.lastIndexOf(0));
+
+ assertEquals(index, arr.indexOf(v));
+ assertEquals(index, arr.lastIndexOf(v));
+}
+
+f(-(4/3));
+f(-(4/3));
+%OptimizeFunctionOnNextCall(f);
+f(-(4/3));
+
+g(0, 2, 2);
+g(0, 3.1, 3);
+%OptimizeFunctionOnNextCall(g);
+g(0, 1.1, 1);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-382513.js b/deps/v8/test/mjsunit/regress/regress-crbug-382513.js
new file mode 100644
index 000000000..59d2dcac7
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-382513.js
@@ -0,0 +1,11 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function foo() { return [+0,false].indexOf(-(4/3)); }
+foo();
+foo();
+%OptimizeFunctionOnNextCall(foo);
+foo();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-385002.js b/deps/v8/test/mjsunit/regress/regress-crbug-385002.js
new file mode 100644
index 000000000..34713e27d
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-385002.js
@@ -0,0 +1,15 @@
+// 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.
+
+// Flags: --stack-size=200 --allow-natives-syntax
+
+%Break(); // Schedule an interrupt that does not go away.
+
+function f() { f(); }
+assertThrows(f, RangeError);
+
+var locals = "";
+for (var i = 0; i < 1024; i++) locals += "var v" + i + ";";
+eval("function g() {" + locals + "f();}");
+assertThrows("g()", RangeError);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-387599.js b/deps/v8/test/mjsunit/regress/regress-crbug-387599.js
new file mode 100644
index 000000000..98750aa91
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-387599.js
@@ -0,0 +1,19 @@
+// 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.
+
+// Flags: --allow-natives-syntax --expose-debug-as debug
+
+Debug = debug.Debug;
+Debug.setListener(function() {});
+
+function f() {
+ for (var i = 0; i < 100; i++) {
+ %OptimizeFunctionOnNextCall(f, "osr");
+ }
+}
+
+Debug.setBreakPoint(f, 0, 0);
+f();
+f();
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-387627.js b/deps/v8/test/mjsunit/regress/regress-crbug-387627.js
new file mode 100644
index 000000000..5c6389b5f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-387627.js
@@ -0,0 +1,13 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function f() {}
+%FunctionBindArguments(f, {}, undefined, 1);
+
+f();
+f();
+%OptimizeFunctionOnNextCall(f);
+f();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-387636.js b/deps/v8/test/mjsunit/regress/regress-crbug-387636.js
new file mode 100644
index 000000000..1e50ace45
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-387636.js
@@ -0,0 +1,14 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function f() {
+ [].indexOf(0x40000000);
+}
+
+f();
+f();
+%OptimizeFunctionOnNextCall(f);
+f();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-390918.js b/deps/v8/test/mjsunit/regress/regress-crbug-390918.js
new file mode 100644
index 000000000..4c202b3a9
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-390918.js
@@ -0,0 +1,18 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function f(scale) {
+ var arr = {a: 1.1};
+
+ for (var i = 0; i < 2; i++) {
+ arr[2 * scale] = 0;
+ }
+}
+
+f({});
+f({});
+%OptimizeFunctionOnNextCall(f);
+f(1004);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-390925.js b/deps/v8/test/mjsunit/regress/regress-crbug-390925.js
new file mode 100644
index 000000000..24873df17
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-390925.js
@@ -0,0 +1,9 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+var a = new Array();
+Object.freeze(a);
+assertThrows(function() { %LiveEditCheckAndDropActivations(a, true); });
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-393988.js b/deps/v8/test/mjsunit/regress/regress-crbug-393988.js
new file mode 100644
index 000000000..9543e1e4c
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-393988.js
@@ -0,0 +1,8 @@
+// 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.
+
+var o = {};
+Error.captureStackTrace(o);
+Object.defineProperty(o, "stack", { value: 1 });
+assertEquals(1, o.stack);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-401915.js b/deps/v8/test/mjsunit/regress/regress-crbug-401915.js
new file mode 100644
index 000000000..96dce0486
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-401915.js
@@ -0,0 +1,20 @@
+// 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.
+
+// Flags: --allow-natives-syntax --expose-debug-as debug
+
+Debug = debug.Debug;
+Debug.setListener(function() {});
+Debug.setBreakOnException();
+
+try {
+ try {
+ %DebugPushPromise(new Promise(function() {}));
+ } catch (e) {
+ }
+ throw new Error();
+} catch (e) {
+}
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/regress/regress-create-exception.js b/deps/v8/test/mjsunit/regress/regress-create-exception.js
index e0553041a..440449cf5 100644
--- a/deps/v8/test/mjsunit/regress/regress-create-exception.js
+++ b/deps/v8/test/mjsunit/regress/regress-create-exception.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --max-new-space-size=2
+// Flags: --max-semi-space-size=1
"use strict";
// Check for GC bug constructing exceptions.
diff --git a/deps/v8/test/mjsunit/regress/regress-debug-context-load.js b/deps/v8/test/mjsunit/regress/regress-debug-context-load.js
new file mode 100644
index 000000000..0b3c275f9
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-debug-context-load.js
@@ -0,0 +1,8 @@
+// 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.
+
+// Flags: --expose-debug-as debug
+
+Debug = debug.Debug;
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/regress/regress-double-property.js b/deps/v8/test/mjsunit/regress/regress-double-property.js
new file mode 100644
index 000000000..2ddb45b4b
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-double-property.js
@@ -0,0 +1,9 @@
+// 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.
+
+function f(a) {
+ return {0.1: a};
+}
+
+f();
diff --git a/deps/v8/test/mjsunit/regress/regress-escape-preserve-smi-representation.js b/deps/v8/test/mjsunit/regress/regress-escape-preserve-smi-representation.js
index 551147ed5..fd899d64e 100644
--- a/deps/v8/test/mjsunit/regress/regress-escape-preserve-smi-representation.js
+++ b/deps/v8/test/mjsunit/regress/regress-escape-preserve-smi-representation.js
@@ -12,7 +12,7 @@ function deepEquals(a, b) {
if (objectClass === "RegExp") { return (a.toString() === b.toString()); }
if (objectClass === "Function") return false;
if (objectClass === "Array") {
- var elementCount = 0;
+ var elementsCount = 0;
if (a.length != b.length) { return false; }
for (var i = 0; i < a.length; i++) {
if (!deepEquals(a[i], b[i])) return false;
@@ -23,12 +23,11 @@ function deepEquals(a, b) {
function __f_1(){
- var __v_0 = [];
- for(var i=0; i<2; i++){
- var __v_1=[];
- __v_0.push([])
- deepEquals(2, __v_0.length);
- }
+ var __v_0 = [];
+ for(var i=0; i<2; i++){
+ __v_0.push([])
+ deepEquals(2, __v_0.length);
+ }
}
__f_1();
%OptimizeFunctionOnNextCall(__f_1);
diff --git a/deps/v8/test/mjsunit/regress/regress-global-freeze-const.js b/deps/v8/test/mjsunit/regress/regress-freeze-setter.js
index 0b9e1f3eb..c5ac98667 100644
--- a/deps/v8/test/mjsunit/regress/regress-global-freeze-const.js
+++ b/deps/v8/test/mjsunit/regress/regress-freeze-setter.js
@@ -2,6 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-__defineSetter__('x', function() { });
+Object.defineProperty(this, 'x', {set: function() { }});
Object.freeze(this);
-eval('const x = 1');
+eval('"use strict"; x = 20;');
diff --git a/deps/v8/test/mjsunit/regress/regress-function-constructor-receiver.js b/deps/v8/test/mjsunit/regress/regress-function-constructor-receiver.js
new file mode 100644
index 000000000..f345435ad
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-function-constructor-receiver.js
@@ -0,0 +1,17 @@
+// 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.
+
+// Return the raw CallSites array.
+Error.prepareStackTrace = function (a,b) { return b; };
+
+var threw = false;
+try {
+ new Function({toString:0,valueOf:0});
+} catch (e) {
+ threw = true;
+ // Ensure that the receiver during "new Function" is the global proxy.
+ assertEquals(this, e.stack[0].getThis());
+}
+
+assertTrue(threw);
diff --git a/deps/v8/test/mjsunit/regress/regress-mask-array-length.js b/deps/v8/test/mjsunit/regress/regress-mask-array-length.js
new file mode 100644
index 000000000..bd87e7c5d
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-mask-array-length.js
@@ -0,0 +1,10 @@
+// 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.
+
+var a = [];
+var o = {
+ __proto__: a
+};
+Object.preventExtensions(o);
+o.length = 'abc';
diff --git a/deps/v8/test/cctest/test-platform-macos.cc b/deps/v8/test/mjsunit/regress/regress-regexp-nocase.js
index 5bc5f9784..27637da09 100644
--- a/deps/v8/test/cctest/test-platform-macos.cc
+++ b/deps/v8/test/mjsunit/regress/regress-regexp-nocase.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// 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:
@@ -24,12 +24,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Tests of the TokenLock class from lock.h
-
-#include <stdlib.h>
-#include "v8.h"
-#include "cctest.h"
+var s = "('')x\nx\uF670";
-using namespace ::v8::internal;
+assertEquals(s.match(/\((').*\1\)/i), ["('')", "'"]);
diff --git a/deps/v8/test/mjsunit/regress/regress-set-flags-stress-compact.js b/deps/v8/test/mjsunit/regress/regress-set-flags-stress-compact.js
new file mode 100644
index 000000000..5bc59a7e1
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-set-flags-stress-compact.js
@@ -0,0 +1,10 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+%SetFlags("--gc-interval=164 --stress-compaction");
+
+var a = [];
+for (var i = 0; i < 10000; i++) { a[i * 100] = 0; }
diff --git a/deps/v8/test/mjsunit/regress/regress-update-field-type-attributes.js b/deps/v8/test/mjsunit/regress/regress-update-field-type-attributes.js
new file mode 100644
index 000000000..c23d06206
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-update-field-type-attributes.js
@@ -0,0 +1,12 @@
+// 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.
+
+function test(){
+ function InnerClass(){}
+ var container = {field: new InnerClass()};
+ return Object.freeze(container);
+};
+
+assertTrue(Object.isFrozen(test()));
+assertTrue(Object.isFrozen(test()));
diff --git a/deps/v8/test/mjsunit/runtime-gen/apply.js b/deps/v8/test/mjsunit/runtime-gen/apply.js
new file mode 100644
index 000000000..94c4753cb
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/apply.js
@@ -0,0 +1,9 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = function() {};
+var _receiver = new Object();
+var _arguments = new Object();
+var _offset = 1;
+var _argc = 1;
+%Apply(arg0, _receiver, _arguments, _offset, _argc);
diff --git a/deps/v8/test/mjsunit/runtime-gen/arraybuffergetbytelength.js b/deps/v8/test/mjsunit/runtime-gen/arraybuffergetbytelength.js
new file mode 100644
index 000000000..8aff9ac07
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/arraybuffergetbytelength.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new ArrayBuffer(8);
+%ArrayBufferGetByteLength(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/arraybufferinitialize.js b/deps/v8/test/mjsunit/runtime-gen/arraybufferinitialize.js
new file mode 100644
index 000000000..c4520c6a6
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/arraybufferinitialize.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new ArrayBuffer(8);
+var _byteLength = 1.5;
+%ArrayBufferInitialize(_holder, _byteLength);
diff --git a/deps/v8/test/mjsunit/runtime-gen/arraybufferisview.js b/deps/v8/test/mjsunit/runtime-gen/arraybufferisview.js
new file mode 100644
index 000000000..46cc5ba99
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/arraybufferisview.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+%ArrayBufferIsView(_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/arraybufferneuter.js b/deps/v8/test/mjsunit/runtime-gen/arraybufferneuter.js
new file mode 100644
index 000000000..89e9ee96b
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/arraybufferneuter.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _array_buffer = new ArrayBuffer(8);
+%ArrayBufferNeuter(_array_buffer);
diff --git a/deps/v8/test/mjsunit/runtime-gen/arraybuffersliceimpl.js b/deps/v8/test/mjsunit/runtime-gen/arraybuffersliceimpl.js
new file mode 100644
index 000000000..cb02bb069
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/arraybuffersliceimpl.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _source = new ArrayBuffer(8);
+var _target = new ArrayBuffer(8);
+var arg2 = 0;
+%ArrayBufferSliceImpl(_source, _target, arg2);
diff --git a/deps/v8/test/mjsunit/runtime-gen/arraybufferviewgetbytelength.js b/deps/v8/test/mjsunit/runtime-gen/arraybufferviewgetbytelength.js
new file mode 100644
index 000000000..e32ea0d4e
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/arraybufferviewgetbytelength.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Int32Array(2);
+%ArrayBufferViewGetByteLength(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/arraybufferviewgetbyteoffset.js b/deps/v8/test/mjsunit/runtime-gen/arraybufferviewgetbyteoffset.js
new file mode 100644
index 000000000..4c64ff206
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/arraybufferviewgetbyteoffset.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Int32Array(2);
+%ArrayBufferViewGetByteOffset(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/arrayconcat.js b/deps/v8/test/mjsunit/runtime-gen/arrayconcat.js
new file mode 100644
index 000000000..09487a607
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/arrayconcat.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = [1, 'a'];
+%ArrayConcat(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/availablelocalesof.js b/deps/v8/test/mjsunit/runtime-gen/availablelocalesof.js
new file mode 100644
index 000000000..a59c9b077
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/availablelocalesof.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _service = "foo";
+%AvailableLocalesOf(_service);
diff --git a/deps/v8/test/mjsunit/runtime-gen/basicjsonstringify.js b/deps/v8/test/mjsunit/runtime-gen/basicjsonstringify.js
new file mode 100644
index 000000000..55d197831
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/basicjsonstringify.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+%BasicJSONStringify(_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/booleanize.js b/deps/v8/test/mjsunit/runtime-gen/booleanize.js
new file mode 100644
index 000000000..8685368e4
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/booleanize.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _value_raw = new Object();
+var _token_raw = 1;
+%Booleanize(_value_raw, _token_raw);
diff --git a/deps/v8/test/mjsunit/runtime-gen/boundfunctiongetbindings.js b/deps/v8/test/mjsunit/runtime-gen/boundfunctiongetbindings.js
new file mode 100644
index 000000000..9221d3dd2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/boundfunctiongetbindings.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _callable = new Object();
+%BoundFunctionGetBindings(_callable);
diff --git a/deps/v8/test/mjsunit/runtime-gen/break.js b/deps/v8/test/mjsunit/runtime-gen/break.js
new file mode 100644
index 000000000..4b600d8e3
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/break.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%Break();
diff --git a/deps/v8/test/mjsunit/runtime-gen/breakiteratoradopttext.js b/deps/v8/test/mjsunit/runtime-gen/breakiteratoradopttext.js
new file mode 100644
index 000000000..64b6059da
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/breakiteratoradopttext.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = %GetImplFromInitializedIntlObject(new Intl.v8BreakIterator());
+var _text = "foo";
+%BreakIteratorAdoptText(arg0, _text);
diff --git a/deps/v8/test/mjsunit/runtime-gen/breakiteratorbreaktype.js b/deps/v8/test/mjsunit/runtime-gen/breakiteratorbreaktype.js
new file mode 100644
index 000000000..08cceb87f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/breakiteratorbreaktype.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = %GetImplFromInitializedIntlObject(new Intl.v8BreakIterator());
+%BreakIteratorBreakType(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/breakiteratorcurrent.js b/deps/v8/test/mjsunit/runtime-gen/breakiteratorcurrent.js
new file mode 100644
index 000000000..42000a846
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/breakiteratorcurrent.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = %GetImplFromInitializedIntlObject(new Intl.v8BreakIterator());
+%BreakIteratorCurrent(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/breakiteratorfirst.js b/deps/v8/test/mjsunit/runtime-gen/breakiteratorfirst.js
new file mode 100644
index 000000000..3fad88c9e
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/breakiteratorfirst.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = %GetImplFromInitializedIntlObject(new Intl.v8BreakIterator());
+%BreakIteratorFirst(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/breakiteratornext.js b/deps/v8/test/mjsunit/runtime-gen/breakiteratornext.js
new file mode 100644
index 000000000..be72ffc1d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/breakiteratornext.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = %GetImplFromInitializedIntlObject(new Intl.v8BreakIterator());
+%BreakIteratorNext(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/canonicalizelanguagetag.js b/deps/v8/test/mjsunit/runtime-gen/canonicalizelanguagetag.js
new file mode 100644
index 000000000..45df230a4
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/canonicalizelanguagetag.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _locale_id_str = "foo";
+%CanonicalizeLanguageTag(_locale_id_str);
diff --git a/deps/v8/test/mjsunit/runtime-gen/changebreakonexception.js b/deps/v8/test/mjsunit/runtime-gen/changebreakonexception.js
new file mode 100644
index 000000000..4bc0d43d0
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/changebreakonexception.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _type_arg = 32;
+var _enable = true;
+%ChangeBreakOnException(_type_arg, _enable);
diff --git a/deps/v8/test/mjsunit/runtime-gen/charfromcode.js b/deps/v8/test/mjsunit/runtime-gen/charfromcode.js
new file mode 100644
index 000000000..20823391d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/charfromcode.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _code = 32;
+%CharFromCode(_code);
diff --git a/deps/v8/test/mjsunit/runtime-gen/checkexecutionstate.js b/deps/v8/test/mjsunit/runtime-gen/checkexecutionstate.js
new file mode 100644
index 000000000..7e740c39f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/checkexecutionstate.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _break_id = 32;
+try {
+%CheckExecutionState(_break_id);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/checkisbootstrapping.js b/deps/v8/test/mjsunit/runtime-gen/checkisbootstrapping.js
new file mode 100644
index 000000000..114b20c1c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/checkisbootstrapping.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+try {
+%CheckIsBootstrapping();
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/clearbreakpoint.js b/deps/v8/test/mjsunit/runtime-gen/clearbreakpoint.js
new file mode 100644
index 000000000..1c11bc8f7
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/clearbreakpoint.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _break_point_object_arg = new Object();
+%ClearBreakPoint(_break_point_object_arg);
diff --git a/deps/v8/test/mjsunit/runtime-gen/clearfunctiontypefeedback.js b/deps/v8/test/mjsunit/runtime-gen/clearfunctiontypefeedback.js
new file mode 100644
index 000000000..f42b8da20
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/clearfunctiontypefeedback.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _function = function() {};
+%ClearFunctionTypeFeedback(_function);
diff --git a/deps/v8/test/mjsunit/runtime-gen/clearstepping.js b/deps/v8/test/mjsunit/runtime-gen/clearstepping.js
new file mode 100644
index 000000000..bfab2cde0
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/clearstepping.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%ClearStepping();
diff --git a/deps/v8/test/mjsunit/runtime-gen/collectstacktrace.js b/deps/v8/test/mjsunit/runtime-gen/collectstacktrace.js
new file mode 100644
index 000000000..bac9b6a66
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/collectstacktrace.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _error_object = new Object();
+var _caller = new Object();
+%CollectStackTrace(_error_object, _caller);
diff --git a/deps/v8/test/mjsunit/runtime-gen/compilestring.js b/deps/v8/test/mjsunit/runtime-gen/compilestring.js
new file mode 100644
index 000000000..659afcaae
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/compilestring.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _source = "foo";
+var arg1 = false;
+%CompileString(_source, arg1);
diff --git a/deps/v8/test/mjsunit/runtime-gen/constructdouble.js b/deps/v8/test/mjsunit/runtime-gen/constructdouble.js
new file mode 100644
index 000000000..9ac3dee9c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/constructdouble.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _hi = 32;
+var _lo = 32;
+%ConstructDouble(_hi, _lo);
diff --git a/deps/v8/test/mjsunit/runtime-gen/createbreakiterator.js b/deps/v8/test/mjsunit/runtime-gen/createbreakiterator.js
new file mode 100644
index 000000000..a8750b339
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/createbreakiterator.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = 'en-US';
+var arg1 = {type: 'string'};
+var _resolved = new Object();
+%CreateBreakIterator(arg0, arg1, _resolved);
diff --git a/deps/v8/test/mjsunit/runtime-gen/createcollator.js b/deps/v8/test/mjsunit/runtime-gen/createcollator.js
new file mode 100644
index 000000000..0d5b18d55
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/createcollator.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _locale = "foo";
+var _options = new Object();
+var _resolved = new Object();
+%CreateCollator(_locale, _options, _resolved);
diff --git a/deps/v8/test/mjsunit/runtime-gen/createglobalprivatesymbol.js b/deps/v8/test/mjsunit/runtime-gen/createglobalprivatesymbol.js
new file mode 100644
index 000000000..e4968c14f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/createglobalprivatesymbol.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _name = "foo";
+%CreateGlobalPrivateSymbol(_name);
diff --git a/deps/v8/test/mjsunit/runtime-gen/createjsfunctionproxy.js b/deps/v8/test/mjsunit/runtime-gen/createjsfunctionproxy.js
new file mode 100644
index 000000000..b4e1c31ae
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/createjsfunctionproxy.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _handler = new Object();
+var arg1 = function() {};
+var _construct_trap = function() {};
+var _prototype = new Object();
+%CreateJSFunctionProxy(_handler, arg1, _construct_trap, _prototype);
diff --git a/deps/v8/test/mjsunit/runtime-gen/createjsproxy.js b/deps/v8/test/mjsunit/runtime-gen/createjsproxy.js
new file mode 100644
index 000000000..ecdef6022
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/createjsproxy.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _handler = new Object();
+var _prototype = new Object();
+%CreateJSProxy(_handler, _prototype);
diff --git a/deps/v8/test/mjsunit/runtime-gen/createprivateownsymbol.js b/deps/v8/test/mjsunit/runtime-gen/createprivateownsymbol.js
new file mode 100644
index 000000000..74548287c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/createprivateownsymbol.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = "foo";
+%CreatePrivateOwnSymbol(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/createprivatesymbol.js b/deps/v8/test/mjsunit/runtime-gen/createprivatesymbol.js
new file mode 100644
index 000000000..bbd99c12b
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/createprivatesymbol.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = "foo";
+%CreatePrivateSymbol(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/createsymbol.js b/deps/v8/test/mjsunit/runtime-gen/createsymbol.js
new file mode 100644
index 000000000..8452b9c90
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/createsymbol.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = "foo";
+%CreateSymbol(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewgetbuffer.js b/deps/v8/test/mjsunit/runtime-gen/dataviewgetbuffer.js
new file mode 100644
index 000000000..84bab807f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewgetbuffer.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+%DataViewGetBuffer(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewgetfloat32.js b/deps/v8/test/mjsunit/runtime-gen/dataviewgetfloat32.js
new file mode 100644
index 000000000..57f3c2a59
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewgetfloat32.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _is_little_endian = true;
+%DataViewGetFloat32(_holder, _offset, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewgetfloat64.js b/deps/v8/test/mjsunit/runtime-gen/dataviewgetfloat64.js
new file mode 100644
index 000000000..7f80c5b0a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewgetfloat64.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _is_little_endian = true;
+%DataViewGetFloat64(_holder, _offset, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewgetint16.js b/deps/v8/test/mjsunit/runtime-gen/dataviewgetint16.js
new file mode 100644
index 000000000..e618c1c00
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewgetint16.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _is_little_endian = true;
+%DataViewGetInt16(_holder, _offset, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewgetint32.js b/deps/v8/test/mjsunit/runtime-gen/dataviewgetint32.js
new file mode 100644
index 000000000..2395a6dd9
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewgetint32.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _is_little_endian = true;
+%DataViewGetInt32(_holder, _offset, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewgetint8.js b/deps/v8/test/mjsunit/runtime-gen/dataviewgetint8.js
new file mode 100644
index 000000000..fe92ed7c3
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewgetint8.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _is_little_endian = true;
+%DataViewGetInt8(_holder, _offset, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewgetuint16.js b/deps/v8/test/mjsunit/runtime-gen/dataviewgetuint16.js
new file mode 100644
index 000000000..50be62b00
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewgetuint16.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _is_little_endian = true;
+%DataViewGetUint16(_holder, _offset, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewgetuint32.js b/deps/v8/test/mjsunit/runtime-gen/dataviewgetuint32.js
new file mode 100644
index 000000000..2f85aeef8
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewgetuint32.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _is_little_endian = true;
+%DataViewGetUint32(_holder, _offset, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewgetuint8.js b/deps/v8/test/mjsunit/runtime-gen/dataviewgetuint8.js
new file mode 100644
index 000000000..6a682e173
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewgetuint8.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _is_little_endian = true;
+%DataViewGetUint8(_holder, _offset, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewinitialize.js b/deps/v8/test/mjsunit/runtime-gen/dataviewinitialize.js
new file mode 100644
index 000000000..167d53156
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewinitialize.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _buffer = new ArrayBuffer(8);
+var _byte_offset = 1.5;
+var _byte_length = 1.5;
+%DataViewInitialize(_holder, _buffer, _byte_offset, _byte_length);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewsetfloat32.js b/deps/v8/test/mjsunit/runtime-gen/dataviewsetfloat32.js
new file mode 100644
index 000000000..46d00afff
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewsetfloat32.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _value = 1.5;
+var _is_little_endian = true;
+%DataViewSetFloat32(_holder, _offset, _value, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewsetfloat64.js b/deps/v8/test/mjsunit/runtime-gen/dataviewsetfloat64.js
new file mode 100644
index 000000000..c57b514dd
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewsetfloat64.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _value = 1.5;
+var _is_little_endian = true;
+%DataViewSetFloat64(_holder, _offset, _value, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewsetint16.js b/deps/v8/test/mjsunit/runtime-gen/dataviewsetint16.js
new file mode 100644
index 000000000..1f45448f6
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewsetint16.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _value = 1.5;
+var _is_little_endian = true;
+%DataViewSetInt16(_holder, _offset, _value, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewsetint32.js b/deps/v8/test/mjsunit/runtime-gen/dataviewsetint32.js
new file mode 100644
index 000000000..837d4f26d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewsetint32.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _value = 1.5;
+var _is_little_endian = true;
+%DataViewSetInt32(_holder, _offset, _value, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewsetint8.js b/deps/v8/test/mjsunit/runtime-gen/dataviewsetint8.js
new file mode 100644
index 000000000..725e658ec
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewsetint8.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _value = 1.5;
+var _is_little_endian = true;
+%DataViewSetInt8(_holder, _offset, _value, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewsetuint16.js b/deps/v8/test/mjsunit/runtime-gen/dataviewsetuint16.js
new file mode 100644
index 000000000..d1b1a24bc
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewsetuint16.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _value = 1.5;
+var _is_little_endian = true;
+%DataViewSetUint16(_holder, _offset, _value, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewsetuint32.js b/deps/v8/test/mjsunit/runtime-gen/dataviewsetuint32.js
new file mode 100644
index 000000000..e46c8f302
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewsetuint32.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _value = 1.5;
+var _is_little_endian = true;
+%DataViewSetUint32(_holder, _offset, _value, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dataviewsetuint8.js b/deps/v8/test/mjsunit/runtime-gen/dataviewsetuint8.js
new file mode 100644
index 000000000..6c3672308
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dataviewsetuint8.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new DataView(new ArrayBuffer(24));
+var _offset = 1.5;
+var _value = 1.5;
+var _is_little_endian = true;
+%DataViewSetUint8(_holder, _offset, _value, _is_little_endian);
diff --git a/deps/v8/test/mjsunit/runtime-gen/datecacheversion.js b/deps/v8/test/mjsunit/runtime-gen/datecacheversion.js
new file mode 100644
index 000000000..ea56c73c7
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/datecacheversion.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%DateCacheVersion();
diff --git a/deps/v8/test/mjsunit/runtime-gen/datecurrenttime.js b/deps/v8/test/mjsunit/runtime-gen/datecurrenttime.js
new file mode 100644
index 000000000..759ebd003
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/datecurrenttime.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%DateCurrentTime();
diff --git a/deps/v8/test/mjsunit/runtime-gen/datelocaltimezone.js b/deps/v8/test/mjsunit/runtime-gen/datelocaltimezone.js
new file mode 100644
index 000000000..bfc1a81c7
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/datelocaltimezone.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%DateLocalTimezone(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/datemakeday.js b/deps/v8/test/mjsunit/runtime-gen/datemakeday.js
new file mode 100644
index 000000000..3d2334f51
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/datemakeday.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _year = 1;
+var _month = 1;
+%DateMakeDay(_year, _month);
diff --git a/deps/v8/test/mjsunit/runtime-gen/dateparsestring.js b/deps/v8/test/mjsunit/runtime-gen/dateparsestring.js
new file mode 100644
index 000000000..fdf5faa7e
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/dateparsestring.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _str = "foo";
+var arg1 = new Array(8);
+%DateParseString(_str, arg1);
diff --git a/deps/v8/test/mjsunit/runtime-gen/datesetvalue.js b/deps/v8/test/mjsunit/runtime-gen/datesetvalue.js
new file mode 100644
index 000000000..dac1a3644
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/datesetvalue.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _date = new Date();
+var _time = 1.5;
+var _is_utc = 1;
+%DateSetValue(_date, _time, _is_utc);
diff --git a/deps/v8/test/mjsunit/runtime-gen/datetoutc.js b/deps/v8/test/mjsunit/runtime-gen/datetoutc.js
new file mode 100644
index 000000000..f46644e95
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/datetoutc.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%DateToUTC(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugasynctaskevent.js b/deps/v8/test/mjsunit/runtime-gen/debugasynctaskevent.js
new file mode 100644
index 000000000..ceeaf1377
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugasynctaskevent.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _data = new Object();
+%DebugAsyncTaskEvent(_data);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugbreak.js b/deps/v8/test/mjsunit/runtime-gen/debugbreak.js
new file mode 100644
index 000000000..68220dfa9
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugbreak.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%DebugBreak();
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugcallbacksupportsstepping.js b/deps/v8/test/mjsunit/runtime-gen/debugcallbacksupportsstepping.js
new file mode 100644
index 000000000..b683be0aa
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugcallbacksupportsstepping.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _callback = new Object();
+%DebugCallbackSupportsStepping(_callback);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugconstructedby.js b/deps/v8/test/mjsunit/runtime-gen/debugconstructedby.js
new file mode 100644
index 000000000..885034429
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugconstructedby.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _constructor = function() {};
+var _max_references = 32;
+%DebugConstructedBy(_constructor, _max_references);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugdisassembleconstructor.js b/deps/v8/test/mjsunit/runtime-gen/debugdisassembleconstructor.js
new file mode 100644
index 000000000..c2faca4f0
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugdisassembleconstructor.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _func = function() {};
+%DebugDisassembleConstructor(_func);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugdisassemblefunction.js b/deps/v8/test/mjsunit/runtime-gen/debugdisassemblefunction.js
new file mode 100644
index 000000000..f65886779
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugdisassemblefunction.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _func = function() {};
+%DebugDisassembleFunction(_func);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugevaluate.js b/deps/v8/test/mjsunit/runtime-gen/debugevaluate.js
new file mode 100644
index 000000000..60e1e63fd
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugevaluate.js
@@ -0,0 +1,12 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _break_id = 32;
+var _wrapped_id = 1;
+var _inlined_jsframe_index = 32;
+var _source = "foo";
+var _disable_break = true;
+var _context_extension = new Object();
+try {
+%DebugEvaluate(_break_id, _wrapped_id, _inlined_jsframe_index, _source, _disable_break, _context_extension);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugevaluateglobal.js b/deps/v8/test/mjsunit/runtime-gen/debugevaluateglobal.js
new file mode 100644
index 000000000..11411d199
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugevaluateglobal.js
@@ -0,0 +1,10 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _break_id = 32;
+var _source = "foo";
+var _disable_break = true;
+var _context_extension = new Object();
+try {
+%DebugEvaluateGlobal(_break_id, _source, _disable_break, _context_extension);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/debuggetproperty.js b/deps/v8/test/mjsunit/runtime-gen/debuggetproperty.js
new file mode 100644
index 000000000..90109d1dc
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debuggetproperty.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+var _name = "name";
+%DebugGetProperty(_obj, _name);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debuggetpropertydetails.js b/deps/v8/test/mjsunit/runtime-gen/debuggetpropertydetails.js
new file mode 100644
index 000000000..0fe2f3104
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debuggetpropertydetails.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+var _name = "name";
+%DebugGetPropertyDetails(_obj, _name);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debuggetprototype.js b/deps/v8/test/mjsunit/runtime-gen/debuggetprototype.js
new file mode 100644
index 000000000..27de855b7
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debuggetprototype.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%DebugGetPrototype(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugindexedinterceptorelementvalue.js b/deps/v8/test/mjsunit/runtime-gen/debugindexedinterceptorelementvalue.js
new file mode 100644
index 000000000..22d24eead
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugindexedinterceptorelementvalue.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+var _index = 32;
+try {
+%DebugIndexedInterceptorElementValue(_obj, _index);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugnamedinterceptorpropertyvalue.js b/deps/v8/test/mjsunit/runtime-gen/debugnamedinterceptorpropertyvalue.js
new file mode 100644
index 000000000..13641d2c2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugnamedinterceptorpropertyvalue.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+var _name = "name";
+try {
+%DebugNamedInterceptorPropertyValue(_obj, _name);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugpoppromise.js b/deps/v8/test/mjsunit/runtime-gen/debugpoppromise.js
new file mode 100644
index 000000000..9b81b1370
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugpoppromise.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%DebugPopPromise();
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugpreparestepinifstepping.js b/deps/v8/test/mjsunit/runtime-gen/debugpreparestepinifstepping.js
new file mode 100644
index 000000000..a6061e6f9
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugpreparestepinifstepping.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _callback = function() {};
+%DebugPrepareStepInIfStepping(_callback);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugprintscopes.js b/deps/v8/test/mjsunit/runtime-gen/debugprintscopes.js
new file mode 100644
index 000000000..2f106ddb6
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugprintscopes.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%DebugPrintScopes();
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugpromiseevent.js b/deps/v8/test/mjsunit/runtime-gen/debugpromiseevent.js
new file mode 100644
index 000000000..20ae13c67
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugpromiseevent.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _data = new Object();
+%DebugPromiseEvent(_data);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugpromiserejectevent.js b/deps/v8/test/mjsunit/runtime-gen/debugpromiserejectevent.js
new file mode 100644
index 000000000..4e6e63342
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugpromiserejectevent.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _promise = new Object();
+var _value = new Object();
+%DebugPromiseRejectEvent(_promise, _value);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugpropertyattributesfromdetails.js b/deps/v8/test/mjsunit/runtime-gen/debugpropertyattributesfromdetails.js
new file mode 100644
index 000000000..7802a3524
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugpropertyattributesfromdetails.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _details = 513;
+%DebugPropertyAttributesFromDetails(_details);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugpropertyindexfromdetails.js b/deps/v8/test/mjsunit/runtime-gen/debugpropertyindexfromdetails.js
new file mode 100644
index 000000000..02edeeee2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugpropertyindexfromdetails.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _details = 513;
+%DebugPropertyIndexFromDetails(_details);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugpropertytypefromdetails.js b/deps/v8/test/mjsunit/runtime-gen/debugpropertytypefromdetails.js
new file mode 100644
index 000000000..551ff2c62
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugpropertytypefromdetails.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _details = 513;
+%DebugPropertyTypeFromDetails(_details);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugpushpromise.js b/deps/v8/test/mjsunit/runtime-gen/debugpushpromise.js
new file mode 100644
index 000000000..350a61354
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugpushpromise.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _promise = new Object();
+%DebugPushPromise(_promise);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugreferencedby.js b/deps/v8/test/mjsunit/runtime-gen/debugreferencedby.js
new file mode 100644
index 000000000..94e124279
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugreferencedby.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _target = new Object();
+var _instance_filter = new Object();
+var _max_references = 32;
+%DebugReferencedBy(_target, _instance_filter, _max_references);
diff --git a/deps/v8/test/mjsunit/runtime-gen/debugtrace.js b/deps/v8/test/mjsunit/runtime-gen/debugtrace.js
new file mode 100644
index 000000000..2933ad114
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/debugtrace.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%DebugTrace();
diff --git a/deps/v8/test/mjsunit/runtime-gen/defineaccessorpropertyunchecked.js b/deps/v8/test/mjsunit/runtime-gen/defineaccessorpropertyunchecked.js
new file mode 100644
index 000000000..c6cbb91cc
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/defineaccessorpropertyunchecked.js
@@ -0,0 +1,9 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+var _name = "name";
+var arg2 = function() {};
+var arg3 = function() {};
+var arg4 = 2;
+%DefineAccessorPropertyUnchecked(_obj, _name, arg2, arg3, arg4);
diff --git a/deps/v8/test/mjsunit/runtime-gen/defineapiaccessorproperty.js b/deps/v8/test/mjsunit/runtime-gen/defineapiaccessorproperty.js
new file mode 100644
index 000000000..856a53129
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/defineapiaccessorproperty.js
@@ -0,0 +1,9 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+var _name = "name";
+var arg2 = undefined;
+var arg3 = undefined;
+var _attribute = 1;
+%DefineApiAccessorProperty(_object, _name, arg2, arg3, _attribute);
diff --git a/deps/v8/test/mjsunit/runtime-gen/definedatapropertyunchecked.js b/deps/v8/test/mjsunit/runtime-gen/definedatapropertyunchecked.js
new file mode 100644
index 000000000..cb0f07f60
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/definedatapropertyunchecked.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _js_object = new Object();
+var _name = "name";
+var _obj_value = new Object();
+var _unchecked = 1;
+%DefineDataPropertyUnchecked(_js_object, _name, _obj_value, _unchecked);
diff --git a/deps/v8/test/mjsunit/runtime-gen/deleteproperty.js b/deps/v8/test/mjsunit/runtime-gen/deleteproperty.js
new file mode 100644
index 000000000..66a882b1a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/deleteproperty.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+var _key = "name";
+var _strict_mode = 1;
+%DeleteProperty(_object, _key, _strict_mode);
diff --git a/deps/v8/test/mjsunit/runtime-gen/deoptimizefunction.js b/deps/v8/test/mjsunit/runtime-gen/deoptimizefunction.js
new file mode 100644
index 000000000..ec5db2dda
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/deoptimizefunction.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _function = function() {};
+%DeoptimizeFunction(_function);
diff --git a/deps/v8/test/mjsunit/runtime-gen/doublehi.js b/deps/v8/test/mjsunit/runtime-gen/doublehi.js
new file mode 100644
index 000000000..ac945dcd2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/doublehi.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%DoubleHi(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/doublelo.js b/deps/v8/test/mjsunit/runtime-gen/doublelo.js
new file mode 100644
index 000000000..42c4c2549
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/doublelo.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%DoubleLo(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/enqueuemicrotask.js b/deps/v8/test/mjsunit/runtime-gen/enqueuemicrotask.js
new file mode 100644
index 000000000..2f2166761
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/enqueuemicrotask.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _microtask = function() {};
+%EnqueueMicrotask(_microtask);
diff --git a/deps/v8/test/mjsunit/runtime-gen/estimatenumberofelements.js b/deps/v8/test/mjsunit/runtime-gen/estimatenumberofelements.js
new file mode 100644
index 000000000..cf3b9b606
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/estimatenumberofelements.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _array = new Array();
+%EstimateNumberOfElements(_array);
diff --git a/deps/v8/test/mjsunit/runtime-gen/executeindebugcontext.js b/deps/v8/test/mjsunit/runtime-gen/executeindebugcontext.js
new file mode 100644
index 000000000..18bfac9b5
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/executeindebugcontext.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _function = function() {};
+var _without_debugger = true;
+%ExecuteInDebugContext(_function, _without_debugger);
diff --git a/deps/v8/test/mjsunit/runtime-gen/finisharrayprototypesetup.js b/deps/v8/test/mjsunit/runtime-gen/finisharrayprototypesetup.js
new file mode 100644
index 000000000..e4e8eabab
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/finisharrayprototypesetup.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _prototype = new Array();
+%FinishArrayPrototypeSetup(_prototype);
diff --git a/deps/v8/test/mjsunit/runtime-gen/fix.js b/deps/v8/test/mjsunit/runtime-gen/fix.js
new file mode 100644
index 000000000..010d2bcb7
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/fix.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _proxy = Proxy.create({});
+%Fix(_proxy);
diff --git a/deps/v8/test/mjsunit/runtime-gen/flattenstring.js b/deps/v8/test/mjsunit/runtime-gen/flattenstring.js
new file mode 100644
index 000000000..3f0b38d6c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/flattenstring.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _str = "foo";
+%FlattenString(_str);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functionbindarguments.js b/deps/v8/test/mjsunit/runtime-gen/functionbindarguments.js
new file mode 100644
index 000000000..4d3671625
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functionbindarguments.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _bound_function = function() {};
+var _bindee = new Object();
+var arg2 = undefined;
+var _new_length = 1.5;
+%FunctionBindArguments(_bound_function, _bindee, arg2, _new_length);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functiongetinferredname.js b/deps/v8/test/mjsunit/runtime-gen/functiongetinferredname.js
new file mode 100644
index 000000000..8d765007c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functiongetinferredname.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _f = function() {};
+%FunctionGetInferredName(_f);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functiongetname.js b/deps/v8/test/mjsunit/runtime-gen/functiongetname.js
new file mode 100644
index 000000000..ad23b11a6
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functiongetname.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _f = function() {};
+%FunctionGetName(_f);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functiongetscript.js b/deps/v8/test/mjsunit/runtime-gen/functiongetscript.js
new file mode 100644
index 000000000..bd4364447
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functiongetscript.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _fun = function() {};
+%FunctionGetScript(_fun);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functiongetscriptsourceposition.js b/deps/v8/test/mjsunit/runtime-gen/functiongetscriptsourceposition.js
new file mode 100644
index 000000000..eb462f96f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functiongetscriptsourceposition.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _fun = function() {};
+%FunctionGetScriptSourcePosition(_fun);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functiongetsourcecode.js b/deps/v8/test/mjsunit/runtime-gen/functiongetsourcecode.js
new file mode 100644
index 000000000..b9de88a15
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functiongetsourcecode.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _f = function() {};
+%FunctionGetSourceCode(_f);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functionisapifunction.js b/deps/v8/test/mjsunit/runtime-gen/functionisapifunction.js
new file mode 100644
index 000000000..7fb8a21e0
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functionisapifunction.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _f = function() {};
+%FunctionIsAPIFunction(_f);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functionisarrow.js b/deps/v8/test/mjsunit/runtime-gen/functionisarrow.js
new file mode 100644
index 000000000..08410b49d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functionisarrow.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = () => null;
+%FunctionIsArrow(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functionisbuiltin.js b/deps/v8/test/mjsunit/runtime-gen/functionisbuiltin.js
new file mode 100644
index 000000000..a8dd6c6a8
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functionisbuiltin.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _f = function() {};
+%FunctionIsBuiltin(_f);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functionisgenerator.js b/deps/v8/test/mjsunit/runtime-gen/functionisgenerator.js
new file mode 100644
index 000000000..8be6aab2a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functionisgenerator.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _f = function() {};
+%FunctionIsGenerator(_f);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functionmarknameshouldprintasanonymous.js b/deps/v8/test/mjsunit/runtime-gen/functionmarknameshouldprintasanonymous.js
new file mode 100644
index 000000000..74f18e258
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functionmarknameshouldprintasanonymous.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _f = function() {};
+%FunctionMarkNameShouldPrintAsAnonymous(_f);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functionnameshouldprintasanonymous.js b/deps/v8/test/mjsunit/runtime-gen/functionnameshouldprintasanonymous.js
new file mode 100644
index 000000000..aa5bcddc1
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functionnameshouldprintasanonymous.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _f = function() {};
+%FunctionNameShouldPrintAsAnonymous(_f);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functionremoveprototype.js b/deps/v8/test/mjsunit/runtime-gen/functionremoveprototype.js
new file mode 100644
index 000000000..a7ec5f52a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functionremoveprototype.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _f = function() {};
+%FunctionRemovePrototype(_f);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functionsetinstanceclassname.js b/deps/v8/test/mjsunit/runtime-gen/functionsetinstanceclassname.js
new file mode 100644
index 000000000..6986a15b1
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functionsetinstanceclassname.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _fun = function() {};
+var _name = "foo";
+%FunctionSetInstanceClassName(_fun, _name);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functionsetlength.js b/deps/v8/test/mjsunit/runtime-gen/functionsetlength.js
new file mode 100644
index 000000000..5582e82cf
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functionsetlength.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _fun = function() {};
+var _length = 1;
+%FunctionSetLength(_fun, _length);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functionsetname.js b/deps/v8/test/mjsunit/runtime-gen/functionsetname.js
new file mode 100644
index 000000000..0d44b2031
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functionsetname.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _f = function() {};
+var _name = "foo";
+%FunctionSetName(_f, _name);
diff --git a/deps/v8/test/mjsunit/runtime-gen/functionsetprototype.js b/deps/v8/test/mjsunit/runtime-gen/functionsetprototype.js
new file mode 100644
index 000000000..eb69ea8f5
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/functionsetprototype.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _fun = function() {};
+var _value = new Object();
+%FunctionSetPrototype(_fun, _value);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getallscopesdetails.js b/deps/v8/test/mjsunit/runtime-gen/getallscopesdetails.js
new file mode 100644
index 000000000..97ad7cb53
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getallscopesdetails.js
@@ -0,0 +1,10 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _break_id = 32;
+var _wrapped_id = 1;
+var _inlined_jsframe_index = 32;
+var _flag = true;
+try {
+%GetAllScopesDetails(_break_id, _wrapped_id, _inlined_jsframe_index, _flag);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/getargumentsproperty.js b/deps/v8/test/mjsunit/runtime-gen/getargumentsproperty.js
new file mode 100644
index 000000000..646e56be9
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getargumentsproperty.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _raw_key = new Object();
+%GetArgumentsProperty(_raw_key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getarraykeys.js b/deps/v8/test/mjsunit/runtime-gen/getarraykeys.js
new file mode 100644
index 000000000..341faa69e
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getarraykeys.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _array = new Object();
+var _length = 32;
+%GetArrayKeys(_array, _length);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getbreaklocations.js b/deps/v8/test/mjsunit/runtime-gen/getbreaklocations.js
new file mode 100644
index 000000000..d31fa15c5
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getbreaklocations.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _fun = function() {};
+var arg1 = 0;
+%GetBreakLocations(_fun, arg1);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getcalltrap.js b/deps/v8/test/mjsunit/runtime-gen/getcalltrap.js
new file mode 100644
index 000000000..406af9ffd
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getcalltrap.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _proxy = Proxy.createFunction({}, function() {});
+%GetCallTrap(_proxy);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getconstructordelegate.js b/deps/v8/test/mjsunit/runtime-gen/getconstructordelegate.js
new file mode 100644
index 000000000..6d0141566
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getconstructordelegate.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+%GetConstructorDelegate(_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getconstructtrap.js b/deps/v8/test/mjsunit/runtime-gen/getconstructtrap.js
new file mode 100644
index 000000000..116d301eb
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getconstructtrap.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _proxy = Proxy.createFunction({}, function() {});
+%GetConstructTrap(_proxy);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getdataproperty.js b/deps/v8/test/mjsunit/runtime-gen/getdataproperty.js
new file mode 100644
index 000000000..59cfba56d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getdataproperty.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+var _key = "name";
+%GetDataProperty(_object, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getdefaulticulocale.js b/deps/v8/test/mjsunit/runtime-gen/getdefaulticulocale.js
new file mode 100644
index 000000000..920f25668
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getdefaulticulocale.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%GetDefaultICULocale();
diff --git a/deps/v8/test/mjsunit/runtime-gen/getdefaultreceiver.js b/deps/v8/test/mjsunit/runtime-gen/getdefaultreceiver.js
new file mode 100644
index 000000000..1d5b1cb44
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getdefaultreceiver.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = function() {};
+%GetDefaultReceiver(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getframecount.js b/deps/v8/test/mjsunit/runtime-gen/getframecount.js
new file mode 100644
index 000000000..a958efcd7
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getframecount.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _break_id = 32;
+try {
+%GetFrameCount(_break_id);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/getframedetails.js b/deps/v8/test/mjsunit/runtime-gen/getframedetails.js
new file mode 100644
index 000000000..113842484
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getframedetails.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _break_id = 32;
+var _index = 32;
+try {
+%GetFrameDetails(_break_id, _index);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/getfunctioncodepositionfromsource.js b/deps/v8/test/mjsunit/runtime-gen/getfunctioncodepositionfromsource.js
new file mode 100644
index 000000000..473b26324
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getfunctioncodepositionfromsource.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _function = function() {};
+var _source_position = 32;
+%GetFunctionCodePositionFromSource(_function, _source_position);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getfunctiondelegate.js b/deps/v8/test/mjsunit/runtime-gen/getfunctiondelegate.js
new file mode 100644
index 000000000..4d02ec219
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getfunctiondelegate.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+%GetFunctionDelegate(_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getfunctionscopecount.js b/deps/v8/test/mjsunit/runtime-gen/getfunctionscopecount.js
new file mode 100644
index 000000000..fb854cff4
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getfunctionscopecount.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _fun = function() {};
+%GetFunctionScopeCount(_fun);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getfunctionscopedetails.js b/deps/v8/test/mjsunit/runtime-gen/getfunctionscopedetails.js
new file mode 100644
index 000000000..c24314003
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getfunctionscopedetails.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _fun = function() {};
+var _index = 32;
+%GetFunctionScopeDetails(_fun, _index);
diff --git a/deps/v8/test/mjsunit/runtime-gen/gethandler.js b/deps/v8/test/mjsunit/runtime-gen/gethandler.js
new file mode 100644
index 000000000..ea982cbb5
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/gethandler.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _proxy = Proxy.create({});
+%GetHandler(_proxy);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getheapusage.js b/deps/v8/test/mjsunit/runtime-gen/getheapusage.js
new file mode 100644
index 000000000..cb174b72f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getheapusage.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%GetHeapUsage();
diff --git a/deps/v8/test/mjsunit/runtime-gen/getimplfrominitializedintlobject.js b/deps/v8/test/mjsunit/runtime-gen/getimplfrominitializedintlobject.js
new file mode 100644
index 000000000..899ba8859
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getimplfrominitializedintlobject.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = new Intl.NumberFormat('en-US');
+%GetImplFromInitializedIntlObject(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getindexedinterceptorelementnames.js b/deps/v8/test/mjsunit/runtime-gen/getindexedinterceptorelementnames.js
new file mode 100644
index 000000000..8a83f0acd
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getindexedinterceptorelementnames.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%GetIndexedInterceptorElementNames(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getinterceptorinfo.js b/deps/v8/test/mjsunit/runtime-gen/getinterceptorinfo.js
new file mode 100644
index 000000000..b33ba6491
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getinterceptorinfo.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%GetInterceptorInfo(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getlanguagetagvariants.js b/deps/v8/test/mjsunit/runtime-gen/getlanguagetagvariants.js
new file mode 100644
index 000000000..0ecfee522
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getlanguagetagvariants.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _input = new Array();
+%GetLanguageTagVariants(_input);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getnamedinterceptorpropertynames.js b/deps/v8/test/mjsunit/runtime-gen/getnamedinterceptorpropertynames.js
new file mode 100644
index 000000000..0dee531be
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getnamedinterceptorpropertynames.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%GetNamedInterceptorPropertyNames(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getobjectcontextnotifierperformchange.js b/deps/v8/test/mjsunit/runtime-gen/getobjectcontextnotifierperformchange.js
new file mode 100644
index 000000000..2960acee4
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getobjectcontextnotifierperformchange.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object_info = new Object();
+%GetObjectContextNotifierPerformChange(_object_info);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getobjectcontextobjectgetnotifier.js b/deps/v8/test/mjsunit/runtime-gen/getobjectcontextobjectgetnotifier.js
new file mode 100644
index 000000000..d6a043061
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getobjectcontextobjectgetnotifier.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+%GetObjectContextObjectGetNotifier(_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getobjectcontextobjectobserve.js b/deps/v8/test/mjsunit/runtime-gen/getobjectcontextobjectobserve.js
new file mode 100644
index 000000000..f1669e738
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getobjectcontextobjectobserve.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+%GetObjectContextObjectObserve(_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getobservationstate.js b/deps/v8/test/mjsunit/runtime-gen/getobservationstate.js
new file mode 100644
index 000000000..429cdcd91
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getobservationstate.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%GetObservationState();
diff --git a/deps/v8/test/mjsunit/runtime-gen/getoptimizationcount.js b/deps/v8/test/mjsunit/runtime-gen/getoptimizationcount.js
new file mode 100644
index 000000000..da1ab9efc
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getoptimizationcount.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _function = function() {};
+%GetOptimizationCount(_function);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getownelementnames.js b/deps/v8/test/mjsunit/runtime-gen/getownelementnames.js
new file mode 100644
index 000000000..54d9a6985
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getownelementnames.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%GetOwnElementNames(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getownproperty.js b/deps/v8/test/mjsunit/runtime-gen/getownproperty.js
new file mode 100644
index 000000000..1e5a808f7
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getownproperty.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+var _name = "name";
+%GetOwnProperty(_obj, _name);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getownpropertynames.js b/deps/v8/test/mjsunit/runtime-gen/getownpropertynames.js
new file mode 100644
index 000000000..10f7f2c77
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getownpropertynames.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+var _filter_value = 1;
+%GetOwnPropertyNames(_obj, _filter_value);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getproperty.js b/deps/v8/test/mjsunit/runtime-gen/getproperty.js
new file mode 100644
index 000000000..569189a3a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getproperty.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+var _key = new Object();
+%GetProperty(_object, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getpropertynames.js b/deps/v8/test/mjsunit/runtime-gen/getpropertynames.js
new file mode 100644
index 000000000..ad94eedc9
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getpropertynames.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+%GetPropertyNames(_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getpropertynamesfast.js b/deps/v8/test/mjsunit/runtime-gen/getpropertynamesfast.js
new file mode 100644
index 000000000..c2d14cb65
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getpropertynamesfast.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _raw_object = new Object();
+%GetPropertyNamesFast(_raw_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getprototype.js b/deps/v8/test/mjsunit/runtime-gen/getprototype.js
new file mode 100644
index 000000000..b9ef1f991
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getprototype.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%GetPrototype(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getrootnan.js b/deps/v8/test/mjsunit/runtime-gen/getrootnan.js
new file mode 100644
index 000000000..b6df0fd5f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getrootnan.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+try {
+%GetRootNaN();
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/getscopecount.js b/deps/v8/test/mjsunit/runtime-gen/getscopecount.js
new file mode 100644
index 000000000..d53bece37
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getscopecount.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _break_id = 32;
+var _wrapped_id = 1;
+try {
+%GetScopeCount(_break_id, _wrapped_id);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/getscopedetails.js b/deps/v8/test/mjsunit/runtime-gen/getscopedetails.js
new file mode 100644
index 000000000..4ea28ac73
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getscopedetails.js
@@ -0,0 +1,10 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _break_id = 32;
+var _wrapped_id = 1;
+var _inlined_jsframe_index = 32;
+var _index = 32;
+try {
+%GetScopeDetails(_break_id, _wrapped_id, _inlined_jsframe_index, _index);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/getscript.js b/deps/v8/test/mjsunit/runtime-gen/getscript.js
new file mode 100644
index 000000000..cae0087cc
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getscript.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _script_name = "foo";
+%GetScript(_script_name);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getstepinpositions.js b/deps/v8/test/mjsunit/runtime-gen/getstepinpositions.js
new file mode 100644
index 000000000..221c586ed
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getstepinpositions.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _break_id = 32;
+var _wrapped_id = 1;
+try {
+%GetStepInPositions(_break_id, _wrapped_id);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/gettemplatefield.js b/deps/v8/test/mjsunit/runtime-gen/gettemplatefield.js
new file mode 100644
index 000000000..16d3824b2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/gettemplatefield.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _templ = new Object();
+var _index = 1;
+try {
+%GetTemplateField(_templ, _index);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/getthreadcount.js b/deps/v8/test/mjsunit/runtime-gen/getthreadcount.js
new file mode 100644
index 000000000..5037066a7
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getthreadcount.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _break_id = 32;
+try {
+%GetThreadCount(_break_id);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/getthreaddetails.js b/deps/v8/test/mjsunit/runtime-gen/getthreaddetails.js
new file mode 100644
index 000000000..6fc0d14ce
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getthreaddetails.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _break_id = 32;
+var _index = 32;
+try {
+%GetThreadDetails(_break_id, _index);
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/getv8version.js b/deps/v8/test/mjsunit/runtime-gen/getv8version.js
new file mode 100644
index 000000000..e311eef13
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getv8version.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%GetV8Version();
diff --git a/deps/v8/test/mjsunit/runtime-gen/getweakmapentries.js b/deps/v8/test/mjsunit/runtime-gen/getweakmapentries.js
new file mode 100644
index 000000000..ced728d3b
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getweakmapentries.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new WeakMap();
+%GetWeakMapEntries(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/getweaksetvalues.js b/deps/v8/test/mjsunit/runtime-gen/getweaksetvalues.js
new file mode 100644
index 000000000..650c947d0
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/getweaksetvalues.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new WeakMap();
+%GetWeakSetValues(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/globalprint.js b/deps/v8/test/mjsunit/runtime-gen/globalprint.js
new file mode 100644
index 000000000..059f08efe
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/globalprint.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _string = "foo";
+%GlobalPrint(_string);
diff --git a/deps/v8/test/mjsunit/runtime-gen/globalproxy.js b/deps/v8/test/mjsunit/runtime-gen/globalproxy.js
new file mode 100644
index 000000000..80e500c88
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/globalproxy.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _global = new Object();
+%GlobalProxy(_global);
diff --git a/deps/v8/test/mjsunit/runtime-gen/haselement.js b/deps/v8/test/mjsunit/runtime-gen/haselement.js
new file mode 100644
index 000000000..3d32ac5f0
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/haselement.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _receiver = new Object();
+var _index = 1;
+%HasElement(_receiver, _index);
diff --git a/deps/v8/test/mjsunit/runtime-gen/hasownproperty.js b/deps/v8/test/mjsunit/runtime-gen/hasownproperty.js
new file mode 100644
index 000000000..7443bff10
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/hasownproperty.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+var _key = "name";
+%HasOwnProperty(_object, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/hasproperty.js b/deps/v8/test/mjsunit/runtime-gen/hasproperty.js
new file mode 100644
index 000000000..df4de8eb3
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/hasproperty.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _receiver = new Object();
+var _key = "name";
+%HasProperty(_receiver, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/havesamemap.js b/deps/v8/test/mjsunit/runtime-gen/havesamemap.js
new file mode 100644
index 000000000..b399d17cb
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/havesamemap.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj1 = new Object();
+var _obj2 = new Object();
+%HaveSameMap(_obj1, _obj2);
diff --git a/deps/v8/test/mjsunit/runtime-gen/internalcompare.js b/deps/v8/test/mjsunit/runtime-gen/internalcompare.js
new file mode 100644
index 000000000..95cc006f3
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/internalcompare.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = %GetImplFromInitializedIntlObject(new Intl.Collator('en-US'));
+var _string1 = "foo";
+var _string2 = "foo";
+%InternalCompare(arg0, _string1, _string2);
diff --git a/deps/v8/test/mjsunit/runtime-gen/internaldateformat.js b/deps/v8/test/mjsunit/runtime-gen/internaldateformat.js
new file mode 100644
index 000000000..933714e93
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/internaldateformat.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = %GetImplFromInitializedIntlObject(new Intl.DateTimeFormat('en-US'));
+var _date = new Date();
+%InternalDateFormat(arg0, _date);
diff --git a/deps/v8/test/mjsunit/runtime-gen/internaldateparse.js b/deps/v8/test/mjsunit/runtime-gen/internaldateparse.js
new file mode 100644
index 000000000..be8c49a94
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/internaldateparse.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = %GetImplFromInitializedIntlObject(new Intl.DateTimeFormat('en-US'));
+var _date_string = "foo";
+%InternalDateParse(arg0, _date_string);
diff --git a/deps/v8/test/mjsunit/runtime-gen/internalnumberformat.js b/deps/v8/test/mjsunit/runtime-gen/internalnumberformat.js
new file mode 100644
index 000000000..cd21edc24
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/internalnumberformat.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = %GetImplFromInitializedIntlObject(new Intl.NumberFormat('en-US'));
+var _number = new Object();
+%InternalNumberFormat(arg0, _number);
diff --git a/deps/v8/test/mjsunit/runtime-gen/internalnumberparse.js b/deps/v8/test/mjsunit/runtime-gen/internalnumberparse.js
new file mode 100644
index 000000000..cdbd322c4
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/internalnumberparse.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = %GetImplFromInitializedIntlObject(new Intl.NumberFormat('en-US'));
+var _number_string = "foo";
+%InternalNumberParse(arg0, _number_string);
diff --git a/deps/v8/test/mjsunit/runtime-gen/internalsetprototype.js b/deps/v8/test/mjsunit/runtime-gen/internalsetprototype.js
new file mode 100644
index 000000000..1bc67d382
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/internalsetprototype.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+var _prototype = new Object();
+%InternalSetPrototype(_obj, _prototype);
diff --git a/deps/v8/test/mjsunit/runtime-gen/isattachedglobal.js b/deps/v8/test/mjsunit/runtime-gen/isattachedglobal.js
new file mode 100644
index 000000000..9ead91a40
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isattachedglobal.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _global = new Object();
+%IsAttachedGlobal(_global);
diff --git a/deps/v8/test/mjsunit/runtime-gen/isbreakonexception.js b/deps/v8/test/mjsunit/runtime-gen/isbreakonexception.js
new file mode 100644
index 000000000..e55c7d030
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isbreakonexception.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _type_arg = 32;
+%IsBreakOnException(_type_arg);
diff --git a/deps/v8/test/mjsunit/runtime-gen/isconcurrentrecompilationsupported.js b/deps/v8/test/mjsunit/runtime-gen/isconcurrentrecompilationsupported.js
new file mode 100644
index 000000000..44e2917d7
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isconcurrentrecompilationsupported.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%IsConcurrentRecompilationSupported();
diff --git a/deps/v8/test/mjsunit/runtime-gen/isextensible.js b/deps/v8/test/mjsunit/runtime-gen/isextensible.js
new file mode 100644
index 000000000..20a7c8d8a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isextensible.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%IsExtensible(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/isinitializedintlobject.js b/deps/v8/test/mjsunit/runtime-gen/isinitializedintlobject.js
new file mode 100644
index 000000000..2816e5e27
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isinitializedintlobject.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _input = new Object();
+%IsInitializedIntlObject(_input);
diff --git a/deps/v8/test/mjsunit/runtime-gen/isinitializedintlobjectoftype.js b/deps/v8/test/mjsunit/runtime-gen/isinitializedintlobjectoftype.js
new file mode 100644
index 000000000..60e385008
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isinitializedintlobjectoftype.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _input = new Object();
+var _expected_type = "foo";
+%IsInitializedIntlObjectOfType(_input, _expected_type);
diff --git a/deps/v8/test/mjsunit/runtime-gen/isinprototypechain.js b/deps/v8/test/mjsunit/runtime-gen/isinprototypechain.js
new file mode 100644
index 000000000..37048348d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isinprototypechain.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _O = new Object();
+var _V = new Object();
+%IsInPrototypeChain(_O, _V);
diff --git a/deps/v8/test/mjsunit/runtime-gen/isjsfunctionproxy.js b/deps/v8/test/mjsunit/runtime-gen/isjsfunctionproxy.js
new file mode 100644
index 000000000..ca6ea5a91
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isjsfunctionproxy.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%IsJSFunctionProxy(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/isjsglobalproxy.js b/deps/v8/test/mjsunit/runtime-gen/isjsglobalproxy.js
new file mode 100644
index 000000000..f0de61015
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isjsglobalproxy.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%IsJSGlobalProxy(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/isjsmodule.js b/deps/v8/test/mjsunit/runtime-gen/isjsmodule.js
new file mode 100644
index 000000000..8b43a729f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isjsmodule.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%IsJSModule(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/isjsproxy.js b/deps/v8/test/mjsunit/runtime-gen/isjsproxy.js
new file mode 100644
index 000000000..a4d32beb1
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isjsproxy.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%IsJSProxy(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/isobserved.js b/deps/v8/test/mjsunit/runtime-gen/isobserved.js
new file mode 100644
index 000000000..f649a1b33
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isobserved.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%IsObserved(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/isoptimized.js b/deps/v8/test/mjsunit/runtime-gen/isoptimized.js
new file mode 100644
index 000000000..e1daf0da8
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isoptimized.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%IsOptimized();
diff --git a/deps/v8/test/mjsunit/runtime-gen/ispropertyenumerable.js b/deps/v8/test/mjsunit/runtime-gen/ispropertyenumerable.js
new file mode 100644
index 000000000..575ee3468
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/ispropertyenumerable.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+var _key = "name";
+%IsPropertyEnumerable(_object, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/issloppymodefunction.js b/deps/v8/test/mjsunit/runtime-gen/issloppymodefunction.js
new file mode 100644
index 000000000..a0c75b32d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/issloppymodefunction.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = function() {};
+%IsSloppyModeFunction(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/istemplate.js b/deps/v8/test/mjsunit/runtime-gen/istemplate.js
new file mode 100644
index 000000000..421229fe6
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/istemplate.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _arg = new Object();
+%IsTemplate(_arg);
diff --git a/deps/v8/test/mjsunit/runtime-gen/isvalidsmi.js b/deps/v8/test/mjsunit/runtime-gen/isvalidsmi.js
new file mode 100644
index 000000000..98cf53bb2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/isvalidsmi.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _number = 32;
+%IsValidSmi(_number);
diff --git a/deps/v8/test/mjsunit/runtime-gen/keyedgetproperty.js b/deps/v8/test/mjsunit/runtime-gen/keyedgetproperty.js
new file mode 100644
index 000000000..cd8473c99
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/keyedgetproperty.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _receiver_obj = new Object();
+var _key_obj = new Object();
+%KeyedGetProperty(_receiver_obj, _key_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/liveeditcheckanddropactivations.js b/deps/v8/test/mjsunit/runtime-gen/liveeditcheckanddropactivations.js
new file mode 100644
index 000000000..7247acc3a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/liveeditcheckanddropactivations.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _shared_array = new Array();
+var _do_drop = true;
+%LiveEditCheckAndDropActivations(_shared_array, _do_drop);
diff --git a/deps/v8/test/mjsunit/runtime-gen/liveeditcomparestrings.js b/deps/v8/test/mjsunit/runtime-gen/liveeditcomparestrings.js
new file mode 100644
index 000000000..611d78b03
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/liveeditcomparestrings.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _s1 = "foo";
+var _s2 = "foo";
+%LiveEditCompareStrings(_s1, _s2);
diff --git a/deps/v8/test/mjsunit/runtime-gen/liveeditfunctionsetscript.js b/deps/v8/test/mjsunit/runtime-gen/liveeditfunctionsetscript.js
new file mode 100644
index 000000000..51d61d3bc
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/liveeditfunctionsetscript.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _function_object = new Object();
+var _script_object = new Object();
+%LiveEditFunctionSetScript(_function_object, _script_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/loadmutabledouble.js b/deps/v8/test/mjsunit/runtime-gen/loadmutabledouble.js
new file mode 100644
index 000000000..1a2e7e9f9
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/loadmutabledouble.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = {foo: 1.2};
+var _index = 1;
+%LoadMutableDouble(arg0, _index);
diff --git a/deps/v8/test/mjsunit/runtime-gen/lookupaccessor.js b/deps/v8/test/mjsunit/runtime-gen/lookupaccessor.js
new file mode 100644
index 000000000..89f40d76c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/lookupaccessor.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _receiver = new Object();
+var _name = "name";
+var _flag = 1;
+%LookupAccessor(_receiver, _name, _flag);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mapclear.js b/deps/v8/test/mjsunit/runtime-gen/mapclear.js
new file mode 100644
index 000000000..b34e69451
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mapclear.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Map();
+%MapClear(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mapdelete.js b/deps/v8/test/mjsunit/runtime-gen/mapdelete.js
new file mode 100644
index 000000000..ab7895442
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mapdelete.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Map();
+var _key = new Object();
+%MapDelete(_holder, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mapget.js b/deps/v8/test/mjsunit/runtime-gen/mapget.js
new file mode 100644
index 000000000..0e996f523
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mapget.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Map();
+var _key = new Object();
+%MapGet(_holder, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mapgetsize.js b/deps/v8/test/mjsunit/runtime-gen/mapgetsize.js
new file mode 100644
index 000000000..50a06044b
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mapgetsize.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Map();
+%MapGetSize(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/maphas.js b/deps/v8/test/mjsunit/runtime-gen/maphas.js
new file mode 100644
index 000000000..2dc70c93e
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/maphas.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Map();
+var _key = new Object();
+%MapHas(_holder, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mapinitialize.js b/deps/v8/test/mjsunit/runtime-gen/mapinitialize.js
new file mode 100644
index 000000000..6240a0259
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mapinitialize.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Map();
+%MapInitialize(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mapiteratorinitialize.js b/deps/v8/test/mjsunit/runtime-gen/mapiteratorinitialize.js
new file mode 100644
index 000000000..584fe18a4
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mapiteratorinitialize.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Map().entries();
+var _map = new Map();
+var _kind = 1;
+%MapIteratorInitialize(_holder, _map, _kind);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mapiteratornext.js b/deps/v8/test/mjsunit/runtime-gen/mapiteratornext.js
new file mode 100644
index 000000000..e15522702
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mapiteratornext.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Map().entries();
+var _value_array = new Array();
+%MapIteratorNext(_holder, _value_array);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mapset.js b/deps/v8/test/mjsunit/runtime-gen/mapset.js
new file mode 100644
index 000000000..32c2080a8
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mapset.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Map();
+var _key = new Object();
+var _value = new Object();
+%MapSet(_holder, _key, _value);
diff --git a/deps/v8/test/mjsunit/runtime-gen/markasinitializedintlobjectoftype.js b/deps/v8/test/mjsunit/runtime-gen/markasinitializedintlobjectoftype.js
new file mode 100644
index 000000000..bd0c581c8
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/markasinitializedintlobjectoftype.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _input = new Object();
+var _type = "foo";
+var _impl = new Object();
+%MarkAsInitializedIntlObjectOfType(_input, _type, _impl);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mathacos.js b/deps/v8/test/mjsunit/runtime-gen/mathacos.js
new file mode 100644
index 000000000..fa4426838
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mathacos.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%MathAcos(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mathasin.js b/deps/v8/test/mjsunit/runtime-gen/mathasin.js
new file mode 100644
index 000000000..0d20b3108
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mathasin.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%MathAsin(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mathatan.js b/deps/v8/test/mjsunit/runtime-gen/mathatan.js
new file mode 100644
index 000000000..0e2708f1f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mathatan.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%MathAtan(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mathatan2.js b/deps/v8/test/mjsunit/runtime-gen/mathatan2.js
new file mode 100644
index 000000000..429479711
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mathatan2.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+var _y = 1.5;
+%MathAtan2(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mathexprt.js b/deps/v8/test/mjsunit/runtime-gen/mathexprt.js
new file mode 100644
index 000000000..e4584366d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mathexprt.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%MathExpRT(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mathfloorrt.js b/deps/v8/test/mjsunit/runtime-gen/mathfloorrt.js
new file mode 100644
index 000000000..2ae83aab5
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mathfloorrt.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%MathFloorRT(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mathfround.js b/deps/v8/test/mjsunit/runtime-gen/mathfround.js
new file mode 100644
index 000000000..10a92986c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mathfround.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%MathFround(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mathlogrt.js b/deps/v8/test/mjsunit/runtime-gen/mathlogrt.js
new file mode 100644
index 000000000..5c484cbbb
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mathlogrt.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%MathLogRT(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/mathsqrtrt.js b/deps/v8/test/mjsunit/runtime-gen/mathsqrtrt.js
new file mode 100644
index 000000000..e0df8d72d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/mathsqrtrt.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%MathSqrtRT(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/maxsmi.js b/deps/v8/test/mjsunit/runtime-gen/maxsmi.js
new file mode 100644
index 000000000..717a6544e
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/maxsmi.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%MaxSmi();
diff --git a/deps/v8/test/mjsunit/runtime-gen/movearraycontents.js b/deps/v8/test/mjsunit/runtime-gen/movearraycontents.js
new file mode 100644
index 000000000..41c4ee1cd
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/movearraycontents.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _from = new Array();
+var _to = new Array();
+%MoveArrayContents(_from, _to);
diff --git a/deps/v8/test/mjsunit/runtime-gen/neveroptimizefunction.js b/deps/v8/test/mjsunit/runtime-gen/neveroptimizefunction.js
new file mode 100644
index 000000000..b03e42f1f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/neveroptimizefunction.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _function = function() {};
+%NeverOptimizeFunction(_function);
diff --git a/deps/v8/test/mjsunit/runtime-gen/newarguments.js b/deps/v8/test/mjsunit/runtime-gen/newarguments.js
new file mode 100644
index 000000000..908fc3af7
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/newarguments.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _callee = function() {};
+%NewArguments(_callee);
diff --git a/deps/v8/test/mjsunit/runtime-gen/newobjectfrombound.js b/deps/v8/test/mjsunit/runtime-gen/newobjectfrombound.js
new file mode 100644
index 000000000..36f75077b
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/newobjectfrombound.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = (function() {}).bind({});
+%NewObjectFromBound(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/newstring.js b/deps/v8/test/mjsunit/runtime-gen/newstring.js
new file mode 100644
index 000000000..24b01489e
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/newstring.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _length = 1;
+var _is_one_byte = true;
+%NewString(_length, _is_one_byte);
diff --git a/deps/v8/test/mjsunit/runtime-gen/newstringwrapper.js b/deps/v8/test/mjsunit/runtime-gen/newstringwrapper.js
new file mode 100644
index 000000000..cf53a3af2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/newstringwrapper.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _value = "foo";
+%NewStringWrapper(_value);
diff --git a/deps/v8/test/mjsunit/runtime-gen/newsymbolwrapper.js b/deps/v8/test/mjsunit/runtime-gen/newsymbolwrapper.js
new file mode 100644
index 000000000..08c0ea7e6
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/newsymbolwrapper.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _symbol = Symbol("symbol");
+%NewSymbolWrapper(_symbol);
diff --git a/deps/v8/test/mjsunit/runtime-gen/notifycontextdisposed.js b/deps/v8/test/mjsunit/runtime-gen/notifycontextdisposed.js
new file mode 100644
index 000000000..d353fc5ce
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/notifycontextdisposed.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%NotifyContextDisposed();
diff --git a/deps/v8/test/mjsunit/runtime-gen/numberadd.js b/deps/v8/test/mjsunit/runtime-gen/numberadd.js
new file mode 100644
index 000000000..f85017d49
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numberadd.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+var _y = 1.5;
+%NumberAdd(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numberand.js b/deps/v8/test/mjsunit/runtime-gen/numberand.js
new file mode 100644
index 000000000..9635e11bb
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numberand.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 32;
+var _y = 32;
+%NumberAnd(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbercompare.js b/deps/v8/test/mjsunit/runtime-gen/numbercompare.js
new file mode 100644
index 000000000..5f7ac9363
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbercompare.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+var _y = 1.5;
+var _uncomparable_result = new Object();
+%NumberCompare(_x, _y, _uncomparable_result);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numberdiv.js b/deps/v8/test/mjsunit/runtime-gen/numberdiv.js
new file mode 100644
index 000000000..c62d5921c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numberdiv.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+var _y = 1.5;
+%NumberDiv(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numberequals.js b/deps/v8/test/mjsunit/runtime-gen/numberequals.js
new file mode 100644
index 000000000..3b919fc02
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numberequals.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+var _y = 1.5;
+%NumberEquals(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numberimul.js b/deps/v8/test/mjsunit/runtime-gen/numberimul.js
new file mode 100644
index 000000000..f3c98bdc2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numberimul.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 32;
+var _y = 32;
+%NumberImul(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbermod.js b/deps/v8/test/mjsunit/runtime-gen/numbermod.js
new file mode 100644
index 000000000..6d5faeb2c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbermod.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+var _y = 1.5;
+%NumberMod(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbermul.js b/deps/v8/test/mjsunit/runtime-gen/numbermul.js
new file mode 100644
index 000000000..0bdc7c237
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbermul.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+var _y = 1.5;
+%NumberMul(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numberor.js b/deps/v8/test/mjsunit/runtime-gen/numberor.js
new file mode 100644
index 000000000..c5ac65fc8
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numberor.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 32;
+var _y = 32;
+%NumberOr(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbersar.js b/deps/v8/test/mjsunit/runtime-gen/numbersar.js
new file mode 100644
index 000000000..639270a08
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbersar.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 32;
+var _y = 32;
+%NumberSar(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbershl.js b/deps/v8/test/mjsunit/runtime-gen/numbershl.js
new file mode 100644
index 000000000..b505ff6ed
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbershl.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 32;
+var _y = 32;
+%NumberShl(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbershr.js b/deps/v8/test/mjsunit/runtime-gen/numbershr.js
new file mode 100644
index 000000000..bd1a3c454
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbershr.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 32;
+var _y = 32;
+%NumberShr(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbersub.js b/deps/v8/test/mjsunit/runtime-gen/numbersub.js
new file mode 100644
index 000000000..5c99f872f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbersub.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+var _y = 1.5;
+%NumberSub(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbertoexponential.js b/deps/v8/test/mjsunit/runtime-gen/numbertoexponential.js
new file mode 100644
index 000000000..30159bb3a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbertoexponential.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _value = 1.5;
+var _f_number = 1.5;
+%NumberToExponential(_value, _f_number);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbertofixed.js b/deps/v8/test/mjsunit/runtime-gen/numbertofixed.js
new file mode 100644
index 000000000..0df152541
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbertofixed.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _value = 1.5;
+var _f_number = 1.5;
+%NumberToFixed(_value, _f_number);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbertointeger.js b/deps/v8/test/mjsunit/runtime-gen/numbertointeger.js
new file mode 100644
index 000000000..eada58f45
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbertointeger.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _number = 1.5;
+%NumberToInteger(_number);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbertointegermapminuszero.js b/deps/v8/test/mjsunit/runtime-gen/numbertointegermapminuszero.js
new file mode 100644
index 000000000..ce3248061
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbertointegermapminuszero.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _number = 1.5;
+%NumberToIntegerMapMinusZero(_number);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbertojsint32.js b/deps/v8/test/mjsunit/runtime-gen/numbertojsint32.js
new file mode 100644
index 000000000..77321f9c6
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbertojsint32.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _number = 1.5;
+%NumberToJSInt32(_number);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbertojsuint32.js b/deps/v8/test/mjsunit/runtime-gen/numbertojsuint32.js
new file mode 100644
index 000000000..d4f7302fe
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbertojsuint32.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _number = 32;
+%NumberToJSUint32(_number);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbertoprecision.js b/deps/v8/test/mjsunit/runtime-gen/numbertoprecision.js
new file mode 100644
index 000000000..6591117ec
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbertoprecision.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _value = 1.5;
+var _f_number = 1.5;
+%NumberToPrecision(_value, _f_number);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbertoradixstring.js b/deps/v8/test/mjsunit/runtime-gen/numbertoradixstring.js
new file mode 100644
index 000000000..020aac285
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbertoradixstring.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _value = 1.5;
+var arg1 = 2;
+%NumberToRadixString(_value, arg1);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numbertostringrt.js b/deps/v8/test/mjsunit/runtime-gen/numbertostringrt.js
new file mode 100644
index 000000000..4b2b6d93b
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numbertostringrt.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _number = 1.5;
+%NumberToStringRT(_number);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numberunaryminus.js b/deps/v8/test/mjsunit/runtime-gen/numberunaryminus.js
new file mode 100644
index 000000000..54dc49eda
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numberunaryminus.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%NumberUnaryMinus(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/numberxor.js b/deps/v8/test/mjsunit/runtime-gen/numberxor.js
new file mode 100644
index 000000000..237269803
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/numberxor.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 32;
+var _y = 32;
+%NumberXor(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/objectfreeze.js b/deps/v8/test/mjsunit/runtime-gen/objectfreeze.js
new file mode 100644
index 000000000..cfc066c6f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/objectfreeze.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+%ObjectFreeze(_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/objectwascreatedincurrentorigin.js b/deps/v8/test/mjsunit/runtime-gen/objectwascreatedincurrentorigin.js
new file mode 100644
index 000000000..776997009
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/objectwascreatedincurrentorigin.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+%ObjectWasCreatedInCurrentOrigin(_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/observationweakmapcreate.js b/deps/v8/test/mjsunit/runtime-gen/observationweakmapcreate.js
new file mode 100644
index 000000000..6c71eace4
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/observationweakmapcreate.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%ObservationWeakMapCreate();
diff --git a/deps/v8/test/mjsunit/runtime-gen/observerobjectandrecordhavesameorigin.js b/deps/v8/test/mjsunit/runtime-gen/observerobjectandrecordhavesameorigin.js
new file mode 100644
index 000000000..6c251ecd9
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/observerobjectandrecordhavesameorigin.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _observer = function() {};
+var _object = new Object();
+var _record = new Object();
+%ObserverObjectAndRecordHaveSameOrigin(_observer, _object, _record);
diff --git a/deps/v8/test/mjsunit/runtime-gen/optimizeobjectforaddingmultipleproperties.js b/deps/v8/test/mjsunit/runtime-gen/optimizeobjectforaddingmultipleproperties.js
new file mode 100644
index 000000000..7016e1c06
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/optimizeobjectforaddingmultipleproperties.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+var _properties = 1;
+%OptimizeObjectForAddingMultipleProperties(_object, _properties);
diff --git a/deps/v8/test/mjsunit/runtime-gen/ownkeys.js b/deps/v8/test/mjsunit/runtime-gen/ownkeys.js
new file mode 100644
index 000000000..0a392422c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/ownkeys.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _raw_object = new Object();
+%OwnKeys(_raw_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/parsejson.js b/deps/v8/test/mjsunit/runtime-gen/parsejson.js
new file mode 100644
index 000000000..0a038790e
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/parsejson.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = "{}";
+%ParseJson(arg0);
diff --git a/deps/v8/test/mjsunit/runtime-gen/preventextensions.js b/deps/v8/test/mjsunit/runtime-gen/preventextensions.js
new file mode 100644
index 000000000..8e24b75e0
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/preventextensions.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%PreventExtensions(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/pushifabsent.js b/deps/v8/test/mjsunit/runtime-gen/pushifabsent.js
new file mode 100644
index 000000000..c998121f5
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/pushifabsent.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _array = new Array();
+var _element = new Object();
+%PushIfAbsent(_array, _element);
diff --git a/deps/v8/test/mjsunit/runtime-gen/quotejsonstring.js b/deps/v8/test/mjsunit/runtime-gen/quotejsonstring.js
new file mode 100644
index 000000000..61ade3426
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/quotejsonstring.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _string = "foo";
+%QuoteJSONString(_string);
diff --git a/deps/v8/test/mjsunit/runtime-gen/regexpcompile.js b/deps/v8/test/mjsunit/runtime-gen/regexpcompile.js
new file mode 100644
index 000000000..c0edfa6fc
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/regexpcompile.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _re = /ab/g;
+var _pattern = "foo";
+var _flags = "foo";
+%RegExpCompile(_re, _pattern, _flags);
diff --git a/deps/v8/test/mjsunit/runtime-gen/regexpconstructresult.js b/deps/v8/test/mjsunit/runtime-gen/regexpconstructresult.js
new file mode 100644
index 000000000..50d2e0d8f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/regexpconstructresult.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _size = 1;
+var _index = new Object();
+var _input = new Object();
+%_RegExpConstructResult(_size, _index, _input);
diff --git a/deps/v8/test/mjsunit/runtime-gen/regexpexecmultiple.js b/deps/v8/test/mjsunit/runtime-gen/regexpexecmultiple.js
new file mode 100644
index 000000000..9db6e6d2b
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/regexpexecmultiple.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _regexp = /ab/g;
+var _subject = "foo";
+var arg2 = ['a'];
+var arg3 = ['a'];
+%RegExpExecMultiple(_regexp, _subject, arg2, arg3);
diff --git a/deps/v8/test/mjsunit/runtime-gen/regexpexecrt.js b/deps/v8/test/mjsunit/runtime-gen/regexpexecrt.js
new file mode 100644
index 000000000..3b20191f2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/regexpexecrt.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _regexp = /ab/g;
+var _subject = "foo";
+var _index = 1;
+var _last_match_info = new Array();
+%RegExpExecRT(_regexp, _subject, _index, _last_match_info);
diff --git a/deps/v8/test/mjsunit/runtime-gen/regexpinitializeobject.js b/deps/v8/test/mjsunit/runtime-gen/regexpinitializeobject.js
new file mode 100644
index 000000000..fccdeeed7
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/regexpinitializeobject.js
@@ -0,0 +1,9 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _regexp = /ab/g;
+var _source = "foo";
+var _global = new Object();
+var _ignoreCase = new Object();
+var _multiline = new Object();
+%RegExpInitializeObject(_regexp, _source, _global, _ignoreCase, _multiline);
diff --git a/deps/v8/test/mjsunit/runtime-gen/removearrayholes.js b/deps/v8/test/mjsunit/runtime-gen/removearrayholes.js
new file mode 100644
index 000000000..971e63cab
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/removearrayholes.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+var _limit = 32;
+%RemoveArrayHoles(_object, _limit);
diff --git a/deps/v8/test/mjsunit/runtime-gen/rempio2.js b/deps/v8/test/mjsunit/runtime-gen/rempio2.js
new file mode 100644
index 000000000..6d47bac4a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/rempio2.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = 1.5;
+%RemPiO2(_x);
diff --git a/deps/v8/test/mjsunit/runtime-gen/roundnumber.js b/deps/v8/test/mjsunit/runtime-gen/roundnumber.js
new file mode 100644
index 000000000..2ec1159b2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/roundnumber.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _input = 1.5;
+%RoundNumber(_input);
diff --git a/deps/v8/test/mjsunit/runtime-gen/runmicrotasks.js b/deps/v8/test/mjsunit/runtime-gen/runmicrotasks.js
new file mode 100644
index 000000000..945260a8d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/runmicrotasks.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%RunMicrotasks();
diff --git a/deps/v8/test/mjsunit/runtime-gen/runninginsimulator.js b/deps/v8/test/mjsunit/runtime-gen/runninginsimulator.js
new file mode 100644
index 000000000..fe5678259
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/runninginsimulator.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%RunningInSimulator();
diff --git a/deps/v8/test/mjsunit/runtime-gen/setadd.js b/deps/v8/test/mjsunit/runtime-gen/setadd.js
new file mode 100644
index 000000000..75b923fbf
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setadd.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Set();
+var _key = new Object();
+%SetAdd(_holder, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setclear.js b/deps/v8/test/mjsunit/runtime-gen/setclear.js
new file mode 100644
index 000000000..82ef6d955
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setclear.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Set();
+%SetClear(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setcode.js b/deps/v8/test/mjsunit/runtime-gen/setcode.js
new file mode 100644
index 000000000..4e2206fbc
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setcode.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _target = function() {};
+var _source = function() {};
+%SetCode(_target, _source);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setdebugeventlistener.js b/deps/v8/test/mjsunit/runtime-gen/setdebugeventlistener.js
new file mode 100644
index 000000000..d51b277b8
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setdebugeventlistener.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = undefined;
+var _data = new Object();
+%SetDebugEventListener(arg0, _data);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setdelete.js b/deps/v8/test/mjsunit/runtime-gen/setdelete.js
new file mode 100644
index 000000000..80bd343d0
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setdelete.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Set();
+var _key = new Object();
+%SetDelete(_holder, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setdisablebreak.js b/deps/v8/test/mjsunit/runtime-gen/setdisablebreak.js
new file mode 100644
index 000000000..461942b60
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setdisablebreak.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _disable_break = true;
+%SetDisableBreak(_disable_break);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setflags.js b/deps/v8/test/mjsunit/runtime-gen/setflags.js
new file mode 100644
index 000000000..70db03ee9
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setflags.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _arg = "foo";
+%SetFlags(_arg);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setfunctionbreakpoint.js b/deps/v8/test/mjsunit/runtime-gen/setfunctionbreakpoint.js
new file mode 100644
index 000000000..010330e5a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setfunctionbreakpoint.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _function = function() {};
+var arg1 = 218;
+var _break_point_object_arg = new Object();
+%SetFunctionBreakPoint(_function, arg1, _break_point_object_arg);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setgetsize.js b/deps/v8/test/mjsunit/runtime-gen/setgetsize.js
new file mode 100644
index 000000000..842016bb2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setgetsize.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Set();
+%SetGetSize(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/sethas.js b/deps/v8/test/mjsunit/runtime-gen/sethas.js
new file mode 100644
index 000000000..8cec0d8c3
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/sethas.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Set();
+var _key = new Object();
+%SetHas(_holder, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setinitialize.js b/deps/v8/test/mjsunit/runtime-gen/setinitialize.js
new file mode 100644
index 000000000..b21a08969
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setinitialize.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Set();
+%SetInitialize(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setisobserved.js b/deps/v8/test/mjsunit/runtime-gen/setisobserved.js
new file mode 100644
index 000000000..d885113ff
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setisobserved.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%SetIsObserved(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setiteratorinitialize.js b/deps/v8/test/mjsunit/runtime-gen/setiteratorinitialize.js
new file mode 100644
index 000000000..34769e51d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setiteratorinitialize.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Set().values();
+var _set = new Set();
+var arg2 = 2;
+%SetIteratorInitialize(_holder, _set, arg2);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setiteratornext.js b/deps/v8/test/mjsunit/runtime-gen/setiteratornext.js
new file mode 100644
index 000000000..02b74d44d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setiteratornext.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Set().values();
+var _value_array = new Array();
+%SetIteratorNext(_holder, _value_array);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setprototype.js b/deps/v8/test/mjsunit/runtime-gen/setprototype.js
new file mode 100644
index 000000000..6353151f4
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setprototype.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+var _prototype = new Object();
+%SetPrototype(_obj, _prototype);
diff --git a/deps/v8/test/mjsunit/runtime-gen/setscopevariablevalue.js b/deps/v8/test/mjsunit/runtime-gen/setscopevariablevalue.js
new file mode 100644
index 000000000..680bab52c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/setscopevariablevalue.js
@@ -0,0 +1,10 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _fun = function() {};
+var _wrapped_id = 1;
+var _inlined_jsframe_index = 32;
+var _index = 32;
+var _variable_name = "foo";
+var _new_value = new Object();
+%SetScopeVariableValue(_fun, _wrapped_id, _inlined_jsframe_index, _index, _variable_name, _new_value);
diff --git a/deps/v8/test/mjsunit/runtime-gen/smilexicographiccompare.js b/deps/v8/test/mjsunit/runtime-gen/smilexicographiccompare.js
new file mode 100644
index 000000000..d227a9ffc
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/smilexicographiccompare.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x_value = 1;
+var _y_value = 1;
+%SmiLexicographicCompare(_x_value, _y_value);
diff --git a/deps/v8/test/mjsunit/runtime-gen/sparsejoinwithseparator.js b/deps/v8/test/mjsunit/runtime-gen/sparsejoinwithseparator.js
new file mode 100644
index 000000000..3a8e7754d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/sparsejoinwithseparator.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _elements_array = new Array();
+var _array_length = 32;
+var _separator = "foo";
+%SparseJoinWithSeparator(_elements_array, _array_length, _separator);
diff --git a/deps/v8/test/mjsunit/runtime-gen/specialarrayfunctions.js b/deps/v8/test/mjsunit/runtime-gen/specialarrayfunctions.js
new file mode 100644
index 000000000..5956e8422
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/specialarrayfunctions.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%SpecialArrayFunctions();
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringbuilderconcat.js b/deps/v8/test/mjsunit/runtime-gen/stringbuilderconcat.js
new file mode 100644
index 000000000..9d7c78a3e
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringbuilderconcat.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = [1, 2, 3];
+var arg1 = 3;
+var _special = "foo";
+%StringBuilderConcat(arg0, arg1, _special);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringbuilderjoin.js b/deps/v8/test/mjsunit/runtime-gen/stringbuilderjoin.js
new file mode 100644
index 000000000..bf990c62d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringbuilderjoin.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = ['a', 'b'];
+var arg1 = 4;
+var _separator = "foo";
+%StringBuilderJoin(arg0, arg1, _separator);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringcharcodeatrt.js b/deps/v8/test/mjsunit/runtime-gen/stringcharcodeatrt.js
new file mode 100644
index 000000000..fa016ac00
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringcharcodeatrt.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _subject = "foo";
+var _i = 32;
+%StringCharCodeAtRT(_subject, _i);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringequals.js b/deps/v8/test/mjsunit/runtime-gen/stringequals.js
new file mode 100644
index 000000000..14e40eb02
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringequals.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _x = "foo";
+var _y = "foo";
+%StringEquals(_x, _y);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringindexof.js b/deps/v8/test/mjsunit/runtime-gen/stringindexof.js
new file mode 100644
index 000000000..3c5cab31c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringindexof.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _sub = "foo";
+var _pat = "foo";
+var _index = new Object();
+%StringIndexOf(_sub, _pat, _index);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringlastindexof.js b/deps/v8/test/mjsunit/runtime-gen/stringlastindexof.js
new file mode 100644
index 000000000..afbc51f5a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringlastindexof.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _sub = "foo";
+var _pat = "foo";
+var _index = new Object();
+%StringLastIndexOf(_sub, _pat, _index);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringlocalecompare.js b/deps/v8/test/mjsunit/runtime-gen/stringlocalecompare.js
new file mode 100644
index 000000000..b37e23118
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringlocalecompare.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _str1 = "foo";
+var _str2 = "foo";
+%StringLocaleCompare(_str1, _str2);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringmatch.js b/deps/v8/test/mjsunit/runtime-gen/stringmatch.js
new file mode 100644
index 000000000..330aeae9c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringmatch.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _subject = "foo";
+var _regexp = /ab/g;
+var arg2 = ['a', 'b'];
+%StringMatch(_subject, _regexp, arg2);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringnormalize.js b/deps/v8/test/mjsunit/runtime-gen/stringnormalize.js
new file mode 100644
index 000000000..fb408a41a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringnormalize.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _stringValue = "foo";
+var arg1 = 2;
+%StringNormalize(_stringValue, arg1);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringparsefloat.js b/deps/v8/test/mjsunit/runtime-gen/stringparsefloat.js
new file mode 100644
index 000000000..520a24e75
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringparsefloat.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _subject = "foo";
+%StringParseFloat(_subject);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringparseint.js b/deps/v8/test/mjsunit/runtime-gen/stringparseint.js
new file mode 100644
index 000000000..43116554e
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringparseint.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _subject = "foo";
+var _radix = 32;
+%StringParseInt(_subject, _radix);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringreplaceglobalregexpwithstring.js b/deps/v8/test/mjsunit/runtime-gen/stringreplaceglobalregexpwithstring.js
new file mode 100644
index 000000000..ad2b6e67d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringreplaceglobalregexpwithstring.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _subject = "foo";
+var _regexp = /ab/g;
+var _replacement = "foo";
+var arg3 = ['a'];
+%StringReplaceGlobalRegExpWithString(_subject, _regexp, _replacement, arg3);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringreplaceonecharwithstring.js b/deps/v8/test/mjsunit/runtime-gen/stringreplaceonecharwithstring.js
new file mode 100644
index 000000000..5e38a79f4
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringreplaceonecharwithstring.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _subject = "foo";
+var _search = "foo";
+var _replace = "foo";
+%StringReplaceOneCharWithString(_subject, _search, _replace);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringsplit.js b/deps/v8/test/mjsunit/runtime-gen/stringsplit.js
new file mode 100644
index 000000000..dfe683194
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringsplit.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _subject = "foo";
+var _pattern = "foo";
+var _limit = 32;
+%StringSplit(_subject, _pattern, _limit);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringtoarray.js b/deps/v8/test/mjsunit/runtime-gen/stringtoarray.js
new file mode 100644
index 000000000..6ed48a771
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringtoarray.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _s = "foo";
+var _limit = 32;
+%StringToArray(_s, _limit);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringtolowercase.js b/deps/v8/test/mjsunit/runtime-gen/stringtolowercase.js
new file mode 100644
index 000000000..3a7261a0e
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringtolowercase.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _s = "foo";
+%StringToLowerCase(_s);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringtonumber.js b/deps/v8/test/mjsunit/runtime-gen/stringtonumber.js
new file mode 100644
index 000000000..88e2e84a2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringtonumber.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _subject = "foo";
+%StringToNumber(_subject);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringtouppercase.js b/deps/v8/test/mjsunit/runtime-gen/stringtouppercase.js
new file mode 100644
index 000000000..b7d973101
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringtouppercase.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _s = "foo";
+%StringToUpperCase(_s);
diff --git a/deps/v8/test/mjsunit/runtime-gen/stringtrim.js b/deps/v8/test/mjsunit/runtime-gen/stringtrim.js
new file mode 100644
index 000000000..75d197efa
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/stringtrim.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _string = "foo";
+var _trimLeft = true;
+var _trimRight = true;
+%StringTrim(_string, _trimLeft, _trimRight);
diff --git a/deps/v8/test/mjsunit/runtime-gen/symboldescription.js b/deps/v8/test/mjsunit/runtime-gen/symboldescription.js
new file mode 100644
index 000000000..13360828b
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/symboldescription.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _symbol = Symbol("symbol");
+%SymbolDescription(_symbol);
diff --git a/deps/v8/test/mjsunit/runtime-gen/symbolisprivate.js b/deps/v8/test/mjsunit/runtime-gen/symbolisprivate.js
new file mode 100644
index 000000000..8e5343e1d
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/symbolisprivate.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _symbol = Symbol("symbol");
+%SymbolIsPrivate(_symbol);
diff --git a/deps/v8/test/mjsunit/runtime-gen/symbolregistry.js b/deps/v8/test/mjsunit/runtime-gen/symbolregistry.js
new file mode 100644
index 000000000..71964e6ea
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/symbolregistry.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%SymbolRegistry();
diff --git a/deps/v8/test/mjsunit/runtime-gen/tobool.js b/deps/v8/test/mjsunit/runtime-gen/tobool.js
new file mode 100644
index 000000000..ca522c8a9
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/tobool.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+%ToBool(_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/tofastproperties.js b/deps/v8/test/mjsunit/runtime-gen/tofastproperties.js
new file mode 100644
index 000000000..f9c1890b1
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/tofastproperties.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+%ToFastProperties(_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/traceenter.js b/deps/v8/test/mjsunit/runtime-gen/traceenter.js
new file mode 100644
index 000000000..768a0c243
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/traceenter.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%TraceEnter();
diff --git a/deps/v8/test/mjsunit/runtime-gen/traceexit.js b/deps/v8/test/mjsunit/runtime-gen/traceexit.js
new file mode 100644
index 000000000..378d008c9
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/traceexit.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%TraceExit(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/truncatestring.js b/deps/v8/test/mjsunit/runtime-gen/truncatestring.js
new file mode 100644
index 000000000..64ef628e5
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/truncatestring.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _string = "seqstring";
+var _new_length = 1;
+%TruncateString(_string, _new_length);
diff --git a/deps/v8/test/mjsunit/runtime-gen/trymigrateinstance.js b/deps/v8/test/mjsunit/runtime-gen/trymigrateinstance.js
new file mode 100644
index 000000000..b82eb741b
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/trymigrateinstance.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _object = new Object();
+%TryMigrateInstance(_object);
diff --git a/deps/v8/test/mjsunit/runtime-gen/typedarraygetbuffer.js b/deps/v8/test/mjsunit/runtime-gen/typedarraygetbuffer.js
new file mode 100644
index 000000000..56a805b3b
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/typedarraygetbuffer.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Int32Array(2);
+%TypedArrayGetBuffer(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/typedarraygetlength.js b/deps/v8/test/mjsunit/runtime-gen/typedarraygetlength.js
new file mode 100644
index 000000000..8d1865f40
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/typedarraygetlength.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Int32Array(2);
+%TypedArrayGetLength(_holder);
diff --git a/deps/v8/test/mjsunit/runtime-gen/typedarrayinitialize.js b/deps/v8/test/mjsunit/runtime-gen/typedarrayinitialize.js
new file mode 100644
index 000000000..be1e29607
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/typedarrayinitialize.js
@@ -0,0 +1,9 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Int32Array(2);
+var arg1 = 6;
+var arg2 = new ArrayBuffer(8);
+var _byte_offset_object = 1.5;
+var arg4 = 4;
+%TypedArrayInitialize(_holder, arg1, arg2, _byte_offset_object, arg4);
diff --git a/deps/v8/test/mjsunit/runtime-gen/typedarrayinitializefromarraylike.js b/deps/v8/test/mjsunit/runtime-gen/typedarrayinitializefromarraylike.js
new file mode 100644
index 000000000..0ca7a0f7c
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/typedarrayinitializefromarraylike.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _holder = new Int32Array(2);
+var arg1 = 6;
+var _source = new Object();
+var _length_obj = 1.5;
+%TypedArrayInitializeFromArrayLike(_holder, arg1, _source, _length_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/typedarraymaxsizeinheap.js b/deps/v8/test/mjsunit/runtime-gen/typedarraymaxsizeinheap.js
new file mode 100644
index 000000000..61467bd9f
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/typedarraymaxsizeinheap.js
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+%TypedArrayMaxSizeInHeap();
diff --git a/deps/v8/test/mjsunit/runtime-gen/typedarraysetfastcases.js b/deps/v8/test/mjsunit/runtime-gen/typedarraysetfastcases.js
new file mode 100644
index 000000000..495212952
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/typedarraysetfastcases.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _target_obj = new Int32Array(2);
+var _source_obj = new Int32Array(2);
+var arg2 = 0;
+%TypedArraySetFastCases(_target_obj, _source_obj, arg2);
diff --git a/deps/v8/test/mjsunit/runtime-gen/typeof.js b/deps/v8/test/mjsunit/runtime-gen/typeof.js
new file mode 100644
index 000000000..78bfa6ea2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/typeof.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+%Typeof(_obj);
diff --git a/deps/v8/test/mjsunit/runtime-gen/unblockconcurrentrecompilation.js b/deps/v8/test/mjsunit/runtime-gen/unblockconcurrentrecompilation.js
new file mode 100644
index 000000000..a08add7b2
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/unblockconcurrentrecompilation.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+try {
+%UnblockConcurrentRecompilation();
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/runtime-gen/uriescape.js b/deps/v8/test/mjsunit/runtime-gen/uriescape.js
new file mode 100644
index 000000000..f32edc98e
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/uriescape.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _source = "foo";
+%URIEscape(_source);
diff --git a/deps/v8/test/mjsunit/runtime-gen/uriunescape.js b/deps/v8/test/mjsunit/runtime-gen/uriunescape.js
new file mode 100644
index 000000000..2ba812c58
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/uriunescape.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _source = "foo";
+%URIUnescape(_source);
diff --git a/deps/v8/test/mjsunit/runtime-gen/weakcollectiondelete.js b/deps/v8/test/mjsunit/runtime-gen/weakcollectiondelete.js
new file mode 100644
index 000000000..a6fff79e1
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/weakcollectiondelete.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _weak_collection = new WeakMap();
+var _key = new Object();
+%WeakCollectionDelete(_weak_collection, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/weakcollectionget.js b/deps/v8/test/mjsunit/runtime-gen/weakcollectionget.js
new file mode 100644
index 000000000..f248ac05a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/weakcollectionget.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _weak_collection = new WeakMap();
+var _key = new Object();
+%WeakCollectionGet(_weak_collection, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/weakcollectionhas.js b/deps/v8/test/mjsunit/runtime-gen/weakcollectionhas.js
new file mode 100644
index 000000000..af600c3e8
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/weakcollectionhas.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _weak_collection = new WeakMap();
+var _key = new Object();
+%WeakCollectionHas(_weak_collection, _key);
diff --git a/deps/v8/test/mjsunit/runtime-gen/weakcollectioninitialize.js b/deps/v8/test/mjsunit/runtime-gen/weakcollectioninitialize.js
new file mode 100644
index 000000000..97f5ce56a
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/weakcollectioninitialize.js
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _weak_collection = new WeakMap();
+%WeakCollectionInitialize(_weak_collection);
diff --git a/deps/v8/test/mjsunit/runtime-gen/weakcollectionset.js b/deps/v8/test/mjsunit/runtime-gen/weakcollectionset.js
new file mode 100644
index 000000000..3479ba603
--- /dev/null
+++ b/deps/v8/test/mjsunit/runtime-gen/weakcollectionset.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _weak_collection = new WeakMap();
+var _key = new Object();
+var _value = new Object();
+%WeakCollectionSet(_weak_collection, _key, _value);
diff --git a/deps/v8/test/mjsunit/sin-cos.js b/deps/v8/test/mjsunit/sin-cos.js
index 02ae57ba2..71fae2056 100644
--- a/deps/v8/test/mjsunit/sin-cos.js
+++ b/deps/v8/test/mjsunit/sin-cos.js
@@ -157,8 +157,8 @@ assertEquals(0, Math.sin("0x00000"));
assertEquals(1, Math.cos("0x00000"));
assertTrue(isNaN(Math.sin(Infinity)));
assertTrue(isNaN(Math.cos("-Infinity")));
-assertEquals("Infinity", String(Math.tan(Math.PI/2)));
-assertEquals("-Infinity", String(Math.tan(-Math.PI/2)));
+assertTrue(Math.tan(Math.PI/2) > 1e16);
+assertTrue(Math.tan(-Math.PI/2) < -1e16);
assertEquals("-Infinity", String(1/Math.sin("-0")));
// Assert that the remainder after division by pi is reasonably precise.
@@ -185,3 +185,96 @@ for (var i = -1024; i < 1024; i++) {
assertFalse(isNaN(Math.cos(1.57079632679489700)));
assertFalse(isNaN(Math.cos(-1e-100)));
assertFalse(isNaN(Math.cos(-1e-323)));
+
+// Tests for specific values expected from the fdlibm implementation.
+
+var two_32 = Math.pow(2, -32);
+var two_28 = Math.pow(2, -28);
+
+// Tests for Math.sin for |x| < pi/4
+assertEquals(Infinity, 1/Math.sin(+0.0));
+assertEquals(-Infinity, 1/Math.sin(-0.0));
+// sin(x) = x for x < 2^-27
+assertEquals(two_32, Math.sin(two_32));
+assertEquals(-two_32, Math.sin(-two_32));
+// sin(pi/8) = sqrt(sqrt(2)-1)/2^(3/4)
+assertEquals(0.3826834323650898, Math.sin(Math.PI/8));
+assertEquals(-0.3826834323650898, -Math.sin(Math.PI/8));
+
+// Tests for Math.cos for |x| < pi/4
+// cos(x) = 1 for |x| < 2^-27
+assertEquals(1, Math.cos(two_32));
+assertEquals(1, Math.cos(-two_32));
+// Test KERNELCOS for |x| < 0.3.
+// cos(pi/20) = sqrt(sqrt(2)*sqrt(sqrt(5)+5)+4)/2^(3/2)
+assertEquals(0.9876883405951378, Math.cos(Math.PI/20));
+// Test KERNELCOS for x ~= 0.78125
+assertEquals(0.7100335477927638, Math.cos(0.7812504768371582));
+assertEquals(0.7100338835660797, Math.cos(0.78125));
+// Test KERNELCOS for |x| > 0.3.
+// cos(pi/8) = sqrt(sqrt(2)+1)/2^(3/4)
+assertEquals(0.9238795325112867, Math.cos(Math.PI/8));
+// Test KERNELTAN for |x| < 0.67434.
+assertEquals(0.9238795325112867, Math.cos(-Math.PI/8));
+
+// Tests for Math.tan for |x| < pi/4
+assertEquals(Infinity, 1/Math.tan(0.0));
+assertEquals(-Infinity, 1/Math.tan(-0.0));
+// tan(x) = x for |x| < 2^-28
+assertEquals(two_32, Math.tan(two_32));
+assertEquals(-two_32, Math.tan(-two_32));
+// Test KERNELTAN for |x| > 0.67434.
+assertEquals(0.8211418015898941, Math.tan(11/16));
+assertEquals(-0.8211418015898941, Math.tan(-11/16));
+assertEquals(0.41421356237309503, Math.tan(Math.PI / 8));
+
+// Tests for Math.sin.
+assertEquals(0.479425538604203, Math.sin(0.5));
+assertEquals(-0.479425538604203, Math.sin(-0.5));
+assertEquals(1, Math.sin(Math.PI/2));
+assertEquals(-1, Math.sin(-Math.PI/2));
+// Test that Math.sin(Math.PI) != 0 since Math.PI is not exact.
+assertEquals(1.2246467991473532e-16, Math.sin(Math.PI));
+assertEquals(-7.047032979958965e-14, Math.sin(2200*Math.PI));
+// Test Math.sin for various phases.
+assertEquals(-0.7071067811865477, Math.sin(7/4 * Math.PI));
+assertEquals(0.7071067811865474, Math.sin(9/4 * Math.PI));
+assertEquals(0.7071067811865483, Math.sin(11/4 * Math.PI));
+assertEquals(-0.7071067811865479, Math.sin(13/4 * Math.PI));
+assertEquals(-3.2103381051568376e-11, Math.sin(1048576/4 * Math.PI));
+
+// Tests for Math.cos.
+assertEquals(1, Math.cos(two_28));
+// Cover different code paths in KERNELCOS.
+assertEquals(0.9689124217106447, Math.cos(0.25));
+assertEquals(0.8775825618903728, Math.cos(0.5));
+assertEquals(0.7073882691671998, Math.cos(0.785));
+// Test that Math.cos(Math.PI/2) != 0 since Math.PI is not exact.
+assertEquals(6.123233995736766e-17, Math.cos(Math.PI/2));
+// Test Math.cos for various phases.
+assertEquals(0.7071067811865474, Math.cos(7/4 * Math.PI));
+assertEquals(0.7071067811865477, Math.cos(9/4 * Math.PI));
+assertEquals(-0.7071067811865467, Math.cos(11/4 * Math.PI));
+assertEquals(-0.7071067811865471, Math.cos(13/4 * Math.PI));
+assertEquals(0.9367521275331447, Math.cos(1000000));
+assertEquals(-3.435757038074824e-12, Math.cos(1048575/2 * Math.PI));
+
+// Tests for Math.tan.
+assertEquals(two_28, Math.tan(two_28));
+// Test that Math.tan(Math.PI/2) != Infinity since Math.PI is not exact.
+assertEquals(1.633123935319537e16, Math.tan(Math.PI/2));
+// Cover different code paths in KERNELTAN (tangent and cotangent)
+assertEquals(0.5463024898437905, Math.tan(0.5));
+assertEquals(2.0000000000000027, Math.tan(1.107148717794091));
+assertEquals(-1.0000000000000004, Math.tan(7/4*Math.PI));
+assertEquals(0.9999999999999994, Math.tan(9/4*Math.PI));
+assertEquals(-6.420676210313675e-11, Math.tan(1048576/2*Math.PI));
+assertEquals(2.910566692924059e11, Math.tan(1048575/2*Math.PI));
+
+// Test Hayne-Panek reduction.
+assertEquals(0.377820109360752e0, Math.sin(Math.pow(2, 120)));
+assertEquals(-0.9258790228548379e0, Math.cos(Math.pow(2, 120)));
+assertEquals(-0.40806638884180424e0, Math.tan(Math.pow(2, 120)));
+assertEquals(-0.377820109360752e0, Math.sin(-Math.pow(2, 120)));
+assertEquals(-0.9258790228548379e0, Math.cos(-Math.pow(2, 120)));
+assertEquals(0.40806638884180424e0, Math.tan(-Math.pow(2, 120)));
diff --git a/deps/v8/test/mjsunit/stack-traces-overflow.js b/deps/v8/test/mjsunit/stack-traces-overflow.js
index 7722e93bd..e20c6091d 100644
--- a/deps/v8/test/mjsunit/stack-traces-overflow.js
+++ b/deps/v8/test/mjsunit/stack-traces-overflow.js
@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --stack-size=100
+
function rec1(a) { rec1(a+1); }
function rec2(a) { rec3(a+1); }
function rec3(a) { rec2(a+1); }
@@ -61,8 +63,8 @@ try {
function testErrorPrototype(prototype) {
var object = {};
object.__proto__ = prototype;
- object.stack = "123";
- assertEquals("123", object.stack);
+ object.stack = "123"; // Overwriting stack property fails.
+ assertEquals(prototype.stack, object.stack);
assertTrue("123" != prototype.stack);
}
@@ -106,11 +108,28 @@ try {
assertEquals(1, e.stack.split('\n').length);
}
+// A limit outside the range of integers.
+Error.stackTraceLimit = 1e12;
+try {
+ rec1(0);
+} catch (e) {
+ assertTrue(e.stack.split('\n').length > 100);
+}
+
+Error.stackTraceLimit = Infinity;
+try {
+ rec1(0);
+} catch (e) {
+ assertTrue(e.stack.split('\n').length > 100);
+}
+
Error.stackTraceLimit = "not a number";
try {
rec1(0);
} catch (e) {
assertEquals(undefined, e.stack);
+ e.stack = "abc";
+ assertEquals("abc", e.stack);
}
Error.stackTraceLimit = 3;
diff --git a/deps/v8/test/mjsunit/stack-traces.js b/deps/v8/test/mjsunit/stack-traces.js
index 46a16eb87..f80a627b2 100644
--- a/deps/v8/test/mjsunit/stack-traces.js
+++ b/deps/v8/test/mjsunit/stack-traces.js
@@ -331,3 +331,23 @@ Error.prepareStackTrace = function() { Error.prepareStackTrace = "custom"; };
new Error().stack;
assertEquals("custom", Error.prepareStackTrace);
+
+// Check that the formatted stack trace can be set to undefined.
+error = new Error();
+error.stack = undefined;
+assertEquals(undefined, error.stack);
+
+// Check that the stack trace accessors are not forcibly set.
+var my_error = {};
+Object.freeze(my_error);
+assertThrows(function() { Error.captureStackTrace(my_error); });
+
+my_error = {};
+Object.preventExtensions(my_error);
+assertThrows(function() { Error.captureStackTrace(my_error); });
+
+var fake_error = {};
+my_error = new Error();
+var stolen_getter = Object.getOwnPropertyDescriptor(my_error, 'stack').get;
+Object.defineProperty(fake_error, 'stack', { get: stolen_getter });
+assertEquals(undefined, fake_error.stack);
diff --git a/deps/v8/test/mjsunit/tools/profviz-test.default b/deps/v8/test/mjsunit/tools/profviz-test.default
index 04185a260..bff249d65 100644
--- a/deps/v8/test/mjsunit/tools/profviz-test.default
+++ b/deps/v8/test/mjsunit/tools/profviz-test.default
@@ -1,5 +1,5 @@
[
- "set yrange [0:24.5]",
+ "set yrange [0:25.5]",
"set xlabel \"execution time in ms\"",
"set xrange [2.4204999999999997:141.1669999999999]",
"set style fill pattern 2 bo 1",
@@ -17,7 +17,7 @@
"set object 6 rect from 57.242999999999974, 7 to 57.329716562499975, 6.766323024054983 fc rgb \"#9944CC\"",
"set object 7 rect from 58.751499999999965, 7 to 58.838216562499966, 6.766323024054983 fc rgb \"#9944CC\"",
"set object 8 rect from 60.72499999999996, 7 to 60.81171656249996, 6.766323024054983 fc rgb \"#9944CC\"",
- "set ytics out nomirror (\"execution (59.6%%)\" 12.5, \"external (0.2%%)\" 13.5, \"compile unopt (3.1%%)\" 14.5, \"recompile sync (6.7%%)\" 15.5, \"recompile async (11.6%%)\" 16.5, \"compile eval (0.0%%)\" 17.5, \"parse (10.0%%)\" 18.5, \"preparse (0.8%%)\" 19.5, \"lazy parse (2.9%%)\" 20.5, \"gc scavenge (1.7%%)\" 21.5, \"gc compaction (3.3%%)\" 22.5, \"gc context (0.0%%)\" 23.5, \"code kind color coding\" 11, \"code kind in execution\" 10, \"top 8 js stack frames\" 9, \"pause times\" 0, \"max deopt size: 9.1 kB\" 7)",
+ "set ytics out nomirror (\"execution (59.6%%)\" 12.5, \"external (0.2%%)\" 13.5, \"compile unopt (3.1%%)\" 14.5, \"recompile sync (6.6%%)\" 15.5, \"recompile async (11.6%%)\" 16.5, \"compile eval (0.0%%)\" 17.5, \"ic miss (0.0%%)\" 18.5, \"parse (9.9%%)\" 19.5, \"preparse (0.6%%)\" 20.5, \"lazy parse (2.9%%)\" 21.5, \"gc scavenge (1.6%%)\" 22.5, \"gc compaction (3.3%%)\" 23.5, \"gc context (0.0%%)\" 24.5, \"code kind color coding\" 11, \"code kind in execution\" 10, \"top 8 js stack frames\" 9, \"pause times\" 0, \"max deopt size: 9.1 kB\" 7)",
"set object 9 rect from 42.11000000000001, 12.83 to 42.28050000000001, 12.17 fc rgb \"#000000\"",
"set object 10 rect from 42.298000000000016, 12.83 to 42.30000000000002, 12.17 fc rgb \"#000000\"",
"set object 11 rect from 42.31450000000002, 12.83 to 42.62700000000002, 12.17 fc rgb \"#000000\"",
@@ -448,232 +448,232 @@
"set object 436 rect from 108.1159999999999, 16.83 to 110.07649999999991, 16.17 fc rgb \"#CC4499\"",
"set object 437 rect from 131.1424999999999, 16.83 to 133.02899999999988, 16.17 fc rgb \"#CC4499\"",
"set object 438 rect from 141.13349999999986, 16.83 to 141.1669999999999, 16.17 fc rgb \"#CC4499\"",
- "set object 439 rect from 22.2675, 18.83 to 22.3815, 18.17 fc rgb \"#00CC00\"",
- "set object 440 rect from 22.665, 18.83 to 23.1135, 18.17 fc rgb \"#00CC00\"",
- "set object 441 rect from 27.951000000000004, 18.83 to 27.972500000000004, 18.17 fc rgb \"#00CC00\"",
- "set object 442 rect from 27.993000000000002, 18.83 to 28.013500000000004, 18.17 fc rgb \"#00CC00\"",
- "set object 443 rect from 28.043000000000003, 18.83 to 28.063500000000005, 18.17 fc rgb \"#00CC00\"",
- "set object 444 rect from 28.085000000000004, 18.83 to 28.087500000000002, 18.17 fc rgb \"#00CC00\"",
- "set object 445 rect from 28.115000000000002, 18.83 to 28.139500000000005, 18.17 fc rgb \"#00CC00\"",
- "set object 446 rect from 28.154000000000007, 18.83 to 28.260000000000005, 18.17 fc rgb \"#00CC00\"",
- "set object 447 rect from 28.309500000000003, 18.83 to 28.374000000000006, 18.17 fc rgb \"#00CC00\"",
- "set object 448 rect from 28.383500000000005, 18.83 to 28.385000000000005, 18.17 fc rgb \"#00CC00\"",
- "set object 449 rect from 28.396500000000003, 18.83 to 28.445000000000007, 18.17 fc rgb \"#00CC00\"",
- "set object 450 rect from 28.459500000000006, 18.83 to 28.463000000000005, 18.17 fc rgb \"#00CC00\"",
- "set object 451 rect from 28.489500000000007, 18.83 to 28.499000000000006, 18.17 fc rgb \"#00CC00\"",
- "set object 452 rect from 28.512500000000006, 18.83 to 28.516000000000005, 18.17 fc rgb \"#00CC00\"",
- "set object 453 rect from 28.529500000000006, 18.83 to 28.533000000000005, 18.17 fc rgb \"#00CC00\"",
- "set object 454 rect from 28.554500000000004, 18.83 to 28.557000000000006, 18.17 fc rgb \"#00CC00\"",
- "set object 455 rect from 28.573500000000006, 18.83 to 28.579000000000008, 18.17 fc rgb \"#00CC00\"",
- "set object 456 rect from 28.59950000000001, 18.83 to 28.602000000000007, 18.17 fc rgb \"#00CC00\"",
- "set object 457 rect from 28.623500000000007, 18.83 to 28.625000000000007, 18.17 fc rgb \"#00CC00\"",
- "set object 458 rect from 28.637500000000006, 18.83 to 28.647000000000006, 18.17 fc rgb \"#00CC00\"",
- "set object 459 rect from 28.657500000000006, 18.83 to 28.669000000000008, 18.17 fc rgb \"#00CC00\"",
- "set object 460 rect from 28.682500000000005, 18.83 to 28.686000000000007, 18.17 fc rgb \"#00CC00\"",
- "set object 461 rect from 28.695500000000006, 18.83 to 28.701000000000008, 18.17 fc rgb \"#00CC00\"",
- "set object 462 rect from 28.72450000000001, 18.83 to 28.811000000000007, 18.17 fc rgb \"#00CC00\"",
- "set object 463 rect from 28.83250000000001, 18.83 to 28.907500000000006, 18.17 fc rgb \"#00CC00\"",
- "set object 464 rect from 28.97100000000001, 18.83 to 28.97450000000001, 18.17 fc rgb \"#00CC00\"",
- "set object 465 rect from 28.99600000000001, 18.83 to 28.99850000000001, 18.17 fc rgb \"#00CC00\"",
- "set object 466 rect from 29.01200000000001, 18.83 to 29.01350000000001, 18.17 fc rgb \"#00CC00\"",
- "set object 467 rect from 29.02600000000001, 18.83 to 29.056500000000007, 18.17 fc rgb \"#00CC00\"",
- "set object 468 rect from 29.06900000000001, 18.83 to 29.159500000000012, 18.17 fc rgb \"#00CC00\"",
- "set object 469 rect from 29.17100000000001, 18.83 to 29.18450000000001, 18.17 fc rgb \"#00CC00\"",
- "set object 470 rect from 29.19400000000001, 18.83 to 41.84850000000001, 18.17 fc rgb \"#00CC00\"",
- "set object 471 rect from 41.87900000000001, 18.83 to 41.88650000000001, 18.17 fc rgb \"#00CC00\"",
- "set object 472 rect from 27.972500000000004, 19.83 to 28.053000000000004, 19.17 fc rgb \"#44CC00\"",
- "set object 473 rect from 28.063500000000005, 19.83 to 28.169000000000004, 19.17 fc rgb \"#44CC00\"",
- "set object 474 rect from 28.260000000000005, 19.83 to 28.489500000000007, 19.17 fc rgb \"#44CC00\"",
- "set object 475 rect from 28.499000000000006, 19.83 to 28.761500000000005, 19.17 fc rgb \"#44CC00\"",
- "set object 476 rect from 28.78900000000001, 19.83 to 28.847500000000007, 19.17 fc rgb \"#44CC00\"",
- "set object 477 rect from 28.907500000000006, 19.83 to 29.047000000000008, 19.17 fc rgb \"#44CC00\"",
- "set object 478 rect from 29.056500000000007, 19.83 to 29.111000000000008, 19.17 fc rgb \"#44CC00\"",
- "set object 479 rect from 29.12350000000001, 19.83 to 29.21900000000001, 19.17 fc rgb \"#44CC00\"",
- "set object 480 rect from 41.82650000000001, 19.83 to 41.83500000000001, 19.17 fc rgb \"#44CC00\"",
- "set object 481 rect from 41.84850000000001, 19.83 to 41.87900000000001, 19.17 fc rgb \"#44CC00\"",
- "set object 482 rect from 16.737, 20.83 to 16.9595, 20.17 fc rgb \"#00CC44\"",
- "set object 483 rect from 17.8715, 20.83 to 18.017000000000003, 20.17 fc rgb \"#00CC44\"",
- "set object 484 rect from 18.992, 20.83 to 19.0685, 20.17 fc rgb \"#00CC44\"",
- "set object 485 rect from 20.52, 20.83 to 20.5975, 20.17 fc rgb \"#00CC44\"",
- "set object 486 rect from 21.109, 20.83 to 21.1335, 20.17 fc rgb \"#00CC44\"",
- "set object 487 rect from 21.212, 20.83 to 21.2695, 20.17 fc rgb \"#00CC44\"",
- "set object 488 rect from 21.4595, 20.83 to 21.49, 20.17 fc rgb \"#00CC44\"",
- "set object 489 rect from 21.566499999999998, 20.83 to 21.588, 20.17 fc rgb \"#00CC44\"",
- "set object 490 rect from 21.6535, 20.83 to 21.727, 20.17 fc rgb \"#00CC44\"",
- "set object 491 rect from 22.445, 20.83 to 22.4625, 20.17 fc rgb \"#00CC44\"",
- "set object 492 rect from 22.502000000000002, 20.83 to 22.5165, 20.17 fc rgb \"#00CC44\"",
- "set object 493 rect from 22.553, 20.83 to 22.5645, 20.17 fc rgb \"#00CC44\"",
- "set object 494 rect from 23.233, 20.83 to 23.336000000000002, 20.17 fc rgb \"#00CC44\"",
- "set object 495 rect from 23.4255, 20.83 to 23.506, 20.17 fc rgb \"#00CC44\"",
- "set object 496 rect from 23.5895, 20.83 to 23.613, 20.17 fc rgb \"#00CC44\"",
- "set object 497 rect from 23.870500000000003, 20.83 to 23.907, 20.17 fc rgb \"#00CC44\"",
- "set object 498 rect from 24.393, 20.83 to 24.430500000000002, 20.17 fc rgb \"#00CC44\"",
- "set object 499 rect from 24.470000000000002, 20.83 to 24.504500000000004, 20.17 fc rgb \"#00CC44\"",
- "set object 500 rect from 25.267500000000002, 20.83 to 25.283, 20.17 fc rgb \"#00CC44\"",
- "set object 501 rect from 25.4195, 20.83 to 25.427, 20.17 fc rgb \"#00CC44\"",
- "set object 502 rect from 25.519500000000004, 20.83 to 25.526000000000003, 20.17 fc rgb \"#00CC44\"",
- "set object 503 rect from 42.28050000000001, 20.83 to 42.298000000000016, 20.17 fc rgb \"#00CC44\"",
- "set object 504 rect from 42.62700000000002, 20.83 to 42.656500000000015, 20.17 fc rgb \"#00CC44\"",
- "set object 505 rect from 42.747000000000014, 20.83 to 42.763500000000015, 20.17 fc rgb \"#00CC44\"",
- "set object 506 rect from 42.80300000000001, 20.83 to 42.81050000000001, 20.17 fc rgb \"#00CC44\"",
- "set object 507 rect from 42.844000000000015, 20.83 to 42.858500000000014, 20.17 fc rgb \"#00CC44\"",
- "set object 508 rect from 43.60550000000001, 20.83 to 43.62000000000002, 20.17 fc rgb \"#00CC44\"",
- "set object 509 rect from 44.796000000000014, 20.83 to 44.81150000000002, 20.17 fc rgb \"#00CC44\"",
- "set object 510 rect from 44.84500000000001, 20.83 to 44.87150000000002, 20.17 fc rgb \"#00CC44\"",
- "set object 511 rect from 44.996000000000016, 20.83 to 45.00850000000001, 20.17 fc rgb \"#00CC44\"",
- "set object 512 rect from 45.04700000000001, 20.83 to 45.06450000000002, 20.17 fc rgb \"#00CC44\"",
- "set object 513 rect from 45.09600000000001, 20.83 to 45.107500000000016, 20.17 fc rgb \"#00CC44\"",
- "set object 514 rect from 45.14400000000002, 20.83 to 45.16150000000002, 20.17 fc rgb \"#00CC44\"",
- "set object 515 rect from 45.32050000000002, 20.83 to 45.33700000000002, 20.17 fc rgb \"#00CC44\"",
- "set object 516 rect from 45.38750000000002, 20.83 to 45.402000000000015, 20.17 fc rgb \"#00CC44\"",
- "set object 517 rect from 45.43250000000002, 20.83 to 45.442000000000014, 20.17 fc rgb \"#00CC44\"",
- "set object 518 rect from 45.46050000000002, 20.83 to 45.46500000000002, 20.17 fc rgb \"#00CC44\"",
- "set object 519 rect from 45.47750000000001, 20.83 to 45.48300000000001, 20.17 fc rgb \"#00CC44\"",
- "set object 520 rect from 45.49750000000001, 20.83 to 45.55900000000001, 20.17 fc rgb \"#00CC44\"",
- "set object 521 rect from 45.66050000000001, 20.83 to 45.70300000000001, 20.17 fc rgb \"#00CC44\"",
- "set object 522 rect from 45.79350000000001, 20.83 to 45.81700000000001, 20.17 fc rgb \"#00CC44\"",
- "set object 523 rect from 45.86950000000001, 20.83 to 45.92300000000001, 20.17 fc rgb \"#00CC44\"",
- "set object 524 rect from 45.99450000000001, 20.83 to 46.060500000000005, 20.17 fc rgb \"#00CC44\"",
- "set object 525 rect from 46.18500000000001, 20.83 to 46.28150000000001, 20.17 fc rgb \"#00CC44\"",
- "set object 526 rect from 46.550000000000004, 20.83 to 46.5915, 20.17 fc rgb \"#00CC44\"",
- "set object 527 rect from 46.65500000000001, 20.83 to 46.691500000000005, 20.17 fc rgb \"#00CC44\"",
- "set object 528 rect from 46.861000000000004, 20.83 to 46.8935, 20.17 fc rgb \"#00CC44\"",
- "set object 529 rect from 47.039500000000004, 20.83 to 47.049, 20.17 fc rgb \"#00CC44\"",
- "set object 530 rect from 47.0765, 20.83 to 47.135000000000005, 20.17 fc rgb \"#00CC44\"",
- "set object 531 rect from 47.4125, 20.83 to 47.465, 20.17 fc rgb \"#00CC44\"",
- "set object 532 rect from 49.454499999999996, 20.83 to 49.467, 20.17 fc rgb \"#00CC44\"",
- "set object 533 rect from 49.6855, 20.83 to 49.726, 20.17 fc rgb \"#00CC44\"",
- "set object 534 rect from 49.799499999999995, 20.83 to 49.812999999999995, 20.17 fc rgb \"#00CC44\"",
- "set object 535 rect from 49.841499999999996, 20.83 to 49.849999999999994, 20.17 fc rgb \"#00CC44\"",
- "set object 536 rect from 49.894499999999994, 20.83 to 49.9695, 20.17 fc rgb \"#00CC44\"",
- "set object 537 rect from 50.083999999999996, 20.83 to 50.14149999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 538 rect from 50.29299999999999, 20.83 to 50.31249999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 539 rect from 50.36699999999999, 20.83 to 50.39849999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 540 rect from 50.520999999999994, 20.83 to 50.528499999999994, 20.17 fc rgb \"#00CC44\"",
- "set object 541 rect from 50.54899999999999, 20.83 to 50.62049999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 542 rect from 51.27549999999999, 20.83 to 51.29099999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 543 rect from 51.52249999999999, 20.83 to 51.56899999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 544 rect from 51.87299999999998, 20.83 to 51.89049999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 545 rect from 52.115999999999985, 20.83 to 52.13449999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 546 rect from 52.286999999999985, 20.83 to 52.300499999999985, 20.17 fc rgb \"#00CC44\"",
- "set object 547 rect from 52.326999999999984, 20.83 to 52.33049999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 548 rect from 52.362999999999985, 20.83 to 52.404499999999985, 20.17 fc rgb \"#00CC44\"",
- "set object 549 rect from 54.566499999999984, 20.83 to 54.64299999999998, 20.17 fc rgb \"#00CC44\"",
- "set object 550 rect from 55.49149999999998, 20.83 to 55.53099999999998, 20.17 fc rgb \"#00CC44\"",
- "set object 551 rect from 56.64049999999998, 20.83 to 56.64999999999998, 20.17 fc rgb \"#00CC44\"",
- "set object 552 rect from 56.750999999999976, 20.83 to 56.76449999999998, 20.17 fc rgb \"#00CC44\"",
- "set object 553 rect from 57.039499999999975, 20.83 to 57.076499999999974, 20.17 fc rgb \"#00CC44\"",
- "set object 554 rect from 57.885999999999974, 20.83 to 57.893499999999975, 20.17 fc rgb \"#00CC44\"",
- "set object 555 rect from 57.97749999999997, 20.83 to 57.99099999999997, 20.17 fc rgb \"#00CC44\"",
- "set object 556 rect from 58.04499999999997, 20.83 to 58.055499999999974, 20.17 fc rgb \"#00CC44\"",
- "set object 557 rect from 58.14549999999997, 20.83 to 58.15399999999997, 20.17 fc rgb \"#00CC44\"",
- "set object 558 rect from 58.17549999999997, 20.83 to 58.18399999999997, 20.17 fc rgb \"#00CC44\"",
- "set object 559 rect from 58.40999999999997, 20.83 to 58.431499999999964, 20.17 fc rgb \"#00CC44\"",
- "set object 560 rect from 58.51699999999997, 20.83 to 58.53049999999997, 20.17 fc rgb \"#00CC44\"",
- "set object 561 rect from 58.590999999999966, 20.83 to 58.60049999999997, 20.17 fc rgb \"#00CC44\"",
- "set object 562 rect from 59.65599999999996, 20.83 to 59.669499999999964, 20.17 fc rgb \"#00CC44\"",
- "set object 563 rect from 60.05149999999996, 20.83 to 60.060999999999964, 20.17 fc rgb \"#00CC44\"",
- "set object 564 rect from 60.176999999999964, 20.83 to 60.19499999999996, 20.17 fc rgb \"#00CC44\"",
- "set object 565 rect from 60.26949999999996, 20.83 to 60.27999999999996, 20.17 fc rgb \"#00CC44\"",
- "set object 566 rect from 60.31149999999996, 20.83 to 60.34699999999996, 20.17 fc rgb \"#00CC44\"",
- "set object 567 rect from 60.471499999999956, 20.83 to 60.48399999999996, 20.17 fc rgb \"#00CC44\"",
- "set object 568 rect from 60.508499999999955, 20.83 to 60.51999999999996, 20.17 fc rgb \"#00CC44\"",
- "set object 569 rect from 60.92099999999996, 20.83 to 60.98249999999996, 20.17 fc rgb \"#00CC44\"",
- "set object 570 rect from 63.15199999999995, 20.83 to 63.228499999999954, 20.17 fc rgb \"#00CC44\"",
- "set object 571 rect from 67.34999999999994, 20.83 to 67.36349999999995, 20.17 fc rgb \"#00CC44\"",
- "set object 572 rect from 67.40699999999995, 20.83 to 67.41249999999995, 20.17 fc rgb \"#00CC44\"",
- "set object 573 rect from 67.45699999999994, 20.83 to 67.46599999999995, 20.17 fc rgb \"#00CC44\"",
- "set object 574 rect from 69.11299999999994, 20.83 to 69.12949999999995, 20.17 fc rgb \"#00CC44\"",
- "set object 575 rect from 69.19199999999995, 20.83 to 69.22649999999994, 20.17 fc rgb \"#00CC44\"",
- "set object 576 rect from 69.30799999999994, 20.83 to 69.31949999999995, 20.17 fc rgb \"#00CC44\"",
- "set object 577 rect from 69.34699999999995, 20.83 to 69.35749999999994, 20.17 fc rgb \"#00CC44\"",
- "set object 578 rect from 69.38399999999996, 20.83 to 69.40549999999995, 20.17 fc rgb \"#00CC44\"",
- "set object 579 rect from 69.45099999999994, 20.83 to 69.46349999999994, 20.17 fc rgb \"#00CC44\"",
- "set object 580 rect from 70.31749999999994, 20.83 to 70.33949999999994, 20.17 fc rgb \"#00CC44\"",
- "set object 581 rect from 74.41449999999995, 20.83 to 74.43899999999994, 20.17 fc rgb \"#00CC44\"",
- "set object 582 rect from 74.52049999999994, 20.83 to 74.54499999999993, 20.17 fc rgb \"#00CC44\"",
- "set object 583 rect from 74.59549999999994, 20.83 to 74.60899999999995, 20.17 fc rgb \"#00CC44\"",
- "set object 584 rect from 84.09999999999994, 20.83 to 84.15349999999994, 20.17 fc rgb \"#00CC44\"",
- "set object 585 rect from 84.26099999999994, 20.83 to 84.27549999999994, 20.17 fc rgb \"#00CC44\"",
- "set object 586 rect from 84.31099999999992, 20.83 to 84.31949999999993, 20.17 fc rgb \"#00CC44\"",
- "set object 587 rect from 84.34199999999993, 20.83 to 84.35349999999993, 20.17 fc rgb \"#00CC44\"",
- "set object 588 rect from 84.37299999999993, 20.83 to 84.40149999999993, 20.17 fc rgb \"#00CC44\"",
- "set object 589 rect from 84.43999999999994, 20.83 to 84.46149999999993, 20.17 fc rgb \"#00CC44\"",
- "set object 590 rect from 84.53049999999993, 20.83 to 84.60099999999994, 20.17 fc rgb \"#00CC44\"",
- "set object 591 rect from 84.68049999999992, 20.83 to 84.69199999999992, 20.17 fc rgb \"#00CC44\"",
- "set object 592 rect from 84.71649999999993, 20.83 to 84.72799999999992, 20.17 fc rgb \"#00CC44\"",
- "set object 593 rect from 84.92199999999994, 20.83 to 84.93849999999993, 20.17 fc rgb \"#00CC44\"",
- "set object 594 rect from 84.99799999999993, 20.83 to 85.01049999999992, 20.17 fc rgb \"#00CC44\"",
- "set object 595 rect from 85.03599999999992, 20.83 to 85.04449999999993, 20.17 fc rgb \"#00CC44\"",
- "set object 596 rect from 85.06199999999993, 20.83 to 85.07249999999993, 20.17 fc rgb \"#00CC44\"",
- "set object 597 rect from 85.09499999999994, 20.83 to 85.10249999999992, 20.17 fc rgb \"#00CC44\"",
- "set object 598 rect from 85.38399999999993, 20.83 to 85.43999999999994, 20.17 fc rgb \"#00CC44\"",
- "set object 599 rect from 85.59949999999992, 20.83 to 85.61599999999993, 20.17 fc rgb \"#00CC44\"",
- "set object 600 rect from 85.63749999999993, 20.83 to 85.65899999999993, 20.17 fc rgb \"#00CC44\"",
- "set object 601 rect from 85.69649999999993, 20.83 to 85.70599999999993, 20.17 fc rgb \"#00CC44\"",
- "set object 602 rect from 85.73249999999993, 20.83 to 85.76899999999992, 20.17 fc rgb \"#00CC44\"",
- "set object 603 rect from 85.86549999999993, 20.83 to 85.87599999999992, 20.17 fc rgb \"#00CC44\"",
- "set object 604 rect from 85.91149999999992, 20.83 to 85.92499999999993, 20.17 fc rgb \"#00CC44\"",
- "set object 605 rect from 102.74599999999992, 20.83 to 102.80749999999992, 20.17 fc rgb \"#00CC44\"",
- "set object 606 rect from 107.5244999999999, 20.83 to 107.57199999999992, 20.17 fc rgb \"#00CC44\"",
- "set object 607 rect from 107.62449999999991, 20.83 to 107.6389999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 608 rect from 107.6674999999999, 20.83 to 107.6759999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 609 rect from 107.69849999999991, 20.83 to 107.70999999999992, 20.17 fc rgb \"#00CC44\"",
- "set object 610 rect from 107.7294999999999, 20.83 to 107.7469999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 611 rect from 107.7834999999999, 20.83 to 107.79299999999992, 20.17 fc rgb \"#00CC44\"",
- "set object 612 rect from 107.82049999999991, 20.83 to 107.8529999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 613 rect from 107.9294999999999, 20.83 to 107.94099999999992, 20.17 fc rgb \"#00CC44\"",
- "set object 614 rect from 107.9654999999999, 20.83 to 107.97599999999991, 20.17 fc rgb \"#00CC44\"",
- "set object 615 rect from 130.5489999999999, 20.83 to 130.5954999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 616 rect from 130.6469999999999, 20.83 to 130.6614999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 617 rect from 130.68999999999988, 20.83 to 130.6994999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 618 rect from 130.7219999999999, 20.83 to 130.7324999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 619 rect from 130.7519999999999, 20.83 to 130.76949999999988, 20.17 fc rgb \"#00CC44\"",
- "set object 620 rect from 130.8059999999999, 20.83 to 130.8154999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 621 rect from 130.84299999999988, 20.83 to 130.87549999999987, 20.17 fc rgb \"#00CC44\"",
- "set object 622 rect from 130.95199999999988, 20.83 to 130.9644999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 623 rect from 130.99099999999987, 20.83 to 131.00249999999988, 20.17 fc rgb \"#00CC44\"",
- "set object 624 rect from 140.86699999999988, 20.83 to 140.8814999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 625 rect from 140.9319999999999, 20.83 to 140.9574999999999, 20.17 fc rgb \"#00CC44\"",
- "set object 626 rect from 141.0299999999999, 20.83 to 141.03849999999989, 20.17 fc rgb \"#00CC44\"",
- "set object 627 rect from 55.79999999999998, 21.83 to 56.198999999999984, 21.17 fc rgb \"#0044CC\"",
- "set object 628 rect from 62.16149999999996, 21.83 to 62.548999999999964, 21.17 fc rgb \"#0044CC\"",
- "set object 629 rect from 65.56449999999995, 21.83 to 65.61699999999995, 21.17 fc rgb \"#0044CC\"",
- "set object 630 rect from 68.70599999999996, 21.83 to 68.76649999999995, 21.17 fc rgb \"#0044CC\"",
- "set object 631 rect from 72.22199999999995, 21.83 to 72.28049999999995, 21.17 fc rgb \"#0044CC\"",
- "set object 632 rect from 75.41849999999994, 21.83 to 75.46799999999995, 21.17 fc rgb \"#0044CC\"",
- "set object 633 rect from 78.16449999999993, 21.83 to 78.23649999999994, 21.17 fc rgb \"#0044CC\"",
- "set object 634 rect from 80.90399999999994, 21.83 to 80.95049999999993, 21.17 fc rgb \"#0044CC\"",
- "set object 635 rect from 83.58349999999993, 21.83 to 83.63999999999993, 21.17 fc rgb \"#0044CC\"",
- "set object 636 rect from 88.75199999999992, 21.83 to 88.82299999999992, 21.17 fc rgb \"#0044CC\"",
- "set object 637 rect from 91.90999999999991, 21.83 to 91.96649999999993, 21.17 fc rgb \"#0044CC\"",
- "set object 638 rect from 94.55599999999993, 21.83 to 94.6054999999999, 21.17 fc rgb \"#0044CC\"",
- "set object 639 rect from 97.20749999999991, 21.83 to 97.26099999999992, 21.17 fc rgb \"#0044CC\"",
- "set object 640 rect from 99.86649999999992, 21.83 to 99.92199999999991, 21.17 fc rgb \"#0044CC\"",
- "set object 641 rect from 102.56049999999992, 21.83 to 102.61199999999991, 21.17 fc rgb \"#0044CC\"",
- "set object 642 rect from 105.88099999999991, 21.83 to 105.93349999999991, 21.17 fc rgb \"#0044CC\"",
- "set object 643 rect from 109.2659999999999, 21.83 to 109.38599999999991, 21.17 fc rgb \"#0044CC\"",
- "set object 644 rect from 109.4024999999999, 21.83 to 109.41799999999989, 21.17 fc rgb \"#0044CC\"",
- "set object 645 rect from 112.6029999999999, 21.83 to 112.6564999999999, 21.17 fc rgb \"#0044CC\"",
- "set object 646 rect from 115.36399999999989, 21.83 to 115.4124999999999, 21.17 fc rgb \"#0044CC\"",
- "set object 647 rect from 118.1434999999999, 21.83 to 118.19199999999991, 21.17 fc rgb \"#0044CC\"",
- "set object 648 rect from 120.9194999999999, 21.83 to 121.0104999999999, 21.17 fc rgb \"#0044CC\"",
- "set object 649 rect from 121.0259999999999, 21.83 to 121.0314999999999, 21.17 fc rgb \"#0044CC\"",
- "set object 650 rect from 123.77499999999989, 21.83 to 123.8254999999999, 21.17 fc rgb \"#0044CC\"",
- "set object 651 rect from 126.55149999999989, 21.83 to 126.59899999999989, 21.17 fc rgb \"#0044CC\"",
- "set object 652 rect from 129.3344999999999, 21.83 to 129.4124999999999, 21.17 fc rgb \"#0044CC\"",
- "set object 653 rect from 129.4249999999999, 21.83 to 129.48849999999987, 21.17 fc rgb \"#0044CC\"",
- "set object 654 rect from 132.8659999999999, 21.83 to 132.92249999999987, 21.17 fc rgb \"#0044CC\"",
- "set object 655 rect from 136.14449999999988, 21.83 to 136.19799999999987, 21.17 fc rgb \"#0044CC\"",
- "set object 656 rect from 138.9289999999999, 21.83 to 138.98049999999986, 21.17 fc rgb \"#0044CC\"",
- "set object 657 rect from 2.4204999999999997, 22.83 to 3.7920000000000003, 22.17 fc rgb \"#4444CC\"",
- "set object 658 rect from 3.8075, 22.83 to 3.8129999999999997, 22.17 fc rgb \"#4444CC\"",
- "set object 659 rect from 6.2695, 22.83 to 7.373, 22.17 fc rgb \"#4444CC\"",
- "set object 660 rect from 7.3865, 22.83 to 7.3919999999999995, 22.17 fc rgb \"#4444CC\"",
- "set object 661 rect from 9.2915, 22.83 to 10.405000000000001, 22.17 fc rgb \"#4444CC\"",
- "set object 662 rect from 10.4235, 22.83 to 10.43, 22.17 fc rgb \"#4444CC\"",
- "set object 663 rect from 12.8765, 22.83 to 13.897, 22.17 fc rgb \"#4444CC\"",
- "set object 664 rect from 13.910499999999999, 22.83 to 13.915999999999999, 22.17 fc rgb \"#4444CC\"",
+ "set object 439 rect from 22.2675, 19.83 to 22.3815, 19.17 fc rgb \"#00CC00\"",
+ "set object 440 rect from 22.665, 19.83 to 23.1135, 19.17 fc rgb \"#00CC00\"",
+ "set object 441 rect from 27.951000000000004, 19.83 to 27.972500000000004, 19.17 fc rgb \"#00CC00\"",
+ "set object 442 rect from 27.993000000000002, 19.83 to 28.013500000000004, 19.17 fc rgb \"#00CC00\"",
+ "set object 443 rect from 28.043000000000003, 19.83 to 28.063500000000005, 19.17 fc rgb \"#00CC00\"",
+ "set object 444 rect from 28.085000000000004, 19.83 to 28.087500000000002, 19.17 fc rgb \"#00CC00\"",
+ "set object 445 rect from 28.115000000000002, 19.83 to 28.139500000000005, 19.17 fc rgb \"#00CC00\"",
+ "set object 446 rect from 28.154000000000007, 19.83 to 28.260000000000005, 19.17 fc rgb \"#00CC00\"",
+ "set object 447 rect from 28.309500000000003, 19.83 to 28.374000000000006, 19.17 fc rgb \"#00CC00\"",
+ "set object 448 rect from 28.383500000000005, 19.83 to 28.385000000000005, 19.17 fc rgb \"#00CC00\"",
+ "set object 449 rect from 28.396500000000003, 19.83 to 28.445000000000007, 19.17 fc rgb \"#00CC00\"",
+ "set object 450 rect from 28.459500000000006, 19.83 to 28.463000000000005, 19.17 fc rgb \"#00CC00\"",
+ "set object 451 rect from 28.489500000000007, 19.83 to 28.499000000000006, 19.17 fc rgb \"#00CC00\"",
+ "set object 452 rect from 28.512500000000006, 19.83 to 28.516000000000005, 19.17 fc rgb \"#00CC00\"",
+ "set object 453 rect from 28.529500000000006, 19.83 to 28.533000000000005, 19.17 fc rgb \"#00CC00\"",
+ "set object 454 rect from 28.554500000000004, 19.83 to 28.557000000000006, 19.17 fc rgb \"#00CC00\"",
+ "set object 455 rect from 28.573500000000006, 19.83 to 28.579000000000008, 19.17 fc rgb \"#00CC00\"",
+ "set object 456 rect from 28.59950000000001, 19.83 to 28.602000000000007, 19.17 fc rgb \"#00CC00\"",
+ "set object 457 rect from 28.623500000000007, 19.83 to 28.625000000000007, 19.17 fc rgb \"#00CC00\"",
+ "set object 458 rect from 28.637500000000006, 19.83 to 28.647000000000006, 19.17 fc rgb \"#00CC00\"",
+ "set object 459 rect from 28.657500000000006, 19.83 to 28.669000000000008, 19.17 fc rgb \"#00CC00\"",
+ "set object 460 rect from 28.682500000000005, 19.83 to 28.686000000000007, 19.17 fc rgb \"#00CC00\"",
+ "set object 461 rect from 28.695500000000006, 19.83 to 28.701000000000008, 19.17 fc rgb \"#00CC00\"",
+ "set object 462 rect from 28.72450000000001, 19.83 to 28.811000000000007, 19.17 fc rgb \"#00CC00\"",
+ "set object 463 rect from 28.83250000000001, 19.83 to 28.907500000000006, 19.17 fc rgb \"#00CC00\"",
+ "set object 464 rect from 28.97100000000001, 19.83 to 28.97450000000001, 19.17 fc rgb \"#00CC00\"",
+ "set object 465 rect from 28.99600000000001, 19.83 to 28.99850000000001, 19.17 fc rgb \"#00CC00\"",
+ "set object 466 rect from 29.01200000000001, 19.83 to 29.01350000000001, 19.17 fc rgb \"#00CC00\"",
+ "set object 467 rect from 29.02600000000001, 19.83 to 29.056500000000007, 19.17 fc rgb \"#00CC00\"",
+ "set object 468 rect from 29.06900000000001, 19.83 to 29.159500000000012, 19.17 fc rgb \"#00CC00\"",
+ "set object 469 rect from 29.17100000000001, 19.83 to 29.18450000000001, 19.17 fc rgb \"#00CC00\"",
+ "set object 470 rect from 29.19400000000001, 19.83 to 41.84850000000001, 19.17 fc rgb \"#00CC00\"",
+ "set object 471 rect from 41.87900000000001, 19.83 to 41.88650000000001, 19.17 fc rgb \"#00CC00\"",
+ "set object 472 rect from 27.972500000000004, 20.83 to 28.053000000000004, 20.17 fc rgb \"#44CC00\"",
+ "set object 473 rect from 28.063500000000005, 20.83 to 28.169000000000004, 20.17 fc rgb \"#44CC00\"",
+ "set object 474 rect from 28.260000000000005, 20.83 to 28.489500000000007, 20.17 fc rgb \"#44CC00\"",
+ "set object 475 rect from 28.499000000000006, 20.83 to 28.761500000000005, 20.17 fc rgb \"#44CC00\"",
+ "set object 476 rect from 28.78900000000001, 20.83 to 28.847500000000007, 20.17 fc rgb \"#44CC00\"",
+ "set object 477 rect from 28.907500000000006, 20.83 to 29.047000000000008, 20.17 fc rgb \"#44CC00\"",
+ "set object 478 rect from 29.056500000000007, 20.83 to 29.111000000000008, 20.17 fc rgb \"#44CC00\"",
+ "set object 479 rect from 29.12350000000001, 20.83 to 29.21900000000001, 20.17 fc rgb \"#44CC00\"",
+ "set object 480 rect from 41.82650000000001, 20.83 to 41.83500000000001, 20.17 fc rgb \"#44CC00\"",
+ "set object 481 rect from 41.84850000000001, 20.83 to 41.87900000000001, 20.17 fc rgb \"#44CC00\"",
+ "set object 482 rect from 16.737, 21.83 to 16.9595, 21.17 fc rgb \"#00CC44\"",
+ "set object 483 rect from 17.8715, 21.83 to 18.017000000000003, 21.17 fc rgb \"#00CC44\"",
+ "set object 484 rect from 18.992, 21.83 to 19.0685, 21.17 fc rgb \"#00CC44\"",
+ "set object 485 rect from 20.52, 21.83 to 20.5975, 21.17 fc rgb \"#00CC44\"",
+ "set object 486 rect from 21.109, 21.83 to 21.1335, 21.17 fc rgb \"#00CC44\"",
+ "set object 487 rect from 21.212, 21.83 to 21.2695, 21.17 fc rgb \"#00CC44\"",
+ "set object 488 rect from 21.4595, 21.83 to 21.49, 21.17 fc rgb \"#00CC44\"",
+ "set object 489 rect from 21.566499999999998, 21.83 to 21.588, 21.17 fc rgb \"#00CC44\"",
+ "set object 490 rect from 21.6535, 21.83 to 21.727, 21.17 fc rgb \"#00CC44\"",
+ "set object 491 rect from 22.445, 21.83 to 22.4625, 21.17 fc rgb \"#00CC44\"",
+ "set object 492 rect from 22.502000000000002, 21.83 to 22.5165, 21.17 fc rgb \"#00CC44\"",
+ "set object 493 rect from 22.553, 21.83 to 22.5645, 21.17 fc rgb \"#00CC44\"",
+ "set object 494 rect from 23.233, 21.83 to 23.336000000000002, 21.17 fc rgb \"#00CC44\"",
+ "set object 495 rect from 23.4255, 21.83 to 23.506, 21.17 fc rgb \"#00CC44\"",
+ "set object 496 rect from 23.5895, 21.83 to 23.613, 21.17 fc rgb \"#00CC44\"",
+ "set object 497 rect from 23.870500000000003, 21.83 to 23.907, 21.17 fc rgb \"#00CC44\"",
+ "set object 498 rect from 24.393, 21.83 to 24.430500000000002, 21.17 fc rgb \"#00CC44\"",
+ "set object 499 rect from 24.470000000000002, 21.83 to 24.504500000000004, 21.17 fc rgb \"#00CC44\"",
+ "set object 500 rect from 25.267500000000002, 21.83 to 25.283, 21.17 fc rgb \"#00CC44\"",
+ "set object 501 rect from 25.4195, 21.83 to 25.427, 21.17 fc rgb \"#00CC44\"",
+ "set object 502 rect from 25.519500000000004, 21.83 to 25.526000000000003, 21.17 fc rgb \"#00CC44\"",
+ "set object 503 rect from 42.28050000000001, 21.83 to 42.298000000000016, 21.17 fc rgb \"#00CC44\"",
+ "set object 504 rect from 42.62700000000002, 21.83 to 42.656500000000015, 21.17 fc rgb \"#00CC44\"",
+ "set object 505 rect from 42.747000000000014, 21.83 to 42.763500000000015, 21.17 fc rgb \"#00CC44\"",
+ "set object 506 rect from 42.80300000000001, 21.83 to 42.81050000000001, 21.17 fc rgb \"#00CC44\"",
+ "set object 507 rect from 42.844000000000015, 21.83 to 42.858500000000014, 21.17 fc rgb \"#00CC44\"",
+ "set object 508 rect from 43.60550000000001, 21.83 to 43.62000000000002, 21.17 fc rgb \"#00CC44\"",
+ "set object 509 rect from 44.796000000000014, 21.83 to 44.81150000000002, 21.17 fc rgb \"#00CC44\"",
+ "set object 510 rect from 44.84500000000001, 21.83 to 44.87150000000002, 21.17 fc rgb \"#00CC44\"",
+ "set object 511 rect from 44.996000000000016, 21.83 to 45.00850000000001, 21.17 fc rgb \"#00CC44\"",
+ "set object 512 rect from 45.04700000000001, 21.83 to 45.06450000000002, 21.17 fc rgb \"#00CC44\"",
+ "set object 513 rect from 45.09600000000001, 21.83 to 45.107500000000016, 21.17 fc rgb \"#00CC44\"",
+ "set object 514 rect from 45.14400000000002, 21.83 to 45.16150000000002, 21.17 fc rgb \"#00CC44\"",
+ "set object 515 rect from 45.32050000000002, 21.83 to 45.33700000000002, 21.17 fc rgb \"#00CC44\"",
+ "set object 516 rect from 45.38750000000002, 21.83 to 45.402000000000015, 21.17 fc rgb \"#00CC44\"",
+ "set object 517 rect from 45.43250000000002, 21.83 to 45.442000000000014, 21.17 fc rgb \"#00CC44\"",
+ "set object 518 rect from 45.46050000000002, 21.83 to 45.46500000000002, 21.17 fc rgb \"#00CC44\"",
+ "set object 519 rect from 45.47750000000001, 21.83 to 45.48300000000001, 21.17 fc rgb \"#00CC44\"",
+ "set object 520 rect from 45.49750000000001, 21.83 to 45.55900000000001, 21.17 fc rgb \"#00CC44\"",
+ "set object 521 rect from 45.66050000000001, 21.83 to 45.70300000000001, 21.17 fc rgb \"#00CC44\"",
+ "set object 522 rect from 45.79350000000001, 21.83 to 45.81700000000001, 21.17 fc rgb \"#00CC44\"",
+ "set object 523 rect from 45.86950000000001, 21.83 to 45.92300000000001, 21.17 fc rgb \"#00CC44\"",
+ "set object 524 rect from 45.99450000000001, 21.83 to 46.060500000000005, 21.17 fc rgb \"#00CC44\"",
+ "set object 525 rect from 46.18500000000001, 21.83 to 46.28150000000001, 21.17 fc rgb \"#00CC44\"",
+ "set object 526 rect from 46.550000000000004, 21.83 to 46.5915, 21.17 fc rgb \"#00CC44\"",
+ "set object 527 rect from 46.65500000000001, 21.83 to 46.691500000000005, 21.17 fc rgb \"#00CC44\"",
+ "set object 528 rect from 46.861000000000004, 21.83 to 46.8935, 21.17 fc rgb \"#00CC44\"",
+ "set object 529 rect from 47.039500000000004, 21.83 to 47.049, 21.17 fc rgb \"#00CC44\"",
+ "set object 530 rect from 47.0765, 21.83 to 47.135000000000005, 21.17 fc rgb \"#00CC44\"",
+ "set object 531 rect from 47.4125, 21.83 to 47.465, 21.17 fc rgb \"#00CC44\"",
+ "set object 532 rect from 49.454499999999996, 21.83 to 49.467, 21.17 fc rgb \"#00CC44\"",
+ "set object 533 rect from 49.6855, 21.83 to 49.726, 21.17 fc rgb \"#00CC44\"",
+ "set object 534 rect from 49.799499999999995, 21.83 to 49.812999999999995, 21.17 fc rgb \"#00CC44\"",
+ "set object 535 rect from 49.841499999999996, 21.83 to 49.849999999999994, 21.17 fc rgb \"#00CC44\"",
+ "set object 536 rect from 49.894499999999994, 21.83 to 49.9695, 21.17 fc rgb \"#00CC44\"",
+ "set object 537 rect from 50.083999999999996, 21.83 to 50.14149999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 538 rect from 50.29299999999999, 21.83 to 50.31249999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 539 rect from 50.36699999999999, 21.83 to 50.39849999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 540 rect from 50.520999999999994, 21.83 to 50.528499999999994, 21.17 fc rgb \"#00CC44\"",
+ "set object 541 rect from 50.54899999999999, 21.83 to 50.62049999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 542 rect from 51.27549999999999, 21.83 to 51.29099999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 543 rect from 51.52249999999999, 21.83 to 51.56899999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 544 rect from 51.87299999999998, 21.83 to 51.89049999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 545 rect from 52.115999999999985, 21.83 to 52.13449999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 546 rect from 52.286999999999985, 21.83 to 52.300499999999985, 21.17 fc rgb \"#00CC44\"",
+ "set object 547 rect from 52.326999999999984, 21.83 to 52.33049999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 548 rect from 52.362999999999985, 21.83 to 52.404499999999985, 21.17 fc rgb \"#00CC44\"",
+ "set object 549 rect from 54.566499999999984, 21.83 to 54.64299999999998, 21.17 fc rgb \"#00CC44\"",
+ "set object 550 rect from 55.49149999999998, 21.83 to 55.53099999999998, 21.17 fc rgb \"#00CC44\"",
+ "set object 551 rect from 56.64049999999998, 21.83 to 56.64999999999998, 21.17 fc rgb \"#00CC44\"",
+ "set object 552 rect from 56.750999999999976, 21.83 to 56.76449999999998, 21.17 fc rgb \"#00CC44\"",
+ "set object 553 rect from 57.039499999999975, 21.83 to 57.076499999999974, 21.17 fc rgb \"#00CC44\"",
+ "set object 554 rect from 57.885999999999974, 21.83 to 57.893499999999975, 21.17 fc rgb \"#00CC44\"",
+ "set object 555 rect from 57.97749999999997, 21.83 to 57.99099999999997, 21.17 fc rgb \"#00CC44\"",
+ "set object 556 rect from 58.04499999999997, 21.83 to 58.055499999999974, 21.17 fc rgb \"#00CC44\"",
+ "set object 557 rect from 58.14549999999997, 21.83 to 58.15399999999997, 21.17 fc rgb \"#00CC44\"",
+ "set object 558 rect from 58.17549999999997, 21.83 to 58.18399999999997, 21.17 fc rgb \"#00CC44\"",
+ "set object 559 rect from 58.40999999999997, 21.83 to 58.431499999999964, 21.17 fc rgb \"#00CC44\"",
+ "set object 560 rect from 58.51699999999997, 21.83 to 58.53049999999997, 21.17 fc rgb \"#00CC44\"",
+ "set object 561 rect from 58.590999999999966, 21.83 to 58.60049999999997, 21.17 fc rgb \"#00CC44\"",
+ "set object 562 rect from 59.65599999999996, 21.83 to 59.669499999999964, 21.17 fc rgb \"#00CC44\"",
+ "set object 563 rect from 60.05149999999996, 21.83 to 60.060999999999964, 21.17 fc rgb \"#00CC44\"",
+ "set object 564 rect from 60.176999999999964, 21.83 to 60.19499999999996, 21.17 fc rgb \"#00CC44\"",
+ "set object 565 rect from 60.26949999999996, 21.83 to 60.27999999999996, 21.17 fc rgb \"#00CC44\"",
+ "set object 566 rect from 60.31149999999996, 21.83 to 60.34699999999996, 21.17 fc rgb \"#00CC44\"",
+ "set object 567 rect from 60.471499999999956, 21.83 to 60.48399999999996, 21.17 fc rgb \"#00CC44\"",
+ "set object 568 rect from 60.508499999999955, 21.83 to 60.51999999999996, 21.17 fc rgb \"#00CC44\"",
+ "set object 569 rect from 60.92099999999996, 21.83 to 60.98249999999996, 21.17 fc rgb \"#00CC44\"",
+ "set object 570 rect from 63.15199999999995, 21.83 to 63.228499999999954, 21.17 fc rgb \"#00CC44\"",
+ "set object 571 rect from 67.34999999999994, 21.83 to 67.36349999999995, 21.17 fc rgb \"#00CC44\"",
+ "set object 572 rect from 67.40699999999995, 21.83 to 67.41249999999995, 21.17 fc rgb \"#00CC44\"",
+ "set object 573 rect from 67.45699999999994, 21.83 to 67.46599999999995, 21.17 fc rgb \"#00CC44\"",
+ "set object 574 rect from 69.11299999999994, 21.83 to 69.12949999999995, 21.17 fc rgb \"#00CC44\"",
+ "set object 575 rect from 69.19199999999995, 21.83 to 69.22649999999994, 21.17 fc rgb \"#00CC44\"",
+ "set object 576 rect from 69.30799999999994, 21.83 to 69.31949999999995, 21.17 fc rgb \"#00CC44\"",
+ "set object 577 rect from 69.34699999999995, 21.83 to 69.35749999999994, 21.17 fc rgb \"#00CC44\"",
+ "set object 578 rect from 69.38399999999996, 21.83 to 69.40549999999995, 21.17 fc rgb \"#00CC44\"",
+ "set object 579 rect from 69.45099999999994, 21.83 to 69.46349999999994, 21.17 fc rgb \"#00CC44\"",
+ "set object 580 rect from 70.31749999999994, 21.83 to 70.33949999999994, 21.17 fc rgb \"#00CC44\"",
+ "set object 581 rect from 74.41449999999995, 21.83 to 74.43899999999994, 21.17 fc rgb \"#00CC44\"",
+ "set object 582 rect from 74.52049999999994, 21.83 to 74.54499999999993, 21.17 fc rgb \"#00CC44\"",
+ "set object 583 rect from 74.59549999999994, 21.83 to 74.60899999999995, 21.17 fc rgb \"#00CC44\"",
+ "set object 584 rect from 84.09999999999994, 21.83 to 84.15349999999994, 21.17 fc rgb \"#00CC44\"",
+ "set object 585 rect from 84.26099999999994, 21.83 to 84.27549999999994, 21.17 fc rgb \"#00CC44\"",
+ "set object 586 rect from 84.31099999999992, 21.83 to 84.31949999999993, 21.17 fc rgb \"#00CC44\"",
+ "set object 587 rect from 84.34199999999993, 21.83 to 84.35349999999993, 21.17 fc rgb \"#00CC44\"",
+ "set object 588 rect from 84.37299999999993, 21.83 to 84.40149999999993, 21.17 fc rgb \"#00CC44\"",
+ "set object 589 rect from 84.43999999999994, 21.83 to 84.46149999999993, 21.17 fc rgb \"#00CC44\"",
+ "set object 590 rect from 84.53049999999993, 21.83 to 84.60099999999994, 21.17 fc rgb \"#00CC44\"",
+ "set object 591 rect from 84.68049999999992, 21.83 to 84.69199999999992, 21.17 fc rgb \"#00CC44\"",
+ "set object 592 rect from 84.71649999999993, 21.83 to 84.72799999999992, 21.17 fc rgb \"#00CC44\"",
+ "set object 593 rect from 84.92199999999994, 21.83 to 84.93849999999993, 21.17 fc rgb \"#00CC44\"",
+ "set object 594 rect from 84.99799999999993, 21.83 to 85.01049999999992, 21.17 fc rgb \"#00CC44\"",
+ "set object 595 rect from 85.03599999999992, 21.83 to 85.04449999999993, 21.17 fc rgb \"#00CC44\"",
+ "set object 596 rect from 85.06199999999993, 21.83 to 85.07249999999993, 21.17 fc rgb \"#00CC44\"",
+ "set object 597 rect from 85.09499999999994, 21.83 to 85.10249999999992, 21.17 fc rgb \"#00CC44\"",
+ "set object 598 rect from 85.38399999999993, 21.83 to 85.43999999999994, 21.17 fc rgb \"#00CC44\"",
+ "set object 599 rect from 85.59949999999992, 21.83 to 85.61599999999993, 21.17 fc rgb \"#00CC44\"",
+ "set object 600 rect from 85.63749999999993, 21.83 to 85.65899999999993, 21.17 fc rgb \"#00CC44\"",
+ "set object 601 rect from 85.69649999999993, 21.83 to 85.70599999999993, 21.17 fc rgb \"#00CC44\"",
+ "set object 602 rect from 85.73249999999993, 21.83 to 85.76899999999992, 21.17 fc rgb \"#00CC44\"",
+ "set object 603 rect from 85.86549999999993, 21.83 to 85.87599999999992, 21.17 fc rgb \"#00CC44\"",
+ "set object 604 rect from 85.91149999999992, 21.83 to 85.92499999999993, 21.17 fc rgb \"#00CC44\"",
+ "set object 605 rect from 102.74599999999992, 21.83 to 102.80749999999992, 21.17 fc rgb \"#00CC44\"",
+ "set object 606 rect from 107.5244999999999, 21.83 to 107.57199999999992, 21.17 fc rgb \"#00CC44\"",
+ "set object 607 rect from 107.62449999999991, 21.83 to 107.6389999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 608 rect from 107.6674999999999, 21.83 to 107.6759999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 609 rect from 107.69849999999991, 21.83 to 107.70999999999992, 21.17 fc rgb \"#00CC44\"",
+ "set object 610 rect from 107.7294999999999, 21.83 to 107.7469999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 611 rect from 107.7834999999999, 21.83 to 107.79299999999992, 21.17 fc rgb \"#00CC44\"",
+ "set object 612 rect from 107.82049999999991, 21.83 to 107.8529999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 613 rect from 107.9294999999999, 21.83 to 107.94099999999992, 21.17 fc rgb \"#00CC44\"",
+ "set object 614 rect from 107.9654999999999, 21.83 to 107.97599999999991, 21.17 fc rgb \"#00CC44\"",
+ "set object 615 rect from 130.5489999999999, 21.83 to 130.5954999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 616 rect from 130.6469999999999, 21.83 to 130.6614999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 617 rect from 130.68999999999988, 21.83 to 130.6994999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 618 rect from 130.7219999999999, 21.83 to 130.7324999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 619 rect from 130.7519999999999, 21.83 to 130.76949999999988, 21.17 fc rgb \"#00CC44\"",
+ "set object 620 rect from 130.8059999999999, 21.83 to 130.8154999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 621 rect from 130.84299999999988, 21.83 to 130.87549999999987, 21.17 fc rgb \"#00CC44\"",
+ "set object 622 rect from 130.95199999999988, 21.83 to 130.9644999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 623 rect from 130.99099999999987, 21.83 to 131.00249999999988, 21.17 fc rgb \"#00CC44\"",
+ "set object 624 rect from 140.86699999999988, 21.83 to 140.8814999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 625 rect from 140.9319999999999, 21.83 to 140.9574999999999, 21.17 fc rgb \"#00CC44\"",
+ "set object 626 rect from 141.0299999999999, 21.83 to 141.03849999999989, 21.17 fc rgb \"#00CC44\"",
+ "set object 627 rect from 55.79999999999998, 22.83 to 56.198999999999984, 22.17 fc rgb \"#0044CC\"",
+ "set object 628 rect from 62.16149999999996, 22.83 to 62.548999999999964, 22.17 fc rgb \"#0044CC\"",
+ "set object 629 rect from 65.56449999999995, 22.83 to 65.61699999999995, 22.17 fc rgb \"#0044CC\"",
+ "set object 630 rect from 68.70599999999996, 22.83 to 68.76649999999995, 22.17 fc rgb \"#0044CC\"",
+ "set object 631 rect from 72.22199999999995, 22.83 to 72.28049999999995, 22.17 fc rgb \"#0044CC\"",
+ "set object 632 rect from 75.41849999999994, 22.83 to 75.46799999999995, 22.17 fc rgb \"#0044CC\"",
+ "set object 633 rect from 78.16449999999993, 22.83 to 78.23649999999994, 22.17 fc rgb \"#0044CC\"",
+ "set object 634 rect from 80.90399999999994, 22.83 to 80.95049999999993, 22.17 fc rgb \"#0044CC\"",
+ "set object 635 rect from 83.58349999999993, 22.83 to 83.63999999999993, 22.17 fc rgb \"#0044CC\"",
+ "set object 636 rect from 88.75199999999992, 22.83 to 88.82299999999992, 22.17 fc rgb \"#0044CC\"",
+ "set object 637 rect from 91.90999999999991, 22.83 to 91.96649999999993, 22.17 fc rgb \"#0044CC\"",
+ "set object 638 rect from 94.55599999999993, 22.83 to 94.6054999999999, 22.17 fc rgb \"#0044CC\"",
+ "set object 639 rect from 97.20749999999991, 22.83 to 97.26099999999992, 22.17 fc rgb \"#0044CC\"",
+ "set object 640 rect from 99.86649999999992, 22.83 to 99.92199999999991, 22.17 fc rgb \"#0044CC\"",
+ "set object 641 rect from 102.56049999999992, 22.83 to 102.61199999999991, 22.17 fc rgb \"#0044CC\"",
+ "set object 642 rect from 105.88099999999991, 22.83 to 105.93349999999991, 22.17 fc rgb \"#0044CC\"",
+ "set object 643 rect from 109.2659999999999, 22.83 to 109.38599999999991, 22.17 fc rgb \"#0044CC\"",
+ "set object 644 rect from 109.4024999999999, 22.83 to 109.41799999999989, 22.17 fc rgb \"#0044CC\"",
+ "set object 645 rect from 112.6029999999999, 22.83 to 112.6564999999999, 22.17 fc rgb \"#0044CC\"",
+ "set object 646 rect from 115.36399999999989, 22.83 to 115.4124999999999, 22.17 fc rgb \"#0044CC\"",
+ "set object 647 rect from 118.1434999999999, 22.83 to 118.19199999999991, 22.17 fc rgb \"#0044CC\"",
+ "set object 648 rect from 120.9194999999999, 22.83 to 121.0104999999999, 22.17 fc rgb \"#0044CC\"",
+ "set object 649 rect from 121.0259999999999, 22.83 to 121.0314999999999, 22.17 fc rgb \"#0044CC\"",
+ "set object 650 rect from 123.77499999999989, 22.83 to 123.8254999999999, 22.17 fc rgb \"#0044CC\"",
+ "set object 651 rect from 126.55149999999989, 22.83 to 126.59899999999989, 22.17 fc rgb \"#0044CC\"",
+ "set object 652 rect from 129.3344999999999, 22.83 to 129.4124999999999, 22.17 fc rgb \"#0044CC\"",
+ "set object 653 rect from 129.4249999999999, 22.83 to 129.48849999999987, 22.17 fc rgb \"#0044CC\"",
+ "set object 654 rect from 132.8659999999999, 22.83 to 132.92249999999987, 22.17 fc rgb \"#0044CC\"",
+ "set object 655 rect from 136.14449999999988, 22.83 to 136.19799999999987, 22.17 fc rgb \"#0044CC\"",
+ "set object 656 rect from 138.9289999999999, 22.83 to 138.98049999999986, 22.17 fc rgb \"#0044CC\"",
+ "set object 657 rect from 2.4204999999999997, 23.83 to 3.7920000000000003, 23.17 fc rgb \"#4444CC\"",
+ "set object 658 rect from 3.8075, 23.83 to 3.8129999999999997, 23.17 fc rgb \"#4444CC\"",
+ "set object 659 rect from 6.2695, 23.83 to 7.373, 23.17 fc rgb \"#4444CC\"",
+ "set object 660 rect from 7.3865, 23.83 to 7.3919999999999995, 23.17 fc rgb \"#4444CC\"",
+ "set object 661 rect from 9.2915, 23.83 to 10.405000000000001, 23.17 fc rgb \"#4444CC\"",
+ "set object 662 rect from 10.4235, 23.83 to 10.43, 23.17 fc rgb \"#4444CC\"",
+ "set object 663 rect from 12.8765, 23.83 to 13.897, 23.17 fc rgb \"#4444CC\"",
+ "set object 664 rect from 13.910499999999999, 23.83 to 13.915999999999999, 23.17 fc rgb \"#4444CC\"",
"set object 665 rect from 18.803, 10.2 to 19.803, 9.8 fc rgb \"#000000\"",
"set object 666 rect from 19.8815, 10.2 to 20.8815, 9.8 fc rgb \"#000000\"",
"set object 667 rect from 20.910999999999998, 10.2 to 21.910999999999998, 9.8 fc rgb \"#000000\"",
@@ -1371,7 +1371,7 @@
"set label \"1 ms\" at 14.3305828125,1 font \"Helvetica,7'\"",
"set label \"0 ms\" at 18.204082812499998,1 font \"Helvetica,7'\"",
"set label \"0 ms\" at 85.27908281249994,1 font \"Helvetica,7'\"",
- "set y2range [0:59.54259090909095]",
+ "set y2range [0:62.076318181818216]",
"plot '-' using 1:2 axes x1y2 with impulses ls 1",
"41.88650000000001 13.935500000000008",
"3.7920000000000003 1.3375000000000004",
@@ -1563,4 +1563,4 @@
"# start: 2.4204999999999997",
"# end: 141.1669999999999",
"# objects: 1547"
-]
+] \ No newline at end of file
diff --git a/deps/v8/test/mjsunit/tools/tickprocessor-test.default b/deps/v8/test/mjsunit/tools/tickprocessor-test.default
index 702f4bcae..3e01532ac 100644
--- a/deps/v8/test/mjsunit/tools/tickprocessor-test.default
+++ b/deps/v8/test/mjsunit/tools/tickprocessor-test.default
@@ -1,13 +1,9 @@
Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0 excluded).
- [Unknown]:
- ticks total nonlib name
- 2 15.4%
-
[Shared libraries]:
ticks total nonlib name
- 3 23.1% 0.0% /lib32/libm-2.7.so
- 1 7.7% 0.0% ffffe000-fffff000
+ 3 23.1% /lib32/libm-2.7.so
+ 1 7.7% ffffe000-fffff000
[JavaScript]:
ticks total nonlib name
@@ -16,13 +12,17 @@ Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0 excluded).
[C++]:
ticks total nonlib name
2 15.4% 22.2% v8::internal::Runtime_Math_exp(v8::internal::Arguments)
- 1 7.7% 11.1% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+ 1 7.7% 11.1% v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
1 7.7% 11.1% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
1 7.7% 11.1% exp
- [GC]:
+ [Summary]:
ticks total nonlib name
- 0 0.0%
+ 1 7.7% 11.1% JavaScript
+ 5 38.5% 55.6% C++
+ 0 0.0% 0.0% GC
+ 4 30.8% Shared libraries
+ 2 15.4% Unaccounted
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
@@ -38,7 +38,7 @@ Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0 excluded).
2 100.0% LazyCompile: exp native math.js:41
2 100.0% Script: exp.js
- 1 7.7% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+ 1 7.7% v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
1 100.0% Script: exp.js
1 7.7% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
diff --git a/deps/v8/test/mjsunit/tools/tickprocessor-test.func-info b/deps/v8/test/mjsunit/tools/tickprocessor-test.func-info
index a66b90f4c..c93b6ec70 100644
--- a/deps/v8/test/mjsunit/tools/tickprocessor-test.func-info
+++ b/deps/v8/test/mjsunit/tools/tickprocessor-test.func-info
@@ -11,9 +11,12 @@ Statistical profiling result from v8.log, (3 ticks, 0 unaccounted, 0 excluded).
[C++]:
ticks total nonlib name
- [GC]:
+ [Summary]:
ticks total nonlib name
- 0 0.0%
+ 3 100.0% 100.0% JavaScript
+ 0 0.0% 0.0% C++
+ 0 0.0% 0.0% GC
+ 0 0.0% Shared libraries
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
diff --git a/deps/v8/test/mjsunit/tools/tickprocessor-test.gc-state b/deps/v8/test/mjsunit/tools/tickprocessor-test.gc-state
index 40f90db4f..6b1a6a3b3 100644
--- a/deps/v8/test/mjsunit/tools/tickprocessor-test.gc-state
+++ b/deps/v8/test/mjsunit/tools/tickprocessor-test.gc-state
@@ -9,9 +9,12 @@ Statistical profiling result from v8.log, (13 ticks, 0 unaccounted, 13 excluded)
[C++]:
ticks total nonlib name
- [GC]:
+ [Summary]:
ticks total nonlib name
- 0 0.0%
+ 0 0.0% 0.0% JavaScript
+ 0 0.0% 0.0% C++
+ 0 0.0% 0.0% GC
+ 0 0.0% Shared libraries
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
diff --git a/deps/v8/test/mjsunit/tools/tickprocessor-test.ignore-unknown b/deps/v8/test/mjsunit/tools/tickprocessor-test.ignore-unknown
index 306d646c1..de70527f9 100644
--- a/deps/v8/test/mjsunit/tools/tickprocessor-test.ignore-unknown
+++ b/deps/v8/test/mjsunit/tools/tickprocessor-test.ignore-unknown
@@ -2,8 +2,8 @@ Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0 excluded).
[Shared libraries]:
ticks total nonlib name
- 3 27.3% 0.0% /lib32/libm-2.7.so
- 1 9.1% 0.0% ffffe000-fffff000
+ 3 27.3% /lib32/libm-2.7.so
+ 1 9.1% ffffe000-fffff000
[JavaScript]:
ticks total nonlib name
@@ -12,13 +12,16 @@ Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0 excluded).
[C++]:
ticks total nonlib name
2 18.2% 28.6% v8::internal::Runtime_Math_exp(v8::internal::Arguments)
- 1 9.1% 14.3% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+ 1 9.1% 14.3% v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
1 9.1% 14.3% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
1 9.1% 14.3% exp
- [GC]:
+ [Summary]:
ticks total nonlib name
- 0 0.0%
+ 1 9.1% 14.3% JavaScript
+ 5 45.5% 71.4% C++
+ 0 0.0% 0.0% GC
+ 4 36.4% Shared libraries
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
@@ -34,7 +37,7 @@ Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0 excluded).
2 100.0% LazyCompile: exp native math.js:41
2 100.0% Script: exp.js
- 1 9.1% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+ 1 9.1% v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
1 100.0% Script: exp.js
1 9.1% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
diff --git a/deps/v8/test/mjsunit/tools/tickprocessor-test.separate-ic b/deps/v8/test/mjsunit/tools/tickprocessor-test.separate-ic
index 3a2041b52..119ccbe71 100644
--- a/deps/v8/test/mjsunit/tools/tickprocessor-test.separate-ic
+++ b/deps/v8/test/mjsunit/tools/tickprocessor-test.separate-ic
@@ -1,13 +1,9 @@
Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0 excluded).
- [Unknown]:
- ticks total nonlib name
- 2 15.4%
-
[Shared libraries]:
ticks total nonlib name
- 3 23.1% 0.0% /lib32/libm-2.7.so
- 1 7.7% 0.0% ffffe000-fffff000
+ 3 23.1% /lib32/libm-2.7.so
+ 1 7.7% ffffe000-fffff000
[JavaScript]:
ticks total nonlib name
@@ -18,13 +14,17 @@ Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0 excluded).
[C++]:
ticks total nonlib name
2 15.4% 22.2% v8::internal::Runtime_Math_exp(v8::internal::Arguments)
- 1 7.7% 11.1% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+ 1 7.7% 11.1% v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
1 7.7% 11.1% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
1 7.7% 11.1% exp
- [GC]:
+ [Summary]:
ticks total nonlib name
- 0 0.0%
+ 3 23.1% 33.3% JavaScript
+ 5 38.5% 55.6% C++
+ 0 0.0% 0.0% GC
+ 4 30.8% Shared libraries
+ 2 15.4% Unaccounted
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
@@ -40,7 +40,7 @@ Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0 excluded).
2 100.0% LazyCompile: exp native math.js:41
2 100.0% Script: exp.js
- 1 7.7% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+ 1 7.7% v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
1 100.0% Script: exp.js
1 7.7% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
diff --git a/deps/v8/test/mjsunit/tools/tickprocessor.js b/deps/v8/test/mjsunit/tools/tickprocessor.js
index 626929de1..f460d349b 100644
--- a/deps/v8/test/mjsunit/tools/tickprocessor.js
+++ b/deps/v8/test/mjsunit/tools/tickprocessor.js
@@ -25,10 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// This test case is not compatible with optimization stress because the
-// generated profile will look vastly different when more is optimized.
-// Flags: --nostress-opt --noalways-opt
-
// Load implementations from <project root>/tools.
// Files: tools/splaytree.js tools/codemap.js tools/csvparser.js
// Files: tools/consarray.js tools/profile.js tools/profile_view.js
@@ -311,7 +307,7 @@ CppEntriesProviderMock.prototype.parseVmSymbols = function(
name, startAddr, endAddr, symbolAdder) {
var symbols = {
'shell':
- [['v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)', 0x080f8800, 0x080f8d90],
+ [['v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)', 0x080f8800, 0x080f8d90],
['v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)', 0x080f8210, 0x080f8800],
['v8::internal::Runtime_Math_exp(v8::internal::Arguments)', 0x08123b20, 0x08123b80]],
'/lib32/libm-2.7.so':
diff --git a/deps/v8/test/mjsunit/value-wrapper-accessor.js b/deps/v8/test/mjsunit/value-wrapper-accessor.js
index f95145652..79db40712 100644
--- a/deps/v8/test/mjsunit/value-wrapper-accessor.js
+++ b/deps/v8/test/mjsunit/value-wrapper-accessor.js
@@ -77,20 +77,14 @@ function test(object, prototype) {
%OptimizeFunctionOnNextCall(nonstrict);
result = undefined;
nonstrict(object);
- // TODO(1475): Support storing to primitive values.
- // This should return "object" once storing to primitive values is
- // supported.
- assertEquals("undefined", typeof result);
+ assertEquals("object", typeof result);
strict(object);
strict(object);
%OptimizeFunctionOnNextCall(strict);
result = undefined;
strict(object);
- // TODO(1475): Support storing to primitive values.
- // This should return "object" once storing to primitive values is
- // supported.
- assertEquals("undefined", typeof result);
+ assertEquals(object, result);
})();
}
diff --git a/deps/v8/test/mjsunit/with-readonly.js b/deps/v8/test/mjsunit/with-readonly.js
index 29982b347..43583348e 100644
--- a/deps/v8/test/mjsunit/with-readonly.js
+++ b/deps/v8/test/mjsunit/with-readonly.js
@@ -27,8 +27,6 @@
// Test that readonly variables are treated correctly.
-// Flags: --es5_readonly
-
// Create an object with a read-only length property in the prototype
// chain by putting the string split function in the prototype chain.
var o = {};
diff --git a/deps/v8/test/mozilla/mozilla.status b/deps/v8/test/mozilla/mozilla.status
index c04412ae9..5662ee414 100644
--- a/deps/v8/test/mozilla/mozilla.status
+++ b/deps/v8/test/mozilla/mozilla.status
@@ -51,6 +51,19 @@
'ecma_3/Number/15.7.4.3-02': [PASS, FAIL],
'ecma_3/Date/15.9.5.5-02': [PASS, FAIL],
+ ################## TURBO-FAN FAILURES ###################
+
+ # TODO(turbofan): These are all covered by mjsunit as well. Enable them once
+ # we pass 'mjsunit' and 'webkit' with TurboFan.
+ 'js1_4/Functions/function-001': [PASS, NO_VARIANTS],
+ 'js1_5/Regress/regress-104077': [PASS, NO_VARIANTS],
+ 'js1_5/Regress/regress-396684': [PASS, NO_VARIANTS],
+ 'js1_5/Regress/regress-80981': [PASS, NO_VARIANTS],
+
+ # TODO(turbofan): Large switch statements crash.
+ 'js1_5/Regress/regress-366601': [PASS, NO_VARIANTS],
+ 'js1_5/Regress/regress-398085-01': [PASS, NO_VARIANTS],
+
##################### SKIPPED TESTS #####################
# This test checks that we behave properly in an out-of-memory
@@ -113,7 +126,7 @@
'js1_5/Regress/regress-360969-04': [PASS, ['mode == debug', TIMEOUT, NO_VARIANTS]],
'js1_5/Regress/regress-360969-05': [PASS, ['mode == debug', TIMEOUT, NO_VARIANTS]],
'js1_5/Regress/regress-360969-06': [PASS, ['mode == debug', TIMEOUT, NO_VARIANTS]],
- 'js1_5/extensions/regress-365527': [PASS, ['mode == debug', TIMEOUT, NO_VARIANTS]],
+ 'js1_5/extensions/regress-365527': [PASS, SLOW, ['mode == debug', TIMEOUT, NO_VARIANTS]],
'js1_5/Regress/regress-280769-3': [PASS, ['mode == debug', FAIL]],
'js1_5/Regress/regress-203278-1': [PASS, ['mode == debug', FAIL]],
@@ -170,7 +183,7 @@
'js1_5/String/regress-56940-02': [PASS, FAIL],
'js1_5/String/regress-157334-01': [PASS, FAIL],
'js1_5/String/regress-322772': [PASS, FAIL],
- 'js1_5/Array/regress-99120-01': [PASS, FAIL],
+ 'js1_5/Array/regress-99120-01': [PASS, FAIL, NO_VARIANTS],
'js1_5/Array/regress-99120-02': [PASS, FAIL],
'js1_5/Regress/regress-347306-01': [PASS, FAIL],
'js1_5/Regress/regress-416628': [PASS, FAIL, ['mode == debug', TIMEOUT, NO_VARIANTS]],
@@ -642,10 +655,6 @@
# We do not correctly handle assignments within "with"
'ecma_3/Statements/12.10-01': [FAIL],
- # We do not throw an exception when a const is redeclared.
- # (We only fail section 1 of the test.)
- 'js1_5/Regress/regress-103602': [FAIL],
-
##################### MOZILLA EXTENSION TESTS #####################
'ecma/extensions/15.1.2.1-1': [FAIL_OK],
@@ -718,6 +727,13 @@
'js1_5/extensions/regress-361964': [FAIL_OK],
'js1_5/extensions/regress-363988': [FAIL_OK],
'js1_5/extensions/regress-365869': [FAIL_OK],
+
+ # Uses non ES5 compatible syntax for setter
+ 'js1_5/extensions/regress-367501-01': [FAIL_OK],
+ 'js1_5/extensions/regress-367501-02': [FAIL_OK],
+ 'js1_5/extensions/regress-367501-03': [FAIL_OK],
+ 'js1_5/extensions/regress-367501-04': [FAIL_OK],
+
'js1_5/extensions/regress-367630': [FAIL_OK],
'js1_5/extensions/regress-367923': [FAIL_OK],
'js1_5/extensions/regress-368859': [FAIL_OK],
@@ -843,7 +859,6 @@
'js1_5/Regress/regress-404755': [SKIP],
'js1_5/Regress/regress-451322': [SKIP],
-
# BUG(1040): Allow this test to timeout.
'js1_5/GC/regress-203278-2': [PASS, TIMEOUT, NO_VARIANTS],
}], # 'arch == arm or arch == arm64'
@@ -852,10 +867,13 @@
['arch == arm64', {
# BUG(v8:3152): Runs out of stack in debug mode.
'js1_5/extensions/regress-355497': [FAIL_OK, ['mode == debug', SKIP]],
+
+ # BUG(v8:3503): Times out in debug mode.
+ 'js1_5/Regress/regress-280769-2': [PASS, FAIL, ['mode == debug', SKIP]],
}], # 'arch == arm64'
-['arch == mipsel', {
+['arch == mipsel or arch == mips64el', {
# BUG(3251229): Times out when running new crankshaft test script.
'ecma_3/RegExp/regress-311414': [SKIP],
@@ -872,7 +890,7 @@
# BUG(1040): Allow this test to timeout.
'js1_5/GC/regress-203278-2': [PASS, TIMEOUT, NO_VARIANTS],
-}], # 'arch == mipsel'
+}], # 'arch == mipsel or arch == mips64el'
['arch == mips', {
diff --git a/deps/v8/test/preparser/duplicate-property.pyt b/deps/v8/test/preparser/duplicate-property.pyt
index 5abf9adbc..594b4786c 100644
--- a/deps/v8/test/preparser/duplicate-property.pyt
+++ b/deps/v8/test/preparser/duplicate-property.pyt
@@ -81,7 +81,7 @@ def PropertyTest(name, propa, propb, allow_strict = True):
""", replacement, None)
StrictTest("$name-nested-set", """
- var o = {set $id1(){}, o: {set $id2(){} } };
+ var o = {set $id1(v){}, o: {set $id2(v){} } };
""", replacement, None)
diff --git a/deps/v8/test/promises-aplus/testcfg.py b/deps/v8/test/promises-aplus/testcfg.py
index a5995a361..bd0337918 100644
--- a/deps/v8/test/promises-aplus/testcfg.py
+++ b/deps/v8/test/promises-aplus/testcfg.py
@@ -31,9 +31,9 @@ import os
import shutil
import sys
import tarfile
-import urllib
from testrunner.local import testsuite
+from testrunner.local import utils
from testrunner.objects import testcase
@@ -102,7 +102,7 @@ class PromiseAplusTestSuite(testsuite.TestSuite):
directory = os.path.join(self.root, TEST_NAME)
if not os.path.exists(archive):
print('Downloading {0} from {1} ...'.format(TEST_NAME, TEST_URL))
- urllib.urlretrieve(TEST_URL, archive)
+ utils.URLRetrieve(TEST_URL, archive)
if os.path.exists(directory):
shutil.rmtree(directory)
@@ -129,7 +129,7 @@ class PromiseAplusTestSuite(testsuite.TestSuite):
os.mkdir(directory)
path = os.path.join(directory, SINON_FILENAME)
if not os.path.exists(path):
- urllib.urlretrieve(SINON_URL, path)
+ utils.URLRetrieve(SINON_URL, path)
hash = hashlib.sha256()
with open(path, 'rb') as f:
for chunk in iter(lambda: f.read(8192), ''):
diff --git a/deps/v8/test/test262/test262.status b/deps/v8/test/test262/test262.status
index 247bd5cb6..dd075d968 100644
--- a/deps/v8/test/test262/test262.status
+++ b/deps/v8/test/test262/test262.status
@@ -31,6 +31,13 @@
'15.5.4.9_CE': [['no_i18n', SKIP]],
+ # TODO(turbofan): Timeouts on TurboFan need investigation.
+ '10.1.1_13': [PASS, NO_VARIANTS],
+
+ # BUG(v8:3455)
+ '11.2.3_b': [FAIL],
+ '12.2.3_b': [FAIL],
+
######################## NEEDS INVESTIGATION ###########################
# These test failures are specific to the intl402 suite and need investigation
@@ -38,10 +45,9 @@
# incompatibilities if the test cases turn out to be broken or ambiguous.
'6.2.3': [FAIL],
'9.2.1_2': [FAIL],
- '9.2.5_11_g_ii_2': [FAIL],
'9.2.6_2': [FAIL],
'10.1.1_a': [FAIL],
- '10.1.1_19_c': [PASS, FAIL],
+ '10.1.1_19_c': [PASS, FAIL, NO_VARIANTS],
'10.1.2.1_4': [FAIL],
'10.2.3_b': [PASS, FAIL],
'10.3_a': [FAIL],
@@ -52,7 +58,6 @@
'11.1.2.1_4': [FAIL],
'11.3.2_FN_2': [PASS, FAIL],
'11.3.2_TRF': [PASS, FAIL],
- '11.3.2_TRP': [FAIL],
'11.3_a': [FAIL],
'12.1.1_a': [FAIL],
'12.1.2.1_4': [FAIL],
@@ -63,14 +68,7 @@
##################### DELIBERATE INCOMPATIBILITIES #####################
- # This tests precision of Math functions. The implementation for those
- # trigonometric functions are platform/compiler dependent. Furthermore, the
- # expectation values by far deviates from the actual result given by an
- # arbitrary-precision calculator, making those tests partly bogus.
- 'S15.8.2.7_A7': [PASS, FAIL_OK], # Math.cos
'S15.8.2.8_A6': [PASS, FAIL_OK], # Math.exp (less precise with --fast-math)
- 'S15.8.2.16_A7': [PASS, FAIL_OK], # Math.sin
- 'S15.8.2.18_A7': [PASS, FAIL_OK], # Math.tan
# Linux for ia32 (and therefore simulators) default to extended 80 bit
# floating point formats, so these tests checking 64-bit FP precision fail.
@@ -99,7 +97,12 @@
'S15.1.3.2_A2.5_T1': [PASS, ['mode == debug', SKIP]],
}], # ALWAYS
-['arch == arm or arch == mipsel or arch == mips or arch == arm64', {
+['system == macos', {
+ '11.3.2_TRP': [FAIL],
+ '9.2.5_11_g_ii_2': [FAIL],
+}], # system == macos
+
+['arch == arm or arch == mipsel or arch == mips or arch == arm64 or arch == mips64el', {
# TODO(mstarzinger): Causes stack overflow on simulators due to eager
# compilation of parenthesized function literals. Needs investigation.
diff --git a/deps/v8/test/test262/testcfg.py b/deps/v8/test/test262/testcfg.py
index 8e129d314..de3c9ad7b 100644
--- a/deps/v8/test/test262/testcfg.py
+++ b/deps/v8/test/test262/testcfg.py
@@ -31,9 +31,9 @@ import os
import shutil
import sys
import tarfile
-import urllib
from testrunner.local import testsuite
+from testrunner.local import utils
from testrunner.objects import testcase
@@ -97,7 +97,7 @@ class Test262TestSuite(testsuite.TestSuite):
directory_old_name = os.path.join(self.root, "data.old")
if not os.path.exists(archive_name):
print "Downloading test data from %s ..." % archive_url
- urllib.urlretrieve(archive_url, archive_name)
+ utils.URLRetrieve(archive_url, archive_name)
if os.path.exists(directory_name):
if os.path.exists(directory_old_name):
shutil.rmtree(directory_old_name)
diff --git a/deps/v8/test/webkit/fast/js/Object-defineProperty-expected.txt b/deps/v8/test/webkit/fast/js/Object-defineProperty-expected.txt
index 7a303f2c5..118f9dddf 100644
--- a/deps/v8/test/webkit/fast/js/Object-defineProperty-expected.txt
+++ b/deps/v8/test/webkit/fast/js/Object-defineProperty-expected.txt
@@ -142,8 +142,8 @@ PASS 'use strict'; var o = {}; o.readOnly = false; o.readOnly threw exception Ty
PASS Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defineProperty({}, 'foo', {get: function() { return false; }, configurable: true}), 'foo', {value:false}), 'foo').writable is false
PASS Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defineProperty({}, 'foo', {get: function() { return false; }, configurable: true}), 'foo', {value:false, writable: false}), 'foo').writable is false
PASS Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defineProperty({}, 'foo', {get: function() { return false; }, configurable: true}), 'foo', {value:false, writable: true}), 'foo').writable is true
-FAIL var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a; should be false. Was true.
-FAIL 'use strict'; var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a; should throw an exception. Was true.
+PASS var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a; is false
+PASS 'use strict'; var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a; threw exception TypeError: Cannot assign to read only property 'length' of [object Array].
PASS var a = Object.defineProperty([42], '0', {writable: false}); a[0] = false; a[0]; is 42
PASS 'use strict'; var a = Object.defineProperty([42], '0', {writable: false}); a[0] = false; a[0]; threw exception TypeError: Cannot assign to read only property '0' of [object Array].
PASS var a = Object.defineProperty([], '0', {set: undefined}); a[0] = 42; a[0]; is undefined.
diff --git a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
index 52babed02..4b8eb1477 100644
--- a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
+++ b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
@@ -53,35 +53,35 @@ PASS getSortedOwnPropertyNames(argumentsObject()) is ['callee', 'length']
PASS getSortedOwnPropertyNames(argumentsObject(1)) is ['0', 'callee', 'length']
PASS getSortedOwnPropertyNames(argumentsObject(1,2,3)) is ['0', '1', '2', 'callee', 'length']
PASS getSortedOwnPropertyNames((function(){arguments.__proto__=[1,2,3];return arguments;})()) is ['callee', 'length']
-FAIL getSortedOwnPropertyNames(parseInt) should be length,name. Was arguments,caller,length,name.
-FAIL getSortedOwnPropertyNames(parseFloat) should be length,name. Was arguments,caller,length,name.
-FAIL getSortedOwnPropertyNames(isNaN) should be length,name. Was arguments,caller,length,name.
-FAIL getSortedOwnPropertyNames(isFinite) should be length,name. Was arguments,caller,length,name.
-FAIL getSortedOwnPropertyNames(escape) should be length,name. Was arguments,caller,length,name.
-FAIL getSortedOwnPropertyNames(unescape) should be length,name. Was arguments,caller,length,name.
-FAIL getSortedOwnPropertyNames(decodeURI) should be length,name. Was arguments,caller,length,name.
-FAIL getSortedOwnPropertyNames(decodeURIComponent) should be length,name. Was arguments,caller,length,name.
-FAIL getSortedOwnPropertyNames(encodeURI) should be length,name. Was arguments,caller,length,name.
-FAIL getSortedOwnPropertyNames(encodeURIComponent) should be length,name. Was arguments,caller,length,name.
-FAIL getSortedOwnPropertyNames(Object) should be create,defineProperties,defineProperty,freeze,getOwnPropertyDescriptor,getOwnPropertyNames,getPrototypeOf,isExtensible,isFrozen,isSealed,keys,length,name,preventExtensions,prototype,seal,setPrototypeOf. Was arguments,caller,create,defineProperties,defineProperty,deliverChangeRecords,freeze,getNotifier,getOwnPropertyDescriptor,getOwnPropertyNames,getPrototypeOf,is,isExtensible,isFrozen,isSealed,keys,length,name,observe,preventExtensions,prototype,seal,setPrototypeOf,unobserve.
+PASS getSortedOwnPropertyNames(parseInt) is ['arguments', 'caller', 'length', 'name']
+PASS getSortedOwnPropertyNames(parseFloat) is ['arguments', 'caller', 'length', 'name']
+PASS getSortedOwnPropertyNames(isNaN) is ['arguments', 'caller', 'length', 'name']
+PASS getSortedOwnPropertyNames(isFinite) is ['arguments', 'caller', 'length', 'name']
+PASS getSortedOwnPropertyNames(escape) is ['arguments', 'caller', 'length', 'name']
+PASS getSortedOwnPropertyNames(unescape) is ['arguments', 'caller', 'length', 'name']
+PASS getSortedOwnPropertyNames(decodeURI) is ['arguments', 'caller', 'length', 'name']
+PASS getSortedOwnPropertyNames(decodeURIComponent) is ['arguments', 'caller', 'length', 'name']
+PASS getSortedOwnPropertyNames(encodeURI) is ['arguments', 'caller', 'length', 'name']
+PASS getSortedOwnPropertyNames(encodeURIComponent) is ['arguments', 'caller', 'length', 'name']
+PASS getSortedOwnPropertyNames(Object) is ['arguments', 'caller', 'create', 'defineProperties', 'defineProperty', 'deliverChangeRecords', 'freeze', 'getNotifier', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'observe', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf', 'unobserve']
PASS getSortedOwnPropertyNames(Object.prototype) is ['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']
-FAIL getSortedOwnPropertyNames(Function) should be length,name,prototype. Was arguments,caller,length,name,prototype.
-FAIL getSortedOwnPropertyNames(Function.prototype) should be apply,bind,call,constructor,length,name,toString. Was apply,arguments,bind,call,caller,constructor,length,name,toString.
-FAIL getSortedOwnPropertyNames(Array) should be isArray,length,name,prototype. Was arguments,caller,isArray,length,name,observe,prototype,unobserve.
-PASS getSortedOwnPropertyNames(Array.prototype) is ['concat', 'constructor', 'every', 'filter', 'forEach', 'indexOf', 'join', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']
-FAIL getSortedOwnPropertyNames(String) should be fromCharCode,length,name,prototype. Was arguments,caller,fromCharCode,length,name,prototype.
+PASS getSortedOwnPropertyNames(Function) is ['arguments', 'caller', 'length', 'name', 'prototype']
+PASS getSortedOwnPropertyNames(Function.prototype) is ['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toString']
+PASS getSortedOwnPropertyNames(Array) is ['arguments', 'caller', 'isArray', 'length', 'name', 'observe', 'prototype', 'unobserve']
+PASS getSortedOwnPropertyNames(Array.prototype) is ['concat', 'constructor', 'entries', 'every', 'filter', 'forEach', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift', 'values']
+PASS getSortedOwnPropertyNames(String) is ['arguments', 'caller', 'fromCharCode', 'length', 'name', 'prototype']
PASS getSortedOwnPropertyNames(String.prototype) is ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 'constructor', 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'replace', 'search', 'slice', 'small', 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']
-FAIL getSortedOwnPropertyNames(Boolean) should be length,name,prototype. Was arguments,caller,length,name,prototype.
+PASS getSortedOwnPropertyNames(Boolean) is ['arguments', 'caller', 'length', 'name', 'prototype']
PASS getSortedOwnPropertyNames(Boolean.prototype) is ['constructor', 'toString', 'valueOf']
-FAIL getSortedOwnPropertyNames(Number) should be MAX_VALUE,MIN_VALUE,NEGATIVE_INFINITY,NaN,POSITIVE_INFINITY,length,name,prototype. Was EPSILON,MAX_SAFE_INTEGER,MAX_VALUE,MIN_SAFE_INTEGER,MIN_VALUE,NEGATIVE_INFINITY,NaN,POSITIVE_INFINITY,arguments,caller,isFinite,isInteger,isNaN,isSafeInteger,length,name,parseFloat,parseInt,prototype.
+PASS getSortedOwnPropertyNames(Number) is ['EPSILON', 'MAX_SAFE_INTEGER', 'MAX_VALUE', 'MIN_SAFE_INTEGER', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'arguments', 'caller', 'isFinite', 'isInteger', 'isNaN', 'isSafeInteger', 'length', 'name', 'parseFloat', 'parseInt', 'prototype']
PASS getSortedOwnPropertyNames(Number.prototype) is ['constructor', 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 'valueOf']
-FAIL getSortedOwnPropertyNames(Date) should be UTC,length,name,now,parse,prototype. Was UTC,arguments,caller,length,name,now,parse,prototype.
+PASS getSortedOwnPropertyNames(Date) is ['UTC', 'arguments', 'caller', 'length', 'name', 'now', 'parse', 'prototype']
PASS getSortedOwnPropertyNames(Date.prototype) is ['constructor', 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'toDateString', 'toGMTString', 'toISOString', 'toJSON', 'toLocaleDateString', 'toLocaleString', 'toLocaleTimeString', 'toString', 'toTimeString', 'toUTCString', 'valueOf']
-FAIL getSortedOwnPropertyNames(RegExp) should be $&,$',$*,$+,$1,$2,$3,$4,$5,$6,$7,$8,$9,$_,$`,input,lastMatch,lastParen,leftContext,length,multiline,name,prototype,rightContext. Was $&,$',$*,$+,$1,$2,$3,$4,$5,$6,$7,$8,$9,$_,$`,$input,arguments,caller,input,lastMatch,lastParen,leftContext,length,multiline,name,prototype,rightContext.
+FAIL getSortedOwnPropertyNames(RegExp) should be $&,$',$*,$+,$1,$2,$3,$4,$5,$6,$7,$8,$9,$_,$`,arguments,caller,input,lastMatch,lastParen,leftContext,length,multiline,name,prototype,rightContext. Was $&,$',$*,$+,$1,$2,$3,$4,$5,$6,$7,$8,$9,$_,$`,$input,arguments,caller,input,lastMatch,lastParen,leftContext,length,multiline,name,prototype,rightContext.
PASS getSortedOwnPropertyNames(RegExp.prototype) is ['compile', 'constructor', 'exec', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'test', 'toString']
-FAIL getSortedOwnPropertyNames(Error) should be length,name,prototype. Was arguments,caller,captureStackTrace,length,name,prototype,stackTraceLimit.
+PASS getSortedOwnPropertyNames(Error) is ['arguments', 'caller', 'captureStackTrace', 'length', 'name', 'prototype', 'stackTraceLimit']
PASS getSortedOwnPropertyNames(Error.prototype) is ['constructor', 'message', 'name', 'toString']
-FAIL getSortedOwnPropertyNames(Math) should be E,LN10,LN2,LOG10E,LOG2E,PI,SQRT1_2,SQRT2,abs,acos,asin,atan,atan2,ceil,cos,exp,floor,log,max,min,pow,random,round,sin,sqrt,tan. Was E,LN10,LN2,LOG10E,LOG2E,PI,SQRT1_2,SQRT2,abs,acos,asin,atan,atan2,ceil,cos,exp,floor,imul,log,max,min,pow,random,round,sin,sqrt,tan.
+PASS getSortedOwnPropertyNames(Math) is ['E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2', 'abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'cbrt', 'ceil', 'clz32', 'cos', 'cosh', 'exp', 'expm1', 'floor', 'fround', 'hypot', 'imul', 'log', 'log10', 'log1p', 'log2', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']
PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify']
PASS globalPropertyNames.indexOf('NaN') != -1 is true
PASS globalPropertyNames.indexOf('Infinity') != -1 is true
diff --git a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js
index 6373cf1ae..c168c37b0 100644
--- a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js
+++ b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js
@@ -60,36 +60,36 @@ var expectedPropertyNamesSet = {
"argumentsObject(1,2,3)": "['0', '1', '2', 'callee', 'length']",
"(function(){arguments.__proto__=[1,2,3];return arguments;})()": "['callee', 'length']",
// Built-in ECMA functions
- "parseInt": "['length', 'name']",
- "parseFloat": "['length', 'name']",
- "isNaN": "['length', 'name']",
- "isFinite": "['length', 'name']",
- "escape": "['length', 'name']",
- "unescape": "['length', 'name']",
- "decodeURI": "['length', 'name']",
- "decodeURIComponent": "['length', 'name']",
- "encodeURI": "['length', 'name']",
- "encodeURIComponent": "['length', 'name']",
+ "parseInt": "['arguments', 'caller', 'length', 'name']",
+ "parseFloat": "['arguments', 'caller', 'length', 'name']",
+ "isNaN": "['arguments', 'caller', 'length', 'name']",
+ "isFinite": "['arguments', 'caller', 'length', 'name']",
+ "escape": "['arguments', 'caller', 'length', 'name']",
+ "unescape": "['arguments', 'caller', 'length', 'name']",
+ "decodeURI": "['arguments', 'caller', 'length', 'name']",
+ "decodeURIComponent": "['arguments', 'caller', 'length', 'name']",
+ "encodeURI": "['arguments', 'caller', 'length', 'name']",
+ "encodeURIComponent": "['arguments', 'caller', 'length', 'name']",
// Built-in ECMA objects
- "Object": "['create', 'defineProperties', 'defineProperty', 'freeze', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getPrototypeOf', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf']",
+ "Object": "['arguments', 'caller', 'create', 'defineProperties', 'defineProperty', 'deliverChangeRecords', 'freeze', 'getNotifier', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'observe', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf', 'unobserve']",
"Object.prototype": "['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']",
- "Function": "['length', 'name', 'prototype']",
- "Function.prototype": "['apply', 'bind', 'call', 'constructor', 'length', 'name', 'toString']",
- "Array": "['isArray', 'length', 'name', 'prototype']",
- "Array.prototype": "['concat', 'constructor', 'every', 'filter', 'forEach', 'indexOf', 'join', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']",
- "String": "['fromCharCode', 'length', 'name', 'prototype']",
+ "Function": "['arguments', 'caller', 'length', 'name', 'prototype']",
+ "Function.prototype": "['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toString']",
+ "Array": "['arguments', 'caller', 'isArray', 'length', 'name', 'observe', 'prototype', 'unobserve']",
+ "Array.prototype": "['concat', 'constructor', 'entries', 'every', 'filter', 'forEach', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift', 'values']",
+ "String": "['arguments', 'caller', 'fromCharCode', 'length', 'name', 'prototype']",
"String.prototype": "['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 'constructor', 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'replace', 'search', 'slice', 'small', 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']",
- "Boolean": "['length', 'name', 'prototype']",
+ "Boolean": "['arguments', 'caller', 'length', 'name', 'prototype']",
"Boolean.prototype": "['constructor', 'toString', 'valueOf']",
- "Number": "['MAX_VALUE', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'length', 'name', 'prototype']",
+ "Number": "['EPSILON', 'MAX_SAFE_INTEGER', 'MAX_VALUE', 'MIN_SAFE_INTEGER', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'arguments', 'caller', 'isFinite', 'isInteger', 'isNaN', 'isSafeInteger', 'length', 'name', 'parseFloat', 'parseInt', 'prototype']",
"Number.prototype": "['constructor', 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 'valueOf']",
- "Date": "['UTC', 'length', 'name', 'now', 'parse', 'prototype']",
+ "Date": "['UTC', 'arguments', 'caller', 'length', 'name', 'now', 'parse', 'prototype']",
"Date.prototype": "['constructor', 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'toDateString', 'toGMTString', 'toISOString', 'toJSON', 'toLocaleDateString', 'toLocaleString', 'toLocaleTimeString', 'toString', 'toTimeString', 'toUTCString', 'valueOf']",
- "RegExp": "['$&', \"$'\", '$*', '$+', '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$_', '$`', 'input', 'lastMatch', 'lastParen', 'leftContext', 'length', 'multiline', 'name', 'prototype', 'rightContext']",
+ "RegExp": "['$&', \"$'\", '$*', '$+', '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$_', '$`', 'arguments', 'caller', 'input', 'lastMatch', 'lastParen', 'leftContext', 'length', 'multiline', 'name', 'prototype', 'rightContext']",
"RegExp.prototype": "['compile', 'constructor', 'exec', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'test', 'toString']",
- "Error": "['length', 'name', 'prototype']",
+ "Error": "['arguments', 'caller', 'captureStackTrace', 'length', 'name', 'prototype', 'stackTraceLimit']",
"Error.prototype": "['constructor', 'message', 'name', 'toString']",
- "Math": "['E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2', 'abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'random', 'round', 'sin', 'sqrt', 'tan']",
+ "Math": "['E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2', 'abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'cbrt', 'ceil', 'clz32', 'cos', 'cosh', 'exp', 'expm1', 'floor', 'fround', 'hypot', 'imul', 'log', 'log10', 'log1p', 'log2', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']",
"JSON": "['parse', 'stringify']"
};
diff --git a/deps/v8/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt b/deps/v8/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt
index f07d273f3..cc273dfba 100644
--- a/deps/v8/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt
+++ b/deps/v8/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt
@@ -29,15 +29,15 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
PASS checkGet(1, Number) is true
PASS checkGet('hello', String) is true
PASS checkGet(true, Boolean) is true
-FAIL checkSet(1, Number) should be true. Was false.
-FAIL checkSet('hello', String) should be true. Was false.
-FAIL checkSet(true, Boolean) should be true. Was false.
+PASS checkSet(1, Number) is true
+PASS checkSet('hello', String) is true
+PASS checkSet(true, Boolean) is true
PASS checkGetStrict(1, Number) is true
PASS checkGetStrict('hello', String) is true
PASS checkGetStrict(true, Boolean) is true
-FAIL checkSetStrict(1, Number) should be true. Was false.
-FAIL checkSetStrict('hello', String) should be true. Was false.
-FAIL checkSetStrict(true, Boolean) should be true. Was false.
+PASS checkSetStrict(1, Number) is true
+PASS checkSetStrict('hello', String) is true
+PASS checkSetStrict(true, Boolean) is true
PASS checkRead(1, Number) is true
PASS checkRead('hello', String) is true
PASS checkRead(true, Boolean) is true
@@ -47,9 +47,9 @@ PASS checkWrite(true, Boolean) is true
PASS checkReadStrict(1, Number) is true
PASS checkReadStrict('hello', String) is true
PASS checkReadStrict(true, Boolean) is true
-FAIL checkWriteStrict(1, Number) should throw an exception. Was true.
-FAIL checkWriteStrict('hello', String) should throw an exception. Was true.
-FAIL checkWriteStrict(true, Boolean) should throw an exception. Was true.
+PASS checkWriteStrict(1, Number) threw exception TypeError: Cannot assign to read only property 'foo' of 1.
+PASS checkWriteStrict('hello', String) threw exception TypeError: Cannot assign to read only property 'foo' of hello.
+PASS checkWriteStrict(true, Boolean) threw exception TypeError: Cannot assign to read only property 'foo' of true.
PASS checkNumericGet(1, Number) is true
PASS checkNumericGet('hello', String) is true
PASS checkNumericGet(true, Boolean) is true
diff --git a/deps/v8/test/webkit/fast/js/read-modify-eval-expected.txt b/deps/v8/test/webkit/fast/js/read-modify-eval-expected.txt
index 4a16d0a7a..b375b3780 100644
--- a/deps/v8/test/webkit/fast/js/read-modify-eval-expected.txt
+++ b/deps/v8/test/webkit/fast/js/read-modify-eval-expected.txt
@@ -42,7 +42,7 @@ PASS preDecTest(); is true
PASS postIncTest(); is true
PASS postDecTest(); is true
PASS primitiveThisTest.call(1); is true
-FAIL strictThisTest.call(1); should throw an exception. Was true.
+PASS strictThisTest.call(1); threw exception TypeError: Cannot assign to read only property 'value' of 1.
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/deps/v8/test/webkit/fast/js/string-anchor-expected.txt b/deps/v8/test/webkit/fast/js/string-anchor-expected.txt
index 3a50054f1..91a833803 100644
--- a/deps/v8/test/webkit/fast/js/string-anchor-expected.txt
+++ b/deps/v8/test/webkit/fast/js/string-anchor-expected.txt
@@ -32,8 +32,8 @@ PASS '_'.anchor(0x2A) is "<a name=\"42\">_</a>"
PASS '_'.anchor('"') is "<a name=\"&quot;\">_</a>"
PASS '_'.anchor('" href="http://www.evil.com') is "<a name=\"&quot; href=&quot;http://www.evil.com\">_</a>"
PASS String.prototype.anchor.call(0x2A, 0x2A) is "<a name=\"42\">42</a>"
-FAIL String.prototype.anchor.call(undefined) should throw TypeError: Type error. Was <a name="undefined">undefined</a>.
-FAIL String.prototype.anchor.call(null) should throw TypeError: Type error. Was <a name="undefined">null</a>.
+FAIL String.prototype.anchor.call(undefined) should throw TypeError: Type error. Threw exception TypeError: String.prototype.anchor called on null or undefined.
+FAIL String.prototype.anchor.call(null) should throw TypeError: Type error. Threw exception TypeError: String.prototype.anchor called on null or undefined.
PASS String.prototype.anchor.length is 1
PASS successfullyParsed is true
diff --git a/deps/v8/test/webkit/fast/js/string-fontcolor-expected.txt b/deps/v8/test/webkit/fast/js/string-fontcolor-expected.txt
index af2c707f3..2ffda69a6 100644
--- a/deps/v8/test/webkit/fast/js/string-fontcolor-expected.txt
+++ b/deps/v8/test/webkit/fast/js/string-fontcolor-expected.txt
@@ -32,8 +32,8 @@ PASS '_'.fontcolor(0x2A) is "<font color=\"42\">_</font>"
PASS '_'.fontcolor('"') is "<font color=\"&quot;\">_</font>"
PASS '_'.fontcolor('" size="2px') is "<font color=\"&quot; size=&quot;2px\">_</font>"
PASS String.prototype.fontcolor.call(0x2A, 0x2A) is "<font color=\"42\">42</font>"
-FAIL String.prototype.fontcolor.call(undefined) should throw TypeError: Type error. Was <font color="undefined">undefined</font>.
-FAIL String.prototype.fontcolor.call(null) should throw TypeError: Type error. Was <font color="undefined">null</font>.
+FAIL String.prototype.fontcolor.call(undefined) should throw TypeError: Type error. Threw exception TypeError: String.prototype.fontcolor called on null or undefined.
+FAIL String.prototype.fontcolor.call(null) should throw TypeError: Type error. Threw exception TypeError: String.prototype.fontcolor called on null or undefined.
PASS String.prototype.fontcolor.length is 1
PASS successfullyParsed is true
diff --git a/deps/v8/test/webkit/fast/js/string-fontsize-expected.txt b/deps/v8/test/webkit/fast/js/string-fontsize-expected.txt
index c114f74b1..656f7fa7f 100644
--- a/deps/v8/test/webkit/fast/js/string-fontsize-expected.txt
+++ b/deps/v8/test/webkit/fast/js/string-fontsize-expected.txt
@@ -33,8 +33,8 @@ PASS '_'.fontsize(0x2A) is "<font size=\"42\">_</font>"
PASS '_'.fontsize('"') is "<font size=\"&quot;\">_</font>"
PASS '_'.fontsize('" color="b') is "<font size=\"&quot; color=&quot;b\">_</font>"
PASS String.prototype.fontsize.call(0x2A, 0x2A) is "<font size=\"42\">42</font>"
-FAIL String.prototype.fontsize.call(undefined) should throw TypeError: Type error. Was <font size="undefined">undefined</font>.
-FAIL String.prototype.fontsize.call(null) should throw TypeError: Type error. Was <font size="undefined">null</font>.
+FAIL String.prototype.fontsize.call(undefined) should throw TypeError: Type error. Threw exception TypeError: String.prototype.fontsize called on null or undefined.
+FAIL String.prototype.fontsize.call(null) should throw TypeError: Type error. Threw exception TypeError: String.prototype.fontsize called on null or undefined.
PASS String.prototype.fontsize.length is 1
PASS successfullyParsed is true
diff --git a/deps/v8/test/webkit/fast/js/string-link-expected.txt b/deps/v8/test/webkit/fast/js/string-link-expected.txt
index afacbe6bb..2443bd4bc 100644
--- a/deps/v8/test/webkit/fast/js/string-link-expected.txt
+++ b/deps/v8/test/webkit/fast/js/string-link-expected.txt
@@ -33,8 +33,8 @@ PASS '_'.link(0x2A) is "<a href=\"42\">_</a>"
PASS '_'.link('"') is "<a href=\"&quot;\">_</a>"
PASS '_'.link('" target="_blank') is "<a href=\"&quot; target=&quot;_blank\">_</a>"
PASS String.prototype.link.call(0x2A, 0x2A) is "<a href=\"42\">42</a>"
-FAIL String.prototype.link.call(undefined) should throw TypeError: Type error. Was <a href="undefined">undefined</a>.
-FAIL String.prototype.link.call(null) should throw TypeError: Type error. Was <a href="undefined">null</a>.
+FAIL String.prototype.link.call(undefined) should throw TypeError: Type error. Threw exception TypeError: String.prototype.link called on null or undefined.
+FAIL String.prototype.link.call(null) should throw TypeError: Type error. Threw exception TypeError: String.prototype.link called on null or undefined.
PASS String.prototype.link.length is 1
PASS successfullyParsed is true
diff --git a/deps/v8/test/webkit/for-in-cached-expected.txt b/deps/v8/test/webkit/for-in-cached-expected.txt
index 0d0c337cf..e5538fe3b 100644
--- a/deps/v8/test/webkit/for-in-cached-expected.txt
+++ b/deps/v8/test/webkit/for-in-cached-expected.txt
@@ -34,8 +34,8 @@ PASS forIn3({ __proto__: { __proto__: { y3 : 2 } } }) is ['x', 'y3']
PASS forIn4(objectWithArrayAsProto) is []
PASS forIn4(objectWithArrayAsProto) is ['0']
PASS forIn5({get foo() { return 'called getter'} }) is ['foo', 'called getter']
-PASS forIn5({set foo() { } }) is ['foo', undefined]
-PASS forIn5({get foo() { return 'called getter'}, set foo() { }}) is ['foo', 'called getter']
+PASS forIn5({set foo(v) { } }) is ['foo', undefined]
+PASS forIn5({get foo() { return 'called getter'}, set foo(v) { }}) is ['foo', 'called getter']
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/deps/v8/test/webkit/for-in-cached.js b/deps/v8/test/webkit/for-in-cached.js
index 1842d6129..760a5b458 100644
--- a/deps/v8/test/webkit/for-in-cached.js
+++ b/deps/v8/test/webkit/for-in-cached.js
@@ -84,8 +84,8 @@ function forIn5(o) {
}
shouldBe("forIn5({get foo() { return 'called getter'} })", "['foo', 'called getter']");
-shouldBe("forIn5({set foo() { } })", "['foo', undefined]");
-shouldBe("forIn5({get foo() { return 'called getter'}, set foo() { }})", "['foo', 'called getter']");
+shouldBe("forIn5({set foo(v) { } })", "['foo', undefined]");
+shouldBe("forIn5({get foo() { return 'called getter'}, set foo(v) { }})", "['foo', 'called getter']");
function cacheClearing() {
for(var j=0; j < 10; j++){
diff --git a/deps/v8/test/webkit/object-literal-direct-put-expected.txt b/deps/v8/test/webkit/object-literal-direct-put-expected.txt
index 46793d20d..3a19f0a0d 100644
--- a/deps/v8/test/webkit/object-literal-direct-put-expected.txt
+++ b/deps/v8/test/webkit/object-literal-direct-put-expected.txt
@@ -28,11 +28,11 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
PASS ({a:true}).a is true
PASS ({__proto__: {a:false}, a:true}).a is true
-PASS ({__proto__: {set a() {throw 'Should not call setter'; }}, a:true}).a is true
+PASS ({__proto__: {set a(v) {throw 'Should not call setter'; }}, a:true}).a is true
PASS ({__proto__: {get a() {throw 'Should not reach getter'; }}, a:true}).a is true
PASS ({__proto__: {get a() {throw 'Should not reach getter'; }, b:true}, a:true}).b is true
PASS ({__proto__: {__proto__: {a:false}}, a:true}).a is true
-PASS ({__proto__: {__proto__: {set a() {throw 'Should not call setter'; }}}, a:true}).a is true
+PASS ({__proto__: {__proto__: {set a(v) {throw 'Should not call setter'; }}}, a:true}).a is true
PASS ({__proto__: {__proto__: {get a() {throw 'Should not reach getter'; }}}, a:true}).a is true
PASS ({__proto__: {__proto__: {get a() {throw 'Should not reach getter'; }, b:true}}, a:true}).b is true
PASS successfullyParsed is true
diff --git a/deps/v8/test/webkit/object-literal-direct-put.js b/deps/v8/test/webkit/object-literal-direct-put.js
index 69c085f06..99f0a60c0 100644
--- a/deps/v8/test/webkit/object-literal-direct-put.js
+++ b/deps/v8/test/webkit/object-literal-direct-put.js
@@ -25,11 +25,11 @@ description("This test ensures that properties on an object literal are put dire
shouldBeTrue("({a:true}).a");
shouldBeTrue("({__proto__: {a:false}, a:true}).a");
-shouldBeTrue("({__proto__: {set a() {throw 'Should not call setter'; }}, a:true}).a");
+shouldBeTrue("({__proto__: {set a(v) {throw 'Should not call setter'; }}, a:true}).a");
shouldBeTrue("({__proto__: {get a() {throw 'Should not reach getter'; }}, a:true}).a");
shouldBeTrue("({__proto__: {get a() {throw 'Should not reach getter'; }, b:true}, a:true}).b");
shouldBeTrue("({__proto__: {__proto__: {a:false}}, a:true}).a");
-shouldBeTrue("({__proto__: {__proto__: {set a() {throw 'Should not call setter'; }}}, a:true}).a");
+shouldBeTrue("({__proto__: {__proto__: {set a(v) {throw 'Should not call setter'; }}}, a:true}).a");
shouldBeTrue("({__proto__: {__proto__: {get a() {throw 'Should not reach getter'; }}}, a:true}).a");
shouldBeTrue("({__proto__: {__proto__: {get a() {throw 'Should not reach getter'; }, b:true}}, a:true}).b");
diff --git a/deps/v8/test/webkit/object-literal-syntax-expected.txt b/deps/v8/test/webkit/object-literal-syntax-expected.txt
index 13b3499ce..f9764454c 100644
--- a/deps/v8/test/webkit/object-literal-syntax-expected.txt
+++ b/deps/v8/test/webkit/object-literal-syntax-expected.txt
@@ -27,25 +27,25 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
PASS ({a:1, get a(){}}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
-PASS ({a:1, set a(){}}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
+PASS ({a:1, set a(v){}}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
PASS ({get a(){}, a:1}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
-PASS ({set a(){}, a:1}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
+PASS ({set a(v){}, a:1}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
PASS ({get a(){}, get a(){}}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
-PASS ({set a(){}, set a(){}}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
-PASS ({set a(){}, get a(){}, set a(){}}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
+PASS ({set a(v){}, set a(v){}}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
+PASS ({set a(v){}, get a(){}, set a(v){}}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
PASS (function(){({a:1, get a(){}})}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
-PASS (function(){({a:1, set a(){}})}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
+PASS (function(){({a:1, set a(v){}})}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
PASS (function(){({get a(){}, a:1})}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
-PASS (function(){({set a(){}, a:1})}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
+PASS (function(){({set a(v){}, a:1})}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
PASS (function(){({get a(){}, get a(){}})}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
-PASS (function(){({set a(){}, set a(){}})}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
-PASS (function(){({set a(){}, get a(){}, set a(){}})}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
+PASS (function(){({set a(v){}, set a(v){}})}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
+PASS (function(){({set a(v){}, get a(){}, set a(v){}})}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
PASS ({a:1, a:1, a:1}), true is true
-PASS ({get a(){}, set a(){}}), true is true
-PASS ({set a(){}, get a(){}}), true is true
+PASS ({get a(){}, set a(v){}}), true is true
+PASS ({set a(v){}, get a(){}}), true is true
PASS (function(){({a:1, a:1, a:1})}), true is true
-PASS (function(){({get a(){}, set a(){}})}), true is true
-PASS (function(){({set a(){}, get a(){}})}), true is true
+PASS (function(){({get a(){}, set a(v){}})}), true is true
+PASS (function(){({set a(v){}, get a(){}})}), true is true
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/deps/v8/test/webkit/object-literal-syntax.js b/deps/v8/test/webkit/object-literal-syntax.js
index 6884bec40..e9cc2dd8c 100644
--- a/deps/v8/test/webkit/object-literal-syntax.js
+++ b/deps/v8/test/webkit/object-literal-syntax.js
@@ -24,22 +24,22 @@
description("Make sure that we correctly identify parse errors in object literals");
shouldThrow("({a:1, get a(){}})");
-shouldThrow("({a:1, set a(){}})");
+shouldThrow("({a:1, set a(v){}})");
shouldThrow("({get a(){}, a:1})");
-shouldThrow("({set a(){}, a:1})");
+shouldThrow("({set a(v){}, a:1})");
shouldThrow("({get a(){}, get a(){}})");
-shouldThrow("({set a(){}, set a(){}})");
-shouldThrow("({set a(){}, get a(){}, set a(){}})");
+shouldThrow("({set a(v){}, set a(v){}})");
+shouldThrow("({set a(v){}, get a(){}, set a(v){}})");
shouldThrow("(function(){({a:1, get a(){}})})");
-shouldThrow("(function(){({a:1, set a(){}})})");
+shouldThrow("(function(){({a:1, set a(v){}})})");
shouldThrow("(function(){({get a(){}, a:1})})");
-shouldThrow("(function(){({set a(){}, a:1})})");
+shouldThrow("(function(){({set a(v){}, a:1})})");
shouldThrow("(function(){({get a(){}, get a(){}})})");
-shouldThrow("(function(){({set a(){}, set a(){}})})");
-shouldThrow("(function(){({set a(){}, get a(){}, set a(){}})})");
+shouldThrow("(function(){({set a(v){}, set a(v){}})})");
+shouldThrow("(function(){({set a(v){}, get a(){}, set a(v){}})})");
shouldBeTrue("({a:1, a:1, a:1}), true");
-shouldBeTrue("({get a(){}, set a(){}}), true");
-shouldBeTrue("({set a(){}, get a(){}}), true");
+shouldBeTrue("({get a(){}, set a(v){}}), true");
+shouldBeTrue("({set a(v){}, get a(){}}), true");
shouldBeTrue("(function(){({a:1, a:1, a:1})}), true");
-shouldBeTrue("(function(){({get a(){}, set a(){}})}), true");
-shouldBeTrue("(function(){({set a(){}, get a(){}})}), true");
+shouldBeTrue("(function(){({get a(){}, set a(v){}})}), true");
+shouldBeTrue("(function(){({set a(v){}, get a(){}})}), true");
diff --git a/deps/v8/test/webkit/string-replacement-outofmemory-expected.txt b/deps/v8/test/webkit/string-replacement-outofmemory-expected.txt
index 68ac21796..946b248ed 100644
--- a/deps/v8/test/webkit/string-replacement-outofmemory-expected.txt
+++ b/deps/v8/test/webkit/string-replacement-outofmemory-expected.txt
@@ -21,3 +21,12 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+This tests that string replacement with a large replacement string causes an out-of-memory exception. See bug 102956 for more details.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS x.replace(/\d/g, y) threw exception RangeError: Invalid string length.
+PASS successfullyParsed is true
+
+TEST COMPLETE
diff --git a/deps/v8/test/webkit/string-replacement-outofmemory.js b/deps/v8/test/webkit/string-replacement-outofmemory.js
index 2b8e18a85..becfdc6a1 100644
--- a/deps/v8/test/webkit/string-replacement-outofmemory.js
+++ b/deps/v8/test/webkit/string-replacement-outofmemory.js
@@ -37,5 +37,5 @@ var y = "2";
x = createStringWithRepeatedChar(x, 1 << 12);
y = createStringWithRepeatedChar(y, (1 << 20) + 1);
-shouldThrow("x.replace(/\\d/g, y)", '"Error: Out of memory"');
+shouldThrow("x.replace(/\\d/g, y)", '"RangeError: Invalid string length"');
var successfullyParsed = true;
diff --git a/deps/v8/test/webkit/webkit.status b/deps/v8/test/webkit/webkit.status
index a6bf845d0..c14d5c13c 100644
--- a/deps/v8/test/webkit/webkit.status
+++ b/deps/v8/test/webkit/webkit.status
@@ -27,16 +27,18 @@
[
[ALWAYS, {
- # BUG(237872). TODO(bmeurer): Investigate.
- 'string-replacement-outofmemory': [FAIL],
-
- ##############################################################################
# Flaky tests.
# BUG(v8:2989).
'dfg-inline-arguments-become-double': [PASS, FAIL],
'dfg-inline-arguments-become-int32': [PASS, FAIL],
'dfg-inline-arguments-reset': [PASS, FAIL],
'dfg-inline-arguments-reset-changetype': [PASS, FAIL],
+ # TODO(turbofan): Sometimes the try-catch blacklist fails.
+ 'exception-with-handler-inside-eval-with-dynamic-scope': [PASS, NO_VARIANTS],
+ # TODO(turbofan): We run out of stack earlier on 64-bit for now.
+ 'fast/js/deep-recursion-test': [PASS, NO_VARIANTS],
+ # TODO(bmeurer,svenpanne): Investigate test failure.
+ 'fast/js/toString-number': [SKIP],
}], # ALWAYS
['mode == debug', {
# Too slow in debug mode.
@@ -51,4 +53,13 @@
['arch == arm64 and simulator_run == True', {
'dfg-int-overflow-in-loop': [SKIP],
}], # 'arch == arm64 and simulator_run == True'
+
+
+##############################################################################
+['gc_stress == True', {
+ # Tests taking too long
+ 'fast/js/excessive-comma-usage': [SKIP]
+}], # 'gc_stress == True'
+
+##############################################################################
]