summaryrefslogtreecommitdiff
path: root/deps/v8/test
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test')
-rw-r--r--deps/v8/test/cctest/cctest.gyp2
-rw-r--r--deps/v8/test/cctest/cctest.h28
-rw-r--r--deps/v8/test/cctest/cctest.status36
-rw-r--r--deps/v8/test/cctest/compiler/c-signature.h147
-rw-r--r--deps/v8/test/cctest/compiler/call-tester.h366
-rw-r--r--deps/v8/test/cctest/compiler/codegen-tester.h79
-rw-r--r--deps/v8/test/cctest/compiler/function-tester.h21
-rw-r--r--deps/v8/test/cctest/compiler/graph-builder-tester.h21
-rw-r--r--deps/v8/test/cctest/compiler/simplified-graph-builder.cc4
-rw-r--r--deps/v8/test/cctest/compiler/simplified-graph-builder.h3
-rw-r--r--deps/v8/test/cctest/compiler/test-changes-lowering.cc10
-rw-r--r--deps/v8/test/cctest/compiler/test-codegen-deopt.cc301
-rw-r--r--deps/v8/test/cctest/compiler/test-control-reducer.cc1641
-rw-r--r--deps/v8/test/cctest/compiler/test-js-constant-cache.cc14
-rw-r--r--deps/v8/test/cctest/compiler/test-js-context-specialization.cc41
-rw-r--r--deps/v8/test/cctest/compiler/test-js-typed-lowering.cc89
-rw-r--r--deps/v8/test/cctest/compiler/test-jump-threading.cc2
-rw-r--r--deps/v8/test/cctest/compiler/test-linkage.cc5
-rw-r--r--deps/v8/test/cctest/compiler/test-loop-analysis.cc2
-rw-r--r--deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc2
-rw-r--r--deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc2
-rw-r--r--deps/v8/test/cctest/compiler/test-osr.cc62
-rw-r--r--deps/v8/test/cctest/compiler/test-pipeline.cc23
-rw-r--r--deps/v8/test/cctest/compiler/test-representation-change.cc8
-rw-r--r--deps/v8/test/cctest/compiler/test-run-deopt.cc88
-rw-r--r--deps/v8/test/cctest/compiler/test-run-inlining.cc129
-rw-r--r--deps/v8/test/cctest/compiler/test-run-intrinsics.cc51
-rw-r--r--deps/v8/test/cctest/compiler/test-run-jscalls.cc2
-rw-r--r--deps/v8/test/cctest/compiler/test-run-jsexceptions.cc43
-rw-r--r--deps/v8/test/cctest/compiler/test-run-jsops.cc2
-rw-r--r--deps/v8/test/cctest/compiler/test-run-machops.cc223
-rw-r--r--deps/v8/test/cctest/compiler/test-run-stubs.cc137
-rw-r--r--deps/v8/test/cctest/compiler/test-simplified-lowering.cc46
-rw-r--r--deps/v8/test/cctest/gay-fixed.cc3
-rw-r--r--deps/v8/test/cctest/gay-precision.cc3
-rw-r--r--deps/v8/test/cctest/gay-shortest.cc3
-rw-r--r--deps/v8/test/cctest/print-extension.cc3
-rw-r--r--deps/v8/test/cctest/profiler-extension.cc3
-rw-r--r--deps/v8/test/cctest/test-accessors.cc2
-rw-r--r--deps/v8/test/cctest/test-api-interceptors.cc113
-rw-r--r--deps/v8/test/cctest/test-api.cc1494
-rw-r--r--deps/v8/test/cctest/test-assembler-arm.cc184
-rw-r--r--deps/v8/test/cctest/test-assembler-mips.cc3670
-rw-r--r--deps/v8/test/cctest/test-assembler-mips64.cc3965
-rw-r--r--deps/v8/test/cctest/test-assembler-ppc.cc88
-rw-r--r--deps/v8/test/cctest/test-code-stubs-arm64.cc4
-rw-r--r--deps/v8/test/cctest/test-code-stubs-mips64.cc3
-rw-r--r--deps/v8/test/cctest/test-compiler.cc95
-rw-r--r--deps/v8/test/cctest/test-constantpool.cc502
-rw-r--r--deps/v8/test/cctest/test-debug.cc379
-rw-r--r--deps/v8/test/cctest/test-decls.cc8
-rw-r--r--deps/v8/test/cctest/test-deoptimization.cc19
-rw-r--r--deps/v8/test/cctest/test-disasm-arm64.cc9
-rw-r--r--deps/v8/test/cctest/test-disasm-mips.cc567
-rw-r--r--deps/v8/test/cctest/test-disasm-mips64.cc601
-rw-r--r--deps/v8/test/cctest/test-extra.js14
-rw-r--r--deps/v8/test/cctest/test-feedback-vector.cc23
-rw-r--r--deps/v8/test/cctest/test-fuzz-arm64.cc4
-rw-r--r--deps/v8/test/cctest/test-global-object.cc6
-rw-r--r--deps/v8/test/cctest/test-hashing.cc2
-rw-r--r--deps/v8/test/cctest/test-hashmap.cc2
-rw-r--r--deps/v8/test/cctest/test-heap.cc942
-rw-r--r--deps/v8/test/cctest/test-hydrogen-types.cc1
-rw-r--r--deps/v8/test/cctest/test-log.cc2
-rw-r--r--deps/v8/test/cctest/test-microtask-delivery.cc25
-rw-r--r--deps/v8/test/cctest/test-migrations.cc3
-rw-r--r--deps/v8/test/cctest/test-parsing.cc682
-rw-r--r--deps/v8/test/cctest/test-profile-generator.cc17
-rw-r--r--deps/v8/test/cctest/test-reloc-info.cc7
-rw-r--r--deps/v8/test/cctest/test-serialize.cc42
-rw-r--r--deps/v8/test/cctest/test-spaces.cc16
-rw-r--r--deps/v8/test/cctest/test-strings.cc2
-rw-r--r--deps/v8/test/cctest/test-thread-termination.cc16
-rw-r--r--deps/v8/test/cctest/test-threads.cc11
-rw-r--r--deps/v8/test/cctest/test-typedarrays.cc2
-rw-r--r--deps/v8/test/cctest/test-types.cc78
-rw-r--r--deps/v8/test/cctest/test-unboxed-doubles.cc10
-rw-r--r--deps/v8/test/cctest/test-utils-arm64.h6
-rw-r--r--deps/v8/test/cctest/test-version.cc3
-rw-r--r--deps/v8/test/cctest/test-weakmaps.cc16
-rw-r--r--deps/v8/test/cctest/test-weaksets.cc13
-rw-r--r--deps/v8/test/cctest/trace-extension.cc3
-rw-r--r--deps/v8/test/js-perf-test/Exceptions/run.js26
-rw-r--r--deps/v8/test/js-perf-test/Exceptions/try-catch.js110
-rw-r--r--deps/v8/test/js-perf-test/JSTests.json22
-rw-r--r--deps/v8/test/js-perf-test/Scope/run.js26
-rw-r--r--deps/v8/test/js-perf-test/Scope/with.js90
-rw-r--r--deps/v8/test/js-perf-test/base.js12
-rw-r--r--deps/v8/test/message/arrow-bare-rest-param.js7
-rw-r--r--deps/v8/test/message/arrow-bare-rest-param.out4
-rw-r--r--deps/v8/test/message/arrow-missing.js7
-rw-r--r--deps/v8/test/message/arrow-missing.out4
-rw-r--r--deps/v8/test/message/arrow-param-after-rest-2.js7
-rw-r--r--deps/v8/test/message/arrow-param-after-rest-2.out4
-rw-r--r--deps/v8/test/message/arrow-param-after-rest.js7
-rw-r--r--deps/v8/test/message/arrow-param-after-rest.out4
-rw-r--r--deps/v8/test/message/arrow-strict-eval-bare-parameter.js8
-rw-r--r--deps/v8/test/message/arrow-strict-eval-bare-parameter.out4
-rw-r--r--deps/v8/test/message/arrow-two-rest-params.js7
-rw-r--r--deps/v8/test/message/arrow-two-rest-params.out4
-rw-r--r--deps/v8/test/message/class-constructor-accessor.js4
-rw-r--r--deps/v8/test/message/class-constructor-generator.js4
-rw-r--r--deps/v8/test/message/destructuring-modify-const.js9
-rw-r--r--deps/v8/test/message/destructuring-modify-const.out5
-rw-r--r--deps/v8/test/message/invalid-spread-2.js7
-rw-r--r--deps/v8/test/message/invalid-spread-2.out4
-rw-r--r--deps/v8/test/message/invalid-spread.js7
-rw-r--r--deps/v8/test/message/invalid-spread.out4
-rw-r--r--deps/v8/test/message/message.status7
-rw-r--r--deps/v8/test/message/no-legacy-const-2.js7
-rw-r--r--deps/v8/test/message/no-legacy-const-2.out5
-rw-r--r--deps/v8/test/message/no-legacy-const-3.js7
-rw-r--r--deps/v8/test/message/no-legacy-const-3.out5
-rw-r--r--deps/v8/test/message/no-legacy-const.js7
-rw-r--r--deps/v8/test/message/no-legacy-const.out5
-rw-r--r--deps/v8/test/message/rest-param-class-setter-strict.js12
-rw-r--r--deps/v8/test/message/rest-param-class-setter-strict.out4
-rw-r--r--deps/v8/test/message/rest-param-object-setter-sloppy.js11
-rw-r--r--deps/v8/test/message/rest-param-object-setter-sloppy.out4
-rw-r--r--deps/v8/test/message/rest-param-object-setter-strict.js12
-rw-r--r--deps/v8/test/message/rest-param-object-setter-strict.out4
-rw-r--r--deps/v8/test/message/strong-object-freeze-prop.js11
-rw-r--r--deps/v8/test/message/strong-object-freeze-prop.out9
-rw-r--r--deps/v8/test/message/strong-object-set-proto.js9
-rw-r--r--deps/v8/test/message/strong-object-set-proto.out9
-rw-r--r--deps/v8/test/message/super-constructor-extra-statement.js4
-rw-r--r--deps/v8/test/message/super-constructor.js4
-rw-r--r--deps/v8/test/message/super-in-function.js4
-rw-r--r--deps/v8/test/mjsunit/arguments.js16
-rw-r--r--deps/v8/test/mjsunit/array-length.js13
-rw-r--r--deps/v8/test/mjsunit/array-sort.js16
-rw-r--r--deps/v8/test/mjsunit/asm/atomics-add.js93
-rw-r--r--deps/v8/test/mjsunit/asm/atomics-and.js94
-rw-r--r--deps/v8/test/mjsunit/asm/atomics-compareexchange.js121
-rw-r--r--deps/v8/test/mjsunit/asm/atomics-exchange.js92
-rw-r--r--deps/v8/test/mjsunit/asm/atomics-load.js102
-rw-r--r--deps/v8/test/mjsunit/asm/atomics-or.js93
-rw-r--r--deps/v8/test/mjsunit/asm/atomics-store.js109
-rw-r--r--deps/v8/test/mjsunit/asm/atomics-sub.js94
-rw-r--r--deps/v8/test/mjsunit/asm/atomics-xor.js93
-rw-r--r--deps/v8/test/mjsunit/big-array-literal.js3
-rw-r--r--deps/v8/test/mjsunit/call-counts.js43
-rw-r--r--deps/v8/test/mjsunit/call-runtime-tail.js81
-rw-r--r--deps/v8/test/mjsunit/compiler/deopt-tonumber-compare.js44
-rw-r--r--deps/v8/test/mjsunit/compiler/deopt-tonumber-shift.js40
-rw-r--r--deps/v8/test/mjsunit/compiler/jsnatives.js4
-rw-r--r--deps/v8/test/mjsunit/compiler/optimize_max.js69
-rw-r--r--deps/v8/test/mjsunit/compiler/optimize_min.js69
-rw-r--r--deps/v8/test/mjsunit/compiler/osr-array-len.js22
-rw-r--r--deps/v8/test/mjsunit/compiler/osr-maze1.js2
-rw-r--r--deps/v8/test/mjsunit/compiler/osr-maze2.js2
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-4206.js28
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-4207.js15
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-445907.js2
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-446647.js2
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-447567.js2
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-491578.js15
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-shift-left.js41
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-shift-right-logical.js41
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-shift-right.js41
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-uint8-deopt.js2
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-variable-liveness.js22
-rw-r--r--deps/v8/test/mjsunit/compiler/stubs/floor-stub.js54
-rw-r--r--deps/v8/test/mjsunit/compiler/try-binop.js45
-rw-r--r--deps/v8/test/mjsunit/compiler/try-deopt.js3
-rw-r--r--deps/v8/test/mjsunit/compiler/try-osr.js51
-rw-r--r--deps/v8/test/mjsunit/d8-worker-sharedarraybuffer.js (renamed from deps/v8/test/mjsunit/regress/regress-1878.js)50
-rw-r--r--deps/v8/test/mjsunit/d8-worker-spawn-worker.js (renamed from deps/v8/test/mjsunit/regress/regress-parse-object-literal.js)19
-rw-r--r--deps/v8/test/mjsunit/d8-worker.js137
-rw-r--r--deps/v8/test/mjsunit/date.js14
-rw-r--r--deps/v8/test/mjsunit/debug-backtrace-text.js2
-rw-r--r--deps/v8/test/mjsunit/debug-backtrace.js4
-rw-r--r--deps/v8/test/mjsunit/debug-break-inline.js2
-rw-r--r--deps/v8/test/mjsunit/debug-breakpoints.js1
-rw-r--r--deps/v8/test/mjsunit/debug-clearbreakpointgroup.js1
-rw-r--r--deps/v8/test/mjsunit/debug-evaluate-arguments.js2
-rw-r--r--deps/v8/test/mjsunit/debug-evaluate-closure.js1
-rw-r--r--deps/v8/test/mjsunit/debug-evaluate-with.js1
-rw-r--r--deps/v8/test/mjsunit/debug-liveedit-breakpoints.js2
-rw-r--r--deps/v8/test/mjsunit/debug-liveedit-patch-positions.js3
-rw-r--r--deps/v8/test/mjsunit/debug-liveedit-stack-padding.js4
-rw-r--r--deps/v8/test/mjsunit/debug-receiver.js2
-rw-r--r--deps/v8/test/mjsunit/debug-references.js3
-rw-r--r--deps/v8/test/mjsunit/debug-scopes.js6
-rw-r--r--deps/v8/test/mjsunit/debug-script-breakpoints.js3
-rw-r--r--deps/v8/test/mjsunit/debug-script.js5
-rw-r--r--deps/v8/test/mjsunit/debug-step-2.js1
-rw-r--r--deps/v8/test/mjsunit/debug-stepframe.js6
-rw-r--r--deps/v8/test/mjsunit/debug-stepin-accessor-ic.js49
-rw-r--r--deps/v8/test/mjsunit/debug-stepin-positions.js11
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part1.js2
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part2.js2
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part3.js2
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part4.js2
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part5.js2
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part6.js2
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part7.js2
-rw-r--r--deps/v8/test/mjsunit/debug-stepout-scope-part8.js2
-rw-r--r--deps/v8/test/mjsunit/declare-locally.js2
-rw-r--r--deps/v8/test/mjsunit/deserialize-script-id.js8
-rw-r--r--deps/v8/test/mjsunit/elements-kind.js2
-rw-r--r--deps/v8/test/mjsunit/enumeration-order.js8
-rw-r--r--deps/v8/test/mjsunit/es6/arguments-iterator.js5
-rw-r--r--deps/v8/test/mjsunit/es6/block-for.js27
-rw-r--r--deps/v8/test/mjsunit/es6/block-non-strict-errors.js2
-rw-r--r--deps/v8/test/mjsunit/es6/class-property-name-eval-arguments.js (renamed from deps/v8/test/mjsunit/harmony/class-property-name-eval-arguments.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/classes-experimental.js (renamed from deps/v8/test/mjsunit/harmony/classes-experimental.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/classes-lazy-parsing.js (renamed from deps/v8/test/mjsunit/harmony/classes-lazy-parsing.js)15
-rw-r--r--deps/v8/test/mjsunit/es6/classes-maps.js (renamed from deps/v8/test/mjsunit/harmony/classes-maps.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/classes-subclass-arrays.js (renamed from deps/v8/test/mjsunit/harmony/classes-subclass-arrays.js)3
-rw-r--r--deps/v8/test/mjsunit/es6/classes.js (renamed from deps/v8/test/mjsunit/harmony/classes.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/debug-blockscopes.js10
-rw-r--r--deps/v8/test/mjsunit/es6/debug-evaluate-blockscopes.js8
-rw-r--r--deps/v8/test/mjsunit/es6/debug-step-into-class-extends.js (renamed from deps/v8/test/mjsunit/harmony/debug-step-into-class-extends.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/debug-step-into-constructor.js (renamed from deps/v8/test/mjsunit/harmony/debug-step-into-constructor.js)21
-rw-r--r--deps/v8/test/mjsunit/es6/debug-stepnext-for.js33
-rw-r--r--deps/v8/test/mjsunit/es6/generators-relocation.js6
-rw-r--r--deps/v8/test/mjsunit/es6/generators-runtime.js33
-rw-r--r--deps/v8/test/mjsunit/es6/indexed-integer-exotics.js21
-rw-r--r--deps/v8/test/mjsunit/es6/iterator-prototype.js58
-rw-r--r--deps/v8/test/mjsunit/es6/method-name-eval-arguments.js (renamed from deps/v8/test/mjsunit/harmony/method-name-eval-arguments.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/object-literals-method.js (renamed from deps/v8/test/mjsunit/harmony/object-literals-method.js)16
-rw-r--r--deps/v8/test/mjsunit/es6/object-literals-property-shorthand.js (renamed from deps/v8/test/mjsunit/harmony/object-literals-property-shorthand.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/promise-internal-setter.js17
-rw-r--r--deps/v8/test/mjsunit/es6/regress/regress-2506.js16
-rw-r--r--deps/v8/test/mjsunit/es6/regress/regress-3750.js (renamed from deps/v8/test/mjsunit/harmony/regress/regress-3750.js)3
-rw-r--r--deps/v8/test/mjsunit/es6/regress/regress-4097.js37
-rw-r--r--deps/v8/test/mjsunit/es6/regress/regress-455141.js (renamed from deps/v8/test/mjsunit/harmony/regress/regress-455141.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/string-html.js42
-rw-r--r--deps/v8/test/mjsunit/es6/templates.js20
-rw-r--r--deps/v8/test/mjsunit/es6/toMethod.js (renamed from deps/v8/test/mjsunit/harmony/toMethod.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-copywithin.js173
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-every.js (renamed from deps/v8/test/mjsunit/harmony/typedarrays-every.js)15
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-fill.js45
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-find.js187
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-findindex.js187
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-foreach.js (renamed from deps/v8/test/mjsunit/harmony/typedarrays-foreach.js)21
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-from.js121
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-indexing.js71
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-iteration.js194
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-of.js (renamed from deps/v8/test/mjsunit/harmony/typedarrays-of.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-proto.js (renamed from deps/v8/test/mjsunit/harmony/typedarray-proto.js)2
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-reduce.js250
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-reverse.js54
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-slice.js71
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-sort.js55
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray-tostring.js86
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray.js (renamed from deps/v8/test/mjsunit/harmony/typedarrays.js)37
-rw-r--r--deps/v8/test/mjsunit/external-array-no-sse2.js715
-rw-r--r--deps/v8/test/mjsunit/for-in.js12
-rw-r--r--deps/v8/test/mjsunit/function-bind-name.js13
-rw-r--r--deps/v8/test/mjsunit/get-caller-js-function-throws.js14
-rw-r--r--deps/v8/test/mjsunit/get-caller-js-function.js21
-rw-r--r--deps/v8/test/mjsunit/global-deleted-property-keyed.js6
-rw-r--r--deps/v8/test/mjsunit/global-hash.js19
-rw-r--r--deps/v8/test/mjsunit/handle-count-ast.js12
-rw-r--r--deps/v8/test/mjsunit/handle-count-runtime-literals.js1230
-rw-r--r--deps/v8/test/mjsunit/harmony/array-concat.js24
-rw-r--r--deps/v8/test/mjsunit/harmony/array-find.js24
-rw-r--r--deps/v8/test/mjsunit/harmony/array-findindex.js24
-rw-r--r--deps/v8/test/mjsunit/harmony/array-from.js28
-rw-r--r--deps/v8/test/mjsunit/harmony/array-of.js30
-rw-r--r--deps/v8/test/mjsunit/harmony/arrow-functions-lexical-arguments.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/arrow-functions-this.js81
-rw-r--r--deps/v8/test/mjsunit/harmony/arrow-rest-params.js142
-rw-r--r--deps/v8/test/mjsunit/harmony/atomics.js444
-rw-r--r--deps/v8/test/mjsunit/harmony/class-computed-property-names-super.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/computed-property-names-classes.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/computed-property-names-deopt.js30
-rw-r--r--deps/v8/test/mjsunit/harmony/computed-property-names-object-literals-methods.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/computed-property-names-super.js3
-rw-r--r--deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount-nolazy.js41
-rw-r--r--deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount.js41
-rw-r--r--deps/v8/test/mjsunit/harmony/destructuring.js738
-rw-r--r--deps/v8/test/mjsunit/harmony/new-target.js370
-rw-r--r--deps/v8/test/mjsunit/harmony/object-literals-super.js51
-rw-r--r--deps/v8/test/mjsunit/harmony/private.js52
-rw-r--r--deps/v8/test/mjsunit/harmony/proxies-for.js17
-rw-r--r--deps/v8/test/mjsunit/harmony/proxies.js3
-rw-r--r--deps/v8/test/mjsunit/harmony/regress/regress-4160.js29
-rw-r--r--deps/v8/test/mjsunit/harmony/regress/regress-arrow-duplicate-params.js7
-rw-r--r--deps/v8/test/mjsunit/harmony/regress/regress-crbug-451770.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/rest-params-lazy-parsing.js18
-rw-r--r--deps/v8/test/mjsunit/harmony/rest-params.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/set-prototype-of.js18
-rw-r--r--deps/v8/test/mjsunit/harmony/sharedarraybuffer.js577
-rw-r--r--deps/v8/test/mjsunit/harmony/spread-array.js179
-rw-r--r--deps/v8/test/mjsunit/harmony/spread-call-super-property.js20
-rw-r--r--deps/v8/test/mjsunit/harmony/super.js151
-rw-r--r--deps/v8/test/mjsunit/has-own-property-evaluation-order.js13
-rw-r--r--deps/v8/test/mjsunit/json-replacer-number-wrapper-tostring.js20
-rw-r--r--deps/v8/test/mjsunit/json-replacer-order.js26
-rw-r--r--deps/v8/test/mjsunit/math-abs.js16
-rw-r--r--deps/v8/test/mjsunit/math-floor-negative.js2
-rw-r--r--deps/v8/test/mjsunit/math-floor-of-div-minus-zero.js2
-rw-r--r--deps/v8/test/mjsunit/math-floor-of-div-nosudiv.js2
-rw-r--r--deps/v8/test/mjsunit/math-floor-of-div.js2
-rw-r--r--deps/v8/test/mjsunit/messages.js98
-rw-r--r--deps/v8/test/mjsunit/migrations.js12
-rw-r--r--deps/v8/test/mjsunit/mjsunit.status33
-rw-r--r--deps/v8/test/mjsunit/own-symbols.js55
-rw-r--r--deps/v8/test/mjsunit/proto-accessor.js18
-rw-r--r--deps/v8/test/mjsunit/regexp-sort.js48
-rw-r--r--deps/v8/test/mjsunit/regress/poly_count_operation.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1119.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1130.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1132.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-115452.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1170187.js1
-rw-r--r--deps/v8/test/mjsunit/regress/regress-119609.js1
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1199637.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-131994.js1
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1419.js10
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1586.js6
-rw-r--r--deps/v8/test/mjsunit/regress/regress-166553.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2318.js3
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2593.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2653.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-325676.js1
-rw-r--r--deps/v8/test/mjsunit/regress/regress-360733.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-370384.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-3718.js21
-rw-r--r--deps/v8/test/mjsunit/regress/regress-3960.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-4121.js3
-rw-r--r--deps/v8/test/mjsunit/regress/regress-4169.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-417709a.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-4214.js6
-rw-r--r--deps/v8/test/mjsunit/regress/regress-4255-1.js26
-rw-r--r--deps/v8/test/mjsunit/regress/regress-4255-2.js24
-rw-r--r--deps/v8/test/mjsunit/regress/regress-4255-3.js24
-rw-r--r--deps/v8/test/mjsunit/regress/regress-4255-4.js24
-rw-r--r--deps/v8/test/mjsunit/regress/regress-436896.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-479528.js13
-rw-r--r--deps/v8/test/mjsunit/regress/regress-489151.js12
-rw-r--r--deps/v8/test/mjsunit/regress/regress-491481.js15
-rw-r--r--deps/v8/test/mjsunit/regress/regress-491536.js10
-rw-r--r--deps/v8/test/mjsunit/regress/regress-499790.js14
-rw-r--r--deps/v8/test/mjsunit/regress/regress-500173.js12
-rw-r--r--deps/v8/test/mjsunit/regress/regress-500176.js13
-rw-r--r--deps/v8/test/mjsunit/regress/regress-500831.js94
-rw-r--r--deps/v8/test/mjsunit/regress/regress-500980.js7
-rw-r--r--deps/v8/test/mjsunit/regress/regress-503565.js21
-rw-r--r--deps/v8/test/mjsunit/regress/regress-507980.js8
-rw-r--r--deps/v8/test/mjsunit/regress/regress-581.js6
-rw-r--r--deps/v8/test/mjsunit/regress/regress-747.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-78270.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-arguments-gc.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-assignment-in-test-context.js3
-rw-r--r--deps/v8/test/mjsunit/regress/regress-binop-nosse2.js167
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-107996.js1
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-171715.js1
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-217858.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-222893.js1
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-424142.js3
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-450960.js8
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-467180.js41
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-471659.js22
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-474297.js5
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-480819.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-481896.js56
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-482998.js23
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-487105.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-487289.js20
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-487608.js22
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-489293.js16
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-489597.js12
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-489597.js-script5
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-490680.js18
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-491062.js22
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-491943.js25
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-492526.js7
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-493284.js10
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-493290.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-493568.js12
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-493779.js11
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-498022.js15
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-498142.js8
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-498811.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-500435.js (renamed from deps/v8/test/mjsunit/regress/regress-crbug-514268.js)7
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-500497.js3
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-500824.js23
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-501711.js14
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-501808.js6
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-501809.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-503578.js14
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-503698.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-503968.js13
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-503991.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-504136.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-504727.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-504729.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-504787.js15
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-505007-1.js14
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-505007-2.js15
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-505354.js14
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-505370.js22
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-505778.js8
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-506443.js89
-rw-r--r--deps/v8/test/mjsunit/regress/regress-debug-code-recompilation.js3
-rw-r--r--deps/v8/test/mjsunit/regress/regress-debug-deopt-while-recompile.js1
-rw-r--r--deps/v8/test/mjsunit/regress/regress-eval-context.js20
-rw-r--r--deps/v8/test/mjsunit/regress/regress-existing-shared-function-info.js18
-rw-r--r--deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js1
-rw-r--r--deps/v8/test/mjsunit/regress/regress-osr-context.js19
-rw-r--r--deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-regexp-codeflush.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-splice-large-index.js1
-rw-r--r--deps/v8/test/mjsunit/regress/regress-x87.js2
-rw-r--r--deps/v8/test/mjsunit/regress/string-set-char-deopt.js2
-rw-r--r--deps/v8/test/mjsunit/samevalue.js2
-rw-r--r--deps/v8/test/mjsunit/strict-mode.js2
-rw-r--r--deps/v8/test/mjsunit/string-normalize.js11
-rw-r--r--deps/v8/test/mjsunit/strong/classes.js3
-rw-r--r--deps/v8/test/mjsunit/strong/declaration-after-use.js14
-rw-r--r--deps/v8/test/mjsunit/strong/function-arity.js355
-rw-r--r--deps/v8/test/mjsunit/strong/functions.js4
-rw-r--r--deps/v8/test/mjsunit/strong/implicit-conversions-constants.js203
-rw-r--r--deps/v8/test/mjsunit/strong/implicit-conversions-count.js168
-rw-r--r--deps/v8/test/mjsunit/strong/implicit-conversions-inlining.js231
-rw-r--r--deps/v8/test/mjsunit/strong/implicit-conversions.js214
-rw-r--r--deps/v8/test/mjsunit/strong/literals.js352
-rw-r--r--deps/v8/test/mjsunit/strong/load-builtins.js42
-rw-r--r--deps/v8/test/mjsunit/strong/load-element-mutate-backing-store.js239
-rw-r--r--deps/v8/test/mjsunit/strong/load-element.js267
-rw-r--r--deps/v8/test/mjsunit/strong/load-property-mutate-backing-store.js174
-rw-r--r--deps/v8/test/mjsunit/strong/load-property.js203
-rw-r--r--deps/v8/test/mjsunit/strong/load-proxy.js98
-rw-r--r--deps/v8/test/mjsunit/strong/load-super.js102
-rw-r--r--deps/v8/test/mjsunit/strong/object-delete.js255
-rw-r--r--deps/v8/test/mjsunit/strong/object-freeze-property.js75
-rw-r--r--deps/v8/test/mjsunit/strong/object-set-prototype.js83
-rw-r--r--deps/v8/test/mjsunit/strong/super.js62
-rw-r--r--deps/v8/test/mjsunit/testcfg.py3
-rw-r--r--deps/v8/test/mjsunit/third_party/object-keys/LICENSE30
-rw-r--r--deps/v8/test/mjsunit/third_party/object-keys/object-keys.js (renamed from deps/v8/test/mjsunit/third_party/object-keys.js)0
-rw-r--r--deps/v8/test/mjsunit/third_party/regexp-pcre/LICENSE68
-rw-r--r--deps/v8/test/mjsunit/third_party/regexp-pcre/regexp-pcre.js (renamed from deps/v8/test/mjsunit/third_party/regexp-pcre.js)0
-rw-r--r--deps/v8/test/mjsunit/this-dynamic-lookup.js10
-rw-r--r--deps/v8/test/mjsunit/unbox-double-field-indexed.js23
-rw-r--r--deps/v8/test/mjsunit/unbox-double-field.js22
-rw-r--r--deps/v8/test/mjsunit/unbox-smi-field-indexed.js23
-rw-r--r--deps/v8/test/mjsunit/unbox-smi-field.js22
-rw-r--r--deps/v8/test/mjsunit/undetectable-compare.js96
-rw-r--r--deps/v8/test/mjsunit/undetectable.js87
-rw-r--r--deps/v8/test/mjsunit/uri.js10
-rw-r--r--deps/v8/test/mozilla/mozilla.status1
-rw-r--r--deps/v8/test/simdjs/SimdJs.json315
-rwxr-xr-xdeps/v8/test/simdjs/generate.py61
-rw-r--r--deps/v8/test/simdjs/harness-adapt.js29
-rw-r--r--deps/v8/test/simdjs/harness-finish.js26
-rw-r--r--deps/v8/test/simdjs/simdjs.status26
-rw-r--r--deps/v8/test/simdjs/testcfg.py101
-rw-r--r--deps/v8/test/test262-es6/README4
-rw-r--r--deps/v8/test/test262-es6/test262-es6.status1066
-rw-r--r--deps/v8/test/test262-es6/testcfg.py34
-rw-r--r--deps/v8/test/test262/test262.status25
-rw-r--r--deps/v8/test/test262/testcfg.py13
-rw-r--r--deps/v8/test/unittests/base/bits-unittest.cc19
-rw-r--r--deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc563
-rw-r--r--deps/v8/test/unittests/compiler/common-operator-reducer-unittest.cc342
-rw-r--r--deps/v8/test/unittests/compiler/common-operator-unittest.cc52
-rw-r--r--deps/v8/test/unittests/compiler/control-equivalence-unittest.cc6
-rw-r--r--deps/v8/test/unittests/compiler/control-flow-optimizer-unittest.cc20
-rw-r--r--deps/v8/test/unittests/compiler/control-reducer-unittest.cc326
-rw-r--r--deps/v8/test/unittests/compiler/dead-code-elimination-unittest.cc375
-rw-r--r--deps/v8/test/unittests/compiler/graph-reducer-unittest.cc165
-rw-r--r--deps/v8/test/unittests/compiler/graph-reducer-unittest.h1
-rw-r--r--deps/v8/test/unittests/compiler/graph-trimmer-unittest.cc85
-rw-r--r--deps/v8/test/unittests/compiler/graph-unittest.cc19
-rw-r--r--deps/v8/test/unittests/compiler/graph-unittest.h2
-rw-r--r--deps/v8/test/unittests/compiler/instruction-selector-unittest.cc110
-rw-r--r--deps/v8/test/unittests/compiler/instruction-selector-unittest.h19
-rw-r--r--deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc4
-rw-r--r--deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc34
-rw-r--r--deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc71
-rw-r--r--deps/v8/test/unittests/compiler/js-operator-unittest.cc9
-rw-r--r--deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc389
-rw-r--r--deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc321
-rw-r--r--deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc10
-rw-r--r--deps/v8/test/unittests/compiler/load-elimination-unittest.cc4
-rw-r--r--deps/v8/test/unittests/compiler/loop-peeling-unittest.cc3
-rw-r--r--deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc84
-rw-r--r--deps/v8/test/unittests/compiler/machine-operator-unittest.cc237
-rw-r--r--deps/v8/test/unittests/compiler/node-properties-unittest.cc114
-rw-r--r--deps/v8/test/unittests/compiler/node-test-utils.cc197
-rw-r--r--deps/v8/test/unittests/compiler/node-test-utils.h24
-rw-r--r--deps/v8/test/unittests/compiler/node-unittest.cc92
-rw-r--r--deps/v8/test/unittests/compiler/scheduler-unittest.cc1382
-rw-r--r--deps/v8/test/unittests/compiler/simplified-operator-unittest.cc1
-rw-r--r--deps/v8/test/unittests/compiler/tail-call-optimization-unittest.cc22
-rw-r--r--deps/v8/test/unittests/counters-unittest.cc28
-rw-r--r--deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc395
-rw-r--r--deps/v8/test/unittests/heap/heap-unittest.cc48
-rw-r--r--deps/v8/test/unittests/heap/memory-reducer-unittest.cc331
-rw-r--r--deps/v8/test/unittests/libplatform/default-platform-unittest.cc88
-rw-r--r--deps/v8/test/unittests/unittests.gyp5
-rw-r--r--deps/v8/test/webkit/class-syntax-extends-expected.txt4
-rw-r--r--deps/v8/test/webkit/cyclic-prototypes-expected.txt2
-rw-r--r--deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt6
-rw-r--r--deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js6
-rw-r--r--deps/v8/test/webkit/fast/js/arguments-expected.txt2
-rw-r--r--deps/v8/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt6
-rw-r--r--deps/v8/test/webkit/webkit.status4
503 files changed, 30539 insertions, 9510 deletions
diff --git a/deps/v8/test/cctest/cctest.gyp b/deps/v8/test/cctest/cctest.gyp
index 276ebd2f97..bcbbe7b226 100644
--- a/deps/v8/test/cctest/cctest.gyp
+++ b/deps/v8/test/cctest/cctest.gyp
@@ -54,8 +54,6 @@
'compiler/test-basic-block-profiler.cc',
'compiler/test-branch-combine.cc',
'compiler/test-changes-lowering.cc',
- 'compiler/test-codegen-deopt.cc',
- 'compiler/test-control-reducer.cc',
'compiler/test-gap-resolver.cc',
'compiler/test-graph-visualizer.cc',
'compiler/test-instruction.cc',
diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h
index bade26308f..cc9edc801f 100644
--- a/deps/v8/test/cctest/cctest.h
+++ b/deps/v8/test/cctest/cctest.h
@@ -93,6 +93,7 @@ class TestHeap : public i::Heap {
using i::Heap::AllocateByteArray;
using i::Heap::AllocateFixedArray;
using i::Heap::AllocateHeapNumber;
+ using i::Heap::AllocateFloat32x4;
using i::Heap::AllocateJSObject;
using i::Heap::AllocateJSObjectFromMap;
using i::Heap::AllocateMap;
@@ -397,6 +398,13 @@ static inline v8::Local<v8::Value> CompileRun(const char* source) {
}
+// Helper functions that compile and run the source.
+static inline v8::MaybeLocal<v8::Value> CompileRun(
+ v8::Local<v8::Context> context, const char* source) {
+ return v8::Script::Compile(v8_str(source))->Run(context);
+}
+
+
// Compiles source as an ES6 module.
static inline v8::Local<v8::Value> CompileRunModule(const char* source) {
v8::ScriptCompiler::Source script_source(v8_str(source));
@@ -504,8 +512,8 @@ static inline void ExpectUndefined(const char* code) {
// Helper function that simulates a full new-space in the heap.
static inline bool FillUpOnePage(v8::internal::NewSpace* space) {
- v8::internal::AllocationResult allocation =
- space->AllocateRaw(v8::internal::Page::kMaxRegularHeapObjectSize);
+ v8::internal::AllocationResult allocation = space->AllocateRawUnaligned(
+ v8::internal::Page::kMaxRegularHeapObjectSize);
if (allocation.IsRetry()) return false;
v8::internal::HeapObject* free_space = NULL;
CHECK(allocation.To(&free_space));
@@ -524,7 +532,7 @@ static inline void AllocateAllButNBytes(v8::internal::NewSpace* space,
int new_linear_size = space_remaining - extra_bytes;
if (new_linear_size == 0) return;
v8::internal::AllocationResult allocation =
- space->AllocateRaw(new_linear_size);
+ space->AllocateRawUnaligned(new_linear_size);
v8::internal::HeapObject* free_space = NULL;
CHECK(allocation.To(&free_space));
space->heap()->CreateFillerObjectAt(free_space->address(), new_linear_size);
@@ -561,7 +569,7 @@ static inline void SimulateIncrementalMarking(i::Heap* heap) {
}
CHECK(marking->IsMarking() || marking->IsStopped());
if (marking->IsStopped()) {
- marking->Start();
+ marking->Start(i::Heap::kNoGCFlags);
}
CHECK(marking->IsMarking());
while (!marking->IsComplete()) {
@@ -574,6 +582,18 @@ static inline void SimulateIncrementalMarking(i::Heap* heap) {
}
+static void DummyDebugEventListener(
+ const v8::Debug::EventDetails& event_details) {}
+
+
+static inline void EnableDebugger() {
+ v8::Debug::SetDebugEventListener(&DummyDebugEventListener);
+}
+
+
+static inline void DisableDebugger() { v8::Debug::SetDebugEventListener(NULL); }
+
+
// 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.
diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status
index 9c4f6ccf05..68c570edcc 100644
--- a/deps/v8/test/cctest/cctest.status
+++ b/deps/v8/test/cctest/cctest.status
@@ -64,11 +64,13 @@
# are actually 13 * 38 * 5 * 128 = 316160 individual tests hidden here.
'test-parsing/ParserSync': [PASS, NO_VARIANTS],
- # This tests only the type system, so there is no point in running several
- # variants.
+ # This tests only the type system, no point in running several variants.
'test-hydrogen-types/*': [PASS, NO_VARIANTS],
'test-types/*': [PASS, NO_VARIANTS],
+ # This tests API threading, no point in running several variants.
+ 'test-api/Threading*': [PASS, NO_VARIANTS],
+
# The cpu profiler tests are notoriously flaky.
# BUG(2999). (test/cpu-profiler/CollectCpuProfile)
# BUG(3287). (test-cpu-profiler/SampleWhenFrameIsNotSetup)
@@ -97,11 +99,7 @@
##############################################################################
# TurboFan compiler failures.
- # TODO(mstarzinger): control edges are messed up in exception tests.
- 'test-run-jsexceptions/*': [PASS, NO_VARIANTS],
-
# Some tests are just too slow to run for now.
- 'test-api/Threading*': [PASS, NO_VARIANTS],
'test-heap/IncrementalMarkingStepMakesBigProgressWithLargeObjects': [PASS, NO_VARIANTS],
'test-heap-profiler/ManyLocalsInSharedContext': [PASS, NO_VARIANTS],
'test-serialize/SerializeToplevelLargeCodeObject': [PASS, NO_VARIANTS],
@@ -119,12 +117,6 @@
'test-debug/ScriptBreakPointByIdThroughJavaScript': [PASS, NO_VARIANTS],
'test-debug/ScriptBreakPointByNameThroughJavaScript': [PASS, NO_VARIANTS],
- # TODO(jarin): Cannot lazy-deoptimize from conversions before comparisons.
- 'test-js-typed-lowering/OrderCompareEffects': [SKIP],
-
- # TODO(jochen): Reenable after we removed the CHECK() from the marking queue.
- 'test-mark-compact/MarkingDeque': [SKIP],
-
############################################################################
# Slow tests.
'test-api/Threading1': [PASS, ['mode == debug', SLOW]],
@@ -194,6 +186,12 @@
['msan == True', {
# ICU upstream issues.
'test-strings/CountBreakIterator': [SKIP],
+
+ # Slow tests.
+ 'test-api/Threading1': [PASS, SLOW],
+ 'test-api/Threading2': [PASS, SLOW],
+ 'test-api/Threading3': [PASS, SLOW],
+ 'test-api/Threading4': [PASS, SLOW],
}], # 'msan == True'
##############################################################################
@@ -258,6 +256,9 @@
['arch == mipsel or arch == mips', {
'test-cpu-profiler/CollectDeoptEvents': [PASS, FAIL],
+ # TODO(mips-team): Improve code-size on large RegExp's.
+ 'test-heap/TestSizeOfRegExpCode': [SKIP],
+
# BUG(1075): Unresolved crashes on MIPS also.
'test-serialize/Deserialize': [SKIP],
'test-serialize/DeserializeFromSecondSerializationAndRunScript2': [SKIP],
@@ -271,12 +272,8 @@
'test-api/ExternalArrays': [PASS, NO_VARIANTS],
# TODO(mips-team): Currently fails on mips board.
- 'test-simplified-lowering/RunNumberMultiply_TruncatingToUint32': [SKIP],
- 'test-simplified-lowering/RunNumberDivide_2_TruncatingToUint32': [SKIP],
'test-parsing/TooManyArguments': [SKIP],
'test-api/Threading3': [SKIP],
- 'test-api/RequestInterruptTestWithNativeAccessor': [SKIP],
- 'test-api/RequestInterruptTestWithAccessor': [SKIP],
}], # 'arch == mips'
##############################################################################
@@ -295,12 +292,7 @@
##############################################################################
['arch == x87', {
-
- # Test requires turbofan:
- 'codegen-tester/CompareWrapper': [SKIP],
- 'codegen-tester/ParametersEqual': [SKIP],
- 'test-simplified-lowering/LowerStringOps_to_call_and_compare': [SKIP],
- 'test-serialize/SerializeInternalReference': [FAIL],
+ 'test-run-machops/RunFloat64InsertLowWord32': [SKIP]
}], # 'arch == x87'
##############################################################################
diff --git a/deps/v8/test/cctest/compiler/c-signature.h b/deps/v8/test/cctest/compiler/c-signature.h
index 5d161dbe7a..83b3328a3b 100644
--- a/deps/v8/test/cctest/compiler/c-signature.h
+++ b/deps/v8/test/cctest/compiler/c-signature.h
@@ -11,76 +11,103 @@ namespace v8 {
namespace internal {
namespace compiler {
+#define FOREACH_CTYPE_MACHINE_TYPE_MAPPING(V) \
+ V(void, kMachNone) \
+ V(bool, kMachBool) \
+ V(int8_t, kMachInt8) \
+ V(uint8_t, kMachUint8) \
+ V(int16_t, kMachInt16) \
+ V(uint16_t, kMachUint16) \
+ V(int32_t, kMachInt32) \
+ V(uint32_t, kMachUint32) \
+ V(int64_t, kMachInt64) \
+ V(uint64_t, kMachUint64) \
+ V(float, kMachFloat32) \
+ V(double, kMachFloat64) \
+ V(void*, kMachPtr) \
+ V(int*, kMachPtr)
+
template <typename T>
inline MachineType MachineTypeForC() {
- CHECK(false); // Instantiated with invalid type.
- return kMachNone;
-}
-
-template <>
-inline MachineType MachineTypeForC<void>() {
- return kMachNone;
-}
-
-template <>
-inline MachineType MachineTypeForC<int8_t>() {
- return kMachInt8;
-}
-
-template <>
-inline MachineType MachineTypeForC<uint8_t>() {
- return kMachUint8;
-}
-
-template <>
-inline MachineType MachineTypeForC<int16_t>() {
- return kMachInt16;
-}
-
-template <>
-inline MachineType MachineTypeForC<uint16_t>() {
- return kMachUint16;
-}
-
-template <>
-inline MachineType MachineTypeForC<int32_t>() {
- return kMachInt32;
+ while (false) {
+ // All other types T must be assignable to Object*
+ *(static_cast<Object* volatile*>(0)) = static_cast<T>(0);
+ }
+ return kMachAnyTagged;
}
-template <>
-inline MachineType MachineTypeForC<uint32_t>() {
- return kMachUint32;
-}
+#define DECLARE_TEMPLATE_SPECIALIZATION(ctype, mtype) \
+ template <> \
+ inline MachineType MachineTypeForC<ctype>() { \
+ return mtype; \
+ }
+FOREACH_CTYPE_MACHINE_TYPE_MAPPING(DECLARE_TEMPLATE_SPECIALIZATION)
+#undef DECLARE_TEMPLATE_SPECIALIZATION
-template <>
-inline MachineType MachineTypeForC<int64_t>() {
- return kMachInt64;
-}
+// Helper for building machine signatures from C types.
+class CSignature : public MachineSignature {
+ protected:
+ CSignature(size_t return_count, size_t parameter_count, MachineType* reps)
+ : MachineSignature(return_count, parameter_count, reps) {}
-template <>
-inline MachineType MachineTypeForC<uint64_t>() {
- return kMachUint64;
-}
+ public:
+ template <typename P1 = void, typename P2 = void, typename P3 = void,
+ typename P4 = void, typename P5 = void>
+ void VerifyParams() {
+ // Verifies the C signature against the machine types. Maximum {5} params.
+ CHECK_LT(parameter_count(), 6u);
+ const int kMax = 5;
+ MachineType params[] = {MachineTypeForC<P1>(), MachineTypeForC<P2>(),
+ MachineTypeForC<P3>(), MachineTypeForC<P4>(),
+ MachineTypeForC<P5>()};
+ for (int p = kMax - 1; p >= 0; p--) {
+ if (p < static_cast<int>(parameter_count())) {
+ CHECK_EQ(GetParam(p), params[p]);
+ } else {
+ CHECK_EQ(kMachNone, params[p]);
+ }
+ }
+ }
-template <>
-inline MachineType MachineTypeForC<double>() {
- return kMachFloat64;
-}
+ static CSignature* New(Zone* zone, MachineType ret,
+ MachineType p1 = kMachNone, MachineType p2 = kMachNone,
+ MachineType p3 = kMachNone, MachineType p4 = kMachNone,
+ MachineType p5 = kMachNone) {
+ MachineType* buffer = zone->NewArray<MachineType>(6);
+ int pos = 0;
+ size_t return_count = 0;
+ if (ret != kMachNone) {
+ buffer[pos++] = ret;
+ return_count++;
+ }
+ buffer[pos++] = p1;
+ buffer[pos++] = p2;
+ buffer[pos++] = p3;
+ buffer[pos++] = p4;
+ buffer[pos++] = p5;
+ size_t param_count = 5;
+ if (p5 == kMachNone) param_count--;
+ if (p4 == kMachNone) param_count--;
+ if (p3 == kMachNone) param_count--;
+ if (p2 == kMachNone) param_count--;
+ if (p1 == kMachNone) param_count--;
+ for (size_t i = 0; i < param_count; i++) {
+ // Check that there are no kMachNone's in the middle of parameters.
+ CHECK_NE(kMachNone, buffer[return_count + i]);
+ }
+ return new (zone) CSignature(return_count, param_count, buffer);
+ }
+};
-template <>
-inline MachineType MachineTypeForC<Object*>() {
- return kMachAnyTagged;
-}
template <typename Ret, uint16_t kParamCount>
-class CSignatureOf : public MachineSignature {
+class CSignatureOf : public CSignature {
protected:
MachineType storage_[1 + kParamCount];
CSignatureOf()
- : MachineSignature(MachineTypeForC<Ret>() != kMachNone ? 1 : 0,
- kParamCount,
- reinterpret_cast<MachineType*>(&storage_)) {
+ : CSignature(MachineTypeForC<Ret>() != kMachNone ? 1 : 0, kParamCount,
+ reinterpret_cast<MachineType*>(&storage_)) {
if (return_count_ == 1) storage_[0] = MachineTypeForC<Ret>();
}
void Set(int index, MachineType type) {
@@ -123,9 +150,11 @@ class CSignature3 : public CSignatureOf<Ret, 3> {
}
};
-static const CSignature2<int32_t, int32_t, int32_t> int32_int32_to_int32;
-static const CSignature2<uint32_t, uint32_t, uint32_t> uint32_uint32_to_uint32;
-static const CSignature2<double, double, double> float64_float64_to_float64;
+typedef CSignature2<int32_t, int32_t, int32_t> CSignature_i_ii;
+typedef CSignature2<uint32_t, uint32_t, uint32_t> CSignature_u_uu;
+typedef CSignature2<float, float, float> CSignature_f_ff;
+typedef CSignature2<double, double, double> CSignature_d_dd;
+typedef CSignature2<Object*, Object*, Object*> CSignature_o_oo;
}
}
} // namespace v8::internal::compiler
diff --git a/deps/v8/test/cctest/compiler/call-tester.h b/deps/v8/test/cctest/compiler/call-tester.h
index 6d8c761452..dc265ea5fa 100644
--- a/deps/v8/test/cctest/compiler/call-tester.h
+++ b/deps/v8/test/cctest/compiler/call-tester.h
@@ -9,6 +9,8 @@
#include "src/simulator.h"
+#include "test/cctest/compiler/c-signature.h"
+
#if V8_TARGET_ARCH_IA32
#if __GNUC__
#define V8_CDECL __attribute__((cdecl))
@@ -23,95 +25,64 @@ namespace v8 {
namespace internal {
namespace compiler {
-// TODO(titzer): use c-signature.h instead of ReturnValueTraits
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 kMachAnyTagged;
- }
-};
+inline R CastReturnValue(uintptr_t r) {
+ return reinterpret_cast<R>(r);
+}
template <>
-struct ReturnValueTraits<int32_t*> {
- static int32_t* Cast(uintptr_t r) { return reinterpret_cast<int32_t*>(r); }
- static MachineType Representation() { return kMachPtr; }
-};
+inline void CastReturnValue(uintptr_t r) {}
template <>
-struct ReturnValueTraits<void> {
- static void Cast(uintptr_t r) {}
- static MachineType Representation() { return kMachPtr; }
-};
+inline bool CastReturnValue(uintptr_t r) {
+ return static_cast<bool>(r);
+}
template <>
-struct ReturnValueTraits<bool> {
- static bool Cast(uintptr_t r) { return static_cast<bool>(r); }
- static MachineType Representation() { return kRepBit; }
-};
+inline int32_t CastReturnValue(uintptr_t r) {
+ return static_cast<int32_t>(r);
+}
template <>
-struct ReturnValueTraits<int32_t> {
- static int32_t Cast(uintptr_t r) { return static_cast<int32_t>(r); }
- static MachineType Representation() { return kMachInt32; }
-};
+inline uint32_t CastReturnValue(uintptr_t r) {
+ return static_cast<uint32_t>(r);
+}
template <>
-struct ReturnValueTraits<uint32_t> {
- static uint32_t Cast(uintptr_t r) { return static_cast<uint32_t>(r); }
- static MachineType Representation() { return kMachUint32; }
-};
-
-template <>
-struct ReturnValueTraits<int64_t> {
- static int64_t Cast(uintptr_t r) { return static_cast<int64_t>(r); }
- static MachineType Representation() { return kMachInt64; }
-};
+inline int64_t CastReturnValue(uintptr_t r) {
+ return static_cast<int64_t>(r);
+}
template <>
-struct ReturnValueTraits<uint64_t> {
- static uint64_t Cast(uintptr_t r) { return static_cast<uint64_t>(r); }
- static MachineType Representation() { return kMachUint64; }
-};
+inline uint64_t CastReturnValue(uintptr_t r) {
+ return static_cast<uint64_t>(r);
+}
template <>
-struct ReturnValueTraits<int16_t> {
- static int16_t Cast(uintptr_t r) { return static_cast<int16_t>(r); }
- static MachineType Representation() { return kMachInt16; }
-};
+inline int16_t CastReturnValue(uintptr_t r) {
+ return static_cast<int16_t>(r);
+}
template <>
-struct ReturnValueTraits<uint16_t> {
- static uint16_t Cast(uintptr_t r) { return static_cast<uint16_t>(r); }
- static MachineType Representation() { return kMachUint16; }
-};
+inline uint16_t CastReturnValue(uintptr_t r) {
+ return static_cast<uint16_t>(r);
+}
template <>
-struct ReturnValueTraits<int8_t> {
- static int8_t Cast(uintptr_t r) { return static_cast<int8_t>(r); }
- static MachineType Representation() { return kMachInt8; }
-};
+inline int8_t CastReturnValue(uintptr_t r) {
+ return static_cast<int8_t>(r);
+}
template <>
-struct ReturnValueTraits<uint8_t> {
- static uint8_t Cast(uintptr_t r) { return static_cast<uint8_t>(r); }
- static MachineType Representation() { return kMachUint8; }
-};
+inline uint8_t CastReturnValue(uintptr_t r) {
+ return static_cast<uint8_t>(r);
+}
template <>
-struct ReturnValueTraits<double> {
- static double Cast(uintptr_t r) {
- UNREACHABLE();
- return 0.0;
- }
- static MachineType Representation() { return kMachFloat64; }
-};
-
+inline double CastReturnValue(uintptr_t r) {
+ UNREACHABLE();
+ return 0.0;
+}
template <typename R>
struct ParameterTraits {
@@ -148,42 +119,52 @@ struct ParameterTraits<uint32_t> {
#endif // !V8_TARGET_ARCH_64_BIT
+template <typename R>
class CallHelper {
public:
- explicit CallHelper(Isolate* isolate, MachineSignature* machine_sig)
- : machine_sig_(machine_sig), isolate_(isolate) {
+ explicit CallHelper(Isolate* isolate, CSignature* csig)
+ : csig_(csig), isolate_(isolate) {
USE(isolate_);
}
virtual ~CallHelper() {}
- static MachineSignature* MakeMachineSignature(
- Zone* zone, MachineType return_type, MachineType p0 = kMachNone,
- MachineType p1 = kMachNone, MachineType p2 = kMachNone,
- MachineType p3 = kMachNone, MachineType p4 = kMachNone) {
- // Count the number of parameters.
- size_t param_count = 5;
- MachineType types[] = {p0, p1, p2, p3, p4};
- while (param_count > 0 && types[param_count - 1] == kMachNone)
- param_count--;
- size_t return_count = return_type == kMachNone ? 0 : 1;
-
- // Build the machine signature.
- MachineSignature::Builder builder(zone, return_count, param_count);
- if (return_count > 0) builder.AddReturn(return_type);
- for (size_t i = 0; i < param_count; i++) {
- builder.AddParam(types[i]);
- }
- return builder.Build();
+ R Call() {
+ typedef R V8_CDECL FType();
+ csig_->VerifyParams();
+ return DoCall(FUNCTION_CAST<FType*>(Generate()));
}
- protected:
- MachineSignature* machine_sig_;
- void VerifyParameters(size_t parameter_count, MachineType* parameter_types) {
- CHECK(machine_sig_->parameter_count() == parameter_count);
- for (size_t i = 0; i < parameter_count; i++) {
- CHECK_EQ(machine_sig_->GetParam(i), parameter_types[i]);
- }
+ template <typename P1>
+ R Call(P1 p1) {
+ typedef R V8_CDECL FType(P1);
+ csig_->VerifyParams<P1>();
+ return DoCall(FUNCTION_CAST<FType*>(Generate()), p1);
+ }
+
+ template <typename P1, typename P2>
+ R Call(P1 p1, P2 p2) {
+ typedef R V8_CDECL FType(P1, P2);
+ csig_->VerifyParams<P1, P2>();
+ return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2);
+ }
+
+ template <typename P1, typename P2, typename P3>
+ R Call(P1 p1, P2 p2, P3 p3) {
+ typedef R V8_CDECL FType(P1, P2, P3);
+ csig_->VerifyParams<P1, P2, P3>();
+ return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3);
+ }
+
+ template <typename P1, typename P2, typename P3, typename P4>
+ R Call(P1 p1, P2 p2, P3 p3, P4 p4) {
+ typedef R V8_CDECL FType(P1, P2, P3, P4);
+ csig_->VerifyParams<P1, P2, P3, P4>();
+ return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4);
}
+
+ protected:
+ CSignature* csig_;
+
virtual byte* Generate() = 0;
private:
@@ -193,39 +174,38 @@ class CallHelper {
return static_cast<uintptr_t>(simulator->CallInt64(f, args));
}
- template <typename R, typename F>
+ template <typename F>
R DoCall(F* f) {
Simulator::CallArgument args[] = {Simulator::CallArgument::End()};
- return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
}
- template <typename R, typename F, typename P1>
+ template <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));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
}
- template <typename R, typename F, typename P1, typename P2>
+ template <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));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
}
- template <typename R, typename F, typename P1, typename P2, typename P3>
+ template <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));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
}
- template <typename R, typename F, typename P1, typename P2, typename P3,
- typename P4>
+ template <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));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
}
#elif USE_SIMULATOR && (V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64)
uintptr_t CallSimulator(byte* f, int64_t p1 = 0, int64_t p2 = 0,
@@ -235,31 +215,30 @@ class CallHelper {
}
- template <typename R, typename F>
+ template <typename F>
R DoCall(F* f) {
- return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f)));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f)));
}
- template <typename R, typename F, typename P1>
+ template <typename F, typename P1>
R DoCall(F* f, P1 p1) {
- return ReturnValueTraits<R>::Cast(
+ return CastReturnValue<R>(
CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1)));
}
- template <typename R, typename F, typename P1, typename P2>
+ template <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)));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f),
+ ParameterTraits<P1>::Cast(p1),
+ ParameterTraits<P2>::Cast(p2)));
}
- template <typename R, typename F, typename P1, typename P2, typename P3>
+ template <typename F, typename P1, typename P2, typename P3>
R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
- return ReturnValueTraits<R>::Cast(CallSimulator(
+ return CastReturnValue<R>(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>
+ template <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(
+ return CastReturnValue<R>(CallSimulator(
FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3),
ParameterTraits<P4>::Cast(p4)));
@@ -271,179 +250,60 @@ class CallHelper {
Simulator* simulator = Simulator::current(isolate_);
return static_cast<uintptr_t>(simulator->Call(f, 4, p1, p2, p3, p4));
}
- template <typename R, typename F>
+ template <typename F>
R DoCall(F* f) {
- return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f)));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f)));
}
- template <typename R, typename F, typename P1>
+ template <typename F, typename P1>
R DoCall(F* f, P1 p1) {
- return ReturnValueTraits<R>::Cast(
+ return CastReturnValue<R>(
CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1)));
}
- template <typename R, typename F, typename P1, typename P2>
+ template <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)));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f),
+ ParameterTraits<P1>::Cast(p1),
+ ParameterTraits<P2>::Cast(p2)));
}
- template <typename R, typename F, typename P1, typename P2, typename P3>
+ template <typename F, typename P1, typename P2, typename P3>
R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
- return ReturnValueTraits<R>::Cast(CallSimulator(
+ return CastReturnValue<R>(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>
+ template <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(
+ return CastReturnValue<R>(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>
+ template <typename F>
R DoCall(F* f) {
return f();
}
- template <typename R, typename F, typename P1>
+ template <typename F, typename P1>
R DoCall(F* f, P1 p1) {
return f(p1);
}
- template <typename R, typename F, typename P1, typename P2>
+ template <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>
+ template <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>
+ template <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(arraysize(parameters), parameters);
- }
-
- template <typename P1, typename P2>
- void VerifyParameters2() {
- MachineType parameters[] = {ReturnValueTraits<P1>::Representation(),
- ReturnValueTraits<P2>::Representation()};
- VerifyParameters(arraysize(parameters), parameters);
- }
-
- template <typename P1, typename P2, typename P3>
- void VerifyParameters3() {
- MachineType parameters[] = {ReturnValueTraits<P1>::Representation(),
- ReturnValueTraits<P2>::Representation(),
- ReturnValueTraits<P3>::Representation()};
- VerifyParameters(arraysize(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(arraysize(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
diff --git a/deps/v8/test/cctest/compiler/codegen-tester.h b/deps/v8/test/cctest/compiler/codegen-tester.h
index f2fc48a479..bc6d938ce1 100644
--- a/deps/v8/test/cctest/compiler/codegen-tester.h
+++ b/deps/v8/test/cctest/compiler/codegen-tester.h
@@ -17,38 +17,26 @@ namespace v8 {
namespace internal {
namespace compiler {
-template <typename MachineAssembler>
-class MachineAssemblerTester : public HandleAndZoneScope,
- public CallHelper,
- public MachineAssembler {
+template <typename ReturnType>
+class RawMachineAssemblerTester : public HandleAndZoneScope,
+ public CallHelper<ReturnType>,
+ public RawMachineAssembler {
public:
- MachineAssemblerTester(MachineType return_type, MachineType p0,
- MachineType p1, MachineType p2, MachineType p3,
- MachineType p4,
- MachineOperatorBuilder::Flags flags =
- MachineOperatorBuilder::Flag::kNoFlags)
+ RawMachineAssemblerTester(MachineType p0 = kMachNone,
+ MachineType p1 = kMachNone,
+ MachineType p2 = kMachNone,
+ MachineType p3 = kMachNone,
+ MachineType p4 = kMachNone)
: HandleAndZoneScope(),
- CallHelper(
+ CallHelper<ReturnType>(
main_isolate(),
- MakeMachineSignature(main_zone(), return_type, p0, p1, p2, p3, p4)),
- MachineAssembler(
+ CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1,
+ p2, p3, p4)),
+ RawMachineAssembler(
main_isolate(), new (main_zone()) Graph(main_zone()),
- MakeMachineSignature(main_zone(), return_type, p0, p1, p2, p3, p4),
- kMachPtr, flags) {}
-
- 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));
- }
+ CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1,
+ p2, p3, p4),
+ kMachPtr, InstructionSelector::SupportedMachineOperatorFlags()) {}
void CheckNumber(double expected, Object* number) {
CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number));
@@ -79,41 +67,6 @@ class MachineAssemblerTester : public HandleAndZoneScope,
};
-template <typename ReturnType>
-class RawMachineAssemblerTester
- : public MachineAssemblerTester<RawMachineAssembler>,
- public CallHelper2<ReturnType, RawMachineAssemblerTester<ReturnType> > {
- public:
- RawMachineAssemblerTester(MachineType p0 = kMachNone,
- MachineType p1 = kMachNone,
- MachineType p2 = kMachNone,
- MachineType p3 = kMachNone,
- MachineType p4 = kMachNone)
- : MachineAssemblerTester<RawMachineAssembler>(
- ReturnValueTraits<ReturnType>::Representation(), p0, p1, p2, p3, p4,
- InstructionSelector::SupportedMachineOperatorFlags()) {}
-
- 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));
- }
- }
- }
-};
-
-
static const bool USE_RESULT_BUFFER = true;
static const bool USE_RETURN_REGISTER = false;
static const int32_t CHECK_VALUE = 0x99BEEDCE;
diff --git a/deps/v8/test/cctest/compiler/function-tester.h b/deps/v8/test/cctest/compiler/function-tester.h
index 20efd1e304..54c62ab634 100644
--- a/deps/v8/test/cctest/compiler/function-tester.h
+++ b/deps/v8/test/cctest/compiler/function-tester.h
@@ -34,15 +34,16 @@ class FunctionTester : public InitializedHandleScope {
flags_(flags) {
Compile(function);
const uint32_t supported_flags = CompilationInfo::kContextSpecializing |
- CompilationInfo::kBuiltinInliningEnabled |
CompilationInfo::kInliningEnabled |
CompilationInfo::kTypingEnabled;
CHECK_EQ(0u, flags_ & ~supported_flags);
}
+ // TODO(turbofan): generalize FunctionTester to work with N arguments. Now, it
+ // can handle up to four.
explicit FunctionTester(Graph* graph)
: isolate(main_isolate()),
- function(NewFunction("(function(a,b){})")),
+ function(NewFunction("(function(a,b,c,d){})")),
flags_(0) {
CompileGraph(graph);
}
@@ -55,8 +56,14 @@ class FunctionTester : public InitializedHandleScope {
return Execution::Call(isolate, function, undefined(), 2, args, false);
}
+ MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b, Handle<Object> c,
+ Handle<Object> d) {
+ Handle<Object> args[] = {a, b, c, d};
+ return Execution::Call(isolate, function, undefined(), 4, args, false);
+ }
+
void CheckThrows(Handle<Object> a, Handle<Object> b) {
- TryCatch try_catch;
+ TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
MaybeHandle<Object> no_result = Call(a, b);
CHECK(isolate->has_pending_exception());
CHECK(try_catch.HasCaught());
@@ -66,7 +73,7 @@ class FunctionTester : public InitializedHandleScope {
v8::Handle<v8::Message> CheckThrowsReturnMessage(Handle<Object> a,
Handle<Object> b) {
- TryCatch try_catch;
+ TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
MaybeHandle<Object> no_result = Call(a, b);
CHECK(isolate->has_pending_exception());
CHECK(try_catch.HasCaught());
@@ -153,6 +160,7 @@ class FunctionTester : public InitializedHandleScope {
Zone zone;
ParseInfo parse_info(&zone, function);
CompilationInfo info(&parse_info);
+ info.MarkAsDeoptimizationEnabled();
CHECK(Parser::ParseStatic(info.parse_info()));
info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
@@ -170,11 +178,8 @@ class FunctionTester : public InitializedHandleScope {
Pipeline pipeline(&info);
Handle<Code> code = pipeline.GenerateCode();
- if (FLAG_turbo_deoptimization) {
- info.context()->native_context()->AddOptimizedCode(*code);
- }
-
CHECK(!code.is_null());
+ info.context()->native_context()->AddOptimizedCode(*code);
function->ReplaceCode(*code);
#elif USE_CRANKSHAFT
Handle<Code> unoptimized = Handle<Code>(function->code());
diff --git a/deps/v8/test/cctest/compiler/graph-builder-tester.h b/deps/v8/test/cctest/compiler/graph-builder-tester.h
index 9a5174c1d7..7270293e0f 100644
--- a/deps/v8/test/cctest/compiler/graph-builder-tester.h
+++ b/deps/v8/test/cctest/compiler/graph-builder-tester.h
@@ -39,12 +39,10 @@ class GraphAndBuilders {
template <typename ReturnType>
-class GraphBuilderTester
- : public HandleAndZoneScope,
- private GraphAndBuilders,
- public CallHelper,
- public SimplifiedGraphBuilder,
- public CallHelper2<ReturnType, GraphBuilderTester<ReturnType> > {
+class GraphBuilderTester : public HandleAndZoneScope,
+ private GraphAndBuilders,
+ public CallHelper<ReturnType>,
+ public SimplifiedGraphBuilder {
public:
explicit GraphBuilderTester(MachineType p0 = kMachNone,
MachineType p1 = kMachNone,
@@ -52,11 +50,10 @@ class GraphBuilderTester
MachineType p3 = kMachNone,
MachineType p4 = kMachNone)
: GraphAndBuilders(main_zone()),
- CallHelper(
+ CallHelper<ReturnType>(
main_isolate(),
- MakeMachineSignature(
- main_zone(), ReturnValueTraits<ReturnType>::Representation(),
- p0, p1, p2, p3, p4)),
+ CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1,
+ p2, p3, p4)),
SimplifiedGraphBuilder(main_isolate(), main_graph_, &main_common_,
&main_machine_, &main_simplified_),
parameters_(main_zone()->template NewArray<Node*>(parameter_count())) {
@@ -79,7 +76,7 @@ class GraphBuilderTester
if (code_.is_null()) {
Zone* zone = graph()->zone();
CallDescriptor* desc =
- Linkage::GetSimplifiedCDescriptor(zone, machine_sig_);
+ Linkage::GetSimplifiedCDescriptor(zone, this->csig_);
code_ = Pipeline::GenerateCodeForTesting(main_isolate(), desc, graph());
}
return code_.ToHandleChecked()->entry();
@@ -92,7 +89,7 @@ class GraphBuilderTester
}
}
- size_t parameter_count() const { return machine_sig_->parameter_count(); }
+ size_t parameter_count() const { return this->csig_->parameter_count(); }
private:
Node** parameters_;
diff --git a/deps/v8/test/cctest/compiler/simplified-graph-builder.cc b/deps/v8/test/cctest/compiler/simplified-graph-builder.cc
index 6afdc0a211..4d57719eff 100644
--- a/deps/v8/test/cctest/compiler/simplified-graph-builder.cc
+++ b/deps/v8/test/cctest/compiler/simplified-graph-builder.cc
@@ -23,7 +23,7 @@ SimplifiedGraphBuilder::SimplifiedGraphBuilder(
void SimplifiedGraphBuilder::Begin(int num_parameters) {
DCHECK(graph()->start() == NULL);
- Node* start = graph()->NewNode(common()->Start(num_parameters));
+ Node* start = graph()->NewNode(common()->Start(num_parameters + 3));
graph()->SetStart(start);
effect_ = start;
}
@@ -37,7 +37,7 @@ void SimplifiedGraphBuilder::Return(Node* value) {
void SimplifiedGraphBuilder::End() {
- Node* end = graph()->NewNode(common()->End(), return_);
+ Node* end = graph()->NewNode(common()->End(1), return_);
graph()->SetEnd(end);
}
diff --git a/deps/v8/test/cctest/compiler/simplified-graph-builder.h b/deps/v8/test/cctest/compiler/simplified-graph-builder.h
index c9ba002c25..50c51d5ed8 100644
--- a/deps/v8/test/cctest/compiler/simplified-graph-builder.h
+++ b/deps/v8/test/cctest/compiler/simplified-graph-builder.h
@@ -92,9 +92,6 @@ class SimplifiedGraphBuilder : public GraphBuilder {
Node* StringLessThanOrEqual(Node* a, Node* b) {
return NewNode(simplified()->StringLessThanOrEqual(), a, b);
}
- Node* StringAdd(Node* a, Node* b) {
- return NewNode(simplified()->StringAdd(), a, b);
- }
Node* ChangeTaggedToInt32(Node* a) {
return NewNode(simplified()->ChangeTaggedToInt32(), a);
diff --git a/deps/v8/test/cctest/compiler/test-changes-lowering.cc b/deps/v8/test/cctest/compiler/test-changes-lowering.cc
index d11210bb8b..04b5b9176b 100644
--- a/deps/v8/test/cctest/compiler/test-changes-lowering.cc
+++ b/deps/v8/test/cctest/compiler/test-changes-lowering.cc
@@ -88,7 +88,7 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> {
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);
+ Node* end = this->graph()->NewNode(this->common()->End(1), ret);
this->graph()->SetEnd(end);
LowerChange(change);
}
@@ -104,7 +104,7 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> {
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);
+ Node* end = this->graph()->NewNode(this->common()->End(1), ret);
this->graph()->SetEnd(end);
LowerChange(change);
}
@@ -119,18 +119,18 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> {
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);
+ Node* end = this->graph()->NewNode(this->common()->End(1), ret);
this->graph()->SetEnd(end);
LowerChange(change);
}
void LowerChange(Node* change) {
// Run the graph reducer with changes lowering on a single node.
- Typer typer(this->isolate(), this->graph(), Handle<Context>());
+ Typer typer(this->isolate(), this->graph());
typer.Run();
ChangeLowering change_lowering(&jsgraph);
SelectLowering select_lowering(this->graph(), this->common());
- GraphReducer reducer(this->graph(), this->zone());
+ GraphReducer reducer(this->zone(), this->graph());
reducer.AddReducer(&change_lowering);
reducer.AddReducer(&select_lowering);
reducer.ReduceNode(change);
diff --git a/deps/v8/test/cctest/compiler/test-codegen-deopt.cc b/deps/v8/test/cctest/compiler/test-codegen-deopt.cc
deleted file mode 100644
index 0b59308216..0000000000
--- a/deps/v8/test/cctest/compiler/test-codegen-deopt.cc
+++ /dev/null
@@ -1,301 +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.
-
-#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/ast-numbering.h"
-#include "src/full-codegen.h"
-#include "src/parser.h"
-#include "src/rewriter.h"
-
-#include "test/cctest/compiler/c-signature.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;
-typedef v8::internal::compiler::InstructionSequence TestInstrSeq;
-
-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)),
- parse_info(scope->main_zone(), function),
- info(&parse_info),
- bailout_id(-1),
- tagged_type(1, kMachAnyTagged, zone()),
- empty_types(zone()) {
- CHECK(Parser::ParseStatic(&parse_info));
- info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
- CHECK(Compiler::Analyze(&parse_info));
- CHECK(Compiler::EnsureDeoptimizationSupport(&info));
-
- DCHECK(info.shared_info()->has_deoptimization_support());
-
- graph = new (scope_->main_zone()) Graph(scope_->main_zone());
- }
-
- virtual ~DeoptCodegenTester() {}
-
- void GenerateCodeFromSchedule(Schedule* schedule) {
- OFStream os(stdout);
- if (FLAG_trace_turbo) {
- os << *schedule;
- }
- result_code = Pipeline::GenerateCodeForTesting(&info, graph, schedule);
-#ifdef OBJECT_PRINT
- if (FLAG_print_opt_code || FLAG_trace_turbo) {
- result_code->Print();
- }
-#endif
- }
-
- Zone* zone() { return scope_->main_zone(); }
- Isolate* isolate() { return scope_->main_isolate(); }
-
- HandleAndZoneScope* scope_;
- Handle<JSFunction> function;
- ParseInfo parse_info;
- CompilationInfo info;
- BailoutId bailout_id;
- Handle<Code> result_code;
- TestInstrSeq* code;
- Graph* graph;
- ZoneVector<MachineType> tagged_type;
- ZoneVector<MachineType> empty_types;
-};
-
-
-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) {
- CommonOperatorBuilder common(zone());
-
- // Manually construct a schedule for the function below:
- // function foo() {
- // deopt();
- // }
-
- CSignature1<Object*, Object*> sig;
- RawMachineAssembler m(isolate(), graph, &sig);
-
- Handle<JSFunction> deopt_function =
- NewFunction("function deopt() { %DeoptimizeFunction(foo); }; deopt");
- Unique<JSFunction> deopt_fun_constant =
- Unique<JSFunction>::CreateUninitialized(deopt_function);
- Node* deopt_fun_node = m.NewNode(common.HeapConstant(deopt_fun_constant));
-
- Handle<Context> caller_context(function->context(), CcTest::i_isolate());
- Unique<Context> caller_context_constant =
- Unique<Context>::CreateUninitialized(caller_context);
- Node* caller_context_node =
- m.NewNode(common.HeapConstant(caller_context_constant));
-
- bailout_id = GetCallBailoutId();
- Node* parameters =
- m.NewNode(common.TypedStateValues(&tagged_type), m.UndefinedConstant());
- Node* locals = m.NewNode(common.TypedStateValues(&empty_types));
- Node* stack = m.NewNode(common.TypedStateValues(&empty_types));
-
- Node* state_node = m.NewNode(
- common.FrameState(JS_FRAME, bailout_id,
- OutputFrameStateCombine::Ignore()),
- parameters, locals, stack, caller_context_node, m.UndefinedConstant());
-
- Handle<Context> context(deopt_function->context(), CcTest::i_isolate());
- Unique<Context> context_constant =
- Unique<Context>::CreateUninitialized(context);
- Node* context_node = m.NewNode(common.HeapConstant(context_constant));
-
- m.CallJS0(deopt_fun_node, m.UndefinedConstant(), context_node, state_node);
-
- m.Return(m.UndefinedConstant());
-
- // Schedule the graph:
- Schedule* schedule = m.Export();
-
- 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);
- }
-};
-
-
-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());
-
- // TODO(jarin) Find a way to test the safepoint.
-
- // Check that we deoptimize to the right AST id.
- 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) {
- CommonOperatorBuilder common(zone());
-
- // Manually construct a schedule for the function below:
- // function foo() {
- // %DeoptimizeFunction(foo);
- // }
-
- CSignature1<Object*, Object*> sig;
- RawMachineAssembler m(isolate(), graph, &sig);
-
- Unique<HeapObject> this_fun_constant =
- Unique<HeapObject>::CreateUninitialized(function);
- Node* this_fun_node = m.NewNode(common.HeapConstant(this_fun_constant));
-
- Handle<Context> context(function->context(), CcTest::i_isolate());
- Unique<HeapObject> context_constant =
- Unique<HeapObject>::CreateUninitialized(context);
- Node* context_node = m.NewNode(common.HeapConstant(context_constant));
-
- bailout_id = GetCallBailoutId();
- Node* parameters =
- m.NewNode(common.TypedStateValues(&tagged_type), m.UndefinedConstant());
- Node* locals = m.NewNode(common.TypedStateValues(&empty_types));
- Node* stack = m.NewNode(common.TypedStateValues(&empty_types));
-
- Node* state_node = m.NewNode(
- common.FrameState(JS_FRAME, bailout_id,
- OutputFrameStateCombine::Ignore()),
- parameters, locals, stack, context_node, m.UndefinedConstant());
-
- m.CallRuntime1(Runtime::kDeoptimizeFunction, this_fun_node, context_node,
- state_node);
-
- m.Return(m.UndefinedConstant());
-
- // Schedule the graph:
- Schedule* schedule = m.Export();
-
- 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);
- }
-};
-
-
-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-control-reducer.cc b/deps/v8/test/cctest/compiler/test-control-reducer.cc
deleted file mode 100644
index e969e27106..0000000000
--- a/deps/v8/test/cctest/compiler/test-control-reducer.cc
+++ /dev/null
@@ -1,1641 +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.
-
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
-#include "src/base/bits.h"
-#include "src/compiler/all-nodes.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/control-reducer.h"
-#include "src/compiler/graph.h"
-#include "src/compiler/js-graph.h"
-#include "src/compiler/node-properties.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-static const size_t kNumLeafs = 4;
-
-enum Decision { kFalse, kUnknown, kTrue };
-
-// TODO(titzer): convert this whole file into unit tests.
-
-static int CheckInputs(Node* node, Node* i0 = NULL, Node* i1 = NULL,
- Node* i2 = NULL) {
- int count = 3;
- if (i2 == NULL) count = 2;
- if (i1 == NULL) count = 1;
- if (i0 == NULL) count = 0;
- CHECK_EQ(count, node->InputCount());
- if (i0 != NULL) CHECK_EQ(i0, node->InputAt(0));
- if (i1 != NULL) CHECK_EQ(i1, node->InputAt(1));
- if (i2 != NULL) CHECK_EQ(i2, node->InputAt(2));
- return count;
-}
-
-
-static int CheckMerge(Node* node, Node* i0 = NULL, Node* i1 = NULL,
- Node* i2 = NULL) {
- CHECK_EQ(IrOpcode::kMerge, node->opcode());
- int count = CheckInputs(node, i0, i1, i2);
- CHECK_EQ(count, node->op()->ControlInputCount());
- return count;
-}
-
-
-static int CheckLoop(Node* node, Node* i0 = NULL, Node* i1 = NULL,
- Node* i2 = NULL) {
- CHECK_EQ(IrOpcode::kLoop, node->opcode());
- int count = CheckInputs(node, i0, i1, i2);
- CHECK_EQ(count, node->op()->ControlInputCount());
- return count;
-}
-
-
-bool IsUsedBy(Node* a, Node* b) {
- auto const uses = a->uses();
- return std::find(uses.begin(), uses.end(), b) != uses.end();
-}
-
-
-// A helper for all tests dealing with ControlTester.
-class ControlReducerTester : HandleAndZoneScope {
- public:
- ControlReducerTester()
- : isolate(main_isolate()),
- common(main_zone()),
- graph(main_zone()),
- jsgraph(main_isolate(), &graph, &common, NULL, NULL),
- start(graph.NewNode(common.Start(1))),
- end(graph.NewNode(common.End(), start)),
- p0(graph.NewNode(common.Parameter(0), start)),
- zero(jsgraph.Int32Constant(0)),
- one(jsgraph.OneConstant()),
- half(jsgraph.Constant(0.5)),
- self(graph.NewNode(common.Int32Constant(0xaabbccdd))),
- dead(graph.NewNode(common.Dead())) {
- graph.SetEnd(end);
- graph.SetStart(start);
- leaf[0] = zero;
- leaf[1] = one;
- leaf[2] = half;
- leaf[3] = p0;
- }
-
- Isolate* isolate;
- CommonOperatorBuilder common;
- Graph graph;
- JSGraph jsgraph;
- Node* start;
- Node* end;
- Node* p0;
- Node* zero;
- Node* one;
- Node* half;
- Node* self;
- Node* dead;
- Node* leaf[kNumLeafs];
-
- Node* Phi(Node* a) {
- return SetSelfReferences(graph.NewNode(op(1, false), a, start));
- }
-
- Node* Phi(Node* a, Node* b) {
- return SetSelfReferences(graph.NewNode(op(2, false), a, b, start));
- }
-
- Node* Phi(Node* a, Node* b, Node* c) {
- return SetSelfReferences(graph.NewNode(op(3, false), a, b, c, start));
- }
-
- Node* Phi(Node* a, Node* b, Node* c, Node* d) {
- return SetSelfReferences(graph.NewNode(op(4, false), a, b, c, d, start));
- }
-
- Node* EffectPhi(Node* a) {
- return SetSelfReferences(graph.NewNode(op(1, true), a, start));
- }
-
- Node* EffectPhi(Node* a, Node* b) {
- return SetSelfReferences(graph.NewNode(op(2, true), a, b, start));
- }
-
- Node* EffectPhi(Node* a, Node* b, Node* c) {
- return SetSelfReferences(graph.NewNode(op(3, true), a, b, c, start));
- }
-
- Node* EffectPhi(Node* a, Node* b, Node* c, Node* d) {
- return SetSelfReferences(graph.NewNode(op(4, true), a, b, c, d, start));
- }
-
- Node* SetSelfReferences(Node* node) {
- for (Edge edge : node->input_edges()) {
- if (edge.to() == self) node->ReplaceInput(edge.index(), node);
- }
- return node;
- }
-
- const Operator* op(int count, bool effect) {
- return effect ? common.EffectPhi(count) : common.Phi(kMachAnyTagged, count);
- }
-
- void Trim() { ControlReducer::TrimGraph(main_zone(), &jsgraph); }
-
- void ReduceGraph() { ControlReducer::ReduceGraph(main_zone(), &jsgraph); }
-
- // Checks one-step reduction of a phi.
- void ReducePhi(Node* expect, Node* phi) {
- Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, phi);
- CHECK_EQ(expect, result);
- ReducePhiIterative(expect, phi); // iterative should give the same result.
- }
-
- // Checks one-step reduction of a phi.
- void ReducePhiNonIterative(Node* expect, Node* phi) {
- Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, phi);
- CHECK_EQ(expect, result);
- }
-
- void ReducePhiIterative(Node* expect, Node* phi) {
- p0->ReplaceInput(0, start); // hack: parameters may be trimmed.
- Node* ret = graph.NewNode(common.Return(), phi, start, start);
- Node* end = graph.NewNode(common.End(), ret);
- graph.SetEnd(end);
- ControlReducer::ReduceGraph(main_zone(), &jsgraph);
- CheckInputs(end, ret);
- CheckInputs(ret, expect, start, start);
- }
-
- void ReduceMerge(Node* expect, Node* merge) {
- Node* result = ControlReducer::ReduceMerge(&jsgraph, merge);
- CHECK_EQ(expect, result);
- }
-
- void ReduceMergeIterative(Node* expect, Node* merge) {
- p0->ReplaceInput(0, start); // hack: parameters may be trimmed.
- Node* end = graph.NewNode(common.End(), merge);
- graph.SetEnd(end);
- ReduceGraph();
- CheckInputs(end, expect);
- }
-
- void ReduceBranch(Decision expected, Node* branch) {
- Node* control = branch->InputAt(1);
- for (Node* use : branch->uses()) {
- if (use->opcode() == IrOpcode::kIfTrue) {
- Node* result = ControlReducer::ReduceIfNodeForTesting(&jsgraph, use);
- if (expected == kTrue) CHECK_EQ(control, result);
- if (expected == kFalse) CHECK_EQ(IrOpcode::kDead, result->opcode());
- if (expected == kUnknown) CHECK_EQ(use, result);
- } else if (use->opcode() == IrOpcode::kIfFalse) {
- Node* result = ControlReducer::ReduceIfNodeForTesting(&jsgraph, use);
- if (expected == kFalse) CHECK_EQ(control, result);
- if (expected == kTrue) CHECK_EQ(IrOpcode::kDead, result->opcode());
- if (expected == kUnknown) CHECK_EQ(use, result);
- } else {
- UNREACHABLE();
- }
- }
- }
-
- Node* Return(Node* val, Node* effect, Node* control) {
- Node* ret = graph.NewNode(common.Return(), val, effect, control);
- end->ReplaceInput(0, ret);
- return ret;
- }
-};
-
-
-struct Branch {
- Node* branch;
- Node* if_true;
- Node* if_false;
-
- Branch(ControlReducerTester& R, Node* cond, Node* control = NULL) {
- if (control == NULL) control = R.start;
- branch = R.graph.NewNode(R.common.Branch(), cond, control);
- if_true = R.graph.NewNode(R.common.IfTrue(), branch);
- if_false = R.graph.NewNode(R.common.IfFalse(), branch);
- }
-};
-
-
-// TODO(titzer): use the diamonds from src/compiler/diamond.h here.
-struct Diamond {
- Node* branch;
- Node* if_true;
- Node* if_false;
- Node* merge;
- Node* phi;
-
- Diamond(ControlReducerTester& R, Node* cond) {
- branch = R.graph.NewNode(R.common.Branch(), cond, R.start);
- if_true = R.graph.NewNode(R.common.IfTrue(), branch);
- if_false = R.graph.NewNode(R.common.IfFalse(), branch);
- merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false);
- phi = NULL;
- }
-
- Diamond(ControlReducerTester& R, Node* cond, Node* tv, Node* fv) {
- branch = R.graph.NewNode(R.common.Branch(), cond, R.start);
- if_true = R.graph.NewNode(R.common.IfTrue(), branch);
- if_false = R.graph.NewNode(R.common.IfFalse(), branch);
- merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false);
- phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 2), tv, fv, merge);
- }
-
- void chain(Diamond& that) { branch->ReplaceInput(1, that.merge); }
-
- // Nest {this} into either the if_true or if_false branch of {that}.
- void nest(Diamond& that, bool if_true) {
- if (if_true) {
- branch->ReplaceInput(1, that.if_true);
- that.merge->ReplaceInput(0, merge);
- } else {
- branch->ReplaceInput(1, that.if_false);
- that.merge->ReplaceInput(1, merge);
- }
- }
-};
-
-
-struct While {
- Node* branch;
- Node* if_true;
- Node* exit;
- Node* loop;
-
- While(ControlReducerTester& R, Node* cond) {
- loop = R.graph.NewNode(R.common.Loop(2), R.start, R.start);
- branch = R.graph.NewNode(R.common.Branch(), cond, loop);
- if_true = R.graph.NewNode(R.common.IfTrue(), branch);
- exit = R.graph.NewNode(R.common.IfFalse(), branch);
- loop->ReplaceInput(1, if_true);
- }
-
- void chain(Node* control) { loop->ReplaceInput(0, control); }
-};
-
-
-// Helper for checking that nodes are *not* reachable from end.
-struct DeadChecker {
- Zone zone;
- AllNodes nodes;
- explicit DeadChecker(Graph* graph) : zone(), nodes(&zone, graph) {}
-
- void Check(Node* node) { CHECK(!nodes.IsLive(node)); }
-
- void Check(Diamond& d) {
- Check(d.branch);
- Check(d.if_true);
- Check(d.if_false);
- Check(d.merge);
- if (d.phi != NULL) Check(d.phi);
- }
-
- void CheckLive(Diamond& d, bool live_phi = true) {
- CheckInputs(d.merge, d.if_true, d.if_false);
- CheckInputs(d.if_true, d.branch);
- CheckInputs(d.if_false, d.branch);
- if (d.phi != NULL) {
- if (live_phi) {
- CHECK_EQ(3, d.phi->InputCount());
- CHECK_EQ(d.merge, d.phi->InputAt(2));
- } else {
- Check(d.phi);
- }
- }
- }
-};
-
-
-TEST(Trim1_live) {
- ControlReducerTester T;
- CHECK(IsUsedBy(T.start, T.p0));
- T.graph.SetEnd(T.p0);
- T.Trim();
- CHECK(IsUsedBy(T.start, T.p0));
- CheckInputs(T.p0, T.start);
-}
-
-
-TEST(Trim1_dead) {
- ControlReducerTester T;
- CHECK(IsUsedBy(T.start, T.p0));
- T.Trim();
- CHECK(!IsUsedBy(T.start, T.p0));
- CHECK(!T.p0->InputAt(0));
-}
-
-
-TEST(Trim2_live) {
- ControlReducerTester T;
- Node* phi =
- T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, T.start);
- CHECK(IsUsedBy(T.one, phi));
- CHECK(IsUsedBy(T.half, phi));
- CHECK(IsUsedBy(T.start, phi));
- T.graph.SetEnd(phi);
- T.Trim();
- CHECK(IsUsedBy(T.one, phi));
- CHECK(IsUsedBy(T.half, phi));
- CHECK(IsUsedBy(T.start, phi));
- CheckInputs(phi, T.one, T.half, T.start);
-}
-
-
-TEST(Trim2_dead) {
- ControlReducerTester T;
- Node* phi =
- T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, T.start);
- CHECK(IsUsedBy(T.one, phi));
- CHECK(IsUsedBy(T.half, phi));
- CHECK(IsUsedBy(T.start, phi));
- T.Trim();
- CHECK(!IsUsedBy(T.one, phi));
- CHECK(!IsUsedBy(T.half, phi));
- CHECK(!IsUsedBy(T.start, phi));
- CHECK(!phi->InputAt(0));
- CHECK(!phi->InputAt(1));
- CHECK(!phi->InputAt(2));
-}
-
-
-TEST(Trim_chain1) {
- ControlReducerTester T;
- const int kDepth = 15;
- Node* live[kDepth];
- Node* dead[kDepth];
- Node* end = T.start;
- for (int i = 0; i < kDepth; i++) {
- live[i] = end = T.graph.NewNode(T.common.Merge(1), end);
- dead[i] = T.graph.NewNode(T.common.Merge(1), end);
- }
- // end -> live[last] -> live[last-1] -> ... -> start
- // dead[last] ^ dead[last-1] ^ ... ^
- T.graph.SetEnd(end);
- T.Trim();
- for (int i = 0; i < kDepth; i++) {
- CHECK(!IsUsedBy(live[i], dead[i]));
- CHECK(!dead[i]->InputAt(0));
- CHECK_EQ(i == 0 ? T.start : live[i - 1], live[i]->InputAt(0));
- }
-}
-
-
-TEST(Trim_chain2) {
- ControlReducerTester T;
- const int kDepth = 15;
- Node* live[kDepth];
- Node* dead[kDepth];
- Node* l = T.start;
- Node* d = T.start;
- for (int i = 0; i < kDepth; i++) {
- live[i] = l = T.graph.NewNode(T.common.Merge(1), l);
- dead[i] = d = T.graph.NewNode(T.common.Merge(1), d);
- }
- // end -> live[last] -> live[last-1] -> ... -> start
- // dead[last] -> dead[last-1] -> ... -> start
- T.graph.SetEnd(l);
- T.Trim();
- CHECK(!IsUsedBy(T.start, dead[0]));
- for (int i = 0; i < kDepth; i++) {
- CHECK_EQ(i == 0 ? NULL : dead[i - 1], dead[i]->InputAt(0));
- CHECK_EQ(i == 0 ? T.start : live[i - 1], live[i]->InputAt(0));
- }
-}
-
-
-TEST(Trim_cycle1) {
- ControlReducerTester T;
- Node* loop = T.graph.NewNode(T.common.Loop(1), T.start, T.start);
- loop->ReplaceInput(1, loop);
- Node* end = T.graph.NewNode(T.common.End(), loop);
- T.graph.SetEnd(end);
-
- CHECK(IsUsedBy(T.start, loop));
- CHECK(IsUsedBy(loop, end));
- CHECK(IsUsedBy(loop, loop));
-
- T.Trim();
-
- // nothing should have happened to the loop itself.
- CHECK(IsUsedBy(T.start, loop));
- CHECK(IsUsedBy(loop, end));
- CHECK(IsUsedBy(loop, loop));
- CheckInputs(loop, T.start, loop);
- CheckInputs(end, loop);
-}
-
-
-TEST(Trim_cycle2) {
- ControlReducerTester T;
- Node* loop = T.graph.NewNode(T.common.Loop(2), T.start, T.start);
- loop->ReplaceInput(1, loop);
- Node* end = T.graph.NewNode(T.common.End(), loop);
- Node* phi =
- T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, loop);
- T.graph.SetEnd(end);
-
- CHECK(IsUsedBy(T.start, loop));
- CHECK(IsUsedBy(loop, end));
- CHECK(IsUsedBy(loop, loop));
- CHECK(IsUsedBy(loop, phi));
- CHECK(IsUsedBy(T.one, phi));
- CHECK(IsUsedBy(T.half, phi));
-
- T.Trim();
-
- // nothing should have happened to the loop itself.
- CHECK(IsUsedBy(T.start, loop));
- CHECK(IsUsedBy(loop, end));
- CHECK(IsUsedBy(loop, loop));
- CheckInputs(loop, T.start, loop);
- CheckInputs(end, loop);
-
- // phi should have been trimmed away.
- CHECK(!IsUsedBy(loop, phi));
- CHECK(!IsUsedBy(T.one, phi));
- CHECK(!IsUsedBy(T.half, phi));
- CHECK(!phi->InputAt(0));
- CHECK(!phi->InputAt(1));
- CHECK(!phi->InputAt(2));
-}
-
-
-void CheckTrimConstant(ControlReducerTester* T, Node* k) {
- Node* phi = T->graph.NewNode(T->common.Phi(kMachInt32, 1), k, T->start);
- CHECK(IsUsedBy(k, phi));
- T->Trim();
- CHECK(!IsUsedBy(k, phi));
- CHECK(!phi->InputAt(0));
- CHECK(!phi->InputAt(1));
-}
-
-
-TEST(Trim_constants) {
- ControlReducerTester T;
- int32_t int32_constants[] = {
- 0, -1, -2, 2, 2, 3, 3, 4, 4, 5, 5, 4, 5, 6, 6, 7, 8, 7, 8, 9,
- 0, -11, -12, 12, 12, 13, 13, 14, 14, 15, 15, 14, 15, 6, 6, 7, 8, 7, 8, 9};
-
- for (size_t i = 0; i < arraysize(int32_constants); i++) {
- CheckTrimConstant(&T, T.jsgraph.Int32Constant(int32_constants[i]));
- CheckTrimConstant(&T, T.jsgraph.Float64Constant(int32_constants[i]));
- CheckTrimConstant(&T, T.jsgraph.Constant(int32_constants[i]));
- }
-
- Node* other_constants[] = {
- T.jsgraph.UndefinedConstant(), T.jsgraph.TheHoleConstant(),
- T.jsgraph.TrueConstant(), T.jsgraph.FalseConstant(),
- T.jsgraph.NullConstant(), T.jsgraph.ZeroConstant(),
- T.jsgraph.OneConstant(), T.jsgraph.NaNConstant(),
- T.jsgraph.Constant(21), T.jsgraph.Constant(22.2)};
-
- for (size_t i = 0; i < arraysize(other_constants); i++) {
- CheckTrimConstant(&T, other_constants[i]);
- }
-}
-
-
-TEST(Trim_EmptyFrameState1) {
- ControlReducerTester T;
-
- Node* node = T.jsgraph.EmptyFrameState();
- T.Trim();
-
- for (Node* input : node->inputs()) {
- CHECK_NOT_NULL(input);
- }
-}
-
-
-TEST(Trim_EmptyFrameState2) {
- ControlReducerTester T;
- CheckTrimConstant(&T, T.jsgraph.EmptyFrameState());
-}
-
-
-TEST(CReducePhi1) {
- ControlReducerTester R;
-
- R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0]));
- R.ReducePhi(R.leaf[1], R.Phi(R.leaf[1]));
- R.ReducePhi(R.leaf[2], R.Phi(R.leaf[2]));
- R.ReducePhi(R.leaf[3], R.Phi(R.leaf[3]));
-}
-
-
-TEST(CReducePhi1_dead) {
- ControlReducerTester R;
-
- R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0], R.dead));
- R.ReducePhi(R.leaf[1], R.Phi(R.leaf[1], R.dead));
- R.ReducePhi(R.leaf[2], R.Phi(R.leaf[2], R.dead));
- R.ReducePhi(R.leaf[3], R.Phi(R.leaf[3], R.dead));
-
- R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.leaf[0]));
- R.ReducePhi(R.leaf[1], R.Phi(R.dead, R.leaf[1]));
- R.ReducePhi(R.leaf[2], R.Phi(R.dead, R.leaf[2]));
- R.ReducePhi(R.leaf[3], R.Phi(R.dead, R.leaf[3]));
-}
-
-
-TEST(CReducePhi1_dead2) {
- ControlReducerTester R;
-
- R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0], R.dead, R.dead));
- R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.leaf[0], R.dead));
- R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.dead, R.leaf[0]));
-}
-
-
-TEST(CReducePhi2a) {
- ControlReducerTester R;
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(a, a));
- }
-}
-
-
-TEST(CReducePhi2b) {
- ControlReducerTester R;
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(R.self, a));
- R.ReducePhi(a, R.Phi(a, R.self));
- }
-}
-
-
-TEST(CReducePhi2c) {
- ControlReducerTester R;
-
- for (size_t i = 1; i < kNumLeafs; i++) {
- Node* a = R.leaf[i], *b = R.leaf[0];
- Node* phi1 = R.Phi(b, a);
- R.ReducePhi(phi1, phi1);
-
- Node* phi2 = R.Phi(a, b);
- R.ReducePhi(phi2, phi2);
- }
-}
-
-
-TEST(CReducePhi2_dead) {
- ControlReducerTester R;
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(a, a, R.dead));
- R.ReducePhi(a, R.Phi(a, R.dead, a));
- R.ReducePhi(a, R.Phi(R.dead, a, a));
- }
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(R.self, a));
- R.ReducePhi(a, R.Phi(a, R.self));
- R.ReducePhi(a, R.Phi(R.self, a, R.dead));
- R.ReducePhi(a, R.Phi(a, R.self, R.dead));
- }
-
- for (size_t i = 1; i < kNumLeafs; i++) {
- Node* a = R.leaf[i], *b = R.leaf[0];
- Node* phi1 = R.Phi(b, a, R.dead);
- R.ReducePhiNonIterative(phi1, phi1);
-
- Node* phi2 = R.Phi(a, b, R.dead);
- R.ReducePhiNonIterative(phi2, phi2);
- }
-}
-
-
-TEST(CReducePhi3) {
- ControlReducerTester R;
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(a, a, a));
- }
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(R.self, a, a));
- R.ReducePhi(a, R.Phi(a, R.self, a));
- R.ReducePhi(a, R.Phi(a, a, R.self));
- }
-
- for (size_t i = 1; i < kNumLeafs; i++) {
- Node* a = R.leaf[i], *b = R.leaf[0];
- Node* phi1 = R.Phi(b, a, a);
- R.ReducePhi(phi1, phi1);
-
- Node* phi2 = R.Phi(a, b, a);
- R.ReducePhi(phi2, phi2);
-
- Node* phi3 = R.Phi(a, a, b);
- R.ReducePhi(phi3, phi3);
- }
-}
-
-
-TEST(CReducePhi4) {
- ControlReducerTester R;
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(a, a, a, a));
- }
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(R.self, a, a, a));
- R.ReducePhi(a, R.Phi(a, R.self, a, a));
- R.ReducePhi(a, R.Phi(a, a, R.self, a));
- R.ReducePhi(a, R.Phi(a, a, a, R.self));
-
- R.ReducePhi(a, R.Phi(R.self, R.self, a, a));
- R.ReducePhi(a, R.Phi(a, R.self, R.self, a));
- R.ReducePhi(a, R.Phi(a, a, R.self, R.self));
- R.ReducePhi(a, R.Phi(R.self, a, a, R.self));
- }
-
- for (size_t i = 1; i < kNumLeafs; i++) {
- Node* a = R.leaf[i], *b = R.leaf[0];
- Node* phi1 = R.Phi(b, a, a, a);
- R.ReducePhi(phi1, phi1);
-
- Node* phi2 = R.Phi(a, b, a, a);
- R.ReducePhi(phi2, phi2);
-
- Node* phi3 = R.Phi(a, a, b, a);
- R.ReducePhi(phi3, phi3);
-
- Node* phi4 = R.Phi(a, a, a, b);
- R.ReducePhi(phi4, phi4);
- }
-}
-
-
-TEST(CReducePhi_iterative1) {
- ControlReducerTester R;
-
- R.ReducePhiIterative(R.leaf[0], R.Phi(R.leaf[0], R.Phi(R.leaf[0])));
- R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0]), R.leaf[0]));
-}
-
-
-TEST(CReducePhi_iterative2) {
- ControlReducerTester R;
-
- R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0]), R.Phi(R.leaf[0])));
-}
-
-
-TEST(CReducePhi_iterative3) {
- ControlReducerTester R;
-
- R.ReducePhiIterative(R.leaf[0],
- R.Phi(R.leaf[0], R.Phi(R.leaf[0], R.leaf[0])));
- R.ReducePhiIterative(R.leaf[0],
- R.Phi(R.Phi(R.leaf[0], R.leaf[0]), R.leaf[0]));
-}
-
-
-TEST(CReducePhi_iterative4) {
- ControlReducerTester R;
-
- R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.leaf[0]),
- R.Phi(R.leaf[0], R.leaf[0])));
-
- Node* p1 = R.Phi(R.leaf[0], R.leaf[0]);
- R.ReducePhiIterative(R.leaf[0], R.Phi(p1, p1));
-
- Node* p2 = R.Phi(R.leaf[0], R.leaf[0], R.leaf[0]);
- R.ReducePhiIterative(R.leaf[0], R.Phi(p2, p2, p2));
-
- Node* p3 = R.Phi(R.leaf[0], R.leaf[0], R.leaf[0]);
- R.ReducePhiIterative(R.leaf[0], R.Phi(p3, p3, R.leaf[0]));
-}
-
-
-TEST(CReducePhi_iterative_self1) {
- ControlReducerTester R;
-
- R.ReducePhiIterative(R.leaf[0], R.Phi(R.leaf[0], R.Phi(R.leaf[0], R.self)));
- R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.self), R.leaf[0]));
-}
-
-
-TEST(CReducePhi_iterative_self2) {
- ControlReducerTester R;
-
- R.ReducePhiIterative(
- R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.self), R.Phi(R.leaf[0], R.self)));
- R.ReducePhiIterative(
- R.leaf[0], R.Phi(R.Phi(R.self, R.leaf[0]), R.Phi(R.self, R.leaf[0])));
-
- Node* p1 = R.Phi(R.leaf[0], R.self);
- R.ReducePhiIterative(R.leaf[0], R.Phi(p1, p1));
-
- Node* p2 = R.Phi(R.self, R.leaf[0]);
- R.ReducePhiIterative(R.leaf[0], R.Phi(p2, p2));
-}
-
-
-TEST(EReducePhi1) {
- ControlReducerTester R;
-
- R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0]));
- R.ReducePhi(R.leaf[1], R.EffectPhi(R.leaf[1]));
- R.ReducePhi(R.leaf[2], R.EffectPhi(R.leaf[2]));
- R.ReducePhi(R.leaf[3], R.EffectPhi(R.leaf[3]));
-}
-
-
-TEST(EReducePhi1_dead) {
- ControlReducerTester R;
-
- R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0], R.dead));
- R.ReducePhi(R.leaf[1], R.EffectPhi(R.leaf[1], R.dead));
- R.ReducePhi(R.leaf[2], R.EffectPhi(R.leaf[2], R.dead));
- R.ReducePhi(R.leaf[3], R.EffectPhi(R.leaf[3], R.dead));
-
- R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.leaf[0]));
- R.ReducePhi(R.leaf[1], R.EffectPhi(R.dead, R.leaf[1]));
- R.ReducePhi(R.leaf[2], R.EffectPhi(R.dead, R.leaf[2]));
- R.ReducePhi(R.leaf[3], R.EffectPhi(R.dead, R.leaf[3]));
-}
-
-
-TEST(EReducePhi1_dead2) {
- ControlReducerTester R;
-
- R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0], R.dead, R.dead));
- R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.leaf[0], R.dead));
- R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.dead, R.leaf[0]));
-}
-
-
-TEST(CMergeReduce_simple1) {
- ControlReducerTester R;
-
- Node* merge = R.graph.NewNode(R.common.Merge(1), R.start);
- R.ReduceMerge(R.start, merge);
-}
-
-
-TEST(CMergeReduce_simple2) {
- ControlReducerTester R;
-
- Node* merge1 = R.graph.NewNode(R.common.Merge(1), R.start);
- Node* merge2 = R.graph.NewNode(R.common.Merge(1), merge1);
- R.ReduceMerge(merge1, merge2);
- R.ReduceMergeIterative(R.start, merge2);
-}
-
-
-TEST(CMergeReduce_none1) {
- ControlReducerTester R;
-
- Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, R.start);
- R.ReduceMerge(merge, merge);
-}
-
-
-TEST(CMergeReduce_none2) {
- ControlReducerTester R;
-
- Node* t1 = R.graph.NewNode(R.common.IfTrue(), R.start);
- Node* t2 = R.graph.NewNode(R.common.IfTrue(), R.start);
- Node* merge = R.graph.NewNode(R.common.Merge(2), t1, t2);
- R.ReduceMerge(merge, merge);
-}
-
-
-TEST(CMergeReduce_self3) {
- ControlReducerTester R;
-
- Node* merge =
- R.SetSelfReferences(R.graph.NewNode(R.common.Merge(2), R.start, R.self));
- R.ReduceMerge(merge, merge);
-}
-
-
-TEST(CMergeReduce_dead1) {
- ControlReducerTester R;
-
- Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, R.dead);
- R.ReduceMerge(R.start, merge);
-}
-
-
-TEST(CMergeReduce_dead2) {
- ControlReducerTester R;
-
- Node* merge1 = R.graph.NewNode(R.common.Merge(1), R.start);
- Node* merge2 = R.graph.NewNode(R.common.Merge(2), merge1, R.dead);
- R.ReduceMerge(merge1, merge2);
- R.ReduceMergeIterative(R.start, merge2);
-}
-
-
-TEST(CMergeReduce_dead_rm1a) {
- ControlReducerTester R;
-
- for (int i = 0; i < 3; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
- merge->ReplaceInput(i, R.dead);
- R.ReduceMerge(merge, merge);
- CheckMerge(merge, R.start, R.start);
- }
-}
-
-
-TEST(CMergeReduce_dead_rm1b) {
- ControlReducerTester R;
-
- Node* t = R.graph.NewNode(R.common.IfTrue(), R.start);
- Node* f = R.graph.NewNode(R.common.IfTrue(), R.start);
- for (int i = 0; i < 2; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(3), R.dead, R.dead, R.dead);
- for (int j = i + 1; j < 3; j++) {
- merge->ReplaceInput(i, t);
- merge->ReplaceInput(j, f);
- R.ReduceMerge(merge, merge);
- CheckMerge(merge, t, f);
- }
- }
-}
-
-
-TEST(CMergeReduce_dead_rm2) {
- ControlReducerTester R;
-
- for (int i = 0; i < 3; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(3), R.dead, R.dead, R.dead);
- merge->ReplaceInput(i, R.start);
- R.ReduceMerge(R.start, merge);
- }
-}
-
-
-TEST(CLoopReduce_dead_rm1) {
- ControlReducerTester R;
-
- for (int i = 0; i < 3; i++) {
- Node* loop = R.graph.NewNode(R.common.Loop(3), R.dead, R.start, R.start);
- R.ReduceMerge(loop, loop);
- CheckLoop(loop, R.start, R.start);
- }
-}
-
-
-TEST(CMergeReduce_edit_phi1) {
- ControlReducerTester R;
-
- for (int i = 0; i < 3; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
- merge->ReplaceInput(i, R.dead);
- Node* phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 3), R.leaf[0],
- R.leaf[1], R.leaf[2], merge);
- R.ReduceMerge(merge, merge);
- CHECK_EQ(IrOpcode::kPhi, phi->opcode());
- CHECK_EQ(2, phi->op()->ValueInputCount());
- CHECK_EQ(3, phi->InputCount());
- CHECK_EQ(R.leaf[i < 1 ? 1 : 0], phi->InputAt(0));
- CHECK_EQ(R.leaf[i < 2 ? 2 : 1], phi->InputAt(1));
- CHECK_EQ(merge, phi->InputAt(2));
- }
-}
-
-
-TEST(CMergeReduce_edit_effect_phi1) {
- ControlReducerTester R;
-
- for (int i = 0; i < 3; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
- merge->ReplaceInput(i, R.dead);
- Node* phi = R.graph.NewNode(R.common.EffectPhi(3), R.leaf[0], R.leaf[1],
- R.leaf[2], merge);
- R.ReduceMerge(merge, merge);
- CHECK_EQ(IrOpcode::kEffectPhi, phi->opcode());
- CHECK_EQ(0, phi->op()->ValueInputCount());
- CHECK_EQ(2, phi->op()->EffectInputCount());
- CHECK_EQ(3, phi->InputCount());
- CHECK_EQ(R.leaf[i < 1 ? 1 : 0], phi->InputAt(0));
- CHECK_EQ(R.leaf[i < 2 ? 2 : 1], phi->InputAt(1));
- CHECK_EQ(merge, phi->InputAt(2));
- }
-}
-
-
-static const int kSelectorSize = 4;
-
-// Helper to select K of N nodes according to a mask, useful for the test below.
-struct Selector {
- int mask;
- int count;
- explicit Selector(int m) {
- mask = m;
- count = v8::base::bits::CountPopulation32(m);
- }
- bool is_selected(int i) { return (mask & (1 << i)) != 0; }
- void CheckNode(Node* node, IrOpcode::Value opcode, Node** inputs,
- Node* control) {
- CHECK_EQ(opcode, node->opcode());
- CHECK_EQ(count + (control != NULL ? 1 : 0), node->InputCount());
- int index = 0;
- for (int i = 0; i < kSelectorSize; i++) {
- if (mask & (1 << i)) {
- CHECK_EQ(inputs[i], node->InputAt(index++));
- }
- }
- CHECK_EQ(count, index);
- if (control != NULL) CHECK_EQ(control, node->InputAt(index++));
- }
- int single_index() {
- CHECK_EQ(1, count);
- return WhichPowerOf2(mask);
- }
-};
-
-
-TEST(CMergeReduce_exhaustive_4) {
- ControlReducerTester R;
- Node* controls[] = {
- R.graph.NewNode(R.common.Start(1)), R.graph.NewNode(R.common.Start(2)),
- R.graph.NewNode(R.common.Start(3)), R.graph.NewNode(R.common.Start(4))};
- Node* values[] = {R.jsgraph.Int32Constant(11), R.jsgraph.Int32Constant(22),
- R.jsgraph.Int32Constant(33), R.jsgraph.Int32Constant(44)};
- Node* effects[] = {
- R.jsgraph.Float64Constant(123.4), R.jsgraph.Float64Constant(223.4),
- R.jsgraph.Float64Constant(323.4), R.jsgraph.Float64Constant(423.4)};
-
- for (int mask = 0; mask < (1 << (kSelectorSize - 1)); mask++) {
- // Reduce a single merge with a given mask.
- Node* merge = R.graph.NewNode(R.common.Merge(4), controls[0], controls[1],
- controls[2], controls[3]);
- Node* phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 4), values[0],
- values[1], values[2], values[3], merge);
- Node* ephi = R.graph.NewNode(R.common.EffectPhi(4), effects[0], effects[1],
- effects[2], effects[3], merge);
-
- Node* phi_use =
- R.graph.NewNode(R.common.Phi(kMachAnyTagged, 1), phi, R.start);
- Node* ephi_use = R.graph.NewNode(R.common.EffectPhi(1), ephi, R.start);
-
- Selector selector(mask);
-
- for (int i = 0; i < kSelectorSize; i++) { // set up dead merge inputs.
- if (!selector.is_selected(i)) merge->ReplaceInput(i, R.dead);
- }
-
- Node* result = ControlReducer::ReduceMerge(&R.jsgraph, merge);
-
- int count = selector.count;
- if (count == 0) {
- // result should be dead.
- CHECK_EQ(IrOpcode::kDead, result->opcode());
- } else if (count == 1) {
- // merge should be replaced with one of the controls.
- CHECK_EQ(controls[selector.single_index()], result);
- // Phis should have been directly replaced.
- CHECK_EQ(values[selector.single_index()], phi_use->InputAt(0));
- CHECK_EQ(effects[selector.single_index()], ephi_use->InputAt(0));
- } else {
- // Otherwise, nodes should be edited in place.
- CHECK_EQ(merge, result);
- selector.CheckNode(merge, IrOpcode::kMerge, controls, NULL);
- selector.CheckNode(phi, IrOpcode::kPhi, values, merge);
- selector.CheckNode(ephi, IrOpcode::kEffectPhi, effects, merge);
- CHECK_EQ(phi, phi_use->InputAt(0));
- CHECK_EQ(ephi, ephi_use->InputAt(0));
- CHECK_EQ(count, phi->op()->ValueInputCount());
- CHECK_EQ(count + 1, phi->InputCount());
- CHECK_EQ(count, ephi->op()->EffectInputCount());
- CHECK_EQ(count + 1, ephi->InputCount());
- }
- }
-}
-
-
-TEST(CMergeReduce_edit_many_phis1) {
- ControlReducerTester R;
-
- const int kPhiCount = 10;
- Node* phis[kPhiCount];
-
- for (int i = 0; i < 3; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
- merge->ReplaceInput(i, R.dead);
- for (int j = 0; j < kPhiCount; j++) {
- phis[j] = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 3), R.leaf[0],
- R.leaf[1], R.leaf[2], merge);
- }
- R.ReduceMerge(merge, merge);
- for (int j = 0; j < kPhiCount; j++) {
- Node* phi = phis[j];
- CHECK_EQ(IrOpcode::kPhi, phi->opcode());
- CHECK_EQ(2, phi->op()->ValueInputCount());
- CHECK_EQ(3, phi->InputCount());
- CHECK_EQ(R.leaf[i < 1 ? 1 : 0], phi->InputAt(0));
- CHECK_EQ(R.leaf[i < 2 ? 2 : 1], phi->InputAt(1));
- CHECK_EQ(merge, phi->InputAt(2));
- }
- }
-}
-
-
-TEST(CMergeReduce_simple_chain1) {
- ControlReducerTester R;
- for (int i = 0; i < 5; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(1), R.start);
- for (int j = 0; j < i; j++) {
- merge = R.graph.NewNode(R.common.Merge(1), merge);
- }
- R.ReduceMergeIterative(R.start, merge);
- }
-}
-
-
-TEST(CMergeReduce_dead_chain1) {
- ControlReducerTester R;
- for (int i = 0; i < 5; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(1), R.dead);
- for (int j = 0; j < i; j++) {
- merge = R.graph.NewNode(R.common.Merge(1), merge);
- }
- Node* end = R.graph.NewNode(R.common.End(), merge);
- R.graph.SetEnd(end);
- R.ReduceGraph();
- CHECK(merge->IsDead());
- CHECK(!end->InputAt(0)); // end dies.
- }
-}
-
-
-TEST(CMergeReduce_dead_chain2) {
- ControlReducerTester R;
- for (int i = 0; i < 5; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(1), R.start);
- for (int j = 0; j < i; j++) {
- merge = R.graph.NewNode(R.common.Merge(2), merge, R.dead);
- }
- R.ReduceMergeIterative(R.start, merge);
- }
-}
-
-
-TEST(CBranchReduce_none1) {
- ControlReducerTester R;
- Diamond d(R, R.p0);
- R.ReduceBranch(kUnknown, d.branch);
-}
-
-
-TEST(CBranchReduce_none2) {
- ControlReducerTester R;
- Diamond d1(R, R.p0);
- Diamond d2(R, R.p0);
- d2.chain(d1);
- R.ReduceBranch(kUnknown, d2.branch);
-}
-
-
-TEST(CBranchReduce_true) {
- ControlReducerTester R;
- Node* true_values[] = {
- R.one, R.jsgraph.Int32Constant(2),
- R.jsgraph.Int32Constant(0x7fffffff), R.jsgraph.Constant(1.0),
- R.jsgraph.Constant(22.1), R.jsgraph.TrueConstant()};
-
- for (size_t i = 0; i < arraysize(true_values); i++) {
- Diamond d(R, true_values[i]);
- R.ReduceBranch(kTrue, d.branch);
- }
-}
-
-
-TEST(CBranchReduce_false) {
- ControlReducerTester R;
- Node* false_values[] = {R.zero, R.jsgraph.Constant(0.0),
- R.jsgraph.Constant(-0.0), R.jsgraph.FalseConstant()};
-
- for (size_t i = 0; i < arraysize(false_values); i++) {
- Diamond d(R, false_values[i]);
- R.ReduceBranch(kFalse, d.branch);
- }
-}
-
-
-TEST(CDiamondReduce_true) {
- ControlReducerTester R;
- Diamond d1(R, R.one);
- R.ReduceMergeIterative(R.start, d1.merge);
-}
-
-
-TEST(CDiamondReduce_false) {
- ControlReducerTester R;
- Diamond d2(R, R.zero);
- R.ReduceMergeIterative(R.start, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_true_false) {
- ControlReducerTester R;
- Diamond d1(R, R.one);
- Diamond d2(R, R.zero);
- d2.chain(d1);
-
- R.ReduceMergeIterative(R.start, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_x_false) {
- ControlReducerTester R;
- Diamond d1(R, R.p0);
- Diamond d2(R, R.zero);
- d2.chain(d1);
-
- R.ReduceMergeIterative(R.start, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_false_x) {
- ControlReducerTester R;
- Diamond d1(R, R.zero);
- Diamond d2(R, R.p0);
- d2.chain(d1);
-
- R.ReduceMergeIterative(R.start, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_phi1) {
- ControlReducerTester R;
- Diamond d1(R, R.zero, R.one, R.zero); // foldable branch, phi.
- Diamond d2(R, d1.phi);
- d2.chain(d1);
-
- R.ReduceMergeIterative(R.start, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_phi2) {
- ControlReducerTester R;
- Diamond d1(R, R.p0, R.one, R.one); // redundant phi.
- Diamond d2(R, d1.phi);
- d2.chain(d1);
-
- R.ReduceMergeIterative(d1.merge, d2.merge);
-}
-
-
-TEST(CNestedDiamondsReduce_true_true_false) {
- ControlReducerTester R;
- Diamond d1(R, R.one);
- Diamond d2(R, R.zero);
- d2.nest(d1, true);
-
- R.ReduceMergeIterative(R.start, d1.merge);
-}
-
-
-TEST(CNestedDiamondsReduce_false_true_false) {
- ControlReducerTester R;
- Diamond d1(R, R.one);
- Diamond d2(R, R.zero);
- d2.nest(d1, false);
-
- R.ReduceMergeIterative(R.start, d1.merge);
-}
-
-
-TEST(CNestedDiamonds_xyz) {
- ControlReducerTester R;
-
- for (int a = 0; a < 2; a++) {
- for (int b = 0; b < 2; b++) {
- for (int c = 0; c < 2; c++) {
- Diamond d1(R, R.jsgraph.Int32Constant(a));
- Diamond d2(R, R.jsgraph.Int32Constant(b));
- d2.nest(d1, c);
-
- R.ReduceMergeIterative(R.start, d1.merge);
- }
- }
- }
-}
-
-
-TEST(CUnusedDiamond1) {
- ControlReducerTester R;
- // if (p0) { } else { }
- Node* branch = R.graph.NewNode(R.common.Branch(), R.p0, R.start);
- Node* if_true = R.graph.NewNode(R.common.IfTrue(), branch);
- Node* if_false = R.graph.NewNode(R.common.IfFalse(), branch);
- Node* merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false);
- R.ReduceMergeIterative(R.start, merge);
-}
-
-
-TEST(CUnusedDiamond2) {
- ControlReducerTester R;
- // if (p0) { } else { }
- Node* branch = R.graph.NewNode(R.common.Branch(), R.p0, R.start);
- Node* if_true = R.graph.NewNode(R.common.IfTrue(), branch);
- Node* if_false = R.graph.NewNode(R.common.IfFalse(), branch);
- Node* merge = R.graph.NewNode(R.common.Merge(2), if_false, if_true);
- R.ReduceMergeIterative(R.start, merge);
-}
-
-
-TEST(CDeadLoop1) {
- ControlReducerTester R;
-
- Node* loop = R.graph.NewNode(R.common.Loop(1), R.start);
- Branch b(R, R.p0, loop);
- loop->ReplaceInput(0, b.if_true); // loop is not connected to start.
- Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, b.if_false);
- R.ReduceMergeIterative(R.start, merge);
-
- DeadChecker dead(&R.graph);
- dead.Check(b.if_true);
- dead.Check(b.if_false);
- dead.Check(b.branch);
- dead.Check(loop);
-}
-
-
-TEST(CDeadLoop2) {
- ControlReducerTester R;
-
- While w(R, R.p0);
- Diamond d(R, R.zero);
- // if (0) { while (p0) ; } else { }
- w.branch->ReplaceInput(1, d.if_true);
- d.merge->ReplaceInput(0, w.exit);
-
- R.ReduceMergeIterative(R.start, d.merge);
-
- DeadChecker dead(&R.graph);
- dead.Check(d);
- dead.Check(w.loop);
-}
-
-
-TEST(Return1) {
- ControlReducerTester R;
- Node* ret = R.Return(R.one, R.start, R.start);
- R.ReduceGraph();
- CheckInputs(R.graph.end(), ret);
- CheckInputs(ret, R.one, R.start, R.start);
-}
-
-
-TEST(Return2) {
- ControlReducerTester R;
- Diamond d(R, R.one);
- Node* ret = R.Return(R.half, R.start, d.merge);
- R.ReduceGraph();
-
- DeadChecker dead(&R.graph);
- dead.Check(d.branch);
- dead.Check(d.if_true);
- dead.Check(d.if_false);
- dead.Check(d.merge);
-
- CheckInputs(R.graph.end(), ret);
- CheckInputs(ret, R.half, R.start, R.start);
-}
-
-
-TEST(Return_true1) {
- ControlReducerTester R;
- Diamond d(R, R.one, R.half, R.zero);
- Node* ret = R.Return(d.phi, R.start, d.merge);
- R.ReduceGraph();
-
- DeadChecker dead(&R.graph);
- dead.Check(d.branch);
- dead.Check(d.if_true);
- dead.Check(d.if_false);
- dead.Check(d.merge);
- dead.Check(d.phi);
-
- CheckInputs(R.graph.end(), ret);
- CheckInputs(ret, R.half, R.start, R.start);
-}
-
-
-TEST(Return_false1) {
- ControlReducerTester R;
- Diamond d(R, R.zero, R.one, R.half);
- Node* ret = R.Return(d.phi, R.start, d.merge);
- R.ReduceGraph();
-
- DeadChecker dead(&R.graph);
- dead.Check(d.branch);
- dead.Check(d.if_true);
- dead.Check(d.if_false);
- dead.Check(d.merge);
- dead.Check(d.phi);
-
- CheckInputs(R.graph.end(), ret);
- CheckInputs(ret, R.half, R.start, R.start);
-}
-
-
-TEST(Return_effect1) {
- ControlReducerTester R;
- Diamond d(R, R.one);
- Node* e1 = R.jsgraph.Float64Constant(-100.1);
- Node* e2 = R.jsgraph.Float64Constant(+100.1);
- Node* effect = R.graph.NewNode(R.common.EffectPhi(2), e1, e2, d.merge);
- Node* ret = R.Return(R.p0, effect, d.merge);
- R.ReduceGraph();
-
- DeadChecker dead(&R.graph);
- dead.Check(d);
- dead.Check(effect);
-
- CheckInputs(R.graph.end(), ret);
- CheckInputs(ret, R.p0, e1, R.start);
-}
-
-
-TEST(Return_nested_diamonds1) {
- ControlReducerTester R;
- Diamond d2(R, R.p0, R.one, R.zero);
- Diamond d3(R, R.p0, R.one, R.zero);
- Diamond d1(R, R.p0, d2.phi, d3.phi);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // nothing should happen.
-
- CheckInputs(ret, d1.phi, R.start, d1.merge);
- CheckInputs(d1.phi, d2.phi, d3.phi, d1.merge);
- CheckInputs(d1.merge, d2.merge, d3.merge);
-
- DeadChecker dead(&R.graph);
- dead.CheckLive(d2);
- dead.CheckLive(d3);
-}
-
-
-TEST(Return_nested_diamonds1_dead1) {
- ControlReducerTester R;
- Diamond d2(R, R.p0); // dead diamond
- Diamond d3(R, R.p0, R.one, R.zero);
- Diamond d1(R, R.p0, R.one, d3.phi);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph();
-
- CheckInputs(ret, d1.phi, R.start, d1.merge);
- CheckInputs(d1.phi, R.one, d3.phi, d1.merge);
- CheckInputs(d1.merge, d1.if_true, d3.merge);
-
- DeadChecker dead(&R.graph);
- dead.Check(d2); // d2 was a dead diamond.
- dead.CheckLive(d3);
-}
-
-
-TEST(Return_nested_diamonds1_dead2) {
- ControlReducerTester R;
- Diamond d2(R, R.p0); // dead diamond
- Diamond d3(R, R.p0); // dead diamond
- Diamond d1(R, R.p0, R.one, R.zero);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph();
-
- CheckInputs(ret, d1.phi, R.start, d1.merge);
- CheckInputs(d1.phi, R.one, R.zero, d1.merge);
- CheckInputs(d1.merge, d1.if_true, d1.if_false);
-
- DeadChecker dead(&R.graph);
- dead.Check(d2);
- dead.Check(d3);
-}
-
-
-TEST(Return_nested_diamonds_true1) {
- ControlReducerTester R;
- Diamond d2(R, R.p0, R.one, R.zero);
- Diamond d1(R, R.one, d2.phi, R.zero);
- Diamond d3(R, R.p0);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 gets folded true.
-
- CheckInputs(ret, d2.phi, R.start, d2.merge);
- CheckInputs(d2.branch, R.p0, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.CheckLive(d2);
- dead.Check(d3);
-}
-
-
-TEST(Return_nested_diamonds_false1) {
- ControlReducerTester R;
- Diamond d3(R, R.p0, R.one, R.zero);
- Diamond d1(R, R.zero, R.one, d3.phi);
- Diamond d2(R, R.p0);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 gets folded false.
-
- CheckInputs(ret, d3.phi, R.start, d3.merge);
- CheckInputs(d3.branch, R.p0, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.Check(d2);
- dead.CheckLive(d3);
-}
-
-
-TEST(Return_nested_diamonds_true_true1) {
- ControlReducerTester R;
- Diamond d1(R, R.one, R.one, R.zero);
- Diamond d2(R, R.one);
- Diamond d3(R, R.p0);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 and d2 both get folded true.
-
- CheckInputs(ret, R.one, R.start, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.Check(d2);
- dead.Check(d3);
-}
-
-
-TEST(Return_nested_diamonds_true_false1) {
- ControlReducerTester R;
- Diamond d1(R, R.one, R.one, R.zero);
- Diamond d2(R, R.zero);
- Diamond d3(R, R.p0);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 gets folded true and d2 gets folded false.
-
- CheckInputs(ret, R.one, R.start, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.Check(d2);
- dead.Check(d3);
-}
-
-
-TEST(Return_nested_diamonds2) {
- ControlReducerTester R;
- Node* x2 = R.jsgraph.Float64Constant(11.1);
- Node* y2 = R.jsgraph.Float64Constant(22.2);
- Node* x3 = R.jsgraph.Float64Constant(33.3);
- Node* y3 = R.jsgraph.Float64Constant(44.4);
-
- Diamond d2(R, R.p0, x2, y2);
- Diamond d3(R, R.p0, x3, y3);
- Diamond d1(R, R.p0, d2.phi, d3.phi);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // nothing should happen.
-
- CheckInputs(ret, d1.phi, R.start, d1.merge);
- CheckInputs(d1.phi, d2.phi, d3.phi, d1.merge);
- CheckInputs(d1.merge, d2.merge, d3.merge);
-
- DeadChecker dead(&R.graph);
- dead.CheckLive(d2);
- dead.CheckLive(d3);
-}
-
-
-TEST(Return_nested_diamonds_true2) {
- ControlReducerTester R;
- Node* x2 = R.jsgraph.Float64Constant(11.1);
- Node* y2 = R.jsgraph.Float64Constant(22.2);
- Node* x3 = R.jsgraph.Float64Constant(33.3);
- Node* y3 = R.jsgraph.Float64Constant(44.4);
-
- Diamond d2(R, R.p0, x2, y2);
- Diamond d3(R, R.p0, x3, y3);
- Diamond d1(R, R.one, d2.phi, d3.phi);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 gets folded true.
-
- CheckInputs(ret, d2.phi, R.start, d2.merge);
- CheckInputs(d2.branch, R.p0, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.CheckLive(d2);
- dead.Check(d3);
-}
-
-
-TEST(Return_nested_diamonds_true_true2) {
- ControlReducerTester R;
- Node* x2 = R.jsgraph.Float64Constant(11.1);
- Node* y2 = R.jsgraph.Float64Constant(22.2);
- Node* x3 = R.jsgraph.Float64Constant(33.3);
- Node* y3 = R.jsgraph.Float64Constant(44.4);
-
- Diamond d2(R, R.one, x2, y2);
- Diamond d3(R, R.p0, x3, y3);
- Diamond d1(R, R.one, d2.phi, d3.phi);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 gets folded true.
-
- CheckInputs(ret, x2, R.start, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.Check(d2);
- dead.Check(d3);
-}
-
-
-TEST(Return_nested_diamonds_true_false2) {
- ControlReducerTester R;
- Node* x2 = R.jsgraph.Float64Constant(11.1);
- Node* y2 = R.jsgraph.Float64Constant(22.2);
- Node* x3 = R.jsgraph.Float64Constant(33.3);
- Node* y3 = R.jsgraph.Float64Constant(44.4);
-
- Diamond d2(R, R.zero, x2, y2);
- Diamond d3(R, R.p0, x3, y3);
- Diamond d1(R, R.one, d2.phi, d3.phi);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 gets folded true.
-
- CheckInputs(ret, y2, R.start, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.Check(d2);
- dead.Check(d3);
-}
diff --git a/deps/v8/test/cctest/compiler/test-js-constant-cache.cc b/deps/v8/test/cctest/compiler/test-js-constant-cache.cc
index 630f911c5e..8774a9a9e3 100644
--- a/deps/v8/test/cctest/compiler/test-js-constant-cache.cc
+++ b/deps/v8/test/cctest/compiler/test-js-constant-cache.cc
@@ -21,7 +21,7 @@ class JSCacheTesterHelper {
: main_graph_(zone),
main_common_(zone),
main_javascript_(zone),
- main_typer_(isolate, &main_graph_, MaybeHandle<Context>()),
+ main_typer_(isolate, &main_graph_),
main_machine_(zone) {}
Graph main_graph_;
CommonOperatorBuilder main_common_;
@@ -41,7 +41,7 @@ class JSConstantCacheTester : public HandleAndZoneScope,
JSGraph(main_isolate(), &main_graph_, &main_common_, &main_javascript_,
&main_machine_) {
main_graph_.SetStart(main_graph_.NewNode(common()->Start(0)));
- main_graph_.SetEnd(main_graph_.NewNode(common()->End()));
+ main_graph_.SetEnd(main_graph_.NewNode(common()->End(1)));
main_typer_.Run();
}
@@ -335,7 +335,7 @@ TEST(JSGraph_GetCachedNodes_int32) {
25, 15, 30, 31, 45, 46, 47, 48};
for (size_t i = 0; i < arraysize(constants); i++) {
- int count_before = T.graph()->NodeCount();
+ size_t count_before = T.graph()->NodeCount();
NodeVector nodes_before(T.main_zone());
T.GetCachedNodes(&nodes_before);
Node* n = T.Int32Constant(constants[i]);
@@ -357,7 +357,7 @@ TEST(JSGraph_GetCachedNodes_float64) {
11, 11, -33.3, -33.3, -22, -11};
for (size_t i = 0; i < arraysize(constants); i++) {
- int count_before = T.graph()->NodeCount();
+ size_t count_before = T.graph()->NodeCount();
NodeVector nodes_before(T.main_zone());
T.GetCachedNodes(&nodes_before);
Node* n = T.Float64Constant(constants[i]);
@@ -379,7 +379,7 @@ TEST(JSGraph_GetCachedNodes_int64) {
19, 20, 20, 21, 21, 22, 23, 24, 25};
for (size_t i = 0; i < arraysize(constants); i++) {
- int count_before = T.graph()->NodeCount();
+ size_t count_before = T.graph()->NodeCount();
NodeVector nodes_before(T.main_zone());
T.GetCachedNodes(&nodes_before);
Node* n = T.Int64Constant(constants[i]);
@@ -401,7 +401,7 @@ TEST(JSGraph_GetCachedNodes_number) {
11, 11, -33.3, -33.3, -22, -11};
for (size_t i = 0; i < arraysize(constants); i++) {
- int count_before = T.graph()->NodeCount();
+ size_t count_before = T.graph()->NodeCount();
NodeVector nodes_before(T.main_zone());
T.GetCachedNodes(&nodes_before);
Node* n = T.Constant(constants[i]);
@@ -428,7 +428,7 @@ TEST(JSGraph_GetCachedNodes_external) {
ExternalReference::address_of_one_half()};
for (size_t i = 0; i < arraysize(constants); i++) {
- int count_before = T.graph()->NodeCount();
+ size_t count_before = T.graph()->NodeCount();
NodeVector nodes_before(T.main_zone());
T.GetCachedNodes(&nodes_before);
Node* n = T.ExternalConstant(constants[i]);
diff --git a/deps/v8/test/cctest/compiler/test-js-context-specialization.cc b/deps/v8/test/cctest/compiler/test-js-context-specialization.cc
index 2450e7cf57..328b0aefdd 100644
--- a/deps/v8/test/cctest/compiler/test-js-context-specialization.cc
+++ b/deps/v8/test/cctest/compiler/test-js-context-specialization.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "src/compiler/js-context-specialization.h"
+#include "src/compiler/js-graph.h"
#include "src/compiler/js-operator.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
@@ -22,8 +23,11 @@ class ContextSpecializationTester : public HandleAndZoneScope {
javascript_(main_zone()),
machine_(main_zone()),
simplified_(main_zone()),
- jsgraph_(main_isolate(), graph(), common(), &javascript_, &machine_) {}
+ jsgraph_(main_isolate(), graph(), common(), &javascript_, &machine_),
+ reducer_(main_zone(), graph()),
+ spec_(&reducer_, jsgraph(), MaybeHandle<Context>()) {}
+ JSContextSpecialization* spec() { return &spec_; }
Factory* factory() { return main_isolate()->factory(); }
CommonOperatorBuilder* common() { return &common_; }
JSOperatorBuilder* javascript() { return &javascript_; }
@@ -38,6 +42,8 @@ class ContextSpecializationTester : public HandleAndZoneScope {
MachineOperatorBuilder machine_;
SimplifiedOperatorBuilder simplified_;
JSGraph jsgraph_;
+ GraphReducer reducer_;
+ JSContextSpecialization spec_;
};
@@ -60,13 +66,12 @@ TEST(ReduceJSLoadContext) {
Node* const_context = t.jsgraph()->Constant(native);
Node* deep_const_context = t.jsgraph()->Constant(subcontext2);
Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
- JSContextSpecializer spec(t.jsgraph());
{
// Mutable slot, constant context, depth = 0 => do nothing.
Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false),
const_context, const_context, start);
- Reduction r = spec.ReduceJSLoadContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
@@ -74,7 +79,7 @@ TEST(ReduceJSLoadContext) {
// Mutable slot, non-constant context, depth = 0 => do nothing.
Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false),
param_context, param_context, start);
- Reduction r = spec.ReduceJSLoadContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
@@ -83,11 +88,11 @@ TEST(ReduceJSLoadContext) {
Node* load = t.graph()->NewNode(
t.javascript()->LoadContext(2, Context::GLOBAL_EVAL_FUN_INDEX, false),
deep_const_context, deep_const_context, start);
- Reduction r = spec.ReduceJSLoadContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(r.Changed());
Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
- HeapObjectMatcher<Context> match(new_context_input);
+ HeapObjectMatcher match(new_context_input);
CHECK_EQ(*native, *match.Value().handle());
ContextAccess access = OpParameter<ContextAccess>(r.replacement());
CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
@@ -99,11 +104,11 @@ TEST(ReduceJSLoadContext) {
// Immutable slot, constant context, depth = 0 => specialize.
Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true),
const_context, const_context, start);
- Reduction r = spec.ReduceJSLoadContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(r.Changed());
CHECK(r.replacement() != load);
- HeapObjectMatcher<Object> match(r.replacement());
+ HeapObjectMatcher match(r.replacement());
CHECK(match.HasValue());
CHECK_EQ(*expected, *match.Value().handle());
}
@@ -132,13 +137,12 @@ TEST(ReduceJSStoreContext) {
Node* const_context = t.jsgraph()->Constant(native);
Node* deep_const_context = t.jsgraph()->Constant(subcontext2);
Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
- JSContextSpecializer spec(t.jsgraph());
{
// Mutable slot, constant context, depth = 0 => do nothing.
Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, 0),
const_context, const_context, start);
- Reduction r = spec.ReduceJSStoreContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
@@ -146,7 +150,7 @@ TEST(ReduceJSStoreContext) {
// Mutable slot, non-constant context, depth = 0 => do nothing.
Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, 0),
param_context, param_context, start);
- Reduction r = spec.ReduceJSStoreContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
@@ -154,7 +158,7 @@ TEST(ReduceJSStoreContext) {
// Immutable slot, constant context, depth = 0 => do nothing.
Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, slot),
const_context, const_context, start);
- Reduction r = spec.ReduceJSStoreContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
@@ -163,11 +167,11 @@ TEST(ReduceJSStoreContext) {
Node* load = t.graph()->NewNode(
t.javascript()->StoreContext(2, Context::GLOBAL_EVAL_FUN_INDEX),
deep_const_context, deep_const_context, start);
- Reduction r = spec.ReduceJSStoreContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(r.Changed());
Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
- HeapObjectMatcher<Context> match(new_context_input);
+ HeapObjectMatcher match(new_context_input);
CHECK_EQ(*native, *match.Value().handle());
ContextAccess access = OpParameter<ContextAccess>(r.replacement());
CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
@@ -197,7 +201,6 @@ TEST(SpecializeToContext) {
Node* const_context = t.jsgraph()->Constant(native);
Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
- JSContextSpecializer spec(t.jsgraph());
{
// Check that specialization replaces values and forwards effects
@@ -222,7 +225,7 @@ TEST(SpecializeToContext) {
Node* ret =
t.graph()->NewNode(t.common()->Return(), add, effect_use, start);
- Node* end = t.graph()->NewNode(t.common()->End(), ret);
+ Node* end = t.graph()->NewNode(t.common()->End(1), ret);
USE(end);
t.graph()->SetEnd(end);
@@ -231,7 +234,9 @@ TEST(SpecializeToContext) {
CheckEffectInput(load, effect_use);
// Perform the reduction on the entire graph.
- GraphReducer graph_reducer(t.graph(), t.main_zone());
+ GraphReducer graph_reducer(t.main_zone(), t.graph());
+ JSContextSpecialization spec(&graph_reducer, t.jsgraph(),
+ MaybeHandle<Context>());
graph_reducer.AddReducer(&spec);
graph_reducer.ReduceGraph();
@@ -242,7 +247,7 @@ TEST(SpecializeToContext) {
CHECK_EQ(other_load, other_use->InputAt(0));
Node* replacement = value_use->InputAt(0);
- HeapObjectMatcher<Object> match(replacement);
+ HeapObjectMatcher match(replacement);
CHECK(match.HasValue());
CHECK_EQ(*expected, *match.Value().handle());
}
diff --git a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
index 92fdb6e874..e512de89b2 100644
--- a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
+++ b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
@@ -38,10 +38,10 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
simplified(main_zone()),
common(main_zone()),
graph(main_zone()),
- typer(main_isolate(), &graph, MaybeHandle<Context>()),
+ typer(main_isolate(), &graph),
context_node(NULL) {
graph.SetStart(graph.NewNode(common.Start(num_parameters)));
- graph.SetEnd(graph.NewNode(common.End()));
+ graph.SetEnd(graph.NewNode(common.End(1)));
typer.Run();
}
@@ -79,17 +79,19 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
Node* locals = graph.NewNode(common.StateValues(0));
Node* stack = graph.NewNode(common.StateValues(0));
- Node* state_node =
- graph.NewNode(common.FrameState(JS_FRAME, BailoutId::None(),
- OutputFrameStateCombine::Ignore()),
- parameters, locals, stack, context, UndefinedConstant());
+ Node* state_node = graph.NewNode(
+ common.FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(),
+ nullptr),
+ parameters, locals, stack, context, UndefinedConstant());
return state_node;
}
Node* reduce(Node* node) {
JSGraph jsgraph(main_isolate(), &graph, &common, &javascript, &machine);
- JSTypedLowering reducer(&jsgraph, main_zone());
+ // TODO(titzer): mock the GraphReducer here for better unit testing.
+ GraphReducer graph_reducer(main_zone(), &graph);
+ JSTypedLowering reducer(&graph_reducer, &jsgraph, main_zone());
Reduction reduction = reducer.Reduce(node);
if (reduction.Changed()) return reduction.replacement();
return node;
@@ -318,11 +320,11 @@ class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester {
: JSTypedLoweringTester(), language_mode_(language_mode) {
int i = 0;
set(i++, javascript.ShiftLeft(language_mode_), true);
- set(i++, machine.Word32Shl(), false);
+ set(i++, simplified.NumberShiftLeft(), false);
set(i++, javascript.ShiftRight(language_mode_), true);
- set(i++, machine.Word32Sar(), false);
+ set(i++, simplified.NumberShiftRight(), false);
set(i++, javascript.ShiftRightLogical(language_mode_), false);
- set(i++, machine.Word32Shr(), false);
+ set(i++, simplified.NumberShiftRightLogical(), false);
}
static const int kNumberOps = 6;
const Operator* ops[kNumberOps];
@@ -362,14 +364,7 @@ TEST(Int32BitwiseShifts) {
Node* r1 = r->InputAt(1);
CheckToI32(p0, r0, R.signedness[k]);
-
- if (r1->opcode() == IrOpcode::kWord32And) {
- R.CheckPureBinop(IrOpcode::kWord32And, r1);
- CheckToI32(p1, r1->InputAt(0), R.signedness[k + 1]);
- R.CheckInt32Constant(0x1F, r1->InputAt(1));
- } else {
- CheckToI32(p1, r1, R.signedness[k]);
- }
+ CheckToI32(p1, r1, false);
}
}
}
@@ -460,8 +455,9 @@ TEST(JSToNumber_replacement) {
for (size_t i = 0; i < arraysize(types); i++) {
Node* n = R.Parameter(types[i]);
- Node* c = R.graph.NewNode(R.javascript.ToNumber(), n, R.context(),
- R.start(), R.start());
+ Node* c =
+ R.graph.NewNode(R.javascript.ToNumber(), n, R.context(),
+ R.EmptyFrameState(R.context()), R.start(), R.start());
Node* effect_use = R.UseForEffect(c);
Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c);
@@ -688,18 +684,20 @@ TEST_WITH_STRONG(MixedComparison1) {
for (size_t j = 0; j < arraysize(types); j++) {
Node* p1 = R.Parameter(types[j], 1);
{
- Node* cmp = R.Binop(R.javascript.LessThan(language_mode), p0, p1);
+ const Operator* less_than = R.javascript.LessThan(language_mode);
+ Node* cmp = R.Binop(less_than, 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);
- }
+ if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) {
+ R.CheckPureBinop(R.simplified.StringLessThan(), r);
+ } else if ((types[i]->Is(Type::Number()) &&
+ types[j]->Is(Type::Number())) ||
+ (!is_strong(language_mode) &&
+ (!types[i]->Maybe(Type::String()) ||
+ !types[j]->Maybe(Type::String())))) {
+ R.CheckPureBinop(R.simplified.NumberLessThan(), r);
} else {
- CHECK_EQ(cmp, r); // No reduction of mixed types.
+ // No reduction of mixed types.
+ CHECK_EQ(r->op(), less_than);
}
}
}
@@ -708,8 +706,6 @@ TEST_WITH_STRONG(MixedComparison1) {
TEST_WITH_STRONG(RemoveToNumberEffects) {
- FLAG_turbo_deoptimization = true;
-
JSTypedLoweringTester R;
Node* effect_use = NULL;
@@ -721,27 +717,16 @@ TEST_WITH_STRONG(RemoveToNumberEffects) {
switch (i) {
case 0:
- if (FLAG_turbo_deoptimization) {
- DCHECK(OperatorProperties::GetFrameStateInputCount(
- R.javascript.ToNumber()) == 1);
- effect_use = R.graph.NewNode(R.javascript.ToNumber(), p0, R.context(),
- frame_state, ton, R.start());
- } else {
+ DCHECK(OperatorProperties::GetFrameStateInputCount(
+ R.javascript.ToNumber()) == 1);
effect_use = R.graph.NewNode(R.javascript.ToNumber(), p0, R.context(),
- ton, R.start());
- }
+ frame_state, ton, R.start());
break;
case 1:
- if (FLAG_turbo_deoptimization) {
- DCHECK(OperatorProperties::GetFrameStateInputCount(
- R.javascript.ToNumber()) == 1);
- effect_use =
- R.graph.NewNode(R.javascript.ToNumber(), ton, R.context(),
- frame_state, ton, R.start());
- } else {
- effect_use = R.graph.NewNode(R.javascript.ToNumber(), ton,
- R.context(), ton, R.start());
- }
+ DCHECK(OperatorProperties::GetFrameStateInputCount(
+ R.javascript.ToNumber()) == 1);
+ effect_use = R.graph.NewNode(R.javascript.ToNumber(), ton, R.context(),
+ frame_state, ton, R.start());
break;
case 2:
effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start());
@@ -950,8 +935,6 @@ TEST(OrderNumberBinopEffects1) {
R.simplified.NumberMultiply(),
R.javascript.Divide(LanguageMode::SLOPPY),
R.simplified.NumberDivide(),
- R.javascript.Modulus(LanguageMode::SLOPPY),
- R.simplified.NumberModulus(),
};
for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -982,8 +965,6 @@ TEST(OrderNumberBinopEffects2) {
R.simplified.NumberMultiply(),
R.javascript.Divide(LanguageMode::SLOPPY),
R.simplified.NumberDivide(),
- R.javascript.Modulus(LanguageMode::SLOPPY),
- R.simplified.NumberModulus(),
};
for (size_t j = 0; j < arraysize(ops); j += 2) {
diff --git a/deps/v8/test/cctest/compiler/test-jump-threading.cc b/deps/v8/test/cctest/compiler/test-jump-threading.cc
index e0a4a2fc62..9fa3c9f28a 100644
--- a/deps/v8/test/cctest/compiler/test-jump-threading.cc
+++ b/deps/v8/test/cctest/compiler/test-jump-threading.cc
@@ -85,7 +85,7 @@ class TestCode : public HandleAndZoneScope {
if (current_ == NULL) {
current_ = new (main_zone())
InstructionBlock(main_zone(), rpo_number_, RpoNumber::Invalid(),
- RpoNumber::Invalid(), deferred);
+ RpoNumber::Invalid(), deferred, false);
blocks_.push_back(current_);
sequence_.StartBlock(rpo_number_);
}
diff --git a/deps/v8/test/cctest/compiler/test-linkage.cc b/deps/v8/test/cctest/compiler/test-linkage.cc
index 212ff3a8f2..252c43133e 100644
--- a/deps/v8/test/cctest/compiler/test-linkage.cc
+++ b/deps/v8/test/cctest/compiler/test-linkage.cc
@@ -34,8 +34,8 @@ static Handle<JSFunction> Compile(const char* source) {
->NewStringFromUtf8(CStrVector(source))
.ToHandleChecked();
Handle<SharedFunctionInfo> shared_function = Compiler::CompileScript(
- source_code, Handle<String>(), 0, 0, false, false, Handle<Object>(),
- Handle<Context>(isolate->native_context()), NULL, NULL,
+ source_code, Handle<String>(), 0, 0, v8::ScriptOriginOptions(),
+ Handle<Object>(), Handle<Context>(isolate->native_context()), NULL, NULL,
v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE, false);
return isolate->factory()->NewFunctionFromSharedFunctionInfo(
shared_function, isolate->native_context());
@@ -114,5 +114,4 @@ TEST(TestLinkageStubCall) {
// TODO(titzer): test linkage creation for outgoing stub calls.
}
-
#endif // V8_TURBOFAN_TARGET
diff --git a/deps/v8/test/cctest/compiler/test-loop-analysis.cc b/deps/v8/test/cctest/compiler/test-loop-analysis.cc
index 06682ef5a9..6560ae337b 100644
--- a/deps/v8/test/cctest/compiler/test-loop-analysis.cc
+++ b/deps/v8/test/cctest/compiler/test-loop-analysis.cc
@@ -41,7 +41,7 @@ class LoopFinderTester : HandleAndZoneScope {
graph(main_zone()),
jsgraph(main_isolate(), &graph, &common, NULL, NULL),
start(graph.NewNode(common.Start(1))),
- end(graph.NewNode(common.End(), start)),
+ end(graph.NewNode(common.End(1), start)),
p0(graph.NewNode(common.Parameter(0), start)),
zero(jsgraph.Int32Constant(0)),
one(jsgraph.OneConstant()),
diff --git a/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc b/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc
index 5f9820c72a..ad05273995 100644
--- a/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc
+++ b/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc
@@ -51,7 +51,7 @@ struct TestHelper : public HandleAndZoneScope {
i::Variable* var = scope->Lookup(name);
CHECK(var);
- if (var->location() == Variable::UNALLOCATED) {
+ if (var->location() == VariableLocation::UNALLOCATED) {
CHECK_EQ(0, expected);
} else {
CHECK(var->IsStackAllocated());
diff --git a/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc b/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc
index beedc459e7..299f0c02ab 100644
--- a/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc
+++ b/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc
@@ -60,7 +60,7 @@ class ReducerTester : public HandleAndZoneScope {
common(main_zone()),
graph(main_zone()),
javascript(main_zone()),
- typer(isolate, &graph, MaybeHandle<Context>()),
+ typer(isolate, &graph),
jsgraph(isolate, &graph, &common, &javascript, &machine),
maxuint32(Constant<int32_t>(kMaxUInt32)) {
Node* s = graph.NewNode(common.Start(num_parameters));
diff --git a/deps/v8/test/cctest/compiler/test-osr.cc b/deps/v8/test/cctest/compiler/test-osr.cc
index d2171188f8..80dbccc633 100644
--- a/deps/v8/test/cctest/compiler/test-osr.cc
+++ b/deps/v8/test/cctest/compiler/test-osr.cc
@@ -51,7 +51,7 @@ class OsrDeconstructorTester : public HandleAndZoneScope {
jsgraph(main_isolate(), &graph, &common, NULL, NULL),
start(graph.NewNode(common.Start(1))),
p0(graph.NewNode(common.Parameter(0), start)),
- end(graph.NewNode(common.End(), start)),
+ end(graph.NewNode(common.End(1), start)),
osr_normal_entry(graph.NewNode(common.OsrNormalEntry(), start, start)),
osr_loop_entry(graph.NewNode(common.OsrLoopEntry(), start, start)),
self(graph.NewNode(common.Int32Constant(0xaabbccdd))) {
@@ -165,30 +165,6 @@ TEST(Deconstruct_osr1) {
}
-TEST(Deconstruct_osr1_type) {
- OsrDeconstructorTester T(1);
-
- Node* loop = T.NewOsrLoop(1);
- Node* osr_phi =
- T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant());
- Type* type = Type::Signed32();
- NodeProperties::SetBounds(osr_phi, Bounds(type, type));
-
- Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, loop);
- T.graph.SetEnd(ret);
-
- OsrHelper helper(0, 0);
- helper.Deconstruct(&T.jsgraph, &T.common, T.main_zone());
-
- CHECK_EQ(type, NodeProperties::GetBounds(T.osr_values[0]).lower);
- CHECK_EQ(type, NodeProperties::GetBounds(T.osr_values[0]).upper);
-
- CheckInputs(loop, T.start, loop);
- CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop);
- CheckInputs(ret, osr_phi, T.start, loop);
-}
-
-
TEST(Deconstruct_osr_remove_prologue) {
OsrDeconstructorTester T(1);
Diamond d(&T.graph, &T.common, T.p0);
@@ -370,14 +346,14 @@ TEST(Deconstruct_osr_nested1) {
Node* outer_phi = outer.Phi(T.p0, T.p0, nullptr);
outer.branch->ReplaceInput(0, outer_phi);
- Node* osr_phi = inner.Phi(T.jsgraph.OneConstant(), T.osr_values[0],
- T.jsgraph.ZeroConstant());
+ Node* osr_phi = inner.Phi(T.jsgraph.TrueConstant(), T.osr_values[0],
+ T.jsgraph.FalseConstant());
inner.branch->ReplaceInput(0, osr_phi);
outer_phi->ReplaceInput(1, osr_phi);
Node* ret =
T.graph.NewNode(T.common.Return(), outer_phi, T.start, outer.exit);
- Node* end = T.graph.NewNode(T.common.End(), ret);
+ Node* end = T.graph.NewNode(T.common.End(1), ret);
T.graph.SetEnd(end);
T.DeconstructOsr();
@@ -385,7 +361,7 @@ TEST(Deconstruct_osr_nested1) {
// Check structure of deconstructed graph.
// Check inner OSR loop is directly connected to start.
CheckInputs(inner.loop, T.start, inner.if_true);
- CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), inner.loop);
+ CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.FalseConstant(), inner.loop);
// Check control transfer to copy of outer loop.
Node* new_outer_loop = FindSuccessor(inner.exit, IrOpcode::kLoop);
@@ -412,8 +388,8 @@ TEST(Deconstruct_osr_nested1) {
Node* new_inner_loop = FindSuccessor(new_outer_if_true, IrOpcode::kLoop);
Node* new_inner_phi = FindSuccessor(new_inner_loop, IrOpcode::kPhi);
- CheckInputs(new_inner_phi, T.jsgraph.OneConstant(), T.jsgraph.ZeroConstant(),
- new_inner_loop);
+ CheckInputs(new_inner_phi, T.jsgraph.TrueConstant(),
+ T.jsgraph.FalseConstant(), new_inner_loop);
CheckInputs(new_outer_phi, osr_phi, new_inner_phi, new_outer_loop);
}
@@ -429,11 +405,11 @@ TEST(Deconstruct_osr_nested2) {
Node* outer_phi = outer.Phi(T.p0, T.p0, T.p0);
outer.branch->ReplaceInput(0, outer_phi);
- Node* osr_phi = inner.Phi(T.jsgraph.OneConstant(), T.osr_values[0],
- T.jsgraph.ZeroConstant());
+ Node* osr_phi = inner.Phi(T.jsgraph.TrueConstant(), T.osr_values[0],
+ T.jsgraph.FalseConstant());
inner.branch->ReplaceInput(0, osr_phi);
outer_phi->ReplaceInput(1, osr_phi);
- outer_phi->ReplaceInput(2, T.jsgraph.ZeroConstant());
+ outer_phi->ReplaceInput(2, T.jsgraph.FalseConstant());
Node* x_branch = T.graph.NewNode(T.common.Branch(), osr_phi, inner.exit);
Node* x_true = T.graph.NewNode(T.common.IfTrue(), x_branch);
@@ -444,7 +420,7 @@ TEST(Deconstruct_osr_nested2) {
Node* ret =
T.graph.NewNode(T.common.Return(), outer_phi, T.start, outer.exit);
- Node* end = T.graph.NewNode(T.common.End(), ret);
+ Node* end = T.graph.NewNode(T.common.End(1), ret);
T.graph.SetEnd(end);
T.DeconstructOsr();
@@ -452,7 +428,7 @@ TEST(Deconstruct_osr_nested2) {
// Check structure of deconstructed graph.
// Check inner OSR loop is directly connected to start.
CheckInputs(inner.loop, T.start, inner.if_true);
- CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), inner.loop);
+ CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.FalseConstant(), inner.loop);
// Check control transfer to copy of outer loop.
Node* new_merge = FindSuccessor(x_true, IrOpcode::kMerge);
@@ -465,7 +441,7 @@ TEST(Deconstruct_osr_nested2) {
CHECK_NE(new_outer_phi, outer_phi);
Node* new_entry_phi = FindSuccessor(new_merge, IrOpcode::kPhi);
- CheckInputs(new_entry_phi, osr_phi, T.jsgraph.ZeroConstant(), new_merge);
+ CheckInputs(new_entry_phi, osr_phi, T.jsgraph.FalseConstant(), new_merge);
CHECK_EQ(new_merge, new_outer_loop->InputAt(0));
@@ -486,10 +462,10 @@ TEST(Deconstruct_osr_nested2) {
Node* new_inner_loop = FindSuccessor(new_outer_if_true, IrOpcode::kLoop);
Node* new_inner_phi = FindSuccessor(new_inner_loop, IrOpcode::kPhi);
- CheckInputs(new_inner_phi, T.jsgraph.OneConstant(), T.jsgraph.ZeroConstant(),
- new_inner_loop);
+ CheckInputs(new_inner_phi, T.jsgraph.TrueConstant(),
+ T.jsgraph.FalseConstant(), new_inner_loop);
CheckInputs(new_outer_phi, new_entry_phi, new_inner_phi,
- T.jsgraph.ZeroConstant(), new_outer_loop);
+ T.jsgraph.FalseConstant(), new_outer_loop);
}
@@ -523,8 +499,8 @@ TEST(Deconstruct_osr_nested3) {
// middle loop.
Node* loop1 = T.graph.NewNode(T.common.Loop(2), loop0.if_true, T.self);
loop1->ReplaceInput(0, loop0.if_true);
- Node* loop1_phi =
- T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), loop0_cntr, loop0_cntr);
+ Node* loop1_phi = T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), loop0_cntr,
+ loop0_cntr, loop1);
// innermost (OSR) loop.
While loop2(T, T.p0, true, 1);
@@ -549,7 +525,7 @@ TEST(Deconstruct_osr_nested3) {
Node* ret =
T.graph.NewNode(T.common.Return(), loop0_cntr, T.start, loop0.exit);
- Node* end = T.graph.NewNode(T.common.End(), ret);
+ Node* end = T.graph.NewNode(T.common.End(1), ret);
T.graph.SetEnd(end);
T.DeconstructOsr();
diff --git a/deps/v8/test/cctest/compiler/test-pipeline.cc b/deps/v8/test/cctest/compiler/test-pipeline.cc
index b67af6ecf7..84550d502a 100644
--- a/deps/v8/test/cctest/compiler/test-pipeline.cc
+++ b/deps/v8/test/cctest/compiler/test-pipeline.cc
@@ -5,23 +5,18 @@
#include "src/v8.h"
#include "test/cctest/cctest.h"
-#include "src/ast-numbering.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) {
- HandleAndZoneScope handles;
- const char* source = "(function(a,b) { return a + b; })";
+static void RunPipeline(Zone* zone, const char* source) {
Handle<JSFunction> function = v8::Utils::OpenHandle(
*v8::Handle<v8::Function>::Cast(CompileRun(source)));
- ParseInfo parse_info(handles.main_zone(), function);
+ ParseInfo parse_info(zone, function);
CHECK(Compiler::ParseAndAnalyze(&parse_info));
CompilationInfo info(&parse_info);
@@ -34,3 +29,17 @@ TEST(PipelineAdd) {
USE(pipeline);
#endif
}
+
+
+TEST(PipelineTyped) {
+ HandleAndZoneScope handles;
+ FLAG_turbo_types = true;
+ RunPipeline(handles.main_zone(), "(function(a,b) { return a + b; })");
+}
+
+
+TEST(PipelineGeneric) {
+ HandleAndZoneScope handles;
+ FLAG_turbo_types = false;
+ RunPipeline(handles.main_zone(), "(function(a,b) { return a + b; })");
+}
diff --git a/deps/v8/test/cctest/compiler/test-representation-change.cc b/deps/v8/test/cctest/compiler/test-representation-change.cc
index 55f054a74b..216f9fd847 100644
--- a/deps/v8/test/cctest/compiler/test-representation-change.cc
+++ b/deps/v8/test/cctest/compiler/test-representation-change.cc
@@ -69,7 +69,7 @@ class RepresentationChangerTester : public HandleAndZoneScope,
}
void CheckHeapConstant(Node* n, HeapObject* expected) {
- HeapObjectMatcher<HeapObject> m(n);
+ HeapObjectMatcher m(n);
CHECK(m.HasValue());
CHECK_EQ(expected, *m.Value().handle());
}
@@ -100,9 +100,9 @@ class RepresentationChangerTester : public HandleAndZoneScope,
CHECK_EQ(n, c);
}
};
-}
-}
-} // namespace v8::internal::compiler
+} // namespace compiler
+} // namespace internal
+} // namespace v8
static const MachineType all_reps[] = {kRepBit, kRepWord32, kRepWord64,
diff --git a/deps/v8/test/cctest/compiler/test-run-deopt.cc b/deps/v8/test/cctest/compiler/test-run-deopt.cc
index 14c024cdbc..d895924324 100644
--- a/deps/v8/test/cctest/compiler/test-run-deopt.cc
+++ b/deps/v8/test/cctest/compiler/test-run-deopt.cc
@@ -7,13 +7,12 @@
#include "test/cctest/cctest.h"
#include "test/cctest/compiler/function-tester.h"
-using namespace v8;
using namespace v8::internal;
using namespace v8::internal::compiler;
#if V8_TURBOFAN_TARGET
-static void IsOptimized(const FunctionCallbackInfo<v8::Value>& args) {
+static void IsOptimized(const v8::FunctionCallbackInfo<v8::Value>& args) {
JavaScriptFrameIterator it(CcTest::i_isolate());
JavaScriptFrame* frame = it.frame();
return args.GetReturnValue().Set(frame->is_optimized());
@@ -21,56 +20,99 @@ static void IsOptimized(const FunctionCallbackInfo<v8::Value>& args) {
static void InstallIsOptimizedHelper(v8::Isolate* isolate) {
- Local<v8::Context> context = isolate->GetCurrentContext();
- Local<v8::FunctionTemplate> t = FunctionTemplate::New(isolate, IsOptimized);
+ v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::FunctionTemplate> t =
+ v8::FunctionTemplate::New(isolate, IsOptimized);
context->Global()->Set(v8_str("IsOptimized"), t->GetFunction());
}
-TEST(TurboSimpleDeopt) {
+TEST(DeoptSimple) {
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; })");
+ " var b = 1;"
+ " if (!IsOptimized()) return 0;"
+ " %DeoptimizeFunction(f);"
+ " if (IsOptimized()) return 0;"
+ " return a + b;"
+ "})");
InstallIsOptimizedHelper(CcTest::isolate());
T.CheckCall(T.Val(2), T.Val(1));
}
-TEST(TurboSimpleDeoptInExpr) {
+TEST(DeoptSimpleInExpr) {
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; })");
+ " var b = 1;"
+ " var c = 2;"
+ " if (!IsOptimized()) return 0;"
+ " var d = b + (%DeoptimizeFunction(f), c);"
+ " if (IsOptimized()) return 0;"
+ " return d + a;"
+ "})");
InstallIsOptimizedHelper(CcTest::isolate());
T.CheckCall(T.Val(6), T.Val(3));
}
+
+TEST(DeoptExceptionHandlerCatch) {
+ FLAG_allow_natives_syntax = true;
+ FLAG_turbo_try_catch = true;
+
+ FunctionTester T(
+ "(function f() {"
+ " var is_opt = IsOptimized;"
+ " try {"
+ " DeoptAndThrow(f);"
+ " } catch (e) {"
+ " return is_opt();"
+ " }"
+ "})");
+
+ CompileRun("function DeoptAndThrow(f) { %DeoptimizeFunction(f); throw 0; }");
+ InstallIsOptimizedHelper(CcTest::isolate());
+ T.CheckCall(T.false_value());
+}
+
+
+TEST(DeoptExceptionHandlerFinally) {
+ FLAG_allow_natives_syntax = true;
+ FLAG_turbo_try_finally = true;
+
+ FunctionTester T(
+ "(function f() {"
+ " var is_opt = IsOptimized;"
+ " try {"
+ " DeoptAndThrow(f);"
+ " } finally {"
+ " return is_opt();"
+ " }"
+ "})");
+
+ CompileRun("function DeoptAndThrow(f) { %DeoptimizeFunction(f); throw 0; }");
+ InstallIsOptimizedHelper(CcTest::isolate());
+#if 0 // TODO(4195,mstarzinger): Reproduces on MIPS64, re-enable once fixed.
+ T.CheckCall(T.false_value());
+#endif
+}
+
#endif
-TEST(TurboTrivialDeopt) {
+TEST(DeoptTrivial) {
FLAG_allow_natives_syntax = true;
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function foo() {"
- "%DeoptimizeFunction(foo);"
- "return 1; })");
+ " %DeoptimizeFunction(foo);"
+ " return 1;"
+ "})");
T.CheckCall(T.Val(1));
}
diff --git a/deps/v8/test/cctest/compiler/test-run-inlining.cc b/deps/v8/test/cctest/compiler/test-run-inlining.cc
index a6d76e4d57..7f8ae25619 100644
--- a/deps/v8/test/cctest/compiler/test-run-inlining.cc
+++ b/deps/v8/test/cctest/compiler/test-run-inlining.cc
@@ -13,7 +13,7 @@ using namespace v8::internal::compiler;
namespace {
-// Helper to determine inline count via JavaScriptFrame::GetInlineCount.
+// Helper to determine inline count via JavaScriptFrame::GetFunctions.
// Note that a count of 1 indicates that no inlining has occured.
void AssertInlineCount(const v8::FunctionCallbackInfo<v8::Value>& args) {
StackTraceFrameIterator it(CcTest::i_isolate());
@@ -21,14 +21,17 @@ void AssertInlineCount(const v8::FunctionCallbackInfo<v8::Value>& args) {
JavaScriptFrame* topmost = it.frame();
while (!it.done()) {
JavaScriptFrame* frame = it.frame();
+ List<JSFunction*> functions(2);
+ frame->GetFunctions(&functions);
PrintF("%d %s, inline count: %d\n", frames_seen,
frame->function()->shared()->DebugName()->ToCString().get(),
- frame->GetInlineCount());
+ functions.length());
frames_seen++;
it.Advance();
}
- CHECK_EQ(args[0]->ToInt32(args.GetIsolate())->Value(),
- topmost->GetInlineCount());
+ List<JSFunction*> functions(2);
+ topmost->GetFunctions(&functions);
+ CHECK_EQ(args[0]->ToInt32(args.GetIsolate())->Value(), functions.length());
}
@@ -40,9 +43,8 @@ void InstallAssertInlineCountHelper(v8::Isolate* isolate) {
}
-const uint32_t kBuiltinInlineFlags = CompilationInfo::kBuiltinInliningEnabled |
- CompilationInfo::kContextSpecializing |
- CompilationInfo::kTypingEnabled;
+const uint32_t kRestrictedInliningFlags =
+ CompilationInfo::kContextSpecializing | CompilationInfo::kTypingEnabled;
const uint32_t kInlineFlags = CompilationInfo::kInliningEnabled |
CompilationInfo::kContextSpecializing |
@@ -52,7 +54,6 @@ const uint32_t kInlineFlags = CompilationInfo::kInliningEnabled |
TEST(SimpleInlining) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function(){"
" function foo(s) { AssertInlineCount(2); return s; };"
@@ -67,7 +68,6 @@ TEST(SimpleInlining) {
TEST(SimpleInliningDeopt) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function(){"
" function foo(s) { %DeoptimizeFunction(bar); return s; };"
@@ -81,8 +81,21 @@ TEST(SimpleInliningDeopt) {
}
+TEST(SimpleInliningDeoptSelf) {
+ FunctionTester T(
+ "(function(){"
+ " function foo(s) { %_DeoptimizeNow(); return s; };"
+ " function bar(s, t) { return foo(s); };"
+ " return bar;"
+ "})();",
+ kInlineFlags);
+
+ InstallAssertInlineCountHelper(CcTest::isolate());
+ T.CheckCall(T.Val(1), T.Val(1), T.Val(2));
+}
+
+
TEST(SimpleInliningContext) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) { AssertInlineCount(2); var x = 12; return s + x; };"
@@ -97,7 +110,6 @@ TEST(SimpleInliningContext) {
TEST(SimpleInliningContextDeopt) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) {"
@@ -115,7 +127,6 @@ TEST(SimpleInliningContextDeopt) {
TEST(CaptureContext) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"var f = (function () {"
" var x = 42;"
@@ -133,7 +144,6 @@ TEST(CaptureContext) {
// TODO(sigurds) For now we do not inline any native functions. If we do at
// some point, change this test.
TEST(DontInlineEval) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"var x = 42;"
"(function () {"
@@ -148,7 +158,6 @@ TEST(DontInlineEval) {
TEST(InlineOmitArguments) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 42;"
@@ -163,7 +172,6 @@ TEST(InlineOmitArguments) {
TEST(InlineOmitArgumentsDeopt) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s,t,u,v) { AssertInlineCount(2);"
@@ -181,7 +189,6 @@ TEST(InlineOmitArgumentsDeopt) {
TEST(InlineSurplusArguments) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 42;"
@@ -197,7 +204,6 @@ TEST(InlineSurplusArguments) {
TEST(InlineSurplusArgumentsDeopt) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) { AssertInlineCount(2); %DeoptimizeFunction(bar);"
@@ -217,7 +223,6 @@ TEST(InlineSurplusArgumentsDeopt) {
TEST(InlineTwice) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 42;"
@@ -232,7 +237,6 @@ TEST(InlineTwice) {
TEST(InlineTwiceDependent) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 42;"
@@ -248,7 +252,6 @@ TEST(InlineTwiceDependent) {
TEST(InlineTwiceDependentDiamond) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 41;"
@@ -265,7 +268,6 @@ TEST(InlineTwiceDependentDiamond) {
TEST(InlineTwiceDependentDiamondDifferent) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 41;"
@@ -282,7 +284,6 @@ TEST(InlineTwiceDependentDiamondDifferent) {
TEST(InlineLoopGuardedEmpty) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) { AssertInlineCount(2); if (s) while (s); return s; };"
@@ -297,7 +298,6 @@ TEST(InlineLoopGuardedEmpty) {
TEST(InlineLoopGuardedOnce) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s,t) { AssertInlineCount(2); if (t > 0) while (s > 0) {"
@@ -313,7 +313,6 @@ TEST(InlineLoopGuardedOnce) {
TEST(InlineLoopGuardedTwice) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s,t) { AssertInlineCount(2); if (t > 0) while (s > 0) {"
@@ -329,7 +328,6 @@ TEST(InlineLoopGuardedTwice) {
TEST(InlineLoopUnguardedEmpty) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) { AssertInlineCount(2); while (s); return s; };"
@@ -344,7 +342,6 @@ TEST(InlineLoopUnguardedEmpty) {
TEST(InlineLoopUnguardedOnce) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) { AssertInlineCount(2); while (s) {"
@@ -360,7 +357,6 @@ TEST(InlineLoopUnguardedOnce) {
TEST(InlineLoopUnguardedTwice) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) { AssertInlineCount(2); while (s > 0) {"
@@ -376,7 +372,6 @@ TEST(InlineLoopUnguardedTwice) {
TEST(InlineStrictIntoNonStrict) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = Object.create({}, { y: { value:42, writable:false } });"
@@ -393,7 +388,6 @@ TEST(InlineStrictIntoNonStrict) {
TEST(InlineNonStrictIntoStrict) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = Object.create({}, { y: { value:42, writable:false } });"
@@ -409,7 +403,6 @@ TEST(InlineNonStrictIntoStrict) {
TEST(InlineIntrinsicIsSmi) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 42;"
@@ -424,7 +417,6 @@ TEST(InlineIntrinsicIsSmi) {
TEST(InlineIntrinsicIsNonNegativeSmi) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 42;"
@@ -439,7 +431,6 @@ TEST(InlineIntrinsicIsNonNegativeSmi) {
TEST(InlineIntrinsicIsArray) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = [1,2,3];"
@@ -474,7 +465,6 @@ TEST(InlineIntrinsicIsArray) {
TEST(InlineWithArguments) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s,t,u) { AssertInlineCount(2);"
@@ -494,15 +484,14 @@ TEST(InlineWithArguments) {
TEST(InlineBuiltin) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s,t,u) { AssertInlineCount(2); return true; }"
" function bar() { return foo(); };"
- " %SetInlineBuiltinFlag(foo);"
+ " %SetForceInlineFlag(foo);"
" return bar;"
"})();",
- kBuiltinInlineFlags);
+ kRestrictedInliningFlags);
InstallAssertInlineCountHelper(CcTest::isolate());
T.CheckCall(T.true_value());
@@ -510,20 +499,80 @@ TEST(InlineBuiltin) {
TEST(InlineNestedBuiltin) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s,t,u) { AssertInlineCount(3); return true; }"
" function baz(s,t,u) { return foo(s,t,u); }"
" function bar() { return baz(); };"
- " %SetInlineBuiltinFlag(foo);"
- " %SetInlineBuiltinFlag(baz);"
+ " %SetForceInlineFlag(foo);"
+ " %SetForceInlineFlag(baz);"
" return bar;"
"})();",
- kBuiltinInlineFlags);
+ kRestrictedInliningFlags);
InstallAssertInlineCountHelper(CcTest::isolate());
T.CheckCall(T.true_value());
}
+
+TEST(StrongModeArity) {
+ FLAG_strong_mode = true;
+ FunctionTester T(
+ "(function () {"
+ " function foo(x, y) { 'use strong'; return x; }"
+ " function bar(x, y) { return foo(x); }"
+ " return bar;"
+ "})();",
+ kInlineFlags);
+ T.CheckThrows(T.undefined(), T.undefined());
+}
+
+
+TEST(StrongModeArityOuter) {
+ FLAG_strong_mode = true;
+ FunctionTester T(
+ "(function () {"
+ " 'use strong';"
+ " function foo(x, y) { return x; }"
+ " function bar(x, y) { return foo(x); }"
+ " return bar;"
+ "})();",
+ kInlineFlags);
+ T.CheckThrows(T.undefined(), T.undefined());
+}
+
+
+TEST(InlineSelfRecursive) {
+ FunctionTester T(
+ "(function () {"
+ " function foo(x) { "
+ " AssertInlineCount(1);"
+ " if (x == 1) return foo(12);"
+ " return x;"
+ " }"
+ " return foo;"
+ "})();",
+ kInlineFlags);
+
+ InstallAssertInlineCountHelper(CcTest::isolate());
+ T.CheckCall(T.Val(12), T.Val(1));
+}
+
+
+TEST(InlineMutuallyRecursive) {
+ FunctionTester T(
+ "(function () {"
+ " function bar(x) { AssertInlineCount(2); return foo(x); }"
+ " function foo(x) { "
+ " if (x == 1) return bar(42);"
+ " return x;"
+ " }"
+ " return foo;"
+ "})();",
+ kInlineFlags);
+
+ InstallAssertInlineCountHelper(CcTest::isolate());
+ T.CheckCall(T.Val(42), T.Val(1));
+}
+
#endif // V8_TURBOFAN_TARGET
diff --git a/deps/v8/test/cctest/compiler/test-run-intrinsics.cc b/deps/v8/test/cctest/compiler/test-run-intrinsics.cc
index 7fc5cc9758..1fa37748c6 100644
--- a/deps/v8/test/cctest/compiler/test-run-intrinsics.cc
+++ b/deps/v8/test/cctest/compiler/test-run-intrinsics.cc
@@ -12,7 +12,6 @@ uint32_t flags = CompilationInfo::kInliningEnabled;
TEST(CallFunction) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_CallFunction(a, 1, 2, 3, b); })",
flags);
CompileRun("function f(a,b,c) { return a + b + c + this.d; }");
@@ -23,7 +22,6 @@ TEST(CallFunction) {
TEST(ClassOf) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_ClassOf(a); })", flags);
T.CheckCall(T.Val("Function"), T.NewObject("(function() {})"));
@@ -38,7 +36,6 @@ TEST(ClassOf) {
TEST(HeapObjectGetMap) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_HeapObjectGetMap(a); })", flags);
Factory* factory = T.main_isolate()->factory();
@@ -58,7 +55,6 @@ static int* LookupCounter(const char* name) {
TEST(IncrementStatsCounter) {
- FLAG_turbo_deoptimization = true;
FLAG_native_code_counters = true;
reinterpret_cast<v8::Isolate*>(CcTest::InitIsolateOnce())
->SetCounterFunction(LookupCounter);
@@ -76,9 +72,9 @@ TEST(IncrementStatsCounter) {
TEST(IsArray) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsArray(a); })", flags);
+ T.CheckFalse(T.NewObject("new Date()"));
T.CheckFalse(T.NewObject("(function() {})"));
T.CheckTrue(T.NewObject("([1])"));
T.CheckFalse(T.NewObject("({})"));
@@ -90,10 +86,25 @@ TEST(IsArray) {
}
+TEST(IsDate) {
+ FunctionTester T("(function(a) { return %_IsDate(a); })", flags);
+
+ T.CheckTrue(T.NewObject("new Date()"));
+ T.CheckFalse(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(IsFunction) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsFunction(a); })", flags);
+ T.CheckFalse(T.NewObject("new Date()"));
T.CheckTrue(T.NewObject("(function() {})"));
T.CheckFalse(T.NewObject("([1])"));
T.CheckFalse(T.NewObject("({})"));
@@ -106,7 +117,6 @@ TEST(IsFunction) {
TEST(IsMinusZero) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsMinusZero(a); })", flags);
T.CheckFalse(T.Val(1));
@@ -119,7 +129,6 @@ TEST(IsMinusZero) {
TEST(IsNonNegativeSmi) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsNonNegativeSmi(a); })", flags);
T.CheckTrue(T.Val(1));
@@ -132,7 +141,6 @@ TEST(IsNonNegativeSmi) {
TEST(IsObject) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsObject(a); })", flags);
T.CheckFalse(T.NewObject("(function() {})"));
@@ -147,9 +155,9 @@ TEST(IsObject) {
TEST(IsRegExp) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsRegExp(a); })", flags);
+ T.CheckFalse(T.NewObject("new Date()"));
T.CheckFalse(T.NewObject("(function() {})"));
T.CheckFalse(T.NewObject("([1])"));
T.CheckFalse(T.NewObject("({})"));
@@ -162,20 +170,23 @@ TEST(IsRegExp) {
TEST(IsSmi) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsSmi(a); })", flags);
+ T.CheckFalse(T.NewObject("new Date()"));
+ T.CheckFalse(T.NewObject("(function() {})"));
+ T.CheckFalse(T.NewObject("([1])"));
+ T.CheckFalse(T.NewObject("({})"));
+ T.CheckFalse(T.NewObject("(/x/)"));
+ T.CheckFalse(T.undefined());
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(MapGetInstanceType) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function(a) { return %_MapGetInstanceType(%_HeapObjectGetMap(a)); })",
flags);
@@ -189,7 +200,6 @@ TEST(MapGetInstanceType) {
TEST(ObjectEquals) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_ObjectEquals(a,b); })", flags);
CompileRun("var o = {}");
@@ -203,7 +213,6 @@ TEST(ObjectEquals) {
TEST(OneByteSeqStringGetChar) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_OneByteSeqStringGetChar(a,b); })",
flags);
@@ -219,7 +228,6 @@ TEST(OneByteSeqStringGetChar) {
TEST(OneByteSeqStringSetChar) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { %_OneByteSeqStringSetChar(a,88,b); })",
flags);
@@ -236,7 +244,6 @@ TEST(OneByteSeqStringSetChar) {
TEST(NewConsString) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function() { "
" return %_NewConsString(14, true, 'abcdefghi', 'jklmn');"
@@ -248,7 +255,6 @@ TEST(NewConsString) {
TEST(SetValueOf) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_SetValueOf(a,b); })", flags);
T.CheckCall(T.Val("a"), T.NewObject("(new String)"), T.Val("a"));
@@ -258,7 +264,6 @@ TEST(SetValueOf) {
TEST(StringAdd) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_StringAdd(a,b); })", flags);
T.CheckCall(T.Val("aaabbb"), T.Val("aaa"), T.Val("bbb"));
@@ -268,7 +273,6 @@ TEST(StringAdd) {
TEST(StringCharAt) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_StringCharAt(a,b); })", flags);
T.CheckCall(T.Val("e"), T.Val("huge fan!"), T.Val(3));
@@ -278,7 +282,6 @@ TEST(StringCharAt) {
TEST(StringCharCodeAt) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_StringCharCodeAt(a,b); })",
flags);
@@ -289,7 +292,6 @@ TEST(StringCharCodeAt) {
TEST(StringCharFromCode) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_StringCharFromCode(a); })", flags);
T.CheckCall(T.Val("a"), T.Val(97));
@@ -299,7 +301,6 @@ TEST(StringCharFromCode) {
TEST(StringCompare) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_StringCompare(a,b); })", flags);
T.CheckCall(T.Val(-1), T.Val("aaa"), T.Val("bbb"));
@@ -309,7 +310,6 @@ TEST(StringCompare) {
TEST(SubString) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_SubString(a,b,b+3); })", flags);
T.CheckCall(T.Val("aaa"), T.Val("aaabbb"), T.Val(0.0));
@@ -319,7 +319,6 @@ TEST(SubString) {
TEST(TwoByteSeqStringGetChar) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_TwoByteSeqStringGetChar(a,b); })",
flags);
@@ -335,7 +334,6 @@ TEST(TwoByteSeqStringGetChar) {
TEST(TwoByteSeqStringSetChar) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { %_TwoByteSeqStringSetChar(a,88,b); })",
flags);
@@ -352,7 +350,6 @@ TEST(TwoByteSeqStringSetChar) {
TEST(ValueOf) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_ValueOf(a); })", flags);
T.CheckCall(T.Val("a"), T.Val("a"));
diff --git a/deps/v8/test/cctest/compiler/test-run-jscalls.cc b/deps/v8/test/cctest/compiler/test-run-jscalls.cc
index a622af8995..8de2d7a214 100644
--- a/deps/v8/test/cctest/compiler/test-run-jscalls.cc
+++ b/deps/v8/test/cctest/compiler/test-run-jscalls.cc
@@ -242,6 +242,7 @@ TEST(ContextLoadedFromActivation) {
i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
jsfun->set_code(T.function->code());
+ jsfun->set_shared(T.function->shared());
context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
CompileRun("var x = 24;");
ExpectInt32("foo();", 24);
@@ -263,6 +264,7 @@ TEST(BuiltinLoadedFromActivation) {
i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
jsfun->set_code(T.function->code());
+ jsfun->set_shared(T.function->shared());
context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
CompileRun("var x = 24;");
ExpectObject("foo()", context->Global());
diff --git a/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc b/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc
index 2e2e10e9de..0e1977b720 100644
--- a/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc
+++ b/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc
@@ -10,19 +10,14 @@ using namespace v8::internal;
using namespace v8::internal::compiler;
TEST(Throw) {
- i::FLAG_turbo_exceptions = true;
FunctionTester T("(function(a,b) { if (a) { throw b; } else { return b; }})");
-// TODO(mstarzinger)
-#if 0
T.CheckThrows(T.true_value(), T.NewObject("new Error"));
-#endif
T.CheckCall(T.Val(23), T.false_value(), T.Val(23));
}
TEST(ThrowMessagePosition) {
- i::FLAG_turbo_exceptions = true;
static const char* src =
"(function(a, b) { \n"
" if (a == 1) throw 1; \n"
@@ -48,7 +43,6 @@ TEST(ThrowMessagePosition) {
TEST(ThrowMessageDirectly) {
- i::FLAG_turbo_exceptions = true;
static const char* src =
"(function(a, b) {"
" if (a) { throw b; } else { throw new Error(b); }"
@@ -56,19 +50,17 @@ TEST(ThrowMessageDirectly) {
FunctionTester T(src);
v8::Handle<v8::Message> message;
-// TODO(mstarzinger)
-#if 0
message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?"));
CHECK(message->Get()->Equals(v8_str("Uncaught Error: Wat?")));
message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!"));
CHECK(message->Get()->Equals(v8_str("Uncaught Kaboom!")));
-#endif
}
TEST(ThrowMessageIndirectly) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_catch = true;
+ i::FLAG_turbo_try_finally = true;
static const char* src =
"(function(a, b) {"
" try {"
@@ -80,23 +72,16 @@ TEST(ThrowMessageIndirectly) {
FunctionTester T(src);
v8::Handle<v8::Message> message;
-// TODO(mstarzinger)
-#if 0
message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?"));
CHECK(message->Get()->Equals(v8_str("Uncaught Error: Wat?")));
message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!"));
CHECK(message->Get()->Equals(v8_str("Uncaught Kaboom!")));
-#endif
}
-// TODO(mstarzinger): Increase test coverage by having similar tests within the
-// mjsunit suite to also test integration with other components (e.g. OSR).
-
-
TEST(Catch) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_catch = true;
const char* src =
"(function(a,b) {"
" var r = '-';"
@@ -115,7 +100,7 @@ TEST(Catch) {
TEST(CatchNested) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_catch = true;
const char* src =
"(function(a,b) {"
" var r = '-';"
@@ -139,7 +124,7 @@ TEST(CatchNested) {
TEST(CatchBreak) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_catch = true;
const char* src =
"(function(a,b) {"
" var r = '-';"
@@ -164,7 +149,7 @@ TEST(CatchBreak) {
TEST(CatchCall) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_catch = true;
const char* src =
"(function(fun) {"
" var r = '-';"
@@ -186,7 +171,7 @@ TEST(CatchCall) {
TEST(Finally) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_finally = true;
const char* src =
"(function(a,b) {"
" var r = '-';"
@@ -204,7 +189,7 @@ TEST(Finally) {
TEST(FinallyBreak) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_finally = true;
const char* src =
"(function(a,b) {"
" var r = '-';"
@@ -228,8 +213,7 @@ TEST(FinallyBreak) {
TEST(DeoptTry) {
- i::FLAG_turbo_exceptions = true;
- i::FLAG_turbo_deoptimization = true;
+ i::FLAG_turbo_try_catch = true;
const char* src =
"(function f(a) {"
" try {"
@@ -246,8 +230,7 @@ TEST(DeoptTry) {
TEST(DeoptCatch) {
- i::FLAG_turbo_exceptions = true;
- i::FLAG_turbo_deoptimization = true;
+ i::FLAG_turbo_try_catch = true;
const char* src =
"(function f(a) {"
" try {"
@@ -264,8 +247,7 @@ TEST(DeoptCatch) {
TEST(DeoptFinallyReturn) {
- i::FLAG_turbo_exceptions = true;
- i::FLAG_turbo_deoptimization = true;
+ i::FLAG_turbo_try_finally = true;
const char* src =
"(function f(a) {"
" try {"
@@ -282,8 +264,7 @@ TEST(DeoptFinallyReturn) {
TEST(DeoptFinallyReThrow) {
- i::FLAG_turbo_exceptions = true;
- i::FLAG_turbo_deoptimization = true;
+ i::FLAG_turbo_try_finally = true;
const char* src =
"(function f(a) {"
" try {"
diff --git a/deps/v8/test/cctest/compiler/test-run-jsops.cc b/deps/v8/test/cctest/compiler/test-run-jsops.cc
index 032db82db3..56ac31cbc9 100644
--- a/deps/v8/test/cctest/compiler/test-run-jsops.cc
+++ b/deps/v8/test/cctest/compiler/test-run-jsops.cc
@@ -523,9 +523,7 @@ TEST(RegExpLiteral) {
TEST(ClassLiteral) {
- FLAG_harmony_classes = true;
FLAG_harmony_sloppy = true;
- FLAG_harmony_object_literals = true;
const char* src =
"(function(a,b) {"
" class C {"
diff --git a/deps/v8/test/cctest/compiler/test-run-machops.cc b/deps/v8/test/cctest/compiler/test-run-machops.cc
index 8d051bc90b..b1fc36968f 100644
--- a/deps/v8/test/cctest/compiler/test-run-machops.cc
+++ b/deps/v8/test/cctest/compiler/test-run-machops.cc
@@ -82,6 +82,63 @@ TEST(CodeGenInt32Binop) {
}
+#if V8_TURBOFAN_BACKEND_64
+static Node* Int64Input(RawMachineAssemblerTester<int64_t>* m, int index) {
+ switch (index) {
+ case 0:
+ return m->Parameter(0);
+ case 1:
+ return m->Parameter(1);
+ case 2:
+ return m->Int64Constant(0);
+ case 3:
+ return m->Int64Constant(1);
+ case 4:
+ return m->Int64Constant(-1);
+ case 5:
+ return m->Int64Constant(0xff);
+ case 6:
+ return m->Int64Constant(0x0123456789abcdefLL);
+ case 7:
+ return m->Load(kMachInt64, m->PointerConstant(NULL));
+ default:
+ return NULL;
+ }
+}
+
+
+TEST(CodeGenInt64Binop) {
+ RawMachineAssemblerTester<void> m;
+
+ const Operator* kOps[] = {
+ m.machine()->Word64And(), m.machine()->Word64Or(),
+ m.machine()->Word64Xor(), m.machine()->Word64Shl(),
+ m.machine()->Word64Shr(), m.machine()->Word64Sar(),
+ m.machine()->Word64Equal(), m.machine()->Int64Add(),
+ m.machine()->Int64Sub(), m.machine()->Int64Mul(), m.machine()->Int64Div(),
+ m.machine()->Uint64Div(), m.machine()->Int64Mod(),
+ m.machine()->Uint64Mod(), m.machine()->Int64LessThan(),
+ m.machine()->Int64LessThanOrEqual(), m.machine()->Uint64LessThan(),
+ m.machine()->Uint64LessThanOrEqual()};
+
+ for (size_t i = 0; i < arraysize(kOps); ++i) {
+ for (int j = 0; j < 8; j++) {
+ for (int k = 0; k < 8; k++) {
+ RawMachineAssemblerTester<int64_t> m(kMachInt64, kMachInt64);
+ Node* a = Int64Input(&m, j);
+ Node* b = Int64Input(&m, k);
+ m.Return(m.NewNode(kOps[i], a, b));
+ m.GenerateCode();
+ }
+ }
+ }
+}
+
+
+// TODO(titzer): add tests that run 64-bit integer operations.
+#endif // V8_TURBOFAN_BACKEND_64
+
+
TEST(RunGoto) {
RawMachineAssemblerTester<int32_t> m;
int constant = 99999;
@@ -164,15 +221,14 @@ template <typename R>
static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node,
MachineType type, Node* true_node,
Node* false_node) {
- MLabel blocka, blockb;
- MLabel* end = m->Exit();
+ MLabel blocka, blockb, end;
m->Branch(cond_node, &blocka, &blockb);
m->Bind(&blocka);
- m->Goto(end);
+ m->Goto(&end);
m->Bind(&blockb);
- m->Goto(end);
+ m->Goto(&end);
- m->Bind(end);
+ m->Bind(&end);
Node* phi = m->Phi(type, true_node, false_node);
m->Return(phi);
}
@@ -237,16 +293,15 @@ TEST(RunLoopPhiConst) {
Node* false_node = m.Int32Constant(false_val);
// x = false_val; while(false) { x = true_val; } return x;
- MLabel body, header;
- MLabel* end = m.Exit();
+ MLabel body, header, end;
m.Goto(&header);
m.Bind(&header);
Node* phi = m.Phi(kMachInt32, false_node, true_node);
- m.Branch(cond_node, &body, end);
+ m.Branch(cond_node, &body, &end);
m.Bind(&body);
m.Goto(&header);
- m.Bind(end);
+ m.Bind(&end);
m.Return(phi);
CHECK_EQ(false_val, m.Call());
@@ -256,20 +311,19 @@ TEST(RunLoopPhiConst) {
TEST(RunLoopPhiParam) {
RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
- MLabel blocka, blockb;
- MLabel* end = m.Exit();
+ MLabel blocka, blockb, end;
m.Goto(&blocka);
m.Bind(&blocka);
Node* phi = m.Phi(kMachInt32, m.Parameter(1), m.Parameter(2));
Node* cond = m.Phi(kMachInt32, m.Parameter(0), m.Int32Constant(0));
- m.Branch(cond, &blockb, end);
+ m.Branch(cond, &blockb, &end);
m.Bind(&blockb);
m.Goto(&blocka);
- m.Bind(end);
+ m.Bind(&end);
m.Return(phi);
int32_t c1 = 0xa81903b4;
@@ -287,22 +341,21 @@ TEST(RunLoopPhiInduction) {
int false_val = 0x10777;
// x = false_val; while(false) { x++; } return x;
- MLabel header, body;
- MLabel* end = m.Exit();
+ MLabel header, body, end;
Node* false_node = m.Int32Constant(false_val);
m.Goto(&header);
m.Bind(&header);
Node* phi = m.Phi(kMachInt32, false_node, false_node);
- m.Branch(m.Int32Constant(0), &body, end);
+ 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.Bind(&end);
m.Return(phi);
CHECK_EQ(false_val, m.Call());
@@ -314,21 +367,20 @@ TEST(RunLoopIncrement) {
Int32BinopTester bt(&m);
// x = 0; while(x ^ param) { x++; } return x;
- MLabel header, body;
- MLabel* end = m.Exit();
+ MLabel header, body, end;
Node* zero = m.Int32Constant(0);
m.Goto(&header);
m.Bind(&header);
Node* phi = m.Phi(kMachInt32, zero, zero);
- m.Branch(m.WordXor(phi, bt.param0), &body, end);
+ 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);
+ m.Bind(&end);
bt.AddReturn(phi);
CHECK_EQ(11, bt.call(11, 0));
@@ -342,21 +394,20 @@ TEST(RunLoopIncrement2) {
Int32BinopTester bt(&m);
// x = 0; while(x < param) { x++; } return x;
- MLabel header, body;
- MLabel* end = m.Exit();
+ MLabel header, body, end;
Node* zero = m.Int32Constant(0);
m.Goto(&header);
m.Bind(&header);
Node* phi = m.Phi(kMachInt32, zero, zero);
- m.Branch(m.Int32LessThan(phi, bt.param0), &body, end);
+ 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);
+ m.Bind(&end);
bt.AddReturn(phi);
CHECK_EQ(11, bt.call(11, 0));
@@ -371,21 +422,20 @@ TEST(RunLoopIncrement3) {
Int32BinopTester bt(&m);
// x = 0; while(x < param) { x++; } return x;
- MLabel header, body;
- MLabel* end = m.Exit();
+ MLabel header, body, end;
Node* zero = m.Int32Constant(0);
m.Goto(&header);
m.Bind(&header);
Node* phi = m.Phi(kMachInt32, zero, zero);
- m.Branch(m.Uint32LessThan(phi, bt.param0), &body, end);
+ 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);
+ m.Bind(&end);
bt.AddReturn(phi);
CHECK_EQ(11, bt.call(11, 0));
@@ -400,20 +450,19 @@ TEST(RunLoopDecrement) {
Int32BinopTester bt(&m);
// x = param; while(x) { x--; } return x;
- MLabel header, body;
- MLabel* end = m.Exit();
+ MLabel header, body, end;
m.Goto(&header);
m.Bind(&header);
Node* phi = m.Phi(kMachInt32, bt.param0, m.Int32Constant(0));
- m.Branch(phi, &body, end);
+ m.Branch(phi, &body, &end);
m.Bind(&body);
phi->ReplaceInput(1, m.Int32Sub(phi, m.Int32Constant(1)));
m.Goto(&header);
- m.Bind(end);
+ m.Bind(&end);
bt.AddReturn(phi);
CHECK_EQ(0, bt.call(11, 0));
@@ -426,8 +475,7 @@ TEST(RunLoopIncrementFloat32) {
RawMachineAssemblerTester<int32_t> m;
// x = -3.0f; while(x < 10f) { x = x + 0.5f; } return (int) (double) x;
- MLabel header, body;
- MLabel* end = m.Exit();
+ MLabel header, body, end;
Node* minus_3 = m.Float32Constant(-3.0f);
Node* ten = m.Float32Constant(10.0f);
@@ -435,13 +483,13 @@ TEST(RunLoopIncrementFloat32) {
m.Bind(&header);
Node* phi = m.Phi(kMachFloat32, minus_3, ten);
- m.Branch(m.Float32LessThan(phi, ten), &body, end);
+ m.Branch(m.Float32LessThan(phi, ten), &body, &end);
m.Bind(&body);
phi->ReplaceInput(1, m.Float32Add(phi, m.Float32Constant(0.5f)));
m.Goto(&header);
- m.Bind(end);
+ m.Bind(&end);
m.Return(m.ChangeFloat64ToInt32(m.ChangeFloat32ToFloat64(phi)));
CHECK_EQ(10, m.Call());
@@ -452,8 +500,7 @@ 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();
+ MLabel header, body, end;
Node* minus_3 = m.Float64Constant(-3.0);
Node* ten = m.Float64Constant(10.0);
@@ -461,13 +508,13 @@ TEST(RunLoopIncrementFloat64) {
m.Bind(&header);
Node* phi = m.Phi(kMachFloat64, minus_3, ten);
- m.Branch(m.Float64LessThan(phi, ten), &body, end);
+ 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.Bind(&end);
m.Return(m.ChangeFloat64ToInt32(phi));
CHECK_EQ(10, m.Call());
@@ -4395,7 +4442,7 @@ TEST(RunTestIntPtrArithmetic) {
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])));
+ Node* elem_size = m.IntPtrConstant(sizeof(inputs[0]));
for (int i = 0; i < kInputSize; i++) {
m.Store(kMachInt32, output, m.Load(kMachInt32, input));
input = m.IntPtrAdd(input, elem_size);
@@ -4412,7 +4459,7 @@ TEST(RunTestIntPtrArithmetic) {
TEST(RunSpillLotsOfThings) {
static const int kInputSize = 1000;
- RawMachineAssemblerTester<void> m;
+ RawMachineAssemblerTester<int32_t> m;
Node* accs[kInputSize];
int32_t outputs[kInputSize];
Node* one = m.Int32Constant(1);
@@ -4793,7 +4840,8 @@ TEST(RunTruncateFloat64ToInt32P) {
{-1.7976931348623157e+308, 0}};
double input = -1.0;
RawMachineAssemblerTester<int32_t> m;
- m.Return(m.TruncateFloat64ToInt32(m.LoadFromPointer(&input, kMachFloat64)));
+ m.Return(m.TruncateFloat64ToInt32(TruncationMode::kJavaScript,
+ m.LoadFromPointer(&input, kMachFloat64)));
for (size_t i = 0; i < arraysize(kValues); ++i) {
input = kValues[i].from;
uint64_t expected = static_cast<int64_t>(kValues[i].raw);
@@ -5080,7 +5128,7 @@ TEST(RunFloat64RoundDown1) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
- if (!m.machine()->HasFloat64RoundDown()) return;
+ if (!m.machine()->Float64RoundDown().IsSupported()) return;
m.StoreToPointer(&result, kMachFloat64,
m.Float64RoundDown(m.LoadFromPointer(&input, kMachFloat64)));
m.Return(m.Int32Constant(0));
@@ -5097,7 +5145,7 @@ TEST(RunFloat64RoundDown2) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
- if (!m.machine()->HasFloat64RoundDown()) return;
+ if (!m.machine()->Float64RoundDown().IsSupported()) return;
m.StoreToPointer(&result, kMachFloat64,
m.Float64Sub(m.Float64Constant(-0.0),
m.Float64RoundDown(m.Float64Sub(
@@ -5117,7 +5165,7 @@ TEST(RunFloat64RoundTruncate) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
- if (!m.machine()->HasFloat64RoundTruncate()) return;
+ if (!m.machine()->Float64RoundTruncate().IsSupported()) return;
m.StoreToPointer(
&result, kMachFloat64,
m.Float64RoundTruncate(m.LoadFromPointer(&input, kMachFloat64)));
@@ -5135,7 +5183,7 @@ TEST(RunFloat64RoundTiesAway) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
- if (!m.machine()->HasFloat64RoundTiesAway()) return;
+ if (!m.machine()->Float64RoundTiesAway().IsSupported()) return;
m.StoreToPointer(
&result, kMachFloat64,
m.Float64RoundTiesAway(m.LoadFromPointer(&input, kMachFloat64)));
@@ -5148,4 +5196,83 @@ TEST(RunFloat64RoundTiesAway) {
}
}
+
+#if !USE_SIMULATOR
+
+namespace {
+
+int32_t const kMagicFoo0 = 0xdeadbeef;
+
+
+int32_t foo0() { return kMagicFoo0; }
+
+
+int32_t foo1(int32_t x) { return x; }
+
+
+int32_t foo2(int32_t x, int32_t y) { return x - y; }
+
+
+int32_t foo8(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f,
+ int32_t g, int32_t h) {
+ return a + b + c + d + e + f + g + h;
+}
+
+} // namespace
+
+
+TEST(RunCallCFunction0) {
+ auto* foo0_ptr = &foo0;
+ RawMachineAssemblerTester<int32_t> m;
+ Node* function = m.LoadFromPointer(&foo0_ptr, kMachPtr);
+ m.Return(m.CallCFunction0(kMachInt32, function));
+ CHECK_EQ(kMagicFoo0, m.Call());
+}
+
+
+TEST(RunCallCFunction1) {
+ auto* foo1_ptr = &foo1;
+ RawMachineAssemblerTester<int32_t> m(kMachInt32);
+ Node* function = m.LoadFromPointer(&foo1_ptr, kMachPtr);
+ m.Return(m.CallCFunction1(kMachInt32, kMachInt32, function, m.Parameter(0)));
+ FOR_INT32_INPUTS(i) {
+ int32_t const expected = *i;
+ CHECK_EQ(expected, m.Call(expected));
+ }
+}
+
+
+TEST(RunCallCFunction2) {
+ auto* foo2_ptr = &foo2;
+ RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+ Node* function = m.LoadFromPointer(&foo2_ptr, kMachPtr);
+ m.Return(m.CallCFunction2(kMachInt32, kMachInt32, kMachInt32, function,
+ m.Parameter(0), m.Parameter(1)));
+ FOR_INT32_INPUTS(i) {
+ int32_t const x = *i;
+ FOR_INT32_INPUTS(j) {
+ int32_t const y = *j;
+ CHECK_EQ(x - y, m.Call(x, y));
+ }
+ }
+}
+
+
+TEST(RunCallCFunction8) {
+ auto* foo8_ptr = &foo8;
+ RawMachineAssemblerTester<int32_t> m(kMachInt32);
+ Node* function = m.LoadFromPointer(&foo8_ptr, kMachPtr);
+ Node* param = m.Parameter(0);
+ m.Return(m.CallCFunction8(kMachInt32, kMachInt32, kMachInt32, kMachInt32,
+ kMachInt32, kMachInt32, kMachInt32, kMachInt32,
+ kMachInt32, function, param, param, param, param,
+ param, param, param, param));
+ FOR_INT32_INPUTS(i) {
+ int32_t const x = *i;
+ CHECK_EQ(x * 8, m.Call(x));
+ }
+}
+
+#endif // USE_SIMULATOR
+
#endif // V8_TURBOFAN_TARGET
diff --git a/deps/v8/test/cctest/compiler/test-run-stubs.cc b/deps/v8/test/cctest/compiler/test-run-stubs.cc
index c81f0f184d..9c7998d7af 100644
--- a/deps/v8/test/cctest/compiler/test-run-stubs.cc
+++ b/deps/v8/test/cctest/compiler/test-run-stubs.cc
@@ -6,7 +6,10 @@
#include "src/code-stubs.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/js-operator.h"
#include "src/compiler/linkage.h"
+#include "src/compiler/machine-operator.h"
#include "src/compiler/pipeline.h"
#include "src/parser.h"
#include "test/cctest/compiler/function-tester.h"
@@ -17,60 +20,54 @@ using namespace v8::internal;
using namespace v8::internal::compiler;
-static Handle<JSFunction> GetFunction(Isolate* isolate, const char* name) {
- v8::ExtensionConfiguration no_extensions;
- Handle<Context> ctx = isolate->bootstrapper()->CreateEnvironment(
- MaybeHandle<JSGlobalProxy>(), v8::Handle<v8::ObjectTemplate>(),
- &no_extensions);
- Handle<JSBuiltinsObject> builtins = handle(ctx->builtins());
- MaybeHandle<Object> fun = Object::GetProperty(isolate, builtins, name);
- Handle<JSFunction> function = Handle<JSFunction>::cast(fun.ToHandleChecked());
- // Just to make sure nobody calls this...
- function->set_code(isolate->builtins()->builtin(Builtins::kIllegal));
- return function;
-}
-
-
-class StringLengthStubTF : public CodeStub {
- public:
- explicit StringLengthStubTF(Isolate* isolate) : CodeStub(isolate) {}
+TEST(RunMathFloorStub) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
- StringLengthStubTF(uint32_t key, Isolate* isolate) : CodeStub(key, isolate) {}
+ // Create code and an accompanying descriptor.
+ MathFloorStub stub(isolate);
+ Handle<Code> code = stub.GenerateCode();
+ Zone* zone = scope.main_zone();
- CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
- return LoadDescriptor(isolate());
- };
+ CompilationInfo info(&stub, isolate, zone);
+ CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info);
- Handle<Code> GenerateCode() override {
- Zone zone;
- // Build a "hybrid" CompilationInfo for a JSFunction/CodeStub pair.
- ParseInfo parse_info(&zone, GetFunction(isolate(), "STRING_LENGTH_STUB"));
- CompilationInfo info(&parse_info);
- info.SetStub(this);
- // Run a "mini pipeline", extracted from compiler.cc.
- CHECK(Parser::ParseStatic(info.parse_info()));
- CHECK(Compiler::Analyze(info.parse_info()));
- return Pipeline(&info).GenerateCode();
- }
+ // Create a function to call the code using the descriptor.
+ Graph graph(zone);
+ CommonOperatorBuilder common(zone);
+ JSOperatorBuilder javascript(zone);
+ MachineOperatorBuilder machine(zone);
+ JSGraph js(isolate, &graph, &common, &javascript, &machine);
- Major MajorKey() const override { return StringLength; };
- Code::Kind GetCodeKind() const override { return Code::HANDLER; }
- InlineCacheState GetICState() const override { return MONOMORPHIC; }
- ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
- Code::StubType GetStubType() const override { return Code::FAST; }
+ // FunctionTester (ab)uses a 2-argument function
+ Node* start = graph.NewNode(common.Start(4));
+ // Parameter 0 is the number to round
+ Node* numberParam = graph.NewNode(common.Parameter(1), start);
+ Unique<HeapObject> u = Unique<HeapObject>::CreateImmovable(code);
+ Node* theCode = graph.NewNode(common.HeapConstant(u));
+ Node* dummyContext = graph.NewNode(common.NumberConstant(0.0));
+ Node* call = graph.NewNode(common.Call(descriptor), theCode,
+ js.UndefinedConstant(), js.UndefinedConstant(),
+ numberParam, dummyContext, start, start);
+ Node* ret = graph.NewNode(common.Return(), call, call, start);
+ Node* end = graph.NewNode(common.End(1), ret);
+ graph.SetStart(start);
+ graph.SetEnd(end);
+ FunctionTester ft(&graph);
- private:
- DISALLOW_COPY_AND_ASSIGN(StringLengthStubTF);
-};
+ Handle<Object> value = ft.Val(1.5);
+ Handle<Object> result = ft.Call(value, value).ToHandleChecked();
+ CHECK_EQ(1, Smi::cast(*result)->value());
+}
-TEST(RunStringLengthStubTF) {
+TEST(RunStringLengthTFStub) {
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
Zone* zone = scope.main_zone();
// Create code and an accompanying descriptor.
- StringLengthStubTF stub(isolate);
+ StringLengthTFStub stub(isolate);
Handle<Code> code = stub.GenerateCode();
CompilationInfo info(&stub, isolate, zone);
CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info);
@@ -78,18 +75,21 @@ TEST(RunStringLengthStubTF) {
// Create a function to call the code using the descriptor.
Graph graph(zone);
CommonOperatorBuilder common(zone);
- // FunctionTester (ab)uses a 2-argument function
- Node* start = graph.NewNode(common.Start(2));
+ // FunctionTester (ab)uses a 4-argument function
+ Node* start = graph.NewNode(common.Start(6));
// Parameter 0 is the receiver
Node* receiverParam = graph.NewNode(common.Parameter(1), start);
Node* nameParam = graph.NewNode(common.Parameter(2), start);
+ Node* slotParam = graph.NewNode(common.Parameter(3), start);
+ Node* vectorParam = graph.NewNode(common.Parameter(4), start);
Unique<HeapObject> u = Unique<HeapObject>::CreateImmovable(code);
Node* theCode = graph.NewNode(common.HeapConstant(u));
Node* dummyContext = graph.NewNode(common.NumberConstant(0.0));
- Node* call = graph.NewNode(common.Call(descriptor), theCode, receiverParam,
- nameParam, dummyContext, start, start);
+ Node* call =
+ graph.NewNode(common.Call(descriptor), theCode, receiverParam, nameParam,
+ slotParam, vectorParam, dummyContext, start, start);
Node* ret = graph.NewNode(common.Return(), call, call, start);
- Node* end = graph.NewNode(common.End(), ret);
+ Node* end = graph.NewNode(common.End(1), ret);
graph.SetStart(start);
graph.SetEnd(end);
FunctionTester ft(&graph);
@@ -99,8 +99,49 @@ TEST(RunStringLengthStubTF) {
Handle<JSReceiver> receiverArg =
Object::ToObject(isolate, ft.Val(testString)).ToHandleChecked();
Handle<String> nameArg = ft.Val("length");
- Handle<Object> result = ft.Call(receiverArg, nameArg).ToHandleChecked();
+ Handle<Object> slot = ft.Val(0.0);
+ Handle<Object> vector = ft.Val(0.0);
+ Handle<Object> result =
+ ft.Call(receiverArg, nameArg, slot, vector).ToHandleChecked();
CHECK_EQ(static_cast<int>(strlen(testString)), Smi::cast(*result)->value());
}
+
+TEST(RunStringAddTFStub) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+
+ // Create code and an accompanying descriptor.
+ StringAddTFStub stub(isolate, STRING_ADD_CHECK_BOTH, NOT_TENURED);
+ Handle<Code> code = stub.GenerateCode();
+ CompilationInfo info(&stub, isolate, zone);
+ CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info);
+
+ // Create a function to call the code using the descriptor.
+ Graph graph(zone);
+ CommonOperatorBuilder common(zone);
+ // FunctionTester (ab)uses a 2-argument function
+ Node* start = graph.NewNode(common.Start(4));
+ // Parameter 0 is the receiver
+ Node* leftParam = graph.NewNode(common.Parameter(1), start);
+ Node* rightParam = graph.NewNode(common.Parameter(2), start);
+ Unique<HeapObject> u = Unique<HeapObject>::CreateImmovable(code);
+ Node* theCode = graph.NewNode(common.HeapConstant(u));
+ Node* dummyContext = graph.NewNode(common.NumberConstant(0.0));
+ Node* call = graph.NewNode(common.Call(descriptor), theCode, leftParam,
+ rightParam, dummyContext, start, start);
+ Node* ret = graph.NewNode(common.Return(), call, call, start);
+ Node* end = graph.NewNode(common.End(1), ret);
+ graph.SetStart(start);
+ graph.SetEnd(end);
+ FunctionTester ft(&graph);
+
+ // Actuall call through to the stub, verifying its result.
+ Handle<String> leftArg = ft.Val("links");
+ Handle<String> rightArg = ft.Val("rechts");
+ Handle<Object> result = ft.Call(leftArg, rightArg).ToHandleChecked();
+ CHECK(String::Equals(ft.Val("linksrechts"), Handle<String>::cast(result)));
+}
+
#endif // V8_TURBOFAN_TARGET
diff --git a/deps/v8/test/cctest/compiler/test-simplified-lowering.cc b/deps/v8/test/cctest/compiler/test-simplified-lowering.cc
index 9242248d60..022e01690b 100644
--- a/deps/v8/test/cctest/compiler/test-simplified-lowering.cc
+++ b/deps/v8/test/cctest/compiler/test-simplified-lowering.cc
@@ -33,12 +33,9 @@ template <typename ReturnType>
class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
public:
SimplifiedLoweringTester(MachineType p0 = kMachNone,
- MachineType p1 = kMachNone,
- MachineType p2 = kMachNone,
- MachineType p3 = kMachNone,
- MachineType p4 = kMachNone)
- : GraphBuilderTester<ReturnType>(p0, p1, p2, p3, p4),
- typer(this->isolate(), this->graph(), MaybeHandle<Context>()),
+ MachineType p1 = kMachNone)
+ : GraphBuilderTester<ReturnType>(p0, p1),
+ typer(this->isolate(), this->graph()),
javascript(this->zone()),
jsgraph(this->isolate(), this->graph(), this->common(), &javascript,
this->machine()),
@@ -63,7 +60,7 @@ class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
lowering.LowerAllNodes();
ChangeLowering lowering(&jsgraph);
- GraphReducer reducer(this->graph(), this->zone());
+ GraphReducer reducer(this->zone(), this->graph());
reducer.AddReducer(&lowering);
reducer.ReduceGraph();
Verifier::Run(this->graph());
@@ -538,8 +535,7 @@ class AccessTester : public HandleAndZoneScope {
E GetElement(int index) {
BoundsCheck(index);
if (tagged) {
- E* raw = reinterpret_cast<E*>(tagged_array->GetDataStartAddress());
- return raw[index];
+ return GetTaggedElement(index);
} else {
return untagged_array[index];
}
@@ -572,8 +568,19 @@ class AccessTester : public HandleAndZoneScope {
CHECK_LT(index, static_cast<int>(num_elements));
CHECK_EQ(static_cast<int>(ByteSize()), tagged_array->length());
}
+
+ E GetTaggedElement(int index) {
+ E* raw = reinterpret_cast<E*>(tagged_array->GetDataStartAddress());
+ return raw[index];
+ }
};
+template <>
+double AccessTester<double>::GetTaggedElement(int index) {
+ return ReadDoubleValue(tagged_array->GetDataStartAddress() +
+ index * sizeof(double));
+}
+
template <typename E>
static void RunAccessTest(MachineType rep, E* original_elements, size_t num) {
@@ -703,14 +710,14 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None(),
Type* p2_type = Type::None())
: GraphAndBuilders(main_zone()),
- typer(main_isolate(), graph(), MaybeHandle<Context>()),
+ typer(main_isolate(), graph()),
javascript(main_zone()),
jsgraph(main_isolate(), graph(), common(), &javascript, machine()) {
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);
+ end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
p0 = graph()->NewNode(common()->Parameter(0), start);
p1 = graph()->NewNode(common()->Parameter(1), start);
@@ -1269,7 +1276,6 @@ TEST(LowerStringOps_to_call_and_compare) {
t.CheckLoweringBinop(compare_eq, t.simplified()->StringEqual());
t.CheckLoweringBinop(compare_lt, t.simplified()->StringLessThan());
t.CheckLoweringBinop(compare_le, t.simplified()->StringLessThanOrEqual());
- t.CheckLoweringBinop(IrOpcode::kCall, t.simplified()->StringAdd());
}
}
@@ -1443,8 +1449,8 @@ TEST(LowerLoadField_to_load) {
FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Handle<Name>::null(), Type::Any(), kMachineReps[i]};
- Node* load =
- t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start);
+ Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0,
+ t.start, t.start);
Node* use = t.Use(load, kMachineReps[i]);
t.Return(use);
t.Lower();
@@ -1624,8 +1630,8 @@ TEST(InsertChangeForLoadField) {
FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Handle<Name>::null(), Type::Any(), kMachFloat64};
- Node* load =
- t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start);
+ Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0,
+ t.start, t.start);
t.Return(load);
t.Lower();
CHECK_EQ(IrOpcode::kLoad, load->opcode());
@@ -1679,10 +1685,10 @@ TEST(UpdatePhi) {
FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Handle<Name>::null(), kTypes[i], kMachineTypes[i]};
- Node* load0 =
- t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start);
- Node* load1 =
- t.graph()->NewNode(t.simplified()->LoadField(access), t.p1, t.start);
+ Node* load0 = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0,
+ t.start, t.start);
+ Node* load1 = t.graph()->NewNode(t.simplified()->LoadField(access), t.p1,
+ t.start, t.start);
Node* phi = t.graph()->NewNode(t.common()->Phi(kMachAnyTagged, 2), load0,
load1, t.start);
t.Return(t.Use(phi, kMachineTypes[i]));
diff --git a/deps/v8/test/cctest/gay-fixed.cc b/deps/v8/test/cctest/gay-fixed.cc
index 81463ac1fa..86ebb24cd8 100644
--- a/deps/v8/test/cctest/gay-fixed.cc
+++ b/deps/v8/test/cctest/gay-fixed.cc
@@ -100046,4 +100046,5 @@ Vector<const PrecomputedFixed> PrecomputedFixedRepresentations() {
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/gay-precision.cc b/deps/v8/test/cctest/gay-precision.cc
index 6ab2715fea..68d29f8cd5 100644
--- a/deps/v8/test/cctest/gay-precision.cc
+++ b/deps/v8/test/cctest/gay-precision.cc
@@ -100047,4 +100047,5 @@ Vector<const PrecomputedPrecision> PrecomputedPrecisionRepresentations() {
number_elements);
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/gay-shortest.cc b/deps/v8/test/cctest/gay-shortest.cc
index 896ea4c514..456055392c 100644
--- a/deps/v8/test/cctest/gay-shortest.cc
+++ b/deps/v8/test/cctest/gay-shortest.cc
@@ -100047,4 +100047,5 @@ Vector<const PrecomputedShortest> PrecomputedShortestRepresentations() {
number_elements);
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/print-extension.cc b/deps/v8/test/cctest/print-extension.cc
index d1af3596e8..33f33cafc2 100644
--- a/deps/v8/test/cctest/print-extension.cc
+++ b/deps/v8/test/cctest/print-extension.cc
@@ -48,4 +48,5 @@ void PrintExtension::Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
printf("\n");
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/profiler-extension.cc b/deps/v8/test/cctest/profiler-extension.cc
index 263fc4f38d..c8cb0fb7ca 100644
--- a/deps/v8/test/cctest/profiler-extension.cc
+++ b/deps/v8/test/cctest/profiler-extension.cc
@@ -72,4 +72,5 @@ void ProfilerExtension::StopProfiling(
: v8::String::Empty(args.GetIsolate()));
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/test-accessors.cc b/deps/v8/test/cctest/test-accessors.cc
index ac631757b2..14303e2371 100644
--- a/deps/v8/test/cctest/test-accessors.cc
+++ b/deps/v8/test/cctest/test-accessors.cc
@@ -552,7 +552,7 @@ THREADED_TEST(AccessorPropertyCrossContext) {
v8::Handle<v8::Function> fun = v8::Function::New(isolate, check_contexts);
LocalContext switch_context;
switch_context->Global()->Set(v8_str("fun"), fun);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
expected_current_context = env.local();
expected_calling_context = switch_context.local();
CompileRun(
diff --git a/deps/v8/test/cctest/test-api-interceptors.cc b/deps/v8/test/cctest/test-api-interceptors.cc
index aba08e23d7..2e9bc74a92 100644
--- a/deps/v8/test/cctest/test-api-interceptors.cc
+++ b/deps/v8/test/cctest/test-api-interceptors.cc
@@ -1007,10 +1007,11 @@ THREADED_TEST(PropertyHandlerInPrototype) {
}
+bool is_bootstrapping = false;
static void PrePropertyHandlerGet(
Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
- if (v8_str("pre")->Equals(key)) {
+ if (!is_bootstrapping && v8_str("pre")->Equals(key)) {
info.GetReturnValue().Set(v8_str("PrePropertyHandler: pre"));
}
}
@@ -1018,7 +1019,7 @@ static void PrePropertyHandlerGet(
static void PrePropertyHandlerQuery(
Local<Name> key, const v8::PropertyCallbackInfo<v8::Integer>& info) {
- if (v8_str("pre")->Equals(key)) {
+ if (!is_bootstrapping && v8_str("pre")->Equals(key)) {
info.GetReturnValue().Set(static_cast<int32_t>(v8::None));
}
}
@@ -1030,7 +1031,9 @@ THREADED_TEST(PrePropertyHandler) {
v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate);
desc->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
PrePropertyHandlerGet, 0, PrePropertyHandlerQuery));
+ is_bootstrapping = true;
LocalContext env(NULL, desc->InstanceTemplate());
+ is_bootstrapping = false;
CompileRun("var pre = 'Object: pre'; var on = 'Object: on';");
v8::Handle<Value> result_pre = CompileRun("pre");
CHECK(v8_str("PrePropertyHandler: pre")->Equals(result_pre));
@@ -1658,6 +1661,12 @@ THREADED_TEST(IndexedInterceptorWithNoSetter) {
}
+static bool AccessAlwaysBlocked(Local<v8::Object> global, Local<Value> name,
+ v8::AccessType type, Local<Value> data) {
+ return false;
+}
+
+
THREADED_TEST(IndexedInterceptorWithAccessorCheck) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
@@ -1665,9 +1674,10 @@ THREADED_TEST(IndexedInterceptorWithAccessorCheck) {
templ->SetHandler(
v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
+ templ->SetAccessCheckCallbacks(AccessAlwaysBlocked, nullptr);
+
LocalContext context;
Local<v8::Object> obj = templ->NewInstance();
- obj->TurnOnAccessCheck();
context->Global()->Set(v8_str("obj"), obj);
const char* code =
@@ -1686,46 +1696,6 @@ THREADED_TEST(IndexedInterceptorWithAccessorCheck) {
}
-THREADED_TEST(IndexedInterceptorWithAccessorCheckSwitchedOn) {
- i::FLAG_allow_natives_syntax = true;
- v8::Isolate* isolate = CcTest::isolate();
- v8::HandleScope scope(isolate);
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetHandler(
- v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
-
- LocalContext context;
- Local<v8::Object> obj = templ->NewInstance();
- context->Global()->Set(v8_str("obj"), obj);
-
- const char* code =
- "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) {"
- " 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;"
- " }"
- " }"
- " if (i == 5) %DisableAccessChecks(obj);"
- "}"
- "result";
- ExpectString(code, "PASSED");
-}
-
-
THREADED_TEST(IndexedInterceptorWithDifferentIndices) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
@@ -2021,9 +1991,9 @@ THREADED_TEST(Enumerators) {
"k.a = 0;"
"k[5] = 0;"
"k.b = 0;"
- "k[4294967295] = 0;"
+ "k[4294967294] = 0;"
"k.c = 0;"
- "k[4294967296] = 0;"
+ "k[4294967295] = 0;"
"k.d = 0;"
"k[140000] = 0;"
"k.e = 0;"
@@ -2046,7 +2016,7 @@ THREADED_TEST(Enumerators) {
CHECK(v8_str("10")->Equals(result->Get(v8::Integer::New(isolate, 1))));
CHECK(v8_str("140000")->Equals(result->Get(v8::Integer::New(isolate, 2))));
CHECK(
- v8_str("4294967295")->Equals(result->Get(v8::Integer::New(isolate, 3))));
+ v8_str("4294967294")->Equals(result->Get(v8::Integer::New(isolate, 3))));
// Indexed interceptor properties in the order they are returned
// from the enumerator interceptor.
CHECK(v8_str("0")->Equals(result->Get(v8::Integer::New(isolate, 4))));
@@ -2056,7 +2026,7 @@ THREADED_TEST(Enumerators) {
CHECK(v8_str("b")->Equals(result->Get(v8::Integer::New(isolate, 7))));
CHECK(v8_str("c")->Equals(result->Get(v8::Integer::New(isolate, 8))));
CHECK(
- v8_str("4294967296")->Equals(result->Get(v8::Integer::New(isolate, 9))));
+ v8_str("4294967295")->Equals(result->Get(v8::Integer::New(isolate, 9))));
CHECK(v8_str("d")->Equals(result->Get(v8::Integer::New(isolate, 10))));
CHECK(v8_str("e")->Equals(result->Get(v8::Integer::New(isolate, 11))));
CHECK(v8_str("30000000000")
@@ -2533,7 +2503,8 @@ static int interceptor_call_count = 0;
static void InterceptorICRefErrorGetter(
Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
- if (v8_str("x")->Equals(name) && interceptor_call_count++ < 20) {
+ if (!is_bootstrapping && v8_str("x")->Equals(name) &&
+ interceptor_call_count++ < 20) {
info.GetReturnValue().Set(call_ic_function2);
}
}
@@ -2548,7 +2519,9 @@ THREADED_TEST(InterceptorICReferenceErrors) {
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetHandler(
v8::NamedPropertyHandlerConfiguration(InterceptorICRefErrorGetter));
+ is_bootstrapping = true;
LocalContext context(0, templ, v8::Handle<Value>());
+ is_bootstrapping = false;
call_ic_function2 = v8_compile("function h(x) { return x; }; h")->Run();
v8::Handle<Value> value = CompileRun(
"function f() {"
@@ -2577,6 +2550,7 @@ static int interceptor_ic_exception_get_count = 0;
static void InterceptorICExceptionGetter(
Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
+ if (is_bootstrapping) return;
if (v8_str("x")->Equals(name) && ++interceptor_ic_exception_get_count < 20) {
info.GetReturnValue().Set(call_ic_function3);
}
@@ -2596,7 +2570,9 @@ THREADED_TEST(InterceptorICGetterExceptions) {
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetHandler(
v8::NamedPropertyHandlerConfiguration(InterceptorICExceptionGetter));
+ is_bootstrapping = true;
LocalContext context(0, templ, v8::Handle<Value>());
+ is_bootstrapping = false;
call_ic_function3 = v8_compile("function h(x) { return x; }; h")->Run();
v8::Handle<Value> value = CompileRun(
"function f() {"
@@ -2975,7 +2951,7 @@ THREADED_TEST(NamedAllCanReadInterceptor) {
LocalContext context;
AccessCheckData access_check_data;
- access_check_data.result = false;
+ access_check_data.result = true;
access_check_data.count = 0;
ShouldInterceptData intercept_data_0;
@@ -3007,7 +2983,7 @@ THREADED_TEST(NamedAllCanReadInterceptor) {
auto checked = v8::ObjectTemplate::New(isolate);
checked->SetAccessCheckCallbacks(
SimpleAccessChecker, nullptr,
- BuildWrappedObject<AccessCheckData>(isolate, &access_check_data), false);
+ BuildWrappedObject<AccessCheckData>(isolate, &access_check_data));
context->Global()->Set(v8_str("intercepted_0"), intercepted_0->NewInstance());
context->Global()->Set(v8_str("intercepted_1"), intercepted_1->NewInstance());
@@ -3018,14 +2994,12 @@ THREADED_TEST(NamedAllCanReadInterceptor) {
"checked.__proto__ = intercepted_1;"
"intercepted_1.__proto__ = intercepted_0;");
- checked_instance->TurnOnAccessCheck();
- CHECK_EQ(0, access_check_data.count);
+ CHECK_EQ(3, access_check_data.count);
- access_check_data.result = true;
ExpectInt32("checked.whatever", 17);
CHECK(!CompileRun("Object.getOwnPropertyDescriptor(checked, 'whatever')")
->IsUndefined());
- CHECK_EQ(2, access_check_data.count);
+ CHECK_EQ(5, access_check_data.count);
access_check_data.result = false;
ExpectInt32("checked.whatever", intercept_data_0.value);
@@ -3034,7 +3008,7 @@ THREADED_TEST(NamedAllCanReadInterceptor) {
CompileRun("Object.getOwnPropertyDescriptor(checked, 'whatever')");
CHECK(try_catch.HasCaught());
}
- CHECK_EQ(4, access_check_data.count);
+ CHECK_EQ(7, access_check_data.count);
intercept_data_1.should_intercept = true;
ExpectInt32("checked.whatever", intercept_data_1.value);
@@ -3043,7 +3017,7 @@ THREADED_TEST(NamedAllCanReadInterceptor) {
CompileRun("Object.getOwnPropertyDescriptor(checked, 'whatever')");
CHECK(try_catch.HasCaught());
}
- CHECK_EQ(6, access_check_data.count);
+ CHECK_EQ(9, access_check_data.count);
}
@@ -3053,7 +3027,7 @@ THREADED_TEST(IndexedAllCanReadInterceptor) {
LocalContext context;
AccessCheckData access_check_data;
- access_check_data.result = false;
+ access_check_data.result = true;
access_check_data.count = 0;
ShouldInterceptData intercept_data_0;
@@ -3085,7 +3059,7 @@ THREADED_TEST(IndexedAllCanReadInterceptor) {
auto checked = v8::ObjectTemplate::New(isolate);
checked->SetAccessCheckCallbacks(
SimpleAccessChecker, nullptr,
- BuildWrappedObject<AccessCheckData>(isolate, &access_check_data), false);
+ BuildWrappedObject<AccessCheckData>(isolate, &access_check_data));
context->Global()->Set(v8_str("intercepted_0"), intercepted_0->NewInstance());
context->Global()->Set(v8_str("intercepted_1"), intercepted_1->NewInstance());
@@ -3096,27 +3070,30 @@ THREADED_TEST(IndexedAllCanReadInterceptor) {
"checked.__proto__ = intercepted_1;"
"intercepted_1.__proto__ = intercepted_0;");
- checked_instance->TurnOnAccessCheck();
- CHECK_EQ(0, access_check_data.count);
+ CHECK_EQ(3, access_check_data.count);
access_check_data.result = true;
ExpectInt32("checked[15]", 17);
CHECK(!CompileRun("Object.getOwnPropertyDescriptor(checked, '15')")
->IsUndefined());
- CHECK_EQ(3, access_check_data.count);
+ CHECK_EQ(5, access_check_data.count);
access_check_data.result = false;
ExpectInt32("checked[15]", intercept_data_0.value);
- // Note: this should throw but without a LookupIterator it's complicated.
- CHECK(!CompileRun("Object.getOwnPropertyDescriptor(checked, '15')")
- ->IsUndefined());
- CHECK_EQ(6, access_check_data.count);
+ {
+ v8::TryCatch try_catch(isolate);
+ CompileRun("Object.getOwnPropertyDescriptor(checked, '15')");
+ CHECK(try_catch.HasCaught());
+ }
+ CHECK_EQ(7, access_check_data.count);
intercept_data_1.should_intercept = true;
ExpectInt32("checked[15]", intercept_data_1.value);
- // Note: this should throw but without a LookupIterator it's complicated.
- CHECK(!CompileRun("Object.getOwnPropertyDescriptor(checked, '15')")
- ->IsUndefined());
+ {
+ v8::TryCatch try_catch(isolate);
+ CompileRun("Object.getOwnPropertyDescriptor(checked, '15')");
+ CHECK(try_catch.HasCaught());
+ }
CHECK_EQ(9, access_check_data.count);
}
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index 145d9bc64d..e464a67e00 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -190,7 +190,7 @@ static void TestSignature(const char* loop_js, Local<Value> receiver,
signature_callback_count = 0;
signature_expected_receiver = receiver;
bool expected_to_throw = receiver.IsEmpty();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(source.start());
CHECK_EQ(expected_to_throw, try_catch.HasCaught());
if (!expected_to_throw) {
@@ -697,7 +697,7 @@ THREADED_TEST(NewExternalForVeryLongString) {
auto isolate = CcTest::isolate();
{
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
RandomLengthOneByteResource r(1 << 30);
v8::Local<v8::String> str = v8::String::NewExternal(isolate, &r);
CHECK(str.IsEmpty());
@@ -706,7 +706,7 @@ THREADED_TEST(NewExternalForVeryLongString) {
{
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
RandomLengthResource r(1 << 30);
v8::Local<v8::String> str = v8::String::NewExternal(isolate, &r);
CHECK(str.IsEmpty());
@@ -1590,6 +1590,17 @@ THREADED_TEST(StringObject) {
}
+TEST(StringObjectDelete) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+ v8::Handle<Value> boxed_string = CompileRun("new String(\"test\")");
+ CHECK(boxed_string->IsStringObject());
+ v8::Handle<v8::Object> str_obj = boxed_string.As<v8::Object>();
+ CHECK(!str_obj->Delete(2));
+ CHECK(!str_obj->Delete(v8_num(2)));
+}
+
+
THREADED_TEST(NumberObject) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -2248,12 +2259,24 @@ THREADED_TEST(IdentityHash) {
}
-THREADED_TEST(GlobalProxyIdentityHash) {
+void GlobalProxyIdentityHash(bool set_in_js) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
v8::HandleScope scope(isolate);
Handle<Object> global_proxy = env->Global();
- int hash1 = global_proxy->GetIdentityHash();
+ i::Handle<i::Object> i_global_proxy = v8::Utils::OpenHandle(*global_proxy);
+ env->Global()->Set(v8_str("global"), global_proxy);
+ i::Handle<i::Object> original_hash;
+ if (set_in_js) {
+ CompileRun("var m = new Set(); m.add(global);");
+ original_hash = i::Handle<i::Object>(i_global_proxy->GetHash(), i_isolate);
+ } else {
+ original_hash = i::Handle<i::Object>(
+ i::Object::GetOrCreateHash(i_isolate, i_global_proxy));
+ }
+ CHECK(original_hash->IsSmi());
+ int32_t hash1 = i::Handle<i::Smi>::cast(original_hash)->value();
// Hash should be retained after being detached.
env->DetachGlobal();
int hash2 = global_proxy->GetIdentityHash();
@@ -2267,6 +2290,12 @@ THREADED_TEST(GlobalProxyIdentityHash) {
}
+THREADED_TEST(GlobalProxyIdentityHash) {
+ GlobalProxyIdentityHash(true);
+ GlobalProxyIdentityHash(false);
+}
+
+
TEST(SymbolIdentityHash) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@@ -2434,65 +2463,6 @@ THREADED_TEST(SymbolTemplateProperties) {
}
-THREADED_TEST(PrivateProperties) {
- LocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
-
- v8::Local<v8::Object> obj = v8::Object::New(isolate);
- v8::Local<v8::Private> priv1 = v8::Private::New(isolate);
- v8::Local<v8::Private> priv2 =
- v8::Private::New(isolate, v8_str("my-private"));
-
- CcTest::heap()->CollectAllGarbage();
-
- CHECK(priv2->Name()->Equals(v8::String::NewFromUtf8(isolate, "my-private")));
-
- // Make sure delete of a non-existent private symbol property works.
- CHECK(obj->DeletePrivate(priv1));
- CHECK(!obj->HasPrivate(priv1));
-
- CHECK(obj->SetPrivate(priv1, v8::Integer::New(isolate, 1503)));
- CHECK(obj->HasPrivate(priv1));
- CHECK_EQ(1503, obj->GetPrivate(priv1)->Int32Value());
- CHECK(obj->SetPrivate(priv1, v8::Integer::New(isolate, 2002)));
- CHECK(obj->HasPrivate(priv1));
- CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value());
-
- CHECK_EQ(0u, obj->GetOwnPropertyNames()->Length());
- unsigned num_props = obj->GetPropertyNames()->Length();
- CHECK(obj->Set(v8::String::NewFromUtf8(isolate, "bla"),
- v8::Integer::New(isolate, 20)));
- CHECK_EQ(1u, obj->GetOwnPropertyNames()->Length());
- CHECK_EQ(num_props + 1, obj->GetPropertyNames()->Length());
-
- CcTest::heap()->CollectAllGarbage();
-
- // Add another property and delete it afterwards to force the object in
- // slow case.
- CHECK(obj->SetPrivate(priv2, v8::Integer::New(isolate, 2008)));
- CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value());
- CHECK_EQ(2008, obj->GetPrivate(priv2)->Int32Value());
- CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value());
- CHECK_EQ(1u, obj->GetOwnPropertyNames()->Length());
-
- CHECK(obj->HasPrivate(priv1));
- CHECK(obj->HasPrivate(priv2));
- CHECK(obj->DeletePrivate(priv2));
- CHECK(obj->HasPrivate(priv1));
- CHECK(!obj->HasPrivate(priv2));
- CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value());
- CHECK_EQ(1u, obj->GetOwnPropertyNames()->Length());
-
- // Private properties are inherited (for the time being).
- v8::Local<v8::Object> child = v8::Object::New(isolate);
- child->SetPrototype(obj);
- CHECK(child->HasPrivate(priv1));
- CHECK_EQ(2002, child->GetPrivate(priv1)->Int32Value());
- CHECK_EQ(0u, child->GetOwnPropertyNames()->Length());
-}
-
-
THREADED_TEST(GlobalSymbols) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@@ -2541,28 +2511,6 @@ THREADED_TEST(WellKnownSymbols) {
}
-THREADED_TEST(GlobalPrivates) {
- LocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
-
- v8::Local<String> name = v8_str("my-private");
- v8::Local<v8::Private> glob = v8::Private::ForApi(isolate, name);
- v8::Local<v8::Object> obj = v8::Object::New(isolate);
- CHECK(obj->SetPrivate(glob, v8::Integer::New(isolate, 3)));
-
- v8::Local<v8::Private> glob2 = v8::Private::ForApi(isolate, name);
- CHECK(obj->HasPrivate(glob2));
-
- v8::Local<v8::Private> priv = v8::Private::New(isolate, name);
- CHECK(!obj->HasPrivate(priv));
-
- CompileRun("var intern = %CreateGlobalPrivateSymbol('my-private')");
- v8::Local<Value> intern = env->Global()->Get(v8_str("intern"));
- CHECK(!obj->Has(intern));
-}
-
-
class ScopedArrayBufferContents {
public:
explicit ScopedArrayBufferContents(const v8::ArrayBuffer::Contents& contents)
@@ -2846,6 +2794,136 @@ THREADED_TEST(ArrayBuffer_NeuteringScript) {
}
+class ScopedSharedArrayBufferContents {
+ public:
+ explicit ScopedSharedArrayBufferContents(
+ const v8::SharedArrayBuffer::Contents& contents)
+ : contents_(contents) {}
+ ~ScopedSharedArrayBufferContents() { free(contents_.Data()); }
+ void* Data() const { return contents_.Data(); }
+ size_t ByteLength() const { return contents_.ByteLength(); }
+
+ private:
+ const v8::SharedArrayBuffer::Contents contents_;
+};
+
+
+THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ Local<v8::SharedArrayBuffer> ab = v8::SharedArrayBuffer::New(isolate, 1024);
+ CheckInternalFieldsAreZero(ab);
+ CHECK_EQ(1024, static_cast<int>(ab->ByteLength()));
+ CHECK(!ab->IsExternal());
+ CcTest::heap()->CollectAllGarbage();
+
+ ScopedSharedArrayBufferContents ab_contents(ab->Externalize());
+ CHECK(ab->IsExternal());
+
+ CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength()));
+ uint8_t* data = static_cast<uint8_t*>(ab_contents.Data());
+ DCHECK(data != NULL);
+ env->Global()->Set(v8_str("ab"), ab);
+
+ v8::Handle<v8::Value> result = CompileRun("ab.byteLength");
+ CHECK_EQ(1024, result->Int32Value());
+
+ result = CompileRun(
+ "var u8 = new Uint8Array(ab);"
+ "u8[0] = 0xFF;"
+ "u8[1] = 0xAA;"
+ "u8.length");
+ CHECK_EQ(1024, result->Int32Value());
+ CHECK_EQ(0xFF, data[0]);
+ CHECK_EQ(0xAA, data[1]);
+ data[0] = 0xCC;
+ data[1] = 0x11;
+ result = CompileRun("u8[0] + u8[1]");
+ CHECK_EQ(0xDD, result->Int32Value());
+}
+
+
+THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+
+ v8::Local<v8::Value> result = CompileRun(
+ "var ab1 = new SharedArrayBuffer(2);"
+ "var u8_a = new Uint8Array(ab1);"
+ "u8_a[0] = 0xAA;"
+ "u8_a[1] = 0xFF; u8_a.buffer");
+ Local<v8::SharedArrayBuffer> ab1 = Local<v8::SharedArrayBuffer>::Cast(result);
+ CheckInternalFieldsAreZero(ab1);
+ CHECK_EQ(2, static_cast<int>(ab1->ByteLength()));
+ CHECK(!ab1->IsExternal());
+ ScopedSharedArrayBufferContents ab1_contents(ab1->Externalize());
+ CHECK(ab1->IsExternal());
+
+ result = CompileRun("ab1.byteLength");
+ CHECK_EQ(2, result->Int32Value());
+ result = CompileRun("u8_a[0]");
+ CHECK_EQ(0xAA, result->Int32Value());
+ result = CompileRun("u8_a[1]");
+ CHECK_EQ(0xFF, result->Int32Value());
+ result = CompileRun(
+ "var u8_b = new Uint8Array(ab1);"
+ "u8_b[0] = 0xBB;"
+ "u8_a[0]");
+ CHECK_EQ(0xBB, result->Int32Value());
+ result = CompileRun("u8_b[1]");
+ CHECK_EQ(0xFF, result->Int32Value());
+
+ CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength()));
+ uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data());
+ CHECK_EQ(0xBB, ab1_data[0]);
+ CHECK_EQ(0xFF, ab1_data[1]);
+ ab1_data[0] = 0xCC;
+ ab1_data[1] = 0x11;
+ result = CompileRun("u8_a[0] + u8_a[1]");
+ CHECK_EQ(0xDD, result->Int32Value());
+}
+
+
+THREADED_TEST(SharedArrayBuffer_External) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ i::ScopedVector<uint8_t> my_data(100);
+ memset(my_data.start(), 0, 100);
+ Local<v8::SharedArrayBuffer> ab3 =
+ v8::SharedArrayBuffer::New(isolate, my_data.start(), 100);
+ CheckInternalFieldsAreZero(ab3);
+ CHECK_EQ(100, static_cast<int>(ab3->ByteLength()));
+ CHECK(ab3->IsExternal());
+
+ env->Global()->Set(v8_str("ab3"), ab3);
+
+ v8::Handle<v8::Value> result = CompileRun("ab3.byteLength");
+ CHECK_EQ(100, result->Int32Value());
+
+ result = CompileRun(
+ "var u8_b = new Uint8Array(ab3);"
+ "u8_b[0] = 0xBB;"
+ "u8_b[1] = 0xCC;"
+ "u8_b.length");
+ CHECK_EQ(100, result->Int32Value());
+ CHECK_EQ(0xBB, my_data[0]);
+ CHECK_EQ(0xCC, my_data[1]);
+ my_data[0] = 0xCC;
+ my_data[1] = 0x11;
+ result = CompileRun("u8_b[0] + u8_b[1]");
+ CHECK_EQ(0xDD, result->Int32Value());
+}
+
+
THREADED_TEST(HiddenProperties) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@@ -3934,7 +4012,7 @@ THREADED_TEST(ScriptException) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
Local<Script> script = v8_compile("throw 'panama!';");
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(env->GetIsolate());
Local<Value> result = script->Run();
CHECK(result.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -3947,7 +4025,7 @@ TEST(TryCatchCustomException) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"function CustomError() { this.a = 'b'; }"
"(function f() { throw new CustomError(); })();");
@@ -4039,8 +4117,9 @@ TEST(MessageHandler2) {
static void check_message_3(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
CHECK(message->IsSharedCrossOrigin());
- CHECK(message->GetScriptOrigin().ResourceIsSharedCrossOrigin()->Value());
- CHECK(message->GetScriptOrigin().ResourceIsEmbedderDebugScript()->Value());
+ CHECK(message->GetScriptOrigin().Options().IsSharedCrossOrigin());
+ CHECK(message->GetScriptOrigin().Options().IsEmbedderDebugScript());
+ CHECK(message->GetScriptOrigin().Options().IsOpaque());
CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue());
CHECK_EQ(7.40, message->GetScriptOrigin().SourceMapUrl()->NumberValue());
message_received = true;
@@ -4057,7 +4136,7 @@ TEST(MessageHandler3) {
v8::ScriptOrigin origin = v8::ScriptOrigin(
v8_str("6.75"), v8::Integer::New(isolate, 1),
v8::Integer::New(isolate, 2), v8::True(isolate), Handle<v8::Integer>(),
- v8::True(isolate), v8_str("7.40"));
+ v8::True(isolate), v8_str("7.40"), v8::True(isolate));
v8::Handle<v8::Script> script =
Script::Compile(v8_str("throw 'error'"), &origin);
script->Run();
@@ -4117,11 +4196,11 @@ TEST(MessageHandler5) {
CHECK(!message_received);
v8::V8::AddMessageListener(check_message_5a);
LocalContext context;
- v8::ScriptOrigin origin =
+ v8::ScriptOrigin origin1 =
v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1),
v8::Integer::New(isolate, 2), v8::True(isolate));
v8::Handle<v8::Script> script =
- Script::Compile(v8_str("throw 'error'"), &origin);
+ Script::Compile(v8_str("throw 'error'"), &origin1);
script->Run();
CHECK(message_received);
// clear out the message listener
@@ -4129,9 +4208,10 @@ TEST(MessageHandler5) {
message_received = false;
v8::V8::AddMessageListener(check_message_5b);
- origin = v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1),
- v8::Integer::New(isolate, 2), v8::False(isolate));
- script = Script::Compile(v8_str("throw 'error'"), &origin);
+ v8::ScriptOrigin origin2 =
+ v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1),
+ v8::Integer::New(isolate, 2), v8::False(isolate));
+ script = Script::Compile(v8_str("throw 'error'"), &origin2);
script->Run();
CHECK(message_received);
// clear out the message listener
@@ -4277,7 +4357,7 @@ THREADED_TEST(PropertyAttributes) {
Local<Value> fake_prop = v8_num(1);
CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(fake_prop));
// exception
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
Local<Value> exception =
CompileRun("({ toString: function() { throw 'exception';} })");
CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(exception));
@@ -4672,7 +4752,7 @@ void CCatcher(const v8::FunctionCallbackInfo<v8::Value>& args) {
return;
}
v8::HandleScope scope(args.GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
Local<Value> result = CompileRun(args[0]->ToString(args.GetIsolate()));
CHECK(!try_catch.HasCaught() || result.IsEmpty());
args.GetReturnValue().Set(try_catch.HasCaught());
@@ -4705,7 +4785,7 @@ THREADED_TEST(APIThrowTryCatch) {
templ->Set(v8_str("ThrowFromC"),
v8::FunctionTemplate::New(isolate, ThrowFromC));
LocalContext context(0, templ);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun("ThrowFromC();");
CHECK(try_catch.HasCaught());
}
@@ -4870,6 +4950,26 @@ TEST(CustomErrorMessage) {
}
+static void check_custom_rethrowing_message(v8::Handle<v8::Message> message,
+ v8::Handle<v8::Value> data) {
+ const char* uncaught_error = "Uncaught exception";
+ CHECK(message->Get()->Equals(v8_str(uncaught_error)));
+}
+
+
+TEST(CustomErrorRethrowsOnToString) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+ v8::V8::AddMessageListener(check_custom_rethrowing_message);
+
+ CompileRun(
+ "var e = { toString: function() { throw e; } };"
+ "try { throw e; } finally {}");
+
+ v8::V8::RemoveMessageListeners(check_custom_rethrowing_message);
+}
+
+
static void receive_message(v8::Handle<v8::Message> message,
v8::Handle<v8::Value> data) {
message->Get();
@@ -4901,7 +5001,7 @@ TEST(APIThrowMessageAndVerboseTryCatch) {
templ->Set(v8_str("ThrowFromC"),
v8::FunctionTemplate::New(isolate, ThrowFromC));
LocalContext context(0, templ);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
try_catch.SetVerbose(true);
Local<Value> result = CompileRun("ThrowFromC();");
CHECK(try_catch.HasCaught());
@@ -4916,7 +5016,7 @@ TEST(APIStackOverflowAndVerboseTryCatch) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
v8::V8::AddMessageListener(receive_message);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
try_catch.SetVerbose(true);
Local<Value> result = CompileRun("function foo() { foo(); } foo();");
CHECK(try_catch.HasCaught());
@@ -4934,7 +5034,7 @@ THREADED_TEST(ExternalScriptException) {
v8::FunctionTemplate::New(isolate, ThrowFromC));
LocalContext context(0, templ);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> result = CompileRun("ThrowFromC(); throw 'panama';");
CHECK(result.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -4956,7 +5056,7 @@ void CThrowCountDown(const v8::FunctionCallbackInfo<v8::Value>& args) {
Local<Value> fun = global->Get(v8_str("JSThrowCountDown"));
v8::Handle<Value> argv[] = {v8_num(count - 1), args[1], args[2], args[3]};
if (count % cInterval == 0) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
Local<Value> result = fun.As<Function>()->Call(global, 4, argv);
int expected = args[3]->Int32Value();
if (try_catch.HasCaught()) {
@@ -4993,7 +5093,7 @@ void JSCheck(const v8::FunctionCallbackInfo<v8::Value>& args) {
THREADED_TEST(EvalInTryFinally) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CompileRun(
"(function() {"
" try {"
@@ -5121,7 +5221,7 @@ THREADED_TEST(ThrowValues) {
THREADED_TEST(CatchZero) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CHECK(!try_catch.HasCaught());
CompileRun("throw 10");
CHECK(try_catch.HasCaught());
@@ -5137,7 +5237,7 @@ THREADED_TEST(CatchZero) {
THREADED_TEST(CatchExceptionFromWith) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CHECK(!try_catch.HasCaught());
CompileRun("var o = {}; with (o) { throw 42; }");
CHECK(try_catch.HasCaught());
@@ -5147,7 +5247,7 @@ THREADED_TEST(CatchExceptionFromWith) {
THREADED_TEST(TryCatchAndFinallyHidingException) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CHECK(!try_catch.HasCaught());
CompileRun("function f(k) { try { this[k]; } finally { return 0; } };");
CompileRun("f({toString: function() { throw 42; }});");
@@ -5156,7 +5256,7 @@ THREADED_TEST(TryCatchAndFinallyHidingException) {
void WithTryCatch(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
}
@@ -5167,7 +5267,7 @@ THREADED_TEST(TryCatchAndFinally) {
context->Global()->Set(
v8_str("native_with_try_catch"),
v8::FunctionTemplate::New(isolate, WithTryCatch)->GetFunction());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(!try_catch.HasCaught());
CompileRun(
"try {\n"
@@ -5181,7 +5281,7 @@ THREADED_TEST(TryCatchAndFinally) {
static void TryCatchNested1Helper(int depth) {
if (depth > 0) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
try_catch.SetVerbose(true);
TryCatchNested1Helper(depth - 1);
CHECK(try_catch.HasCaught());
@@ -5194,7 +5294,7 @@ static void TryCatchNested1Helper(int depth) {
static void TryCatchNested2Helper(int depth) {
if (depth > 0) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
try_catch.SetVerbose(true);
TryCatchNested2Helper(depth - 1);
CHECK(try_catch.HasCaught());
@@ -5212,7 +5312,7 @@ TEST(TryCatchNested) {
{
// Test nested try-catch with a native throw in the end.
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
TryCatchNested1Helper(5);
CHECK(try_catch.HasCaught());
CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "E1"));
@@ -5220,7 +5320,7 @@ TEST(TryCatchNested) {
{
// Test nested try-catch with a JavaScript throw in the end.
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
TryCatchNested2Helper(5);
CHECK(try_catch.HasCaught());
CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "E2"));
@@ -5243,7 +5343,7 @@ void TryCatchMixedNestingCheck(v8::TryCatch* try_catch) {
void TryCatchMixedNestingHelper(
const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
CompileRunWithOrigin("throw new Error('a');\n", "inner", 0, 0);
CHECK(try_catch.HasCaught());
TryCatchMixedNestingCheck(&try_catch);
@@ -5260,7 +5360,7 @@ TEST(TryCatchMixedNesting) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::V8::Initialize();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("TryCatchMixedNestingHelper"),
v8::FunctionTemplate::New(isolate, TryCatchMixedNestingHelper));
@@ -5272,7 +5372,7 @@ TEST(TryCatchMixedNesting) {
void TryCatchNativeHelper(const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
args.GetIsolate()->ThrowException(v8_str("boom"));
CHECK(try_catch.HasCaught());
}
@@ -5282,7 +5382,7 @@ TEST(TryCatchNative) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::V8::Initialize();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("TryCatchNativeHelper"),
v8::FunctionTemplate::New(isolate, TryCatchNativeHelper));
@@ -5295,7 +5395,7 @@ TEST(TryCatchNative) {
void TryCatchNativeResetHelper(
const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
args.GetIsolate()->ThrowException(v8_str("boom"));
CHECK(try_catch.HasCaught());
try_catch.Reset();
@@ -5307,7 +5407,7 @@ TEST(TryCatchNativeReset) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::V8::Initialize();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("TryCatchNativeResetHelper"),
v8::FunctionTemplate::New(isolate, TryCatchNativeResetHelper));
@@ -5433,7 +5533,7 @@ THREADED_TEST(DefinePropertyOnAPIAccessor) {
CHECK_EQ(result->BooleanValue(), false);
// Make sure that it is not possible to redefine again
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
result = script_define->Run();
CHECK(try_catch.HasCaught());
String::Utf8Value exception_value(try_catch.Exception());
@@ -5482,7 +5582,7 @@ THREADED_TEST(DefinePropertyOnDefineGetterSetter) {
CHECK_EQ(result->BooleanValue(), false);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
result = script_define->Run();
CHECK(try_catch.HasCaught());
String::Utf8Value exception_value(try_catch.Exception());
@@ -5604,7 +5704,7 @@ THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) {
->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"Object.defineProperty(obj1, 'x',"
"{get: function() { return 'func'; }})");
@@ -5614,7 +5714,7 @@ THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) {
0, strcmp(*exception_value, "TypeError: Cannot redefine property: x"));
}
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"Object.defineProperty(obj2, 'x',"
"{get: function() { return 'func'; }})");
@@ -7384,10 +7484,10 @@ THREADED_TEST(ToArrayIndex) {
str = v8_str("-42");
index = str->ToArrayIndex();
CHECK(index.IsEmpty());
- str = v8_str("4294967295");
+ str = v8_str("4294967294");
index = str->ToArrayIndex();
CHECK(!index.IsEmpty());
- CHECK_EQ(4294967295.0, index->Uint32Value());
+ CHECK_EQ(4294967294.0, index->Uint32Value());
v8::Handle<v8::Number> num = v8::Number::New(isolate, 1);
index = num->ToArrayIndex();
CHECK(!index.IsEmpty());
@@ -7450,7 +7550,7 @@ THREADED_TEST(ExceptionCreateMessage) {
v8::Local<v8::Object> global = context->Global();
global->Set(v8_str("throwV8Exception"), fun->GetFunction());
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
CompileRun(
"function f1() {\n"
" throwV8Exception();\n"
@@ -7504,6 +7604,22 @@ THREADED_TEST(ExceptionCreateMessage) {
}
+THREADED_TEST(ExceptionCreateMessageLength) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+
+ // Test that the message is not truncated.
+ TryCatch try_catch(context->GetIsolate());
+ CompileRun(
+ "var message = 'm';"
+ "while (message.length < 1000) message += message;"
+ "throw message;");
+ CHECK(try_catch.HasCaught());
+
+ CHECK_LT(1000, try_catch.Message()->Get()->Length());
+}
+
+
static void YGetter(Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
@@ -7684,7 +7800,7 @@ TEST(ExceptionInNativeScript) {
TEST(CompilationErrorUsingTryCatchHandler) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(env->GetIsolate());
v8_compile("This doesn't &*&@#$&*^ compile.");
CHECK(*try_catch.Exception());
CHECK(try_catch.HasCaught());
@@ -7694,7 +7810,7 @@ TEST(CompilationErrorUsingTryCatchHandler) {
TEST(TryCatchFinallyUsingTryCatchHandler) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(env->GetIsolate());
CompileRun("try { throw ''; } catch (e) {}");
CHECK(!try_catch.HasCaught());
CompileRun("try { throw ''; } finally {}");
@@ -7726,7 +7842,7 @@ TEST(TryCatchFinallyStoresMessageUsingTryCatchHandler) {
templ->Set(v8_str("CEvaluate"),
v8::FunctionTemplate::New(isolate, CEvaluate));
LocalContext context(0, templ);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun("try {"
" CEvaluate('throw 1;');"
"} finally {"
@@ -7853,7 +7969,7 @@ THREADED_TEST(SecurityChecks) {
Context::Scope scope_env2(env2);
// Call cross_domain_call, it should throw an exception
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(env1->GetIsolate());
Function::Cast(*spy2)->Call(env2->Global(), 0, NULL);
CHECK(try_catch.HasCaught());
}
@@ -8105,7 +8221,7 @@ TEST(ContextDetachGlobal) {
{
Local<Value> get_prop = global1->Get(v8_str("getProp"));
CHECK(get_prop->IsFunction());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(env1->GetIsolate());
Local<Value> r = Function::Cast(*get_prop)->Call(global1, 0, NULL);
CHECK(!try_catch.HasCaught());
CHECK_EQ(1, r->Int32Value());
@@ -8229,7 +8345,6 @@ TEST(DetachedAccesses) {
}
Local<Object> env2_global = env2->Global();
- env2_global->TurnOnAccessCheck();
env2->DetachGlobal();
Local<Value> result;
@@ -8639,8 +8754,6 @@ THREADED_TEST(AccessControlGetOwnPropertyNames) {
TEST(SuperAccessControl) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_harmony_classes = true;
- i::FLAG_harmony_object_literals = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::ObjectTemplate> obj_template =
@@ -8650,7 +8763,7 @@ TEST(SuperAccessControl) {
env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance());
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"var f = { m() { return super.hasOwnProperty; } }.m;"
"var m = %ToMethod(f, prohibited);"
@@ -8659,7 +8772,7 @@ TEST(SuperAccessControl) {
}
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"var f = {m() { return super[42]; } }.m;"
"var m = %ToMethod(f, prohibited);"
@@ -8668,7 +8781,7 @@ TEST(SuperAccessControl) {
}
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"var f = {m() { super.hasOwnProperty = function () {}; } }.m;"
"var m = %ToMethod(f, prohibited);"
@@ -8677,7 +8790,7 @@ TEST(SuperAccessControl) {
}
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"Object.defineProperty(Object.prototype, 'x', { set : function(){}});"
"var f = {"
@@ -8694,8 +8807,6 @@ TEST(SuperAccessControl) {
TEST(Regress470113) {
- i::FLAG_harmony_classes = true;
- i::FLAG_harmony_object_literals = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::ObjectTemplate> obj_template =
@@ -8705,7 +8816,7 @@ TEST(Regress470113) {
env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance());
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"'use strict';\n"
"class C extends Object {\n"
@@ -9446,7 +9557,7 @@ THREADED_TEST(SetPrototypeThrows) {
CHECK(o0->SetPrototype(o1));
// If setting the prototype leads to the cycle, SetPrototype should
// return false and keep VM in sane state.
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(!o1->SetPrototype(o0));
CHECK(!try_catch.HasCaught());
DCHECK(!CcTest::i_isolate()->has_pending_exception());
@@ -9466,7 +9577,7 @@ THREADED_TEST(FunctionRemovePrototype) {
context->Global()->Set(v8_str("fun"), fun);
CHECK(!CompileRun("'prototype' in fun")->BooleanValue());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun("new fun()");
CHECK(try_catch.HasCaught());
@@ -9488,7 +9599,7 @@ THREADED_TEST(GetterSetterExceptions) {
"x.__defineGetter__('get', Throw);");
Local<v8::Object> x =
Local<v8::Object>::Cast(context->Global()->Get(v8_str("x")));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
x->Set(v8_str("set"), v8::Integer::New(isolate, 8));
x->Get(v8_str("get"));
x->Set(v8_str("set"), v8::Integer::New(isolate, 8));
@@ -9554,7 +9665,7 @@ THREADED_TEST(ConstructorForObject) {
instance_template->SetCallAsFunctionHandler(ConstructorCallback);
Local<Object> instance = instance_template->NewInstance();
context->Global()->Set(v8_str("obj"), instance);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -9630,7 +9741,7 @@ THREADED_TEST(ConstructorForObject) {
Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate);
Local<Object> instance = instance_template->NewInstance();
context->Global()->Set(v8_str("obj2"), instance);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -9655,7 +9766,7 @@ THREADED_TEST(ConstructorForObject) {
instance_template->SetCallAsFunctionHandler(ThrowValue);
Local<Object> instance = instance_template->NewInstance();
context->Global()->Set(v8_str("obj3"), instance);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -9680,7 +9791,7 @@ THREADED_TEST(ConstructorForObject) {
Local<Function> function = function_template->GetFunction();
Local<Object> instance1 = function;
context->Global()->Set(v8_str("obj4"), instance1);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -9764,7 +9875,7 @@ THREADED_TEST(EvalAliasedDynamic) {
CHECK_EQ(0, current->Global()->Get(v8_str("result2"))->Int32Value());
CHECK_EQ(1, current->Global()->Get(v8_str("result3"))->Int32Value());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(current->GetIsolate());
script = v8_compile(
"function f(x) { "
" var bar = 2;"
@@ -9807,7 +9918,7 @@ THREADED_TEST(CrossEval) {
// Check that global variables in current context are not visible in other
// context.
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
script = v8_compile("var bar = 42; other.eval('bar');");
Local<Value> result = script->Run();
CHECK(try_catch.HasCaught());
@@ -9881,7 +9992,7 @@ THREADED_TEST(EvalInDetachedGlobal) {
v8::Handle<v8::Value> x_value = CompileRun("fun('x')");
CHECK_EQ(42, x_value->Int32Value());
context0->DetachGlobal();
- v8::TryCatch catcher;
+ v8::TryCatch catcher(isolate);
x_value = CompileRun("fun('x')");
CHECK_EQ(42, x_value->Int32Value());
context1->Exit();
@@ -9939,7 +10050,7 @@ THREADED_TEST(CallAsFunction) {
instance_template->SetCallAsFunctionHandler(call_as_function);
Local<v8::Object> instance = t->GetFunction()->NewInstance();
context->Global()->Set(v8_str("obj"), instance);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -9994,7 +10105,7 @@ THREADED_TEST(CallAsFunction) {
USE(instance_template);
Local<v8::Object> instance = t->GetFunction()->NewInstance();
context->Global()->Set(v8_str("obj2"), instance);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -10025,7 +10136,7 @@ THREADED_TEST(CallAsFunction) {
instance_template->SetCallAsFunctionHandler(ThrowValue);
Local<v8::Object> instance = t->GetFunction()->NewInstance();
context->Global()->Set(v8_str("obj3"), instance);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -10123,7 +10234,7 @@ THREADED_TEST(CallableObject) {
Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate);
instance_template->SetCallAsFunctionHandler(call_as_function);
Local<Object> instance = instance_template->NewInstance();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(instance->IsCallable());
CHECK(!try_catch.HasCaught());
@@ -10132,7 +10243,7 @@ THREADED_TEST(CallableObject) {
{
Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate);
Local<Object> instance = instance_template->NewInstance();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(!instance->IsCallable());
CHECK(!try_catch.HasCaught());
@@ -10143,7 +10254,7 @@ THREADED_TEST(CallableObject) {
FunctionTemplate::New(isolate, call_as_function);
Local<Function> function = function_template->GetFunction();
Local<Object> instance = function;
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(instance->IsCallable());
CHECK(!try_catch.HasCaught());
@@ -10153,7 +10264,7 @@ THREADED_TEST(CallableObject) {
Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate);
Local<Function> function = function_template->GetFunction();
Local<Object> instance = function;
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(instance->IsCallable());
CHECK(!try_catch.HasCaught());
@@ -10544,7 +10655,7 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) {
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"o.foo = 17;"
"var receiver = {};"
@@ -10587,7 +10698,7 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) {
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"o.foo = 17;"
"var receiver = {};"
@@ -10719,7 +10830,7 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss2) {
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"o.foo = 17;"
"var receiver = {};"
@@ -10758,7 +10869,7 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_TypeError) {
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"o.foo = 17;"
"var receiver = {};"
@@ -10806,7 +10917,7 @@ THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) {
"o\n").As<Object>();
CHECK(!with_js_getter.IsEmpty());
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
Local<Value> result = instance->GetRealNamedProperty(v8_str("f"));
CHECK(try_catch.HasCaught());
@@ -10859,7 +10970,7 @@ THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) {
static void ThrowingCallbackWithTryCatch(
const v8::FunctionCallbackInfo<v8::Value>& args) {
- TryCatch try_catch;
+ TryCatch try_catch(args.GetIsolate());
// Verboseness is important: it triggers message delivery which can call into
// external code.
try_catch.SetVerbose(true);
@@ -10874,7 +10985,7 @@ static int call_depth;
static void WithTryCatch(Handle<Message> message, Handle<Value> data) {
- TryCatch try_catch;
+ TryCatch try_catch(CcTest::isolate());
}
@@ -11163,7 +11274,7 @@ TEST(ObjectProtoToStringES6) {
Local<Value> obj = v8::Object::New(isolate);
obj.As<v8::Object>()->SetAccessor(toStringTag, ThrowingSymbolAccessorGetter);
{
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
value = obj.As<v8::Object>()->ObjectProtoToString();
CHECK(value.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -11174,7 +11285,7 @@ TEST(ObjectProtoToStringES6) {
obj.As<v8::Object>()->SetAccessor(
toStringTag, SymbolAccessorGetterReturnsDefault, 0, v8_str("Test"));
{
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
value = obj.As<v8::Object>()->ObjectProtoToString();
CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
CHECK(!try_catch.HasCaught());
@@ -11183,7 +11294,7 @@ TEST(ObjectProtoToStringES6) {
// JS @@toStringTag value
obj = CompileRun("obj = {}; obj[Symbol.toStringTag] = 'Test'; obj");
{
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
value = obj.As<v8::Object>()->ObjectProtoToString();
CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
CHECK(!try_catch.HasCaught());
@@ -11195,7 +11306,7 @@ TEST(ObjectProtoToStringES6) {
" get: function() { throw 'Test'; }"
"}); obj");
{
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
value = obj.As<v8::Object>()->ObjectProtoToString();
CHECK(value.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -11207,7 +11318,7 @@ TEST(ObjectProtoToStringES6) {
" get: function() { return 'Test'; }"
"}); obj");
{
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
value = obj.As<v8::Object>()->ObjectProtoToString();
CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
CHECK(!try_catch.HasCaught());
@@ -11421,7 +11532,8 @@ static void ThrowInJS(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Locker nested_locker(isolate);
v8::HandleScope scope(isolate);
v8::Handle<Value> exception;
- { v8::TryCatch try_catch;
+ {
+ v8::TryCatch try_catch(isolate);
v8::Handle<Value> value = CompileRun(code);
CHECK(value.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -12447,7 +12559,7 @@ THREADED_TEST(Regress54) {
TEST(CatchStackOverflow) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
v8::Handle<v8::Value> result = CompileRun(
"function f() {"
" return f();"
@@ -12462,7 +12574,7 @@ static void CheckTryCatchSourceInfo(v8::Handle<v8::Script> script,
const char* resource_name,
int line_offset) {
v8::HandleScope scope(CcTest::isolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
v8::Handle<v8::Value> result = script->Run();
CHECK(result.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -12522,7 +12634,7 @@ THREADED_TEST(TryCatchSourceInfo) {
THREADED_TEST(TryCatchSourceInfoForEOSError) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
v8::Script::Compile(v8_str("!\n"));
CHECK(try_catch.HasCaught());
v8::Handle<v8::Message> message = try_catch.Message();
@@ -12714,71 +12826,6 @@ THREADED_TEST(AccessChecksReenabledCorrectly) {
}
-THREADED_TEST(TurnOnAccessCheck) {
- v8::Isolate* isolate = CcTest::isolate();
- v8::HandleScope handle_scope(isolate);
-
- // Create an environment with access check to the global object disabled by
- // default.
- v8::Handle<v8::ObjectTemplate> global_template =
- v8::ObjectTemplate::New(isolate);
- global_template->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL,
- v8::Handle<v8::Value>(), false);
- v8::Local<Context> context = Context::New(isolate, NULL, global_template);
- Context::Scope context_scope(context);
-
- // Set up a property and a number of functions.
- context->Global()->Set(v8_str("a"), v8_num(1));
- CompileRun("function f1() {return a;}"
- "function f2() {return a;}"
- "function g1() {return h();}"
- "function g2() {return h();}"
- "function h() {return 1;}");
- Local<Function> f1 =
- Local<Function>::Cast(context->Global()->Get(v8_str("f1")));
- Local<Function> f2 =
- Local<Function>::Cast(context->Global()->Get(v8_str("f2")));
- Local<Function> g1 =
- Local<Function>::Cast(context->Global()->Get(v8_str("g1")));
- Local<Function> g2 =
- Local<Function>::Cast(context->Global()->Get(v8_str("g2")));
- Local<Function> h =
- Local<Function>::Cast(context->Global()->Get(v8_str("h")));
-
- // Get the global object.
- v8::Handle<v8::Object> global = context->Global();
-
- // Call f1 one time and f2 a number of times. This will ensure that f1 still
- // uses the runtime system to retreive property a whereas f2 uses global load
- // inline cache.
- CHECK(f1->Call(global, 0, NULL)->Equals(v8_num(1)));
- for (int i = 0; i < 4; i++) {
- CHECK(f2->Call(global, 0, NULL)->Equals(v8_num(1)));
- }
-
- // Same for g1 and g2.
- CHECK(g1->Call(global, 0, NULL)->Equals(v8_num(1)));
- for (int i = 0; i < 4; i++) {
- CHECK(g2->Call(global, 0, NULL)->Equals(v8_num(1)));
- }
-
- // Detach the global and turn on access check.
- Local<Object> hidden_global = Local<Object>::Cast(
- context->Global()->GetPrototype());
- context->DetachGlobal();
- hidden_global->TurnOnAccessCheck();
-
- // 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());
-
- // No failing access check when just returning a constant.
- CHECK(h->Call(global, 0, NULL)->Equals(v8_num(1)));
-}
-
-
// Tests that ScriptData can be serialized and deserialized.
TEST(PreCompileSerialization) {
v8::V8::Initialize();
@@ -13106,7 +13153,7 @@ TEST(RegExpInterruption) {
regexp_interruption_data.string_resource = new UC16VectorResource(
i::Vector<const i::uc16>(uc16_content, i::StrLength(one_byte_content)));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
timeout_thread.Start();
CompileRun("/((a*)*)*b/.exec(a)");
@@ -13216,8 +13263,9 @@ TEST(ForceSet) {
CHECK_EQ(3, global->Get(access_property)->Int32Value());
CHECK_EQ(1, force_set_set_count);
CHECK_EQ(2, force_set_get_count);
- // Forcing the property to be set should override the accessor without
- // calling it
+ // ForceSet doesn't call the accessors for now.
+ // TODO(verwaest): Update once blink doesn't rely on ForceSet to delete api
+ // accessors.
global->ForceSet(access_property, v8::Int32::New(isolate, 8));
CHECK_EQ(8, global->Get(access_property)->Int32Value());
CHECK_EQ(1, force_set_set_count);
@@ -13226,18 +13274,19 @@ TEST(ForceSet) {
TEST(ForceSetWithInterceptor) {
- force_set_get_count = 0;
- force_set_set_count = 0;
- pass_on_get = false;
-
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
ForceSetInterceptGetter, ForceSetInterceptSetter));
+ pass_on_get = true;
LocalContext context(NULL, templ);
v8::Handle<v8::Object> global = context->Global();
+ force_set_get_count = 0;
+ force_set_set_count = 0;
+ pass_on_get = false;
+
v8::Handle<v8::String> some_property =
v8::String::NewFromUtf8(isolate, "a");
CHECK_EQ(0, force_set_set_count);
@@ -13276,6 +13325,228 @@ TEST(ForceSetWithInterceptor) {
}
+TEST(CreateDataProperty) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ CompileRun(
+ "var a = {};"
+ "var b = [];"
+ "Object.defineProperty(a, 'foo', {value: 23});"
+ "Object.defineProperty(a, 'bar', {value: 23, configurable: true});");
+
+ v8::Local<v8::Object> obj =
+ v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a")));
+ v8::Local<v8::Array> arr =
+ v8::Local<v8::Array>::Cast(env->Global()->Get(v8_str("b")));
+ {
+ // Can't change a non-configurable properties.
+ v8::TryCatch try_catch(isolate);
+ CHECK(!obj->CreateDataProperty(env.local(), v8_str("foo"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ CHECK(obj->CreateDataProperty(env.local(), v8_str("bar"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val =
+ obj->Get(env.local(), v8_str("bar")).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Set a regular property.
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->CreateDataProperty(env.local(), v8_str("blub"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val =
+ obj->Get(env.local(), v8_str("blub")).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Set an indexed property.
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->CreateDataProperty(env.local(), v8_str("1"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val = obj->Get(env.local(), 1).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Special cases for arrays.
+ v8::TryCatch try_catch(isolate);
+ CHECK(!arr->CreateDataProperty(env.local(), v8_str("length"),
+ v8::Integer::New(isolate, 1)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+ {
+ // Special cases for arrays: index exceeds the array's length
+ v8::TryCatch try_catch(isolate);
+ CHECK(arr->CreateDataProperty(env.local(), 1, v8::Integer::New(isolate, 23))
+ .FromJust());
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(2U, arr->Length());
+ v8::Local<v8::Value> val = arr->Get(env.local(), 1).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(23.0, val->NumberValue(env.local()).FromJust());
+
+ // Set an existing entry.
+ CHECK(arr->CreateDataProperty(env.local(), 0, v8::Integer::New(isolate, 42))
+ .FromJust());
+ CHECK(!try_catch.HasCaught());
+ val = arr->Get(env.local(), 0).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ CompileRun("Object.freeze(a);");
+ {
+ // Can't change non-extensible objects.
+ v8::TryCatch try_catch(isolate);
+ CHECK(!obj->CreateDataProperty(env.local(), v8_str("baz"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
+ templ->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL);
+ v8::Local<v8::Object> access_checked =
+ templ->NewInstance(env.local()).ToLocalChecked();
+ {
+ v8::TryCatch try_catch(isolate);
+ CHECK(access_checked->CreateDataProperty(env.local(), v8_str("foo"),
+ v8::Integer::New(isolate, 42))
+ .IsNothing());
+ CHECK(try_catch.HasCaught());
+ }
+}
+
+
+TEST(DefineOwnProperty) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ CompileRun(
+ "var a = {};"
+ "var b = [];"
+ "Object.defineProperty(a, 'foo', {value: 23});"
+ "Object.defineProperty(a, 'bar', {value: 23, configurable: true});");
+
+ v8::Local<v8::Object> obj =
+ v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a")));
+ v8::Local<v8::Array> arr =
+ v8::Local<v8::Array>::Cast(env->Global()->Get(v8_str("b")));
+ {
+ // Can't change a non-configurable properties.
+ v8::TryCatch try_catch(isolate);
+ CHECK(!obj->DefineOwnProperty(env.local(), v8_str("foo"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ CHECK(obj->DefineOwnProperty(env.local(), v8_str("bar"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val =
+ obj->Get(env.local(), v8_str("bar")).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Set a regular property.
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineOwnProperty(env.local(), v8_str("blub"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val =
+ obj->Get(env.local(), v8_str("blub")).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Set an indexed property.
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineOwnProperty(env.local(), v8_str("1"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val = obj->Get(env.local(), 1).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Special cases for arrays.
+ v8::TryCatch try_catch(isolate);
+ CHECK(!arr->DefineOwnProperty(env.local(), v8_str("length"),
+ v8::Integer::New(isolate, 1)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+ {
+ // Special cases for arrays: index exceeds the array's length
+ v8::TryCatch try_catch(isolate);
+ CHECK(arr->DefineOwnProperty(env.local(), v8_str("1"),
+ v8::Integer::New(isolate, 23)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(2U, arr->Length());
+ v8::Local<v8::Value> val = arr->Get(env.local(), 1).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(23.0, val->NumberValue(env.local()).FromJust());
+
+ // Set an existing entry.
+ CHECK(arr->DefineOwnProperty(env.local(), v8_str("0"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ val = arr->Get(env.local(), 0).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Set a non-writable property.
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineOwnProperty(env.local(), v8_str("lala"),
+ v8::Integer::New(isolate, 42),
+ v8::ReadOnly).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val =
+ obj->Get(env.local(), v8_str("lala")).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ CHECK_EQ(v8::ReadOnly, obj->GetPropertyAttributes(
+ env.local(), v8_str("lala")).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ CompileRun("Object.freeze(a);");
+ {
+ // Can't change non-extensible objects.
+ v8::TryCatch try_catch(isolate);
+ CHECK(!obj->DefineOwnProperty(env.local(), v8_str("baz"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
+ templ->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL);
+ v8::Local<v8::Object> access_checked =
+ templ->NewInstance(env.local()).ToLocalChecked();
+ {
+ v8::TryCatch try_catch(isolate);
+ CHECK(access_checked->DefineOwnProperty(env.local(), v8_str("foo"),
+ v8::Integer::New(isolate, 42))
+ .IsNothing());
+ CHECK(try_catch.HasCaught());
+ }
+}
+
+
static v8::Local<Context> calling_context0;
static v8::Local<Context> calling_context1;
static v8::Local<Context> calling_context2;
@@ -13789,7 +14060,8 @@ THREADED_TEST(FixedFloat64Array) {
}
-template <typename ElementType, typename TypedArray, class ExternalArrayClass>
+template <typename ElementType, typename TypedArray, class ExternalArrayClass,
+ class ArrayBufferType>
void TypedArrayTestHelper(i::ExternalArrayType array_type, int64_t low,
int64_t high) {
const int kElementCount = 50;
@@ -13800,8 +14072,8 @@ void TypedArrayTestHelper(i::ExternalArrayType array_type, int64_t low,
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
- Local<v8::ArrayBuffer> ab =
- v8::ArrayBuffer::New(isolate, backing_store.start(),
+ Local<ArrayBufferType> ab =
+ ArrayBufferType::New(isolate, backing_store.start(),
(kElementCount + 2) * sizeof(ElementType));
Local<TypedArray> ta =
TypedArray::New(ab, 2*sizeof(ElementType), kElementCount);
@@ -13822,56 +14094,58 @@ void TypedArrayTestHelper(i::ExternalArrayType array_type, int64_t low,
THREADED_TEST(Uint8Array) {
- TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUint8Array>(
- i::kExternalUint8Array, 0, 0xFF);
+ TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUint8Array,
+ v8::ArrayBuffer>(i::kExternalUint8Array, 0, 0xFF);
}
THREADED_TEST(Int8Array) {
- TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalInt8Array>(
- i::kExternalInt8Array, -0x80, 0x7F);
+ TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalInt8Array,
+ v8::ArrayBuffer>(i::kExternalInt8Array, -0x80, 0x7F);
}
THREADED_TEST(Uint16Array) {
- TypedArrayTestHelper<uint16_t, v8::Uint16Array, i::ExternalUint16Array>(
- i::kExternalUint16Array, 0, 0xFFFF);
+ TypedArrayTestHelper<uint16_t, v8::Uint16Array, i::ExternalUint16Array,
+ v8::ArrayBuffer>(i::kExternalUint16Array, 0, 0xFFFF);
}
THREADED_TEST(Int16Array) {
- TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalInt16Array>(
- i::kExternalInt16Array, -0x8000, 0x7FFF);
+ TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalInt16Array,
+ v8::ArrayBuffer>(i::kExternalInt16Array, -0x8000,
+ 0x7FFF);
}
THREADED_TEST(Uint32Array) {
- TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUint32Array>(
- i::kExternalUint32Array, 0, UINT_MAX);
+ TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUint32Array,
+ v8::ArrayBuffer>(i::kExternalUint32Array, 0, UINT_MAX);
}
THREADED_TEST(Int32Array) {
- TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalInt32Array>(
- i::kExternalInt32Array, INT_MIN, INT_MAX);
+ TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalInt32Array,
+ v8::ArrayBuffer>(i::kExternalInt32Array, INT_MIN,
+ INT_MAX);
}
THREADED_TEST(Float32Array) {
- TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloat32Array>(
- i::kExternalFloat32Array, -500, 500);
+ TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloat32Array,
+ v8::ArrayBuffer>(i::kExternalFloat32Array, -500, 500);
}
THREADED_TEST(Float64Array) {
- TypedArrayTestHelper<double, v8::Float64Array, i::ExternalFloat64Array>(
- i::kExternalFloat64Array, -500, 500);
+ TypedArrayTestHelper<double, v8::Float64Array, i::ExternalFloat64Array,
+ v8::ArrayBuffer>(i::kExternalFloat64Array, -500, 500);
}
THREADED_TEST(Uint8ClampedArray) {
TypedArrayTestHelper<uint8_t, v8::Uint8ClampedArray,
- i::ExternalUint8ClampedArray>(
+ i::ExternalUint8ClampedArray, v8::ArrayBuffer>(
i::kExternalUint8ClampedArray, 0, 0xFF);
}
@@ -13887,6 +14161,97 @@ THREADED_TEST(DataView) {
Local<v8::ArrayBuffer> ab =
v8::ArrayBuffer::New(isolate, backing_store.start(), 2 + kSize);
+ Local<v8::DataView> dv = v8::DataView::New(ab, 2, kSize);
+ CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv);
+ CHECK_EQ(2u, dv->ByteOffset());
+ CHECK_EQ(kSize, static_cast<int>(dv->ByteLength()));
+ CHECK(ab->Equals(dv->Buffer()));
+}
+
+
+THREADED_TEST(SharedUint8Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUint8Array,
+ v8::SharedArrayBuffer>(i::kExternalUint8Array, 0, 0xFF);
+}
+
+
+THREADED_TEST(SharedInt8Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalInt8Array,
+ v8::SharedArrayBuffer>(i::kExternalInt8Array, -0x80,
+ 0x7F);
+}
+
+
+THREADED_TEST(SharedUint16Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<uint16_t, v8::Uint16Array, i::ExternalUint16Array,
+ v8::SharedArrayBuffer>(i::kExternalUint16Array, 0,
+ 0xFFFF);
+}
+
+
+THREADED_TEST(SharedInt16Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalInt16Array,
+ v8::SharedArrayBuffer>(i::kExternalInt16Array, -0x8000,
+ 0x7FFF);
+}
+
+
+THREADED_TEST(SharedUint32Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUint32Array,
+ v8::SharedArrayBuffer>(i::kExternalUint32Array, 0,
+ UINT_MAX);
+}
+
+
+THREADED_TEST(SharedInt32Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalInt32Array,
+ v8::SharedArrayBuffer>(i::kExternalInt32Array, INT_MIN,
+ INT_MAX);
+}
+
+
+THREADED_TEST(SharedFloat32Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloat32Array,
+ v8::SharedArrayBuffer>(i::kExternalFloat32Array, -500,
+ 500);
+}
+
+
+THREADED_TEST(SharedFloat64Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<double, v8::Float64Array, i::ExternalFloat64Array,
+ v8::SharedArrayBuffer>(i::kExternalFloat64Array, -500,
+ 500);
+}
+
+
+THREADED_TEST(SharedUint8ClampedArray) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<uint8_t, v8::Uint8ClampedArray,
+ i::ExternalUint8ClampedArray, v8::SharedArrayBuffer>(
+ i::kExternalUint8ClampedArray, 0, 0xFF);
+}
+
+
+THREADED_TEST(SharedDataView) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ const int kSize = 50;
+
+ i::ScopedVector<uint8_t> backing_store(kSize + 2);
+
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ Local<v8::SharedArrayBuffer> ab =
+ v8::SharedArrayBuffer::New(isolate, backing_store.start(), 2 + kSize);
Local<v8::DataView> dv =
v8::DataView::New(ab, 2, kSize);
CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv);
@@ -13949,7 +14314,7 @@ THREADED_TEST(ScriptContextDependence) {
THREADED_TEST(StackTrace) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
const char *source = "function foo() { FAIL.FAIL; }; foo();";
v8::Handle<v8::String> src =
v8::String::NewFromUtf8(context->GetIsolate(), source);
@@ -14928,7 +15293,7 @@ TEST(DynamicWithSourceURLInStackTraceString) {
i::ScopedVector<char> code(1024);
i::SNPrintF(code, source, "//# sourceURL=source_url");
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CompileRunWithOrigin(code.start(), "", 0, 0);
CHECK(try_catch.HasCaught());
v8::String::Utf8Value stack(try_catch.StackTrace());
@@ -14949,7 +15314,7 @@ TEST(EvalWithSourceURLInMessageScriptResourceNameOrSourceURL) {
"outer();\n"
"//# sourceURL=outer_url";
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CompileRun(source);
CHECK(try_catch.HasCaught());
@@ -14973,7 +15338,7 @@ TEST(RecursionWithSourceURLInMessageScriptResourceNameOrSourceURL) {
"outer();\n"
"//# sourceURL=outer_url";
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CompileRun(source);
CHECK(try_catch.HasCaught());
@@ -14996,6 +15361,7 @@ static void CreateGarbageInOldSpace() {
// Test that idle notification can be handled and eventually collects garbage.
TEST(TestIdleNotification) {
+ if (!i::FLAG_incremental_marking) return;
const intptr_t MB = 1024 * 1024;
const double IdlePauseInSeconds = 1.0;
LocalContext env;
@@ -15006,6 +15372,9 @@ TEST(TestIdleNotification) {
CHECK_GT(size_with_garbage, initial_size + MB);
bool finished = false;
for (int i = 0; i < 200 && !finished; i++) {
+ if (i < 10 && CcTest::heap()->incremental_marking()->IsStopped()) {
+ CcTest::heap()->StartIdleIncrementalMarking();
+ }
finished = env->GetIsolate()->IdleNotificationDeadline(
(v8::base::TimeTicks::HighResolutionNow().ToInternalValue() /
static_cast<double>(v8::base::Time::kMicrosecondsPerSecond)) +
@@ -15284,9 +15653,6 @@ TEST(ExternalInternalizedStringCollectedAtTearDown) {
TEST(ExternalInternalizedStringCollectedAtGC) {
- // TODO(mvstanton): vector ics need weak support.
- if (i::FLAG_vector_ics) return;
-
int destroyed = 0;
{ LocalContext env;
v8::HandleScope handle_scope(env->GetIsolate());
@@ -15345,7 +15711,7 @@ THREADED_TEST(QuietSignalingNaNs) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
// Special double values.
double snan = DoubleFromBits(0x7ff00000, 0x00000001);
@@ -15432,7 +15798,7 @@ THREADED_TEST(QuietSignalingNaNs) {
static void SpaghettiIncident(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(args.GetIsolate());
- v8::TryCatch tc;
+ v8::TryCatch tc(args.GetIsolate());
v8::Handle<v8::String> str(args[0]->ToString(args.GetIsolate()));
USE(str);
if (tc.HasCaught())
@@ -15449,7 +15815,7 @@ THREADED_TEST(SpaghettiStackReThrow) {
context->Global()->Set(
v8::String::NewFromUtf8(isolate, "s"),
v8::FunctionTemplate::New(isolate, SpaghettiIncident)->GetFunction());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"var i = 0;"
"var o = {"
@@ -15535,7 +15901,7 @@ TEST(Regress528) {
v8::Local<Context> context = Context::New(isolate);
context->Enter();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(source_exception);
CHECK(try_catch.HasCaught());
v8::Handle<v8::Message> message = try_catch.Message();
@@ -15566,7 +15932,8 @@ THREADED_TEST(ScriptOrigin) {
v8::Integer::New(env->GetIsolate(), 1),
v8::Integer::New(env->GetIsolate(), 1), v8::True(env->GetIsolate()),
v8::Handle<v8::Integer>(), v8::True(env->GetIsolate()),
- v8::String::NewFromUtf8(env->GetIsolate(), "http://sourceMapUrl"));
+ v8::String::NewFromUtf8(env->GetIsolate(), "http://sourceMapUrl"),
+ v8::True(env->GetIsolate()));
v8::Handle<v8::String> script = v8::String::NewFromUtf8(
env->GetIsolate(), "function f() {}\n\nfunction g() {}");
v8::Script::Compile(script, &origin)->Run();
@@ -15579,8 +15946,9 @@ THREADED_TEST(ScriptOrigin) {
CHECK_EQ(0, strcmp("test",
*v8::String::Utf8Value(script_origin_f.ResourceName())));
CHECK_EQ(1, script_origin_f.ResourceLineOffset()->Int32Value());
- CHECK(script_origin_f.ResourceIsSharedCrossOrigin()->Value());
- CHECK(script_origin_f.ResourceIsEmbedderDebugScript()->Value());
+ CHECK(script_origin_f.Options().IsSharedCrossOrigin());
+ CHECK(script_origin_f.Options().IsEmbedderDebugScript());
+ CHECK(script_origin_f.Options().IsOpaque());
printf("is name = %d\n", script_origin_f.SourceMapUrl()->IsUndefined());
CHECK_EQ(0, strcmp("http://sourceMapUrl",
@@ -15590,8 +15958,9 @@ THREADED_TEST(ScriptOrigin) {
CHECK_EQ(0, strcmp("test",
*v8::String::Utf8Value(script_origin_g.ResourceName())));
CHECK_EQ(1, script_origin_g.ResourceLineOffset()->Int32Value());
- CHECK(script_origin_g.ResourceIsSharedCrossOrigin()->Value());
- CHECK(script_origin_g.ResourceIsEmbedderDebugScript()->Value());
+ CHECK(script_origin_g.Options().IsSharedCrossOrigin());
+ CHECK(script_origin_g.Options().IsEmbedderDebugScript());
+ CHECK(script_origin_g.Options().IsOpaque());
CHECK_EQ(0, strcmp("http://sourceMapUrl",
*v8::String::Utf8Value(script_origin_g.SourceMapUrl())));
}
@@ -16419,6 +16788,8 @@ void FailedAccessCheckCallbackGC(Local<v8::Object> target,
v8::AccessType type,
Local<v8::Value> data) {
CcTest::heap()->CollectAllGarbage();
+ CcTest::isolate()->ThrowException(
+ v8::Exception::Error(v8_str("cross context")));
}
@@ -16437,7 +16808,7 @@ TEST(GCInFailedAccessCheckCallback) {
v8::Handle<v8::ObjectTemplate> global_template =
v8::ObjectTemplate::New(isolate);
global_template->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL,
- v8::Handle<v8::Value>(), false);
+ v8::Handle<v8::Value>());
// Create a context and set an x property on it's global object.
LocalContext context0(NULL, global_template);
@@ -16449,28 +16820,42 @@ TEST(GCInFailedAccessCheckCallback) {
LocalContext context1(NULL, global_template);
context1->Global()->Set(v8_str("other"), global0);
+ v8::TryCatch try_catch(isolate);
+
// Get property with failed access check.
- ExpectUndefined("other.x");
+ CHECK(CompileRun("other.x").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Get element with failed access check.
- ExpectUndefined("other[0]");
+ CHECK(CompileRun("other[0]").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Set property with failed access check.
- v8::Handle<v8::Value> result = CompileRun("other.x = new Object()");
- CHECK(result->IsObject());
+ CHECK(CompileRun("other.x = new Object()").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Set element with failed access check.
- result = CompileRun("other[0] = new Object()");
- CHECK(result->IsObject());
+ CHECK(CompileRun("other[0] = new Object()").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Get property attribute with failed access check.
- ExpectFalse("\'x\' in other");
+ CHECK(CompileRun("\'x\' in other").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Get property attribute for element with failed access check.
- ExpectFalse("0 in other");
+ CHECK(CompileRun("0 in other").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Delete property.
- ExpectFalse("delete other.x");
+ CHECK(CompileRun("delete other.x").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Delete element.
CHECK_EQ(false, global0->Delete(0));
@@ -16480,15 +16865,25 @@ TEST(GCInFailedAccessCheckCallback) {
global0->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("x")));
// Define JavaScript accessor.
- ExpectUndefined("Object.prototype.__defineGetter__.call("
- " other, \'x\', function() { return 42; })");
+ CHECK(CompileRun(
+ "Object.prototype.__defineGetter__.call("
+ " other, \'x\', function() { return 42; })").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// LookupAccessor.
- ExpectUndefined("Object.prototype.__lookupGetter__.call("
- " other, \'x\')");
+ CHECK(CompileRun(
+ "Object.prototype.__lookupGetter__.call("
+ " other, \'x\')").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// HasOwnElement.
- ExpectFalse("Object.prototype.hasOwnProperty.call(other, \'0\')");
+ CHECK(CompileRun(
+ "Object.prototype.hasOwnProperty.call("
+ "other, \'0\')").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
CHECK_EQ(false, global0->HasRealIndexedProperty(0));
CHECK_EQ(false, global0->HasRealNamedProperty(v8_str("x")));
@@ -17145,7 +17540,7 @@ TEST(RegExp) {
v8::Handle<v8::Value> value(CompileRun("re.property"));
CHECK_EQ(32, value->Int32Value());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
re = v8::RegExp::New(v8_str("foo["), v8::RegExp::kNone);
CHECK(re.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -17485,7 +17880,7 @@ void CheckCodeGenerationAllowed() {
void CheckCodeGenerationDisallowed() {
- TryCatch try_catch;
+ TryCatch try_catch(CcTest::isolate());
Handle<Value> result = CompileRun("eval('42')");
CHECK(result.IsEmpty());
@@ -17548,7 +17943,7 @@ THREADED_TEST(AllowCodeGenFromStrings) {
TEST(SetErrorMessageForCodeGenFromStrings) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
Handle<String> message = v8_str("Message") ;
Handle<String> expected_message = v8_str("Uncaught EvalError: Message");
@@ -17575,7 +17970,7 @@ THREADED_TEST(CallAPIFunctionOnNonObject) {
v8::FunctionTemplate::New(isolate, NonObjectThis);
Handle<Function> function = templ->GetFunction();
context->Global()->Set(v8_str("f"), function);
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
CompileRun("f.call(2)");
}
@@ -18024,7 +18419,7 @@ TEST(RunMicrotasksIgnoresThrownExceptions) {
Function::New(isolate, MicrotaskExceptionOne));
isolate->EnqueueMicrotask(
Function::New(isolate, MicrotaskExceptionTwo));
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
CompileRun("1+1;");
CHECK(!try_catch.HasCaught());
CHECK_EQ(1, CompileRun("exception1Calls")->Int32Value());
@@ -18345,7 +18740,7 @@ static void CheckInstanceCheckedResult(int getters, int setters,
static void CheckInstanceCheckedAccessors(bool expects_callbacks) {
instance_checked_getter_count = 0;
instance_checked_setter_count = 0;
- TryCatch try_catch;
+ TryCatch try_catch(CcTest::isolate());
// Test path through generic runtime code.
CompileRun("obj.foo");
@@ -18493,7 +18888,7 @@ TEST(TryFinallyMessage) {
// Test that the original error message is not lost if there is a
// recursive call into Javascript is done in the finally block, e.g. to
// initialize an IC. (crbug.com/129171)
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
const char* trigger_ic =
"try { \n"
" throw new Error('test'); \n"
@@ -18511,7 +18906,7 @@ TEST(TryFinallyMessage) {
{
// Test that the original exception message is indeed overwritten if
// a new error is thrown in the finally block.
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
const char* throw_again =
"try { \n"
" throw new Error('test'); \n"
@@ -18681,7 +19076,7 @@ THREADED_TEST(Regress137496) {
// Compile a try-finally clause where the finally block causes a GC
// while there still is a message pending for external reporting.
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
try_catch.SetVerbose(true);
CompileRun("try { throw new Error(); } finally { gc(); }");
CHECK(try_catch.HasCaught());
@@ -18859,16 +19254,6 @@ TEST(JSONStringifyAccessCheck) {
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"));
- array->Set(1, v8_str("b"));
- context1->Global()->Set(v8_str("array"), array);
- ExpectString("JSON.stringify(array)", "[\"a\",\"b\"]");
- array->TurnOnAccessCheck();
- CHECK(CompileRun("JSON.stringify(array)").IsEmpty());
- CHECK(CompileRun("JSON.stringify([array])").IsEmpty());
- CHECK(CompileRun("JSON.stringify({'a' : array})").IsEmpty());
}
}
@@ -18924,6 +19309,7 @@ void CheckCorrectThrow(const char* script) {
TEST(AccessCheckThrows) {
i::FLAG_allow_natives_syntax = true;
+ i::FLAG_turbo_try_catch = true;
v8::V8::Initialize();
v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckThrows);
v8::Isolate* isolate = CcTest::isolate();
@@ -18953,7 +19339,8 @@ TEST(AccessCheckThrows) {
context1->Global()->Set(v8_str("has_own_property"),
has_own_property_fun->GetFunction());
- { v8::TryCatch try_catch;
+ {
+ v8::TryCatch try_catch(isolate);
access_check_fail_thrown = false;
CompileRun("other.x;");
CHECK(access_check_fail_thrown);
@@ -19570,7 +19957,7 @@ class ApiCallOptimizationChecker {
"%%OptimizeFunctionOnNextCall(wrap_set_%d);\n"
"check(wrap_set());\n",
wrap_function.start(), key, key, key, key, key, key);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(source.start());
DCHECK(!try_catch.HasCaught());
CHECK_EQ(9, count);
@@ -19994,7 +20381,7 @@ TEST(ThrowOnJavascriptExecution) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
v8::Isolate::DisallowJavascriptExecutionScope throw_js(
isolate, v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
CompileRun("1+1");
@@ -20054,7 +20441,7 @@ TEST(CaptureStackTraceForStackOverflow) {
v8::HandleScope scope(isolate);
V8::SetCaptureStackTraceForUncaughtExceptions(
true, 10, v8::StackTrace::kDetailed);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun("(function f(x) { f(x+1); })(0)");
CHECK(try_catch.HasCaught());
}
@@ -20295,7 +20682,7 @@ void RunStreamingTest(const char** chunks,
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
v8::ScriptCompiler::StreamedSource source(new TestSourceStream(chunks),
encoding);
@@ -20568,6 +20955,7 @@ TEST(StreamingWithDebuggingDoesNotProduceParserCache) {
CompileRun("function break_here() { }");
i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(
v8::Utils::OpenHandle(*env->Global()->Get(v8_str("break_here"))));
+ EnableDebugger();
v8::internal::Debug* debug = CcTest::i_isolate()->debug();
int position = 0;
debug->SetBreakPoint(func, i::Handle<i::Object>(v8::internal::Smi::FromInt(1),
@@ -20588,6 +20976,7 @@ TEST(StreamingWithDebuggingDoesNotProduceParserCache) {
// Check that we got no cached data.
CHECK(source.GetCachedData() == NULL);
+ DisableDebugger();
}
@@ -20667,7 +21056,7 @@ TEST(StreamingWithHarmonyScopes) {
// variable again.
const char* chunks[] = {"\"use strict\"; let x = 2;", NULL};
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
v8::ScriptCompiler::StreamedSource source(
new TestSourceStream(chunks),
v8::ScriptCompiler::StreamedSource::ONE_BYTE);
@@ -20695,6 +21084,58 @@ TEST(StreamingWithHarmonyScopes) {
}
+TEST(CodeCache) {
+ v8::Isolate::CreateParams create_params;
+ create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+
+ const char* source = "Math.sqrt(4)";
+ const char* origin = "code cache test";
+ v8::ScriptCompiler::CachedData* cache;
+
+ v8::Isolate* isolate1 = v8::Isolate::New(create_params);
+ {
+ v8::Isolate::Scope iscope(isolate1);
+ v8::HandleScope scope(isolate1);
+ v8::Local<v8::Context> context = v8::Context::New(isolate1);
+ v8::Context::Scope cscope(context);
+ v8::Local<v8::String> source_string = v8_str(source);
+ v8::ScriptOrigin script_origin(v8_str(origin));
+ v8::ScriptCompiler::Source source(source_string, script_origin);
+ v8::ScriptCompiler::CompileOptions option =
+ v8::ScriptCompiler::kProduceCodeCache;
+ v8::ScriptCompiler::Compile(context, &source, option).ToLocalChecked();
+ int length = source.GetCachedData()->length;
+ uint8_t* cache_data = new uint8_t[length];
+ memcpy(cache_data, source.GetCachedData()->data, length);
+ cache = new v8::ScriptCompiler::CachedData(
+ cache_data, length, v8::ScriptCompiler::CachedData::BufferOwned);
+ }
+ isolate1->Dispose();
+
+ v8::Isolate* isolate2 = v8::Isolate::New(create_params);
+ {
+ v8::Isolate::Scope iscope(isolate2);
+ v8::HandleScope scope(isolate2);
+ v8::Local<v8::Context> context = v8::Context::New(isolate2);
+ v8::Context::Scope cscope(context);
+ v8::Local<v8::String> source_string = v8_str(source);
+ v8::ScriptOrigin script_origin(v8_str(origin));
+ v8::ScriptCompiler::Source source(source_string, script_origin, cache);
+ v8::ScriptCompiler::CompileOptions option =
+ v8::ScriptCompiler::kConsumeCodeCache;
+ v8::Local<v8::Script> script;
+ {
+ i::DisallowCompilation no_compile(
+ reinterpret_cast<i::Isolate*>(isolate2));
+ script = v8::ScriptCompiler::Compile(context, &source, option)
+ .ToLocalChecked();
+ }
+ CHECK_EQ(2, script->Run()->ToInt32(isolate2)->Int32Value());
+ }
+ isolate2->Dispose();
+}
+
+
void TestInvalidCacheData(v8::ScriptCompiler::CompileOptions option) {
const char* garbage = "garbage garbage garbage garbage garbage garbage";
const uint8_t* data = reinterpret_cast<const uint8_t*>(garbage);
@@ -20782,7 +21223,7 @@ TEST(StringConcatOverflow) {
new RandomLengthOneByteResource(i::String::kMaxLength);
v8::Local<v8::String> str = v8::String::NewExternal(CcTest::isolate(), r);
CHECK(!str.IsEmpty());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
v8::Local<v8::String> result = v8::String::Concat(str, str);
CHECK(result.IsEmpty());
CHECK(!try_catch.HasCaught());
@@ -20843,7 +21284,7 @@ TEST(GetPrototypeAccessControl) {
env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance());
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"function f() { %_GetPrototype(prohibited); }"
"%OptimizeFunctionOnNextCall(f);"
@@ -20883,7 +21324,6 @@ TEST(GetPrototypeHidden) {
TEST(ClassPrototypeCreationContext) {
- i::FLAG_harmony_classes = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
LocalContext env;
@@ -20927,21 +21367,21 @@ TEST(NewStringRangeError) {
if (buffer == NULL) return;
memset(buffer, 'A', buffer_size);
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
char* data = reinterpret_cast<char*>(buffer);
CHECK(v8::String::NewFromUtf8(isolate, data, v8::String::kNormalString,
length).IsEmpty());
CHECK(!try_catch.HasCaught());
}
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
uint8_t* data = reinterpret_cast<uint8_t*>(buffer);
CHECK(v8::String::NewFromOneByte(isolate, data, v8::String::kNormalString,
length).IsEmpty());
CHECK(!try_catch.HasCaught());
}
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
uint16_t* data = reinterpret_cast<uint16_t*>(buffer);
CHECK(v8::String::NewFromTwoByte(isolate, data, v8::String::kNormalString,
length).IsEmpty());
@@ -20983,6 +21423,404 @@ TEST(SealHandleScopeNested) {
}
+static bool access_was_called = false;
+
+
+static bool AccessAlwaysAllowedWithFlag(Local<v8::Object> global,
+ Local<Value> name, v8::AccessType type,
+ Local<Value> data) {
+ access_was_called = true;
+ return true;
+}
+
+
+static bool AccessAlwaysBlockedWithFlag(Local<v8::Object> global,
+ Local<Value> name, v8::AccessType type,
+ Local<Value> data) {
+ access_was_called = true;
+ return false;
+}
+
+
+TEST(StrongModeAccessCheckAllowed) {
+ i::FLAG_strong_mode = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<Value> value;
+ access_was_called = false;
+
+ v8::Handle<v8::ObjectTemplate> obj_template =
+ v8::ObjectTemplate::New(isolate);
+
+ obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42));
+ obj_template->SetAccessCheckCallbacks(AccessAlwaysAllowedWithFlag, NULL);
+
+ // Create an environment
+ v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template);
+ context0->Enter();
+ v8::Handle<v8::Object> global0 = context0->Global();
+ global0->Set(v8_str("object"), obj_template->NewInstance());
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.x");
+ CHECK(!try_catch.HasCaught());
+ CHECK(!access_was_called);
+ CHECK_EQ(42, value->Int32Value());
+ }
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.foo");
+ CHECK(try_catch.HasCaught());
+ CHECK(!access_was_called);
+ }
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object[10]");
+ CHECK(try_catch.HasCaught());
+ CHECK(!access_was_called);
+ }
+
+ // Create an environment
+ v8::Local<Context> context1 = Context::New(isolate);
+ context1->Enter();
+ v8::Handle<v8::Object> global1 = context1->Global();
+ global1->Set(v8_str("object"), obj_template->NewInstance());
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.x");
+ CHECK(!try_catch.HasCaught());
+ CHECK(access_was_called);
+ CHECK_EQ(42, value->Int32Value());
+ }
+ access_was_called = false;
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.foo");
+ CHECK(try_catch.HasCaught());
+ CHECK(access_was_called);
+ }
+ access_was_called = false;
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object[10]");
+ CHECK(try_catch.HasCaught());
+ CHECK(access_was_called);
+ }
+
+ context1->Exit();
+ context0->Exit();
+}
+
+
+TEST(StrongModeAccessCheckBlocked) {
+ i::FLAG_strong_mode = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<Value> value;
+ access_was_called = false;
+
+ v8::Handle<v8::ObjectTemplate> obj_template =
+ v8::ObjectTemplate::New(isolate);
+
+ obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42));
+ obj_template->SetAccessCheckCallbacks(AccessAlwaysBlockedWithFlag, NULL);
+
+ // Create an environment
+ v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template);
+ context0->Enter();
+ v8::Handle<v8::Object> global0 = context0->Global();
+ global0->Set(v8_str("object"), obj_template->NewInstance());
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.x");
+ CHECK(!try_catch.HasCaught());
+ CHECK(!access_was_called);
+ CHECK_EQ(42, value->Int32Value());
+ }
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.foo");
+ CHECK(try_catch.HasCaught());
+ CHECK(!access_was_called);
+ }
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object[10]");
+ CHECK(try_catch.HasCaught());
+ CHECK(!access_was_called);
+ }
+
+ // Create an environment
+ v8::Local<Context> context1 = Context::New(isolate);
+ context1->Enter();
+ v8::Handle<v8::Object> global1 = context1->Global();
+ global1->Set(v8_str("object"), obj_template->NewInstance());
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.x");
+ CHECK(try_catch.HasCaught());
+ CHECK(access_was_called);
+ }
+ access_was_called = false;
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.foo");
+ CHECK(try_catch.HasCaught());
+ CHECK(access_was_called);
+ }
+ access_was_called = false;
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object[10]");
+ CHECK(try_catch.HasCaught());
+ CHECK(access_was_called);
+ }
+
+ context1->Exit();
+ context0->Exit();
+}
+
+
+TEST(StrongModeArityCallFromApi) {
+ i::FLAG_strong_mode = true;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<Function> fun;
+ {
+ v8::TryCatch try_catch(isolate);
+ fun = Local<Function>::Cast(CompileRun(
+ "function f(x) { 'use strong'; }"
+ "f"));
+
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ fun->Call(v8::Undefined(isolate), 0, nullptr);
+ CHECK(try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ v8::Handle<Value> args[] = {v8_num(42)};
+ fun->Call(v8::Undefined(isolate), arraysize(args), args);
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ v8::Handle<Value> args[] = {v8_num(42), v8_num(555)};
+ fun->Call(v8::Undefined(isolate), arraysize(args), args);
+ CHECK(!try_catch.HasCaught());
+ }
+}
+
+
+TEST(StrongModeArityCallFromApi2) {
+ i::FLAG_strong_mode = true;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<Function> fun;
+ {
+ v8::TryCatch try_catch(isolate);
+ fun = Local<Function>::Cast(CompileRun(
+ "'use strong';"
+ "function f(x) {}"
+ "f"));
+
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ fun->Call(v8::Undefined(isolate), 0, nullptr);
+ CHECK(try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ v8::Handle<Value> args[] = {v8_num(42)};
+ fun->Call(v8::Undefined(isolate), arraysize(args), args);
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ v8::Handle<Value> args[] = {v8_num(42), v8_num(555)};
+ fun->Call(v8::Undefined(isolate), arraysize(args), args);
+ CHECK(!try_catch.HasCaught());
+ }
+}
+
+
+TEST(StrongObjectDelete) {
+ i::FLAG_strong_mode = true;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<Object> obj;
+ {
+ v8::TryCatch try_catch;
+ obj = Local<Object>::Cast(CompileRun(
+ "'use strong';"
+ "({});"));
+ CHECK(!try_catch.HasCaught());
+ }
+ obj->ForceSet(v8_str("foo"), v8_num(1), v8::None);
+ obj->ForceSet(v8_str("2"), v8_num(1), v8::None);
+ CHECK(obj->HasOwnProperty(v8_str("foo")));
+ CHECK(obj->HasOwnProperty(v8_str("2")));
+ CHECK(!obj->Delete(v8_str("foo")));
+ CHECK(!obj->Delete(2));
+}
+
+
+static void ExtrasExportsTestRuntimeFunction(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ CHECK_EQ(3, args[0]->Int32Value());
+ args.GetReturnValue().Set(v8_num(7));
+}
+
+
+TEST(ExtrasExportsObject) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+
+ // standalone.gypi ensures we include the test-extra.js file, which should
+ // export the tested functions.
+ v8::Local<v8::Object> exports = env->GetExtrasExportsObject();
+
+ auto func =
+ exports->Get(v8_str("testExtraShouldReturnFive")).As<v8::Function>();
+ auto undefined = v8::Undefined(isolate);
+ auto result = func->Call(undefined, 0, {}).As<v8::Number>();
+ CHECK_EQ(5, result->Int32Value());
+
+ v8::Handle<v8::FunctionTemplate> runtimeFunction =
+ v8::FunctionTemplate::New(isolate, ExtrasExportsTestRuntimeFunction);
+ exports->Set(v8_str("runtime"), runtimeFunction->GetFunction());
+ func =
+ exports->Get(v8_str("testExtraShouldCallToRuntime")).As<v8::Function>();
+ result = func->Call(undefined, 0, {}).As<v8::Number>();
+ CHECK_EQ(7, result->Int32Value());
+}
+
+
+TEST(Map) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+
+ v8::Local<v8::Map> map = v8::Map::New(isolate);
+ CHECK(map->IsObject());
+ CHECK(map->IsMap());
+ CHECK(map->GetPrototype()->StrictEquals(CompileRun("Map.prototype")));
+ CHECK_EQ(0U, map->Size());
+
+ v8::Local<v8::Value> val = CompileRun("new Map([[1, 2], [3, 4]])");
+ CHECK(val->IsMap());
+ map = v8::Local<v8::Map>::Cast(val);
+ CHECK_EQ(2U, map->Size());
+
+ v8::Local<v8::Array> contents = map->AsArray();
+ CHECK_EQ(4U, contents->Length());
+ CHECK_EQ(1, contents->Get(0).As<v8::Int32>()->Value());
+ CHECK_EQ(2, contents->Get(1).As<v8::Int32>()->Value());
+ CHECK_EQ(3, contents->Get(2).As<v8::Int32>()->Value());
+ CHECK_EQ(4, contents->Get(3).As<v8::Int32>()->Value());
+
+ map = v8::Map::FromArray(env.local(), contents).ToLocalChecked();
+ CHECK_EQ(2U, map->Size());
+
+ CHECK(map->Has(env.local(), v8::Integer::New(isolate, 1)).FromJust());
+ CHECK(map->Has(env.local(), v8::Integer::New(isolate, 3)).FromJust());
+
+ CHECK(!map->Has(env.local(), v8::Integer::New(isolate, 2)).FromJust());
+ CHECK(!map->Has(env.local(), map).FromJust());
+
+ CHECK_EQ(2, map->Get(env.local(), v8::Integer::New(isolate, 1))
+ .ToLocalChecked()
+ ->Int32Value());
+ CHECK_EQ(4, map->Get(env.local(), v8::Integer::New(isolate, 3))
+ .ToLocalChecked()
+ ->Int32Value());
+
+ CHECK(map->Get(env.local(), v8::Integer::New(isolate, 42))
+ .ToLocalChecked()
+ ->IsUndefined());
+
+ CHECK(!map->Set(env.local(), map, map).IsEmpty());
+ CHECK_EQ(3U, map->Size());
+ CHECK(map->Has(env.local(), map).FromJust());
+
+ CHECK(map->Delete(env.local(), map).FromJust());
+ CHECK_EQ(2U, map->Size());
+ CHECK(!map->Has(env.local(), map).FromJust());
+ CHECK(!map->Delete(env.local(), map).FromJust());
+
+ map->Clear();
+ CHECK_EQ(0U, map->Size());
+}
+
+
+TEST(MapFromArrayOddLength) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+ // Odd lengths result in a null MaybeLocal.
+ Local<v8::Array> contents = v8::Array::New(isolate, 41);
+ CHECK(v8::Map::FromArray(env.local(), contents).IsEmpty());
+}
+
+
+TEST(Set) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+
+ v8::Local<v8::Set> set = v8::Set::New(isolate);
+ CHECK(set->IsObject());
+ CHECK(set->IsSet());
+ CHECK(set->GetPrototype()->StrictEquals(CompileRun("Set.prototype")));
+ CHECK_EQ(0U, set->Size());
+
+ v8::Local<v8::Value> val = CompileRun("new Set([1, 2])");
+ CHECK(val->IsSet());
+ set = v8::Local<v8::Set>::Cast(val);
+ CHECK_EQ(2U, set->Size());
+
+ v8::Local<v8::Array> keys = set->AsArray();
+ CHECK_EQ(2U, keys->Length());
+ CHECK_EQ(1, keys->Get(0).As<v8::Int32>()->Value());
+ CHECK_EQ(2, keys->Get(1).As<v8::Int32>()->Value());
+
+ set = v8::Set::FromArray(env.local(), keys).ToLocalChecked();
+ CHECK_EQ(2U, set->Size());
+
+ CHECK(set->Has(env.local(), v8::Integer::New(isolate, 1)).FromJust());
+ CHECK(set->Has(env.local(), v8::Integer::New(isolate, 2)).FromJust());
+
+ CHECK(!set->Has(env.local(), v8::Integer::New(isolate, 3)).FromJust());
+ CHECK(!set->Has(env.local(), set).FromJust());
+
+ CHECK(!set->Add(env.local(), set).IsEmpty());
+ CHECK_EQ(3U, set->Size());
+ CHECK(set->Has(env.local(), set).FromJust());
+
+ CHECK(set->Delete(env.local(), set).FromJust());
+ CHECK_EQ(2U, set->Size());
+ CHECK(!set->Has(env.local(), set).FromJust());
+ CHECK(!set->Delete(env.local(), set).FromJust());
+
+ set->Clear();
+ CHECK_EQ(0U, set->Size());
+}
+
+
TEST(CompatibleReceiverCheckOnCachedICHandler) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
diff --git a/deps/v8/test/cctest/test-assembler-arm.cc b/deps/v8/test/cctest/test-assembler-arm.cc
index 059c04ad40..8f93150fad 100644
--- a/deps/v8/test/cctest/test-assembler-arm.cc
+++ b/deps/v8/test/cctest/test-assembler-arm.cc
@@ -175,17 +175,17 @@ TEST(3) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
__ mov(r4, Operand(r0));
- __ ldr(r0, MemOperand(r4, OFFSET_OF(T, i)));
+ __ ldr(r0, MemOperand(r4, offsetof(T, i)));
__ mov(r2, Operand(r0, ASR, 1));
- __ str(r2, MemOperand(r4, OFFSET_OF(T, i)));
- __ ldrsb(r2, MemOperand(r4, OFFSET_OF(T, c)));
+ __ str(r2, MemOperand(r4, offsetof(T, i)));
+ __ ldrsb(r2, MemOperand(r4, offsetof(T, c)));
__ add(r0, r2, Operand(r0));
__ mov(r2, Operand(r2, LSL, 2));
- __ strb(r2, MemOperand(r4, OFFSET_OF(T, c)));
- __ ldrsh(r2, MemOperand(r4, OFFSET_OF(T, s)));
+ __ strb(r2, MemOperand(r4, offsetof(T, c)));
+ __ ldrsh(r2, MemOperand(r4, offsetof(T, s)));
__ add(r0, r2, Operand(r0));
__ mov(r2, Operand(r2, ASR, 3));
- __ strh(r2, MemOperand(r4, OFFSET_OF(T, s)));
+ __ strh(r2, MemOperand(r4, offsetof(T, s)));
__ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
CodeDesc desc;
@@ -247,68 +247,68 @@ TEST(4) {
__ sub(fp, ip, Operand(4));
__ mov(r4, Operand(r0));
- __ vldr(d6, r4, OFFSET_OF(T, a));
- __ vldr(d7, r4, OFFSET_OF(T, b));
+ __ vldr(d6, r4, offsetof(T, a));
+ __ vldr(d7, r4, offsetof(T, b));
__ vadd(d5, d6, d7);
- __ vstr(d5, r4, OFFSET_OF(T, c));
+ __ vstr(d5, r4, offsetof(T, c));
__ vmla(d5, d6, d7);
__ vmls(d5, d5, d6);
__ vmov(r2, r3, d5);
__ vmov(d4, r2, r3);
- __ vstr(d4, r4, OFFSET_OF(T, b));
+ __ vstr(d4, r4, offsetof(T, b));
// Load t.x and t.y, switch values, and store back to the struct.
- __ vldr(s0, r4, OFFSET_OF(T, x));
- __ vldr(s31, r4, OFFSET_OF(T, y));
+ __ vldr(s0, r4, offsetof(T, x));
+ __ vldr(s31, r4, offsetof(T, y));
__ vmov(s16, s0);
__ vmov(s0, s31);
__ vmov(s31, s16);
- __ vstr(s0, r4, OFFSET_OF(T, x));
- __ vstr(s31, r4, OFFSET_OF(T, y));
+ __ vstr(s0, r4, offsetof(T, x));
+ __ vstr(s31, r4, offsetof(T, y));
// Move a literal into a register that can be encoded in the instruction.
__ vmov(d4, 1.0);
- __ vstr(d4, r4, OFFSET_OF(T, e));
+ __ vstr(d4, r4, offsetof(T, e));
// Move a literal into a register that requires 64 bits to encode.
// 0x3ff0000010000000 = 1.000000059604644775390625
__ vmov(d4, 1.000000059604644775390625);
- __ vstr(d4, r4, OFFSET_OF(T, d));
+ __ vstr(d4, r4, offsetof(T, d));
// Convert from floating point to integer.
__ vmov(d4, 2.0);
__ vcvt_s32_f64(s31, d4);
- __ vstr(s31, r4, OFFSET_OF(T, i));
+ __ vstr(s31, r4, offsetof(T, i));
// Convert from integer to floating point.
__ mov(lr, Operand(42));
__ vmov(s31, lr);
__ vcvt_f64_s32(d4, s31);
- __ vstr(d4, r4, OFFSET_OF(T, f));
+ __ vstr(d4, r4, offsetof(T, f));
// Convert from fixed point to floating point.
__ mov(lr, Operand(2468));
__ vmov(s8, lr);
__ vcvt_f64_s32(d4, 2);
- __ vstr(d4, r4, OFFSET_OF(T, j));
+ __ vstr(d4, r4, offsetof(T, j));
// Test vabs.
- __ vldr(d1, r4, OFFSET_OF(T, g));
+ __ vldr(d1, r4, offsetof(T, g));
__ vabs(d0, d1);
- __ vstr(d0, r4, OFFSET_OF(T, g));
- __ vldr(d2, r4, OFFSET_OF(T, h));
+ __ vstr(d0, r4, offsetof(T, g));
+ __ vldr(d2, r4, offsetof(T, h));
__ vabs(d0, d2);
- __ vstr(d0, r4, OFFSET_OF(T, h));
+ __ vstr(d0, r4, offsetof(T, h));
// Test vneg.
- __ vldr(d1, r4, OFFSET_OF(T, m));
+ __ vldr(d1, r4, offsetof(T, m));
__ vneg(d0, d1);
- __ vstr(d0, r4, OFFSET_OF(T, m));
- __ vldr(d1, r4, OFFSET_OF(T, n));
+ __ vstr(d0, r4, offsetof(T, m));
+ __ vldr(d1, r4, offsetof(T, n));
__ vneg(d0, d1);
- __ vstr(d0, r4, OFFSET_OF(T, n));
+ __ vstr(d0, r4, offsetof(T, n));
__ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
@@ -647,19 +647,19 @@ TEST(8) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
- __ add(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(D, a))));
__ vldm(ia_w, r4, d0, d3);
__ vldm(ia_w, r4, d4, d7);
- __ add(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(D, a))));
__ vstm(ia_w, r4, d6, d7);
__ vstm(ia_w, r4, d0, d5);
- __ add(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ add(r4, r1, Operand(static_cast<int32_t>(offsetof(F, a))));
__ vldm(ia_w, r4, s0, s3);
__ vldm(ia_w, r4, s4, s7);
- __ add(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ add(r4, r1, Operand(static_cast<int32_t>(offsetof(F, a))));
__ vstm(ia_w, r4, s6, s7);
__ vstm(ia_w, r4, s0, s5);
@@ -753,22 +753,22 @@ TEST(9) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
- __ add(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(D, a))));
__ vldm(ia, r4, d0, d3);
__ add(r4, r4, Operand(4 * 8));
__ vldm(ia, r4, d4, d7);
- __ add(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(D, a))));
__ vstm(ia, r4, d6, d7);
__ add(r4, r4, Operand(2 * 8));
__ vstm(ia, r4, d0, d5);
- __ add(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ add(r4, r1, Operand(static_cast<int32_t>(offsetof(F, a))));
__ vldm(ia, r4, s0, s3);
__ add(r4, r4, Operand(4 * 4));
__ vldm(ia, r4, s4, s7);
- __ add(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ add(r4, r1, Operand(static_cast<int32_t>(offsetof(F, a))));
__ vstm(ia, r4, s6, s7);
__ add(r4, r4, Operand(2 * 4));
__ vstm(ia, r4, s0, s5);
@@ -863,19 +863,19 @@ TEST(10) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
- __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(D, h)) + 8));
__ vldm(db_w, r4, d4, d7);
__ vldm(db_w, r4, d0, d3);
- __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(D, h)) + 8));
__ vstm(db_w, r4, d0, d5);
__ vstm(db_w, r4, d6, d7);
- __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4));
+ __ add(r4, r1, Operand(static_cast<int32_t>(offsetof(F, h)) + 4));
__ vldm(db_w, r4, s4, s7);
__ vldm(db_w, r4, s0, s3);
- __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4));
+ __ add(r4, r1, Operand(static_cast<int32_t>(offsetof(F, h)) + 4));
__ vstm(db_w, r4, s0, s5);
__ vstm(db_w, r4, s6, s7);
@@ -951,28 +951,28 @@ TEST(11) {
Assembler assm(isolate, NULL, 0);
// Test HeapObject untagging.
- __ ldr(r1, MemOperand(r0, OFFSET_OF(I, a)));
+ __ ldr(r1, MemOperand(r0, offsetof(I, a)));
__ mov(r1, Operand(r1, ASR, 1), SetCC);
__ adc(r1, r1, Operand(r1), LeaveCC, cs);
- __ str(r1, MemOperand(r0, OFFSET_OF(I, a)));
+ __ str(r1, MemOperand(r0, offsetof(I, a)));
- __ ldr(r2, MemOperand(r0, OFFSET_OF(I, b)));
+ __ ldr(r2, MemOperand(r0, offsetof(I, b)));
__ mov(r2, Operand(r2, ASR, 1), SetCC);
__ adc(r2, r2, Operand(r2), LeaveCC, cs);
- __ str(r2, MemOperand(r0, OFFSET_OF(I, b)));
+ __ str(r2, MemOperand(r0, offsetof(I, b)));
// Test corner cases.
__ mov(r1, Operand(0xffffffff));
__ mov(r2, Operand::Zero());
__ mov(r3, Operand(r1, ASR, 1), SetCC); // Set the carry.
__ adc(r3, r1, Operand(r2));
- __ str(r3, MemOperand(r0, OFFSET_OF(I, c)));
+ __ str(r3, MemOperand(r0, offsetof(I, c)));
__ mov(r1, Operand(0xffffffff));
__ mov(r2, Operand::Zero());
__ mov(r3, Operand(r2, ASR, 1), SetCC); // Unset the carry.
__ adc(r3, r1, Operand(r2));
- __ str(r3, MemOperand(r0, OFFSET_OF(I, d)));
+ __ str(r3, MemOperand(r0, offsetof(I, d)));
__ mov(pc, Operand(lr));
@@ -1048,9 +1048,9 @@ TEST(13) {
// Load a, b, c into d16, d17, d18.
__ mov(r4, Operand(r0));
- __ vldr(d16, r4, OFFSET_OF(T, a));
- __ vldr(d17, r4, OFFSET_OF(T, b));
- __ vldr(d18, r4, OFFSET_OF(T, c));
+ __ vldr(d16, r4, offsetof(T, a));
+ __ vldr(d17, r4, offsetof(T, b));
+ __ vldr(d18, r4, offsetof(T, c));
__ vneg(d25, d16);
__ vadd(d25, d25, d17);
@@ -1066,12 +1066,12 @@ TEST(13) {
// Store d16, d17, d18 into a, b, c.
__ mov(r4, Operand(r0));
- __ vstr(d16, r4, OFFSET_OF(T, a));
- __ vstr(d17, r4, OFFSET_OF(T, b));
- __ vstr(d18, r4, OFFSET_OF(T, c));
+ __ vstr(d16, r4, offsetof(T, a));
+ __ vstr(d17, r4, offsetof(T, b));
+ __ vstr(d18, r4, offsetof(T, c));
// Load x, y, z into d29-d31.
- __ add(r4, r0, Operand(OFFSET_OF(T, x)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, x))));
__ vldm(ia_w, r4, d29, d31);
// Swap d29 and d30 via r registers.
@@ -1084,7 +1084,7 @@ TEST(13) {
__ vcvt_f64_u32(d31, s1);
// Store d29-d31 into x, y, z.
- __ add(r4, r0, Operand(OFFSET_OF(T, x)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, x))));
__ vstm(ia_w, r4, d29, d31);
// Move constants into d20, d21, d22 and store into i, j, k.
@@ -1094,13 +1094,13 @@ TEST(13) {
__ mov(r2, Operand(1079146608));
__ vmov(d22, VmovIndexLo, r1);
__ vmov(d22, VmovIndexHi, r2);
- __ add(r4, r0, Operand(OFFSET_OF(T, i)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i))));
__ vstm(ia_w, r4, d20, d22);
// Move d22 into low and high.
__ vmov(r4, VmovIndexLo, d22);
- __ str(r4, MemOperand(r0, OFFSET_OF(T, low)));
+ __ str(r4, MemOperand(r0, offsetof(T, low)));
__ vmov(r4, VmovIndexHi, d22);
- __ str(r4, MemOperand(r0, OFFSET_OF(T, high)));
+ __ str(r4, MemOperand(r0, offsetof(T, high)));
__ ldm(ia_w, sp, r4.bit() | pc.bit());
@@ -1164,16 +1164,16 @@ TEST(14) {
__ vmsr(r1);
__ bind(&fpscr_done);
- __ vldr(d0, r0, OFFSET_OF(T, left));
- __ vldr(d1, r0, OFFSET_OF(T, right));
+ __ vldr(d0, r0, offsetof(T, left));
+ __ vldr(d1, r0, offsetof(T, right));
__ vadd(d2, d0, d1);
- __ vstr(d2, r0, OFFSET_OF(T, add_result));
+ __ vstr(d2, r0, offsetof(T, add_result));
__ vsub(d2, d0, d1);
- __ vstr(d2, r0, OFFSET_OF(T, sub_result));
+ __ vstr(d2, r0, offsetof(T, sub_result));
__ vmul(d2, d0, d1);
- __ vstr(d2, r0, OFFSET_OF(T, mul_result));
+ __ vstr(d2, r0, offsetof(T, mul_result));
__ vdiv(d2, d0, d1);
- __ vstr(d2, r0, OFFSET_OF(T, div_result));
+ __ vstr(d2, r0, offsetof(T, div_result));
__ mov(pc, Operand(lr));
@@ -1264,23 +1264,23 @@ TEST(15) {
__ stm(db_w, sp, r4.bit() | lr.bit());
// Move 32 bytes with neon.
- __ add(r4, r0, Operand(OFFSET_OF(T, src0)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, src0))));
__ vld1(Neon8, NeonListOperand(d0, 4), NeonMemOperand(r4));
- __ add(r4, r0, Operand(OFFSET_OF(T, dst0)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, dst0))));
__ vst1(Neon8, NeonListOperand(d0, 4), NeonMemOperand(r4));
// Expand 8 bytes into 8 words(16 bits).
- __ add(r4, r0, Operand(OFFSET_OF(T, srcA0)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, srcA0))));
__ vld1(Neon8, NeonListOperand(d0), NeonMemOperand(r4));
__ vmovl(NeonU8, q0, d0);
- __ add(r4, r0, Operand(OFFSET_OF(T, dstA0)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, dstA0))));
__ vst1(Neon8, NeonListOperand(d0, 2), NeonMemOperand(r4));
// The same expansion, but with different source and destination registers.
- __ add(r4, r0, Operand(OFFSET_OF(T, srcA0)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, srcA0))));
__ vld1(Neon8, NeonListOperand(d1), NeonMemOperand(r4));
__ vmovl(NeonU8, q1, d1);
- __ add(r4, r0, Operand(OFFSET_OF(T, dstA4)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, dstA4))));
__ vst1(Neon8, NeonListOperand(d2, 2), NeonMemOperand(r4));
__ ldm(ia_w, sp, r4.bit() | pc.bit());
@@ -1367,24 +1367,24 @@ TEST(16) {
__ stm(db_w, sp, r4.bit() | lr.bit());
__ mov(r4, Operand(r0));
- __ ldr(r0, MemOperand(r4, OFFSET_OF(T, src0)));
- __ ldr(r1, MemOperand(r4, OFFSET_OF(T, src1)));
+ __ ldr(r0, MemOperand(r4, offsetof(T, src0)));
+ __ ldr(r1, MemOperand(r4, offsetof(T, src1)));
__ pkhbt(r2, r0, Operand(r1, LSL, 8));
- __ str(r2, MemOperand(r4, OFFSET_OF(T, dst0)));
+ __ str(r2, MemOperand(r4, offsetof(T, dst0)));
__ pkhtb(r2, r0, Operand(r1, ASR, 8));
- __ str(r2, MemOperand(r4, OFFSET_OF(T, dst1)));
+ __ str(r2, MemOperand(r4, offsetof(T, dst1)));
__ uxtb16(r2, r0, 8);
- __ str(r2, MemOperand(r4, OFFSET_OF(T, dst2)));
+ __ str(r2, MemOperand(r4, offsetof(T, dst2)));
__ uxtb(r2, r0, 8);
- __ str(r2, MemOperand(r4, OFFSET_OF(T, dst3)));
+ __ str(r2, MemOperand(r4, offsetof(T, dst3)));
- __ ldr(r0, MemOperand(r4, OFFSET_OF(T, src2)));
+ __ ldr(r0, MemOperand(r4, offsetof(T, src2)));
__ uxtab(r2, r0, r1, 8);
- __ str(r2, MemOperand(r4, OFFSET_OF(T, dst4)));
+ __ str(r2, MemOperand(r4, offsetof(T, dst4)));
__ ldm(ia_w, sp, r4.bit() | pc.bit());
@@ -1461,11 +1461,11 @@ TEST(sdiv) {
__ mov(r3, Operand(r0));
- __ ldr(r0, MemOperand(r3, OFFSET_OF(T, dividend)));
- __ ldr(r1, MemOperand(r3, OFFSET_OF(T, divisor)));
+ __ ldr(r0, MemOperand(r3, offsetof(T, dividend)));
+ __ ldr(r1, MemOperand(r3, offsetof(T, divisor)));
__ sdiv(r2, r0, r1);
- __ str(r2, MemOperand(r3, OFFSET_OF(T, result)));
+ __ str(r2, MemOperand(r3, offsetof(T, result)));
__ bx(lr);
@@ -1525,11 +1525,11 @@ TEST(udiv) {
__ mov(r3, Operand(r0));
- __ ldr(r0, MemOperand(r3, OFFSET_OF(T, dividend)));
- __ ldr(r1, MemOperand(r3, OFFSET_OF(T, divisor)));
+ __ ldr(r0, MemOperand(r3, offsetof(T, dividend)));
+ __ ldr(r1, MemOperand(r3, offsetof(T, divisor)));
__ sdiv(r2, r0, r1);
- __ str(r2, MemOperand(r3, OFFSET_OF(T, result)));
+ __ str(r2, MemOperand(r3, offsetof(T, result)));
__ bx(lr);
@@ -1917,29 +1917,29 @@ TEST(ARMv8_vrintX) {
__ mov(r4, Operand(r0));
// Test vrinta
- __ vldr(d6, r4, OFFSET_OF(T, input));
+ __ vldr(d6, r4, offsetof(T, input));
__ vrinta(d5, d6);
- __ vstr(d5, r4, OFFSET_OF(T, ar));
+ __ vstr(d5, r4, offsetof(T, ar));
// Test vrintn
- __ vldr(d6, r4, OFFSET_OF(T, input));
+ __ vldr(d6, r4, offsetof(T, input));
__ vrintn(d5, d6);
- __ vstr(d5, r4, OFFSET_OF(T, nr));
+ __ vstr(d5, r4, offsetof(T, nr));
// Test vrintp
- __ vldr(d6, r4, OFFSET_OF(T, input));
+ __ vldr(d6, r4, offsetof(T, input));
__ vrintp(d5, d6);
- __ vstr(d5, r4, OFFSET_OF(T, pr));
+ __ vstr(d5, r4, offsetof(T, pr));
// Test vrintm
- __ vldr(d6, r4, OFFSET_OF(T, input));
+ __ vldr(d6, r4, offsetof(T, input));
__ vrintm(d5, d6);
- __ vstr(d5, r4, OFFSET_OF(T, mr));
+ __ vstr(d5, r4, offsetof(T, mr));
// Test vrintz
- __ vldr(d6, r4, OFFSET_OF(T, input));
+ __ vldr(d6, r4, offsetof(T, input));
__ vrintz(d5, d6);
- __ vstr(d5, r4, OFFSET_OF(T, zr));
+ __ vstr(d5, r4, offsetof(T, zr));
__ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
diff --git a/deps/v8/test/cctest/test-assembler-mips.cc b/deps/v8/test/cctest/test-assembler-mips.cc
index 7a8beaa578..13abbbb447 100644
--- a/deps/v8/test/cctest/test-assembler-mips.cc
+++ b/deps/v8/test/cctest/test-assembler-mips.cc
@@ -278,61 +278,61 @@ TEST(MIPS3) {
Label L, C;
// Double precision floating point instructions.
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
__ add_d(f8, f4, f6);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, c)) ); // c = a + b.
+ __ sdc1(f8, MemOperand(a0, offsetof(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(f10, MemOperand(a0, offsetof(T, d)) ); // d = c - (-b).
- __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, b)) ); // b = a.
+ __ sdc1(f4, MemOperand(a0, offsetof(T, b)) ); // b = a.
__ li(t0, 120);
__ mtc1(t0, 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.
+ __ sdc1(f10, MemOperand(a0, offsetof(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.
+ __ sdc1(f12, MemOperand(a0, offsetof(T, f)) ); // f = e / a = 120.44.
__ sqrt_d(f14, f12);
- __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, g)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(T, g)) );
// g = sqrt(f) = 10.97451593465515908537
if (IsMipsArchVariant(kMips32r2)) {
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, h)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, i)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, h)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, i)) );
__ madd_d(f14, f6, f4, f6);
- __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, h)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(T, h)) );
}
// Single precision floating point instructions.
- __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fa)) );
- __ lwc1(f6, MemOperand(a0, OFFSET_OF(T, fb)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fa)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(T, fb)) );
__ add_s(f8, f4, f6);
- __ swc1(f8, MemOperand(a0, OFFSET_OF(T, fc)) ); // fc = fa + fb.
+ __ swc1(f8, MemOperand(a0, offsetof(T, fc)) ); // fc = fa + fb.
__ neg_s(f10, f6); // -fb
__ sub_s(f10, f8, f10);
- __ swc1(f10, MemOperand(a0, OFFSET_OF(T, fd)) ); // fd = fc - (-fb).
+ __ swc1(f10, MemOperand(a0, offsetof(T, fd)) ); // fd = fc - (-fb).
- __ swc1(f4, MemOperand(a0, OFFSET_OF(T, fb)) ); // fb = fa.
+ __ swc1(f4, MemOperand(a0, offsetof(T, fb)) ); // fb = fa.
__ li(t0, 120);
__ mtc1(t0, f14);
__ cvt_s_w(f14, f14); // f14 = 120.0.
__ mul_s(f10, f10, f14);
- __ swc1(f10, MemOperand(a0, OFFSET_OF(T, fe)) ); // fe = fd * 120
+ __ swc1(f10, MemOperand(a0, offsetof(T, fe)) ); // fe = fd * 120
__ div_s(f12, f10, f4);
- __ swc1(f12, MemOperand(a0, OFFSET_OF(T, ff)) ); // ff = fe / fa
+ __ swc1(f12, MemOperand(a0, offsetof(T, ff)) ); // ff = fe / fa
__ sqrt_s(f14, f12);
- __ swc1(f14, MemOperand(a0, OFFSET_OF(T, fg)) );
+ __ swc1(f14, MemOperand(a0, offsetof(T, fg)) );
__ jr(ra);
__ nop();
@@ -398,8 +398,8 @@ TEST(MIPS4) {
Assembler assm(isolate, NULL, 0);
Label L, C;
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
// Swap f4 and f6, by using four integer registers, t0-t3.
if (!IsFp64Mode()) {
@@ -425,8 +425,8 @@ TEST(MIPS4) {
__ mthc1(t3, f4);
}
// Store the swapped f4 and f5 back to memory.
- __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, c)) );
+ __ sdc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ sdc1(f6, MemOperand(a0, offsetof(T, c)) );
__ jr(ra);
__ nop();
@@ -466,30 +466,30 @@ TEST(MIPS5) {
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(t0, MemOperand(a0, OFFSET_OF(T, i)) );
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, j)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, i)) );
+ __ lw(t1, MemOperand(a0, offsetof(T, j)) );
// Convert double in f4 to int in element i.
__ cvt_w_d(f8, f4);
__ mfc1(t2, f8);
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, i)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, i)) );
// Convert double in f6 to int in element j.
__ cvt_w_d(f10, f6);
__ mfc1(t3, f10);
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, j)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, j)) );
// Convert int in original i (t0) to double in a.
__ mtc1(t0, f12);
__ cvt_d_w(f0, f12);
- __ sdc1(f0, MemOperand(a0, OFFSET_OF(T, a)) );
+ __ sdc1(f0, MemOperand(a0, offsetof(T, a)) );
// Convert int in original j (t1) to double in b.
__ mtc1(t1, f14);
__ cvt_d_w(f2, f14);
- __ sdc1(f2, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ sdc1(f2, MemOperand(a0, offsetof(T, b)) );
__ jr(ra);
__ nop();
@@ -535,31 +535,31 @@ TEST(MIPS6) {
Label L, C;
// Basic word load/store.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, ui)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, r1)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, ui)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, r1)) );
// lh with positive data.
- __ lh(t1, MemOperand(a0, OFFSET_OF(T, ui)) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, r2)) );
+ __ lh(t1, MemOperand(a0, offsetof(T, ui)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, r2)) );
// lh with negative data.
- __ lh(t2, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, r3)) );
+ __ lh(t2, MemOperand(a0, offsetof(T, si)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, r3)) );
// lhu with negative data.
- __ lhu(t3, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, r4)) );
+ __ lhu(t3, MemOperand(a0, offsetof(T, si)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, r4)) );
// lb with negative data.
- __ lb(t4, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(t4, MemOperand(a0, OFFSET_OF(T, r5)) );
+ __ lb(t4, MemOperand(a0, offsetof(T, si)) );
+ __ sw(t4, MemOperand(a0, offsetof(T, r5)) );
// sh writes only 1/2 of word.
__ lui(t5, 0x3333);
__ ori(t5, t5, 0x3333);
- __ sw(t5, MemOperand(a0, OFFSET_OF(T, r6)) );
- __ lhu(t5, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sh(t5, MemOperand(a0, OFFSET_OF(T, r6)) );
+ __ sw(t5, MemOperand(a0, offsetof(T, r6)) );
+ __ lhu(t5, MemOperand(a0, offsetof(T, si)) );
+ __ sh(t5, MemOperand(a0, offsetof(T, r6)) );
__ jr(ra);
__ nop();
@@ -615,8 +615,8 @@ TEST(MIPS7) {
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)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
if (!IsMipsArchVariant(kMips32r6)) {
__ c(UN, D, f4, f6);
__ bc1f(&neither_is_nan);
@@ -625,7 +625,7 @@ TEST(MIPS7) {
__ bc1eqz(&neither_is_nan, f2);
}
__ nop();
- __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
+ __ sw(zero_reg, MemOperand(a0, offsetof(T, result)) );
__ Branch(&outa_here);
__ bind(&neither_is_nan);
@@ -642,12 +642,12 @@ TEST(MIPS7) {
}
__ nop();
- __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
+ __ sw(zero_reg, MemOperand(a0, offsetof(T, result)) );
__ Branch(&outa_here);
__ bind(&less_than);
__ Addu(t0, zero_reg, Operand(1));
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, result)) ); // Set true.
+ __ sw(t0, MemOperand(a0, offsetof(T, result)) ); // Set true.
// This test-case should have additional tests.
@@ -706,7 +706,7 @@ TEST(MIPS8) {
MacroAssembler assm(isolate, NULL, 0);
// Basic word load.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, input)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, input)) );
// ROTR instruction (called through the Ror macro).
__ Ror(t1, t0, 0x0004);
@@ -718,13 +718,13 @@ TEST(MIPS8) {
__ Ror(t7, t0, 0x001c);
// Basic word store.
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotr_4)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotr_8)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotr_12)) );
- __ sw(t4, MemOperand(a0, OFFSET_OF(T, result_rotr_16)) );
- __ sw(t5, MemOperand(a0, OFFSET_OF(T, result_rotr_20)) );
- __ sw(t6, MemOperand(a0, OFFSET_OF(T, result_rotr_24)) );
- __ sw(t7, MemOperand(a0, OFFSET_OF(T, result_rotr_28)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, result_rotr_4)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, result_rotr_8)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, result_rotr_12)) );
+ __ sw(t4, MemOperand(a0, offsetof(T, result_rotr_16)) );
+ __ sw(t5, MemOperand(a0, offsetof(T, result_rotr_20)) );
+ __ sw(t6, MemOperand(a0, offsetof(T, result_rotr_24)) );
+ __ sw(t7, MemOperand(a0, offsetof(T, result_rotr_28)) );
// ROTRV instruction (called through the Ror macro).
__ li(t7, 0x0004);
@@ -743,13 +743,13 @@ TEST(MIPS8) {
__ Ror(t7, t0, t7);
// Basic word store.
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotrv_4)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotrv_8)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotrv_12)) );
- __ sw(t4, MemOperand(a0, OFFSET_OF(T, result_rotrv_16)) );
- __ sw(t5, MemOperand(a0, OFFSET_OF(T, result_rotrv_20)) );
- __ sw(t6, MemOperand(a0, OFFSET_OF(T, result_rotrv_24)) );
- __ sw(t7, MemOperand(a0, OFFSET_OF(T, result_rotrv_28)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, result_rotrv_4)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, result_rotrv_8)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, result_rotrv_12)) );
+ __ sw(t4, MemOperand(a0, offsetof(T, result_rotrv_16)) );
+ __ sw(t5, MemOperand(a0, offsetof(T, result_rotrv_20)) );
+ __ sw(t6, MemOperand(a0, offsetof(T, result_rotrv_24)) );
+ __ sw(t7, MemOperand(a0, offsetof(T, result_rotrv_28)) );
__ jr(ra);
__ nop();
@@ -808,8 +808,9 @@ TEST(MIPS9) {
TEST(MIPS10) {
- // Test conversions between doubles and long integers.
- // Test hos the long ints map to FP regs pairs.
+ // Test conversions between doubles and words.
+ // Test maps double to FP reg pairs in fp32 mode
+ // and into FP reg in fp64 mode.
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
@@ -830,24 +831,32 @@ TEST(MIPS10) {
if (!IsMipsArchVariant(kMips32r2)) return;
// Load all structure elements to registers.
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, a)));
-
- // Save the raw bits of the double.
- __ mfc1(t0, f0);
- __ mfc1(t1, f1);
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, dbl_mant)));
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, dbl_exp)));
+ // (f0, f1) = a (fp32), f0 = a (fp64)
+ __ ldc1(f0, MemOperand(a0, offsetof(T, a)));
+
+ if (IsFp64Mode()) {
+ __ mfc1(t0, f0); // t0 = f0(31..0)
+ __ mfhc1(t1, f0); // t1 = sign_extend(f0(63..32))
+ __ sw(t0, MemOperand(a0, offsetof(T, dbl_mant))); // dbl_mant = t0
+ __ sw(t1, MemOperand(a0, offsetof(T, dbl_exp))); // dbl_exp = t1
+ } else {
+ // Save the raw bits of the double.
+ __ mfc1(t0, f0); // t0 = a1
+ __ mfc1(t1, f1); // t1 = a2
+ __ sw(t0, MemOperand(a0, offsetof(T, dbl_mant))); // dbl_mant = t0
+ __ sw(t1, MemOperand(a0, offsetof(T, dbl_exp))); // dbl_exp = t1
+ }
- // Convert double in f0 to long, save hi/lo parts.
- __ cvt_w_d(f0, f0);
- __ mfc1(t0, f0); // f0 has a 32-bits word.
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, word)));
+ // Convert double in f0 to word, save hi/lo parts.
+ __ cvt_w_d(f0, f0); // a_word = (word)a
+ __ mfc1(t0, f0); // f0 has a 32-bits word. t0 = a_word
+ __ sw(t0, MemOperand(a0, offsetof(T, word))); // word = a_word
- // Convert the b long integers to double b.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, b_word)));
+ // Convert the b word to double b.
+ __ lw(t0, MemOperand(a0, offsetof(T, b_word)));
__ mtc1(t0, f8); // f8 has a 32-bits word.
__ cvt_d_w(f10, f8);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, b)));
+ __ sdc1(f10, MemOperand(a0, offsetof(T, b)));
__ jr(ra);
__ nop();
@@ -861,7 +870,6 @@ TEST(MIPS10) {
t.b_word = 0x0ff00ff0; // 0x0FF00FF0 -> 0x as double.
Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
USE(dummy);
-
CHECK_EQ(static_cast<int32_t>(0x41DFFFFF), t.dbl_exp);
CHECK_EQ(static_cast<int32_t>(0xFF800000), t.dbl_mant);
CHECK_EQ(static_cast<int32_t>(0x7FFFFFFE), t.word);
@@ -903,80 +911,80 @@ TEST(MIPS11) {
Assembler assm(isolate, NULL, 0);
// Test all combinations of LWL and vAddr.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwl(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, lwl_0)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwl(t0, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, lwl_0)) );
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwl(t1, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, lwl_1)) );
+ __ lw(t1, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwl(t1, MemOperand(a0, offsetof(T, mem_init) + 1) );
+ __ sw(t1, MemOperand(a0, offsetof(T, lwl_1)) );
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwl(t2, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, lwl_2)) );
+ __ lw(t2, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwl(t2, MemOperand(a0, offsetof(T, mem_init) + 2) );
+ __ sw(t2, MemOperand(a0, offsetof(T, lwl_2)) );
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwl(t3, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, lwl_3)) );
+ __ lw(t3, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwl(t3, MemOperand(a0, offsetof(T, mem_init) + 3) );
+ __ sw(t3, MemOperand(a0, offsetof(T, lwl_3)) );
// Test all combinations of LWR and vAddr.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwr(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, lwr_0)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwr(t0, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, lwr_0)) );
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwr(t1, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, lwr_1)) );
+ __ lw(t1, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwr(t1, MemOperand(a0, offsetof(T, mem_init) + 1) );
+ __ sw(t1, MemOperand(a0, offsetof(T, lwr_1)) );
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwr(t2, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, lwr_2)) );
+ __ lw(t2, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwr(t2, MemOperand(a0, offsetof(T, mem_init) + 2) );
+ __ sw(t2, MemOperand(a0, offsetof(T, lwr_2)) );
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwr(t3, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, lwr_3)) );
+ __ lw(t3, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwr(t3, MemOperand(a0, offsetof(T, mem_init) + 3) );
+ __ sw(t3, MemOperand(a0, offsetof(T, lwr_3)) );
// Test all combinations of SWL and vAddr.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, swl_0)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swl(t0, MemOperand(a0, OFFSET_OF(T, swl_0)) );
-
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, swl_1)) );
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swl(t1, MemOperand(a0, OFFSET_OF(T, swl_1) + 1) );
-
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, swl_2)) );
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swl(t2, MemOperand(a0, OFFSET_OF(T, swl_2) + 2) );
-
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, swl_3)) );
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swl(t3, MemOperand(a0, OFFSET_OF(T, swl_3) + 3) );
+ __ lw(t0, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, swl_0)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swl(t0, MemOperand(a0, offsetof(T, swl_0)) );
+
+ __ lw(t1, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, swl_1)) );
+ __ lw(t1, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swl(t1, MemOperand(a0, offsetof(T, swl_1) + 1) );
+
+ __ lw(t2, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, swl_2)) );
+ __ lw(t2, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swl(t2, MemOperand(a0, offsetof(T, swl_2) + 2) );
+
+ __ lw(t3, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, swl_3)) );
+ __ lw(t3, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swl(t3, MemOperand(a0, offsetof(T, swl_3) + 3) );
// Test all combinations of SWR and vAddr.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, swr_0)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swr(t0, MemOperand(a0, OFFSET_OF(T, swr_0)) );
-
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, swr_1)) );
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swr(t1, MemOperand(a0, OFFSET_OF(T, swr_1) + 1) );
-
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, swr_2)) );
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swr(t2, MemOperand(a0, OFFSET_OF(T, swr_2) + 2) );
-
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, swr_3)) );
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swr(t3, MemOperand(a0, OFFSET_OF(T, swr_3) + 3) );
+ __ lw(t0, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, swr_0)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swr(t0, MemOperand(a0, offsetof(T, swr_0)) );
+
+ __ lw(t1, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, swr_1)) );
+ __ lw(t1, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swr(t1, MemOperand(a0, offsetof(T, swr_1) + 1) );
+
+ __ lw(t2, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, swr_2)) );
+ __ lw(t2, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swr(t2, MemOperand(a0, offsetof(T, swr_2) + 2) );
+
+ __ lw(t3, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, swr_3)) );
+ __ lw(t3, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swr(t3, MemOperand(a0, offsetof(T, swr_3) + 3) );
__ jr(ra);
__ nop();
@@ -1013,7 +1021,7 @@ TEST(MIPS11) {
CHECK_EQ(static_cast<int32_t>(0xccdd3344), t.swr_2);
CHECK_EQ(static_cast<int32_t>(0xdd223344), t.swr_3);
#elif __BYTE_ORDER == __BIG_ENDIAN
- 11223344, t.lwl_0);
+ CHECK_EQ(static_cast<int32_t>(0x11223344), t.lwl_0);
CHECK_EQ(static_cast<int32_t>(0x223344dd), t.lwl_1);
CHECK_EQ(static_cast<int32_t>(0x3344ccdd), t.lwl_2);
CHECK_EQ(static_cast<int32_t>(0x44bbccdd), t.lwl_3);
@@ -1057,8 +1065,8 @@ TEST(MIPS12) {
__ mov(t6, fp); // Save frame pointer.
__ mov(fp, a0); // Access struct T by fp.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, y)) );
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, y4)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, y)) );
+ __ lw(t3, MemOperand(a0, offsetof(T, y4)) );
__ addu(t1, t0, t3);
__ subu(t4, t0, t3);
@@ -1076,30 +1084,30 @@ TEST(MIPS12) {
__ push(t3);
__ pop(t4);
__ nop();
- __ sw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
- __ lw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ sw(t0, MemOperand(fp, offsetof(T, y)) );
+ __ lw(t0, MemOperand(fp, offsetof(T, y)) );
__ nop();
- __ sw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
- __ lw(t1, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ sw(t0, MemOperand(fp, offsetof(T, y)) );
+ __ lw(t1, MemOperand(fp, offsetof(T, y)) );
__ nop();
__ push(t1);
- __ lw(t1, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(t1, MemOperand(fp, offsetof(T, y)) );
__ pop(t1);
__ nop();
__ push(t1);
- __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(t2, MemOperand(fp, offsetof(T, y)) );
__ pop(t1);
__ nop();
__ push(t1);
- __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(t2, MemOperand(fp, offsetof(T, y)) );
__ pop(t2);
__ nop();
__ push(t2);
- __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(t2, MemOperand(fp, offsetof(T, y)) );
__ pop(t1);
__ nop();
__ push(t1);
- __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(t2, MemOperand(fp, offsetof(T, y)) );
__ pop(t3);
__ nop();
@@ -1144,19 +1152,19 @@ TEST(MIPS13) {
MacroAssembler assm(isolate, NULL, 0);
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_small_in)));
+ __ sw(t0, MemOperand(a0, offsetof(T, cvt_small_in)));
__ Cvt_d_uw(f10, t0, f22);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out)));
+ __ sdc1(f10, MemOperand(a0, offsetof(T, cvt_small_out)));
__ Trunc_uw_d(f10, f10, f22);
- __ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out)));
+ __ swc1(f10, MemOperand(a0, offsetof(T, trunc_small_out)));
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_big_in)));
+ __ sw(t0, MemOperand(a0, offsetof(T, cvt_big_in)));
__ Cvt_d_uw(f8, t0, f22);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out)));
+ __ sdc1(f8, MemOperand(a0, offsetof(T, cvt_big_out)));
__ Trunc_uw_d(f8, f8, f22);
- __ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out)));
+ __ swc1(f8, MemOperand(a0, offsetof(T, trunc_big_out)));
__ jr(ra);
__ nop();
@@ -1226,46 +1234,46 @@ TEST(MIPS14) {
// Disable FPU exceptions.
__ ctc1(zero_reg, FCSR);
#define RUN_ROUND_TEST(x) \
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_up_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, round_up_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_up_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, x##_up_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_down_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, round_down_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_down_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, x##_down_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_up_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, neg_round_up_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_up_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, neg_##x##_up_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_down_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, neg_round_down_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_down_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, neg_##x##_down_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err1_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(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))); \
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err1_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err2_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(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))); \
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err2_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err3_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(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))); \
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err3_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err4_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(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)));
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err4_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, x##_invalid_result)));
RUN_ROUND_TEST(round)
RUN_ROUND_TEST(floor)
@@ -1329,7 +1337,8 @@ TEST(MIPS15) {
}
-TEST(MIPS16) {
+// ----------------------mips32r6 specific tests----------------------
+TEST(seleqz_selnez) {
if (IsMipsArchVariant(kMips32r6)) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -1345,26 +1354,36 @@ TEST(MIPS16) {
double f;
double g;
double h;
+ float i;
+ float j;
+ float k;
+ float l;
} Test;
Test test;
// Integer part of test.
__ addiu(t1, zero_reg, 1); // t1 = 1
__ seleqz(t3, t1, zero_reg); // t3 = 1
- __ sw(t3, MemOperand(a0, OFFSET_OF(Test, a))); // a = 1
+ __ sw(t3, MemOperand(a0, offsetof(Test, a))); // a = 1
__ seleqz(t2, t1, t1); // t2 = 0
- __ sw(t2, MemOperand(a0, OFFSET_OF(Test, b))); // b = 0
+ __ sw(t2, MemOperand(a0, offsetof(Test, b))); // b = 0
__ selnez(t3, t1, zero_reg); // t3 = 1;
- __ sw(t3, MemOperand(a0, OFFSET_OF(Test, c))); // c = 0
+ __ sw(t3, MemOperand(a0, offsetof(Test, c))); // c = 0
__ selnez(t3, t1, t1); // t3 = 1
- __ sw(t3, MemOperand(a0, OFFSET_OF(Test, d))); // d = 1
+ __ sw(t3, MemOperand(a0, offsetof(Test, d))); // d = 1
// Floating point part of test.
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(Test, e)) ); // src
- __ ldc1(f2, MemOperand(a0, OFFSET_OF(Test, f)) ); // test
- __ seleqz(D, f4, f0, f2);
- __ selnez(D, f6, f0, f2);
- __ sdc1(f4, MemOperand(a0, OFFSET_OF(Test, g)) ); // src
- __ sdc1(f6, MemOperand(a0, OFFSET_OF(Test, h)) ); // src
+ __ ldc1(f0, MemOperand(a0, offsetof(Test, e)) ); // src
+ __ ldc1(f2, MemOperand(a0, offsetof(Test, f)) ); // test
+ __ lwc1(f8, MemOperand(a0, offsetof(Test, i)) ); // src
+ __ lwc1(f10, MemOperand(a0, offsetof(Test, j)) ); // test
+ __ seleqz_d(f4, f0, f2);
+ __ selnez_d(f6, f0, f2);
+ __ seleqz_s(f12, f8, f10);
+ __ selnez_s(f14, f8, f10);
+ __ sdc1(f4, MemOperand(a0, offsetof(Test, g)) ); // src
+ __ sdc1(f6, MemOperand(a0, offsetof(Test, h)) ); // src
+ __ swc1(f12, MemOperand(a0, offsetof(Test, k)) ); // src
+ __ swc1(f14, MemOperand(a0, offsetof(Test, l)) ); // src
__ jr(ra);
__ nop();
CodeDesc desc;
@@ -1383,31 +1402,44 @@ TEST(MIPS16) {
const int test_size = 3;
const int input_size = 5;
- double inputs[input_size] = {0.0, 65.2, -70.32,
+ double inputs_D[input_size] = {0.0, 65.2, -70.32,
18446744073709551621.0, -18446744073709551621.0};
- double outputs[input_size] = {0.0, 65.2, -70.32,
+ double outputs_D[input_size] = {0.0, 65.2, -70.32,
18446744073709551621.0, -18446744073709551621.0};
- double tests[test_size*2] = {2.8, 2.9, -2.8, -2.9,
+ double tests_D[test_size*2] = {2.8, 2.9, -2.8, -2.9,
18446744073709551616.0, 18446744073709555712.0};
+ float inputs_S[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ float outputs_S[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ float tests_S[test_size*2] = {2.9, 2.8, -2.9, -2.8,
+ 18446744073709551616.0, 18446746272732807168.0};
for (int j=0; j < test_size; j+=2) {
for (int i=0; i < input_size; i++) {
- test.e = inputs[i];
- test.f = tests[j];
+ test.e = inputs_D[i];
+ test.f = tests_D[j];
+ test.i = inputs_S[i];
+ test.j = tests_S[j];
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.g, outputs[i]);
+ CHECK_EQ(test.g, outputs_D[i]);
CHECK_EQ(test.h, 0);
+ CHECK_EQ(test.k, outputs_S[i]);
+ CHECK_EQ(test.l, 0);
- test.f = tests[j+1];
+ test.f = tests_D[j+1];
+ test.j = tests_S[j+1];
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.g, 0);
- CHECK_EQ(test.h, outputs[i]);
+ CHECK_EQ(test.h, outputs_D[i]);
+ CHECK_EQ(test.k, 0);
+ CHECK_EQ(test.l, outputs_S[i]);
}
}
}
}
-TEST(MIPS17) {
+TEST(min_max) {
if (IsMipsArchVariant(kMips32r6)) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -1419,16 +1451,38 @@ TEST(MIPS17) {
double b;
double c;
double d;
+ float e;
+ float f;
+ float g;
+ float h;
} TestFloat;
TestFloat test;
-
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a)));
- __ ldc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b)));
+ const double dblNaN = std::numeric_limits<double>::quiet_NaN();
+ const float fltNaN = std::numeric_limits<float>::quiet_NaN();
+ const int tableLength = 5;
+ double inputsa[tableLength] = {2.0, 3.0, dblNaN, 3.0, dblNaN};
+ double inputsb[tableLength] = {3.0, 2.0, 3.0, dblNaN, dblNaN};
+ double outputsdmin[tableLength] = {2.0, 2.0, 3.0, 3.0, dblNaN};
+ double outputsdmax[tableLength] = {3.0, 3.0, 3.0, 3.0, dblNaN};
+
+ float inputse[tableLength] = {2.0, 3.0, fltNaN, 3.0, fltNaN};
+ float inputsf[tableLength] = {3.0, 2.0, 3.0, fltNaN, fltNaN};
+ float outputsfmin[tableLength] = {2.0, 2.0, 3.0, 3.0, fltNaN};
+ float outputsfmax[tableLength] = {3.0, 3.0, 3.0, 3.0, fltNaN};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, e)));
+ __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, f)));
__ min_d(f10, f4, f8);
__ max_d(f12, f4, f8);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, c)));
- __ sdc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, d)));
+ __ min_s(f14, f2, f6);
+ __ max_s(f16, f2, f6);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, d)));
+ __ swc1(f14, MemOperand(a0, offsetof(TestFloat, g)));
+ __ swc1(f16, MemOperand(a0, offsetof(TestFloat, h)));
__ jr(ra);
__ nop();
@@ -1437,40 +1491,31 @@ TEST(MIPS17) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
- test.a = 2.0; // a goes to fs
- test.b = 3.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 2.0);
- CHECK_EQ(test.d, 3.0);
-
- test.a = 3.0; // a goes to fs
- test.b = 2.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 2.0);
- CHECK_EQ(test.d, 3.0);
-
- test.a = std::numeric_limits<double>::quiet_NaN();
- test.b = 3.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 3.0);
- CHECK_EQ(test.d, 3.0);
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputsa[i];
+ test.b = inputsb[i];
+ test.e = inputse[i];
+ test.f = inputsf[i];
- test.b = std::numeric_limits<double>::quiet_NaN();
- test.a = 3.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 3.0);
- CHECK_EQ(test.d, 3.0);
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- test.a = std::numeric_limits<double>::quiet_NaN();
- test.b = std::numeric_limits<double>::quiet_NaN();
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- DCHECK(std::isnan(test.c));
- DCHECK(std::isnan(test.d));
+ if (i < tableLength - 1) {
+ CHECK_EQ(test.c, outputsdmin[i]);
+ CHECK_EQ(test.d, outputsdmax[i]);
+ CHECK_EQ(test.g, outputsfmin[i]);
+ CHECK_EQ(test.h, outputsfmax[i]);
+ } else {
+ DCHECK(std::isnan(test.c));
+ DCHECK(std::isnan(test.d));
+ DCHECK(std::isnan(test.g));
+ DCHECK(std::isnan(test.h));
+ }
+ }
}
}
-TEST(MIPS18) {
+TEST(rint_d) {
if (IsMipsArchVariant(kMips32r6)) {
const int tableLength = 30;
CcTest::InitializeVM();
@@ -1548,12 +1593,191 @@ TEST(MIPS18) {
int fcsr_inputs[4] =
{kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(TestFloat, fcsr)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lw(t0, MemOperand(a0, offsetof(TestFloat, fcsr)) );
__ cfc1(t1, FCSR);
__ ctc1(t0, FCSR);
__ rint_d(f8, f4);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b)) );
+ __ sdc1(f8, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ ctc1(t1, 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());
+
+ for (int j = 0; j < 4; j++) {
+ test.fcsr = fcsr_inputs[j];
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, outputs[j][i]);
+ }
+ }
+ }
+}
+
+
+TEST(sel) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test {
+ double dd;
+ double ds;
+ double dt;
+ float fd;
+ float fs;
+ float ft;
+ } Test;
+
+ Test test;
+ __ ldc1(f0, MemOperand(a0, offsetof(Test, dd)) ); // test
+ __ ldc1(f2, MemOperand(a0, offsetof(Test, ds)) ); // src1
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, dt)) ); // src2
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, fd)) ); // test
+ __ lwc1(f8, MemOperand(a0, offsetof(Test, fs)) ); // src1
+ __ lwc1(f10, MemOperand(a0, offsetof(Test, ft)) ); // src2
+ __ sel_d(f0, f2, f4);
+ __ sel_s(f6, f8, f10);
+ __ sdc1(f0, MemOperand(a0, offsetof(Test, dd)) );
+ __ swc1(f6, MemOperand(a0, offsetof(Test, fd)) );
+ __ 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());
+
+ const int test_size = 3;
+ const int input_size = 5;
+
+ double inputs_dt[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ double inputs_ds[input_size] = {0.1, 69.88, -91.325,
+ 18446744073709551625.0, -18446744073709551625.0};
+ float inputs_ft[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ float inputs_fs[input_size] = {0.1, 69.88, -91.325,
+ 18446744073709551625.0, -18446744073709551625.0};
+ double tests_D[test_size*2] = {2.8, 2.9, -2.8, -2.9,
+ 18446744073709551616.0, 18446744073709555712.0};
+ float tests_S[test_size*2] = {2.9, 2.8, -2.9, -2.8,
+ 18446744073709551616.0, 18446746272732807168.0};
+ for (int j=0; j < test_size; j+=2) {
+ for (int i=0; i < input_size; i++) {
+ test.dt = inputs_dt[i];
+ test.dd = tests_D[j];
+ test.ds = inputs_ds[i];
+ test.ft = inputs_ft[i];
+ test.fd = tests_S[j];
+ test.fs = inputs_fs[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dd, inputs_ds[i]);
+ CHECK_EQ(test.fd, inputs_fs[i]);
+
+ test.dd = tests_D[j+1];
+ test.fd = tests_S[j+1];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dd, inputs_dt[i]);
+ CHECK_EQ(test.fd, inputs_ft[i]);
+ }
+ }
+ }
+}
+
+
+TEST(rint_s) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ const int tableLength = 30;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float b;
+ int fcsr;
+ }TestFloat;
+
+ TestFloat test;
+ float inputs[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E+38, 6.27463370218383111104242366943E-37,
+ 309485009821345068724781056.89,
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RN[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 0,
+ 309485009821345068724781057.0,
+ 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
+ -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RZ[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 0,
+ 309485009821345068724781057.0,
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RP[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 1,
+ 309485009821345068724781057.0,
+ 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RM[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 0,
+ 309485009821345068724781057.0,
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ int fcsr_inputs[4] =
+ {kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
+ float* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lw(t0, MemOperand(a0, offsetof(TestFloat, fcsr)) );
+ __ cfc1(t1, FCSR);
+ __ ctc1(t0, FCSR);
+ __ rint_s(f8, f4);
+ __ swc1(f8, MemOperand(a0, offsetof(TestFloat, b)) );
__ ctc1(t1, FCSR);
__ jr(ra);
__ nop();
@@ -1568,7 +1792,6 @@ TEST(MIPS18) {
test.fcsr = fcsr_inputs[j];
for (int i = 0; i < tableLength; i++) {
test.a = inputs[i];
- std::cout << j << " " << i << "\n";
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.b, outputs[j][i]);
}
@@ -1577,7 +1800,356 @@ TEST(MIPS18) {
}
-TEST(MIPS19) {
+TEST(mina_maxa) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ const int tableLength = 12;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ double b;
+ double resd;
+ double resd1;
+ float c;
+ float d;
+ float resf;
+ float resf1;
+ }TestFloat;
+
+ TestFloat test;
+ double inputsa[tableLength] = {
+ 5.3, 4.8, 6.1,
+ 9.8, 9.8, 9.8,
+ -10.0, -8.9, -9.8,
+ -10.0, -8.9, -9.8
+ };
+ double inputsb[tableLength] = {
+ 4.8, 5.3, 6.1,
+ -10.0, -8.9, -9.8,
+ 9.8, 9.8, 9.8,
+ -9.8, -11.2, -9.8
+ };
+ double resd[tableLength] = {
+ 4.8, 4.8, 6.1,
+ 9.8, -8.9, 9.8,
+ 9.8, -8.9, 9.8,
+ -9.8, -8.9, -9.8
+ };
+ double resd1[tableLength] = {
+ 5.3, 5.3, 6.1,
+ -10.0, 9.8, 9.8,
+ -10.0, 9.8, 9.8,
+ -10.0, -11.2, -9.8
+ };
+ float inputsc[tableLength] = {
+ 5.3, 4.8, 6.1,
+ 9.8, 9.8, 9.8,
+ -10.0, -8.9, -9.8,
+ -10.0, -8.9, -9.8
+ };
+ float inputsd[tableLength] = {
+ 4.8, 5.3, 6.1,
+ -10.0, -8.9, -9.8,
+ 9.8, 9.8, 9.8,
+ -9.8, -11.2, -9.8
+ };
+ float resf[tableLength] = {
+ 4.8, 4.8, 6.1,
+ 9.8, -8.9, 9.8,
+ 9.8, -8.9, 9.8,
+ -9.8, -8.9, -9.8
+ };
+ float resf1[tableLength] = {
+ 5.3, 5.3, 6.1,
+ -10.0, 9.8, 9.8,
+ -10.0, 9.8, 9.8,
+ -10.0, -11.2, -9.8
+ };
+
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ lwc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ lwc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ mina_d(f6, f2, f4);
+ __ mina_s(f12, f8, f10);
+ __ maxa_d(f14, f2, f4);
+ __ maxa_s(f16, f8, f10);
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, resf)) );
+ __ sdc1(f6, MemOperand(a0, offsetof(TestFloat, resd)) );
+ __ swc1(f16, MemOperand(a0, offsetof(TestFloat, resf1)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(TestFloat, resd1)) );
+ __ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputsa[i];
+ test.b = inputsb[i];
+ test.c = inputsc[i];
+ test.d = inputsd[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resd, resd[i]);
+ CHECK_EQ(test.resf, resf[i]);
+ CHECK_EQ(test.resd1, resd1[i]);
+ CHECK_EQ(test.resf1, resf1[i]);
+ }
+ }
+}
+
+
+// ----------------------mips32r2 specific tests----------------------
+TEST(trunc_l) {
+ if (IsMipsArchVariant(kMips32r2) && IsFp64Mode()) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c; // a trunc result
+ int64_t d; // b trunc result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ trunc_l_d(f8, f4);
+ __ trunc_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+ }
+}
+
+
+TEST(movz_movn) {
+ if (IsMipsArchVariant(kMips32r2)) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ int64_t rt;
+ double a;
+ double b;
+ double bold;
+ double b1;
+ double bold1;
+ float c;
+ float d;
+ float dold;
+ float d1;
+ float dold1;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ double inputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ float outputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+ double outputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ lw(t0, MemOperand(a0, offsetof(TestFloat, rt)) );
+ __ li(t1, 0x0);
+ __ mtc1(t1, f12);
+ __ mtc1(t1, f10);
+ __ mtc1(t1, f16);
+ __ mtc1(t1, f14);
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, bold)) );
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, dold)) );
+ __ sdc1(f16, MemOperand(a0, offsetof(TestFloat, bold1)) );
+ __ swc1(f14, MemOperand(a0, offsetof(TestFloat, dold1)) );
+ __ movz_s(f10, f6, t0);
+ __ movz_d(f12, f2, t0);
+ __ movn_s(f14, f6, t0);
+ __ movn_d(f16, f2, t0);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ swc1(f14, MemOperand(a0, offsetof(TestFloat, d1)) );
+ __ sdc1(f16, MemOperand(a0, offsetof(TestFloat, b1)) );
+ __ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.c = inputs_S[i];
+
+ test.rt = 1;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, test.bold);
+ CHECK_EQ(test.d, test.dold);
+ CHECK_EQ(test.b1, outputs_D[i]);
+ CHECK_EQ(test.d1, outputs_S[i]);
+
+ test.rt = 0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, outputs_D[i]);
+ CHECK_EQ(test.d, outputs_S[i]);
+ CHECK_EQ(test.b1, test.bold1);
+ CHECK_EQ(test.d1, test.dold1);
+ }
+ }
+}
+
+
+TEST(movt_movd) {
+ if (IsMipsArchVariant(kMips32r2)) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+
+ typedef struct test_float {
+ double srcd;
+ double dstd;
+ double dstdold;
+ double dstd1;
+ double dstdold1;
+ float srcf;
+ float dstf;
+ float dstfold;
+ float dstf1;
+ float dstfold1;
+ int32_t cc;
+ int32_t fcsr;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 5.3, -5.3, 20.8, -2.9
+ };
+ double inputs_S[tableLength] = {
+ 4.88, 4.8, -4.8, -0.29
+ };
+
+ float outputs_S[tableLength] = {
+ 4.88, 4.8, -4.8, -0.29
+ };
+ double outputs_D[tableLength] = {
+ 5.3, -5.3, 20.8, -2.9
+ };
+ int condition_flags[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+
+ for (int i = 0; i < tableLength; i++) {
+ test.srcd = inputs_D[i];
+ test.srcf = inputs_S[i];
+
+ for (int j = 0; j< 8; j++) {
+ test.cc = condition_flags[j];
+ if (test.cc == 0) {
+ test.fcsr = 1 << 23;
+ } else {
+ test.fcsr = 1 << (24+condition_flags[j]);
+ }
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, srcd)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, srcf)) );
+ __ lw(t1, MemOperand(a0, offsetof(TestFloat, fcsr)) );
+ __ cfc1(t0, FCSR);
+ __ ctc1(t1, FCSR);
+ __ li(t2, 0x0);
+ __ mtc1(t2, f12);
+ __ mtc1(t2, f10);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstdold)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstfold)) );
+ __ movt_s(f12, f4, test.cc);
+ __ movt_d(f10, f2, test.cc);
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstf)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstd)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstdold1)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstfold1)) );
+ __ movf_s(f12, f4, test.cc);
+ __ movf_d(f10, f2, test.cc);
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstf1)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstd1)) );
+ __ ctc1(t0, 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());
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dstf, outputs_S[i]);
+ CHECK_EQ(test.dstd, outputs_D[i]);
+ CHECK_EQ(test.dstf1, test.dstfold1);
+ CHECK_EQ(test.dstd1, test.dstdold1);
+ test.fcsr = 0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dstf, test.dstfold);
+ CHECK_EQ(test.dstd, test.dstdold);
+ CHECK_EQ(test.dstf1, outputs_S[i]);
+ CHECK_EQ(test.dstd1, outputs_D[i]);
+ }
+ }
+ }
+}
+
+
+// ----------------------tests for all archs--------------------------
+TEST(cvt_w_d) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
@@ -1628,12 +2200,12 @@ TEST(MIPS19) {
int fcsr_inputs[4] =
{kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, a)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(Test, fcsr)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lw(t0, MemOperand(a0, offsetof(Test, fcsr)) );
__ cfc1(t1, FCSR);
__ ctc1(t0, FCSR);
__ cvt_w_d(f8, f4);
- __ swc1(f8, MemOperand(a0, OFFSET_OF(Test, b)) );
+ __ swc1(f8, MemOperand(a0, offsetof(Test, b)) );
__ ctc1(t1, FCSR);
__ jr(ra);
__ nop();
@@ -1647,7 +2219,6 @@ TEST(MIPS19) {
test.fcsr = fcsr_inputs[j];
for (int i = 0; i < tableLength; i++) {
test.a = inputs[i];
- std::cout << i << " " << j << "\n";
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.b, outputs[j][i]);
}
@@ -1655,6 +2226,750 @@ TEST(MIPS19) {
}
+TEST(trunc_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a trunc result
+ int32_t d; // b trunc result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ trunc_w_d(f8, f4);
+ __ trunc_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(round_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a trunc result
+ int32_t d; // b trunc result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
+ -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ round_w_d(f8, f4);
+ __ round_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(round_l) {
+ if (IsFp64Mode()) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c;
+ int64_t d;
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
+ -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ round_l_d(f8, f4);
+ __ round_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+ }
+}
+
+
+TEST(sub) {
+ const int tableLength = 12;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float b;
+ float resultS;
+ double c;
+ double d;
+ double resultD;
+ }TestFloat;
+
+ TestFloat test;
+ double inputfs_D[tableLength] = {
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9
+ };
+ double inputft_D[tableLength] = {
+ 4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
+ -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
+ };
+ double outputs_D[tableLength] = {
+ 0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
+ 10.1, 10.1, 5.8, -0.5, 0.5, 0.0
+ };
+ float inputfs_S[tableLength] = {
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9
+ };
+ float inputft_S[tableLength] = {
+ 4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
+ -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
+ };
+ float outputs_S[tableLength] = {
+ 0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
+ 10.1, 10.1, 5.8, -0.5, 0.5, 0.0
+ };
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ ldc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ sub_s(f6, f2, f4);
+ __ sub_d(f12, f8, f10);
+ __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputfs_S[i];
+ test.b = inputft_S[i];
+ test.c = inputfs_D[i];
+ test.d = inputft_D[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resultS, outputs_S[i]);
+ CHECK_EQ(test.resultD, outputs_D[i]);
+ }
+}
+
+
+TEST(sqrt_rsqrt_recip) {
+ const int tableLength = 4;
+ const double deltaDouble = 2E-15;
+ const float deltaFloat = 2E-7;
+ const float sqrt2_s = sqrt(2);
+ const double sqrt2_d = sqrt(2);
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float resultS;
+ float resultS1;
+ float resultS2;
+ double c;
+ double resultD;
+ double resultD1;
+ double resultD2;
+ }TestFloat;
+ TestFloat test;
+
+ double inputs_D[tableLength] = {
+ 0.0L, 4.0L, 2.0L, 4e-28L
+ };
+
+ double outputs_D[tableLength] = {
+ 0.0L, 2.0L, sqrt2_d, 2e-14L
+ };
+ float inputs_S[tableLength] = {
+ 0.0, 4.0, 2.0, 4e-28
+ };
+
+ float outputs_S[tableLength] = {
+ 0.0, 2.0, sqrt2_s, 2e-14
+ };
+
+
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ sqrt_s(f6, f2);
+ __ sqrt_d(f12, f8);
+
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ __ rsqrt_d(f14, f8);
+ __ rsqrt_s(f16, f2);
+ __ recip_d(f18, f8);
+ __ recip_s(f20, f2);
+ }
+ __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ __ swc1(f16, MemOperand(a0, offsetof(TestFloat, resultS1)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(TestFloat, resultD1)) );
+ __ swc1(f20, MemOperand(a0, offsetof(TestFloat, resultS2)) );
+ __ sdc1(f18, MemOperand(a0, offsetof(TestFloat, resultD2)) );
+ }
+ __ 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());
+
+ for (int i = 0; i < tableLength; i++) {
+ float f1;
+ double d1;
+ test.a = inputs_S[i];
+ test.c = inputs_D[i];
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+
+ CHECK_EQ(test.resultS, outputs_S[i]);
+ CHECK_EQ(test.resultD, outputs_D[i]);
+
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ if (i != 0) {
+ f1 = test.resultS1 - 1.0F/outputs_S[i];
+ f1 = (f1 < 0) ? f1 : -f1;
+ CHECK(f1 <= deltaFloat);
+ d1 = test.resultD1 - 1.0L/outputs_D[i];
+ d1 = (d1 < 0) ? d1 : -d1;
+ CHECK(d1 <= deltaDouble);
+ f1 = test.resultS2 - 1.0F/inputs_S[i];
+ f1 = (f1 < 0) ? f1 : -f1;
+ CHECK(f1 <= deltaFloat);
+ d1 = test.resultD2 - 1.0L/inputs_D[i];
+ d1 = (d1 < 0) ? d1 : -d1;
+ CHECK(d1 <= deltaDouble);
+ } else {
+ CHECK_EQ(test.resultS1, 1.0F/outputs_S[i]);
+ CHECK_EQ(test.resultD1, 1.0L/outputs_D[i]);
+ CHECK_EQ(test.resultS2, 1.0F/inputs_S[i]);
+ CHECK_EQ(test.resultD2, 1.0L/inputs_D[i]);
+ }
+ }
+ }
+}
+
+
+TEST(neg) {
+ const int tableLength = 3;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float resultS;
+ double c;
+ double resultD;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 0.0, 4.0, -2.0
+ };
+
+ double outputs_D[tableLength] = {
+ 0.0, -4.0, 2.0
+ };
+ float inputs_S[tableLength] = {
+ 0.0, 4.0, -2.0
+ };
+
+ float outputs_S[tableLength] = {
+ 0.0, -4.0, 2.0
+ };
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ neg_s(f6, f2);
+ __ neg_d(f12, f8);
+ __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_S[i];
+ test.c = inputs_D[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resultS, outputs_S[i]);
+ CHECK_EQ(test.resultD, outputs_D[i]);
+ }
+}
+
+
+TEST(mul) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float b;
+ float resultS;
+ double c;
+ double d;
+ double resultD;
+ }TestFloat;
+
+ TestFloat test;
+ double inputfs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ double inputft_D[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ float inputfs_S[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ float inputft_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ mul_s(f10, f2, f4);
+ __ mul_d(f12, f6, f8);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputfs_S[i];
+ test.b = inputft_S[i];
+ test.c = inputfs_D[i];
+ test.d = inputft_D[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resultS, inputfs_S[i]*inputft_S[i]);
+ CHECK_EQ(test.resultD, inputfs_D[i]*inputft_D[i]);
+ }
+}
+
+
+TEST(mov) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ double b;
+ float c;
+ float d;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ double inputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ float outputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+ double outputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ mov_s(f18, f6);
+ __ mov_d(f20, f2);
+ __ swc1(f18, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ sdc1(f20, MemOperand(a0, offsetof(TestFloat, 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.c = inputs_S[i];
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, outputs_D[i]);
+ CHECK_EQ(test.d, outputs_S[i]);
+ }
+}
+
+
+TEST(floor_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a floor result
+ int32_t d; // b floor result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ floor_w_d(f8, f4);
+ __ floor_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(floor_l) {
+ if (IsFp64Mode()) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c;
+ int64_t d;
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ floor_l_d(f8, f4);
+ __ floor_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+ }
+}
+
+
+TEST(ceil_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a floor result
+ int32_t d; // b floor result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ ceil_w_d(f8, f4);
+ __ ceil_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(ceil_l) {
+ if (IsFp64Mode()) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c;
+ int64_t d;
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ ceil_l_d(f8, f4);
+ __ ceil_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+ }
+}
+
+
TEST(jump_tables1) {
// Test jump tables with forward jumps.
CcTest::InitializeVM();
@@ -1869,4 +3184,1879 @@ TEST(jump_tables3) {
}
+TEST(BITSWAP) {
+ // Test BITSWAP
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ int32_t r1;
+ int32_t r2;
+ int32_t r3;
+ int32_t r4;
+ } T;
+ T t;
+
+ Assembler assm(isolate, NULL, 0);
+
+ __ lw(a2, MemOperand(a0, offsetof(T, r1)));
+ __ nop();
+ __ bitswap(a1, a2);
+ __ sw(a1, MemOperand(a0, offsetof(T, r1)));
+
+ __ lw(a2, MemOperand(a0, offsetof(T, r2)));
+ __ nop();
+ __ bitswap(a1, a2);
+ __ sw(a1, MemOperand(a0, offsetof(T, r2)));
+
+ __ 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.r1 = 0x781A15C3;
+ t.r2 = 0x8B71FCDE;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(static_cast<int32_t>(0x1E58A8C3), t.r1);
+ CHECK_EQ(static_cast<int32_t>(0xD18E3F7B), t.r2);
+ }
+}
+
+
+TEST(class_fmt) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ // Test CLASS.fmt instruction.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ double dSignalingNan;
+ double dQuietNan;
+ double dNegInf;
+ double dNegNorm;
+ double dNegSubnorm;
+ double dNegZero;
+ double dPosInf;
+ double dPosNorm;
+ double dPosSubnorm;
+ double dPosZero;
+ float fSignalingNan;
+ float fQuietNan;
+ float fNegInf;
+ float fNegNorm;
+ float fNegSubnorm;
+ float fNegZero;
+ float fPosInf;
+ float fPosNorm;
+ float fPosSubnorm;
+ float fPosZero; } 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);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dSignalingNan)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dSignalingNan)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dQuietNan)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dQuietNan)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegInf)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegInf)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegNorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegNorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegSubnorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegSubnorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegZero)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegZero)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosInf)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosInf)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosNorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosNorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosSubnorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosSubnorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosZero)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosZero)));
+
+ // Testing instruction CLASS.S
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fSignalingNan)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fSignalingNan)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fQuietNan)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fQuietNan)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegInf)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegInf)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegNorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegNorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegSubnorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegSubnorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegZero)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegZero)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosInf)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosInf)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosNorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosNorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosSubnorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosSubnorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosZero)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosZero)));
+
+ __ 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.dSignalingNan = std::numeric_limits<double>::signaling_NaN();
+ t.dQuietNan = std::numeric_limits<double>::quiet_NaN();
+ t.dNegInf = -1.0 / 0.0;
+ t.dNegNorm = -5.0;
+ t.dNegSubnorm = -DBL_MIN / 2.0;
+ t.dNegZero = -0.0;
+ t.dPosInf = 2.0 / 0.0;
+ t.dPosNorm = 275.35;
+ t.dPosSubnorm = DBL_MIN / 2.0;
+ t.dPosZero = +0.0;
+ // Float test values
+
+ t.fSignalingNan = std::numeric_limits<float>::signaling_NaN();
+ t.fQuietNan = std::numeric_limits<float>::quiet_NaN();
+ t.fNegInf = -0.5/0.0;
+ t.fNegNorm = -FLT_MIN;
+ t.fNegSubnorm = -FLT_MIN / 1.5;
+ t.fNegZero = -0.0;
+ t.fPosInf = 100000.0 / 0.0;
+ t.fPosNorm = FLT_MAX;
+ t.fPosSubnorm = FLT_MIN / 20.0;
+ t.fPosZero = +0.0;
+
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+ // Expected double results.
+ CHECK_EQ(bit_cast<int64_t>(t.dSignalingNan), 0x001);
+ CHECK_EQ(bit_cast<int64_t>(t.dQuietNan), 0x002);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegInf), 0x004);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegNorm), 0x008);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegSubnorm), 0x010);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegZero), 0x020);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosInf), 0x040);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosNorm), 0x080);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosSubnorm), 0x100);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosZero), 0x200);
+
+ // Expected float results.
+ CHECK_EQ(bit_cast<int32_t>(t.fSignalingNan), 0x001);
+ CHECK_EQ(bit_cast<int32_t>(t.fQuietNan), 0x002);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegInf), 0x004);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegNorm), 0x008);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegSubnorm), 0x010);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegZero), 0x020);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosInf), 0x040);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosNorm), 0x080);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosSubnorm), 0x100);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosZero), 0x200);
+ }
+}
+
+
+TEST(ABS) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ int64_t fir;
+ double a;
+ float b;
+ double fcsr;
+ } TestFloat;
+
+ TestFloat test;
+
+ // Save FIR.
+ __ cfc1(a1, FCSR);
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
+ __ abs_d(f10, f4);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, a)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)));
+ __ abs_s(f10, f4);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, b)));
+
+ // 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());
+ test.a = -2.0;
+ test.b = -2.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, 2.0);
+ CHECK_EQ(test.b, 2.0);
+
+ test.a = 2.0;
+ test.b = 2.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, 2.0);
+ CHECK_EQ(test.b, 2.0);
+
+ // Testing biggest positive number
+ test.a = std::numeric_limits<double>::max();
+ test.b = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::max());
+ CHECK_EQ(test.b, std::numeric_limits<float>::max());
+
+ // Testing smallest negative number
+ test.a = -std::numeric_limits<double>::max(); // lowest()
+ test.b = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::max());
+ CHECK_EQ(test.b, std::numeric_limits<float>::max());
+
+ // Testing smallest positive number
+ test.a = -std::numeric_limits<double>::min();
+ test.b = -std::numeric_limits<float>::min();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::min());
+ CHECK_EQ(test.b, std::numeric_limits<float>::min());
+
+ // Testing infinity
+ test.a = -std::numeric_limits<double>::max()
+ / std::numeric_limits<double>::min();
+ test.b = -std::numeric_limits<float>::max()
+ / std::numeric_limits<float>::min();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::max()
+ / std::numeric_limits<double>::min());
+ CHECK_EQ(test.b, std::numeric_limits<float>::max()
+ / std::numeric_limits<float>::min());
+
+ test.a = std::numeric_limits<double>::quiet_NaN();
+ test.b = std::numeric_limits<float>::quiet_NaN();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isnan(test.a), true);
+ CHECK_EQ(std::isnan(test.b), true);
+
+ test.a = std::numeric_limits<double>::signaling_NaN();
+ test.b = std::numeric_limits<float>::signaling_NaN();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isnan(test.a), true);
+ CHECK_EQ(std::isnan(test.b), true);
+}
+
+
+TEST(ADD_FMT) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ double b;
+ double c;
+ float fa;
+ float fb;
+ float fc;
+ } TestFloat;
+
+ TestFloat test;
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
+ __ add_d(f10, f8, f4);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, fa)));
+ __ lwc1(f8, MemOperand(a0, offsetof(TestFloat, fb)));
+ __ add_s(f10, f8, f4);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, fc)));
+
+ __ 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());
+ test.a = 2.0;
+ test.b = 3.0;
+ test.fa = 2.0;
+ test.fb = 3.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, 5.0);
+ CHECK_EQ(test.fc, 5.0);
+
+ test.a = std::numeric_limits<double>::max();
+ test.b = -std::numeric_limits<double>::max(); // lowest()
+ test.fa = std::numeric_limits<float>::max();
+ test.fb = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, 0.0);
+ CHECK_EQ(test.fc, 0.0);
+
+ test.a = std::numeric_limits<double>::max();
+ test.b = std::numeric_limits<double>::max();
+ test.fa = std::numeric_limits<float>::max();
+ test.fb = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isfinite(test.c), false);
+ CHECK_EQ(std::isfinite(test.fc), false);
+
+ test.a = 5.0;
+ test.b = std::numeric_limits<double>::signaling_NaN();
+ test.fa = 5.0;
+ test.fb = std::numeric_limits<float>::signaling_NaN();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isnan(test.c), true);
+ CHECK_EQ(std::isnan(test.fc), true);
+}
+
+
+TEST(C_COND_FMT) {
+ if ((IsMipsArchVariant(kMips32r1)) || (IsMipsArchVariant(kMips32r2))) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double dOp1;
+ double dOp2;
+ uint32_t dF;
+ uint32_t dUn;
+ uint32_t dEq;
+ uint32_t dUeq;
+ uint32_t dOlt;
+ uint32_t dUlt;
+ uint32_t dOle;
+ uint32_t dUle;
+ float fOp1;
+ float fOp2;
+ uint32_t fF;
+ uint32_t fUn;
+ uint32_t fEq;
+ uint32_t fUeq;
+ uint32_t fOlt;
+ uint32_t fUlt;
+ uint32_t fOle;
+ uint32_t fUle;
+ } TestFloat;
+
+ TestFloat test;
+
+ __ li(t1, 1);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, dOp1)));
+ __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, dOp2)));
+
+ __ lwc1(f14, MemOperand(a0, offsetof(TestFloat, fOp1)));
+ __ lwc1(f16, MemOperand(a0, offsetof(TestFloat, fOp2)));
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(F, f4, f6, 0);
+ __ c_s(F, f14, f16, 2);
+ __ movt(t2, t1, 0);
+ __ movt(t3, t1, 2);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dF)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fF)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(UN, f4, f6, 2);
+ __ c_s(UN, f14, f16, 4);
+ __ movt(t2, t1, 2);
+ __ movt(t3, t1, 4);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUn)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUn)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(EQ, f4, f6, 4);
+ __ c_s(EQ, f14, f16, 6);
+ __ movt(t2, t1, 4);
+ __ movt(t3, t1, 6);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dEq)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fEq)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(UEQ, f4, f6, 6);
+ __ c_s(UEQ, f14, f16, 0);
+ __ movt(t2, t1, 6);
+ __ movt(t3, t1, 0);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUeq)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUeq)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(OLT, f4, f6, 0);
+ __ c_s(OLT, f14, f16, 2);
+ __ movt(t2, t1, 0);
+ __ movt(t3, t1, 2);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dOlt)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fOlt)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(ULT, f4, f6, 2);
+ __ c_s(ULT, f14, f16, 4);
+ __ movt(t2, t1, 2);
+ __ movt(t3, t1, 4);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUlt)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUlt)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(OLE, f4, f6, 4);
+ __ c_s(OLE, f14, f16, 6);
+ __ movt(t2, t1, 4);
+ __ movt(t3, t1, 6);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dOle)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fOle)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(ULE, f4, f6, 6);
+ __ c_s(ULE, f14, f16, 0);
+ __ movt(t2, t1, 6);
+ __ movt(t3, t1, 0);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUle)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUle)) );
+
+ __ 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());
+ test.dOp1 = 2.0;
+ test.dOp2 = 3.0;
+ test.fOp1 = 2.0;
+ test.fOp2 = 3.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 0U);
+ CHECK_EQ(test.dEq, 0U);
+ CHECK_EQ(test.dUeq, 0U);
+ CHECK_EQ(test.dOlt, 1U);
+ CHECK_EQ(test.dUlt, 1U);
+ CHECK_EQ(test.dOle, 1U);
+ CHECK_EQ(test.dUle, 1U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 0U);
+ CHECK_EQ(test.fEq, 0U);
+ CHECK_EQ(test.fUeq, 0U);
+ CHECK_EQ(test.fOlt, 1U);
+ CHECK_EQ(test.fUlt, 1U);
+ CHECK_EQ(test.fOle, 1U);
+ CHECK_EQ(test.fUle, 1U);
+
+ test.dOp1 = std::numeric_limits<double>::max();
+ test.dOp2 = std::numeric_limits<double>::min();
+ test.fOp1 = std::numeric_limits<float>::min();
+ test.fOp2 = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 0U);
+ CHECK_EQ(test.dEq, 0U);
+ CHECK_EQ(test.dUeq, 0U);
+ CHECK_EQ(test.dOlt, 0U);
+ CHECK_EQ(test.dUlt, 0U);
+ CHECK_EQ(test.dOle, 0U);
+ CHECK_EQ(test.dUle, 0U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 0U);
+ CHECK_EQ(test.fEq, 0U);
+ CHECK_EQ(test.fUeq, 0U);
+ CHECK_EQ(test.fOlt, 0U);
+ CHECK_EQ(test.fUlt, 0U);
+ CHECK_EQ(test.fOle, 0U);
+ CHECK_EQ(test.fUle, 0U);
+
+ test.dOp1 = -std::numeric_limits<double>::max(); // lowest()
+ test.dOp2 = -std::numeric_limits<double>::max(); // lowest()
+ test.fOp1 = std::numeric_limits<float>::max();
+ test.fOp2 = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 0U);
+ CHECK_EQ(test.dEq, 1U);
+ CHECK_EQ(test.dUeq, 1U);
+ CHECK_EQ(test.dOlt, 0U);
+ CHECK_EQ(test.dUlt, 0U);
+ CHECK_EQ(test.dOle, 1U);
+ CHECK_EQ(test.dUle, 1U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 0U);
+ CHECK_EQ(test.fEq, 1U);
+ CHECK_EQ(test.fUeq, 1U);
+ CHECK_EQ(test.fOlt, 0U);
+ CHECK_EQ(test.fUlt, 0U);
+ CHECK_EQ(test.fOle, 1U);
+ CHECK_EQ(test.fUle, 1U);
+
+ test.dOp1 = std::numeric_limits<double>::quiet_NaN();
+ test.dOp2 = 0.0;
+ test.fOp1 = std::numeric_limits<float>::quiet_NaN();
+ test.fOp2 = 0.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 1U);
+ CHECK_EQ(test.dEq, 0U);
+ CHECK_EQ(test.dUeq, 1U);
+ CHECK_EQ(test.dOlt, 0U);
+ CHECK_EQ(test.dUlt, 1U);
+ CHECK_EQ(test.dOle, 0U);
+ CHECK_EQ(test.dUle, 1U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 1U);
+ CHECK_EQ(test.fEq, 0U);
+ CHECK_EQ(test.fUeq, 1U);
+ CHECK_EQ(test.fOlt, 0U);
+ CHECK_EQ(test.fUlt, 1U);
+ CHECK_EQ(test.fOle, 0U);
+ CHECK_EQ(test.fUle, 1U);
+ }
+}
+
+
+TEST(CMP_COND_FMT) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double dOp1;
+ double dOp2;
+ double dF;
+ double dUn;
+ double dEq;
+ double dUeq;
+ double dOlt;
+ double dUlt;
+ double dOle;
+ double dUle;
+ double dOr;
+ double dUne;
+ double dNe;
+ float fOp1;
+ float fOp2;
+ float fF;
+ float fUn;
+ float fEq;
+ float fUeq;
+ float fOlt;
+ float fUlt;
+ float fOle;
+ float fUle;
+ float fOr;
+ float fUne;
+ float fNe;
+ } TestFloat;
+
+ TestFloat test;
+
+ __ li(t1, 1);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, dOp1)));
+ __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, dOp2)));
+
+ __ lwc1(f14, MemOperand(a0, offsetof(TestFloat, fOp1)));
+ __ lwc1(f16, MemOperand(a0, offsetof(TestFloat, fOp2)));
+
+ __ cmp_d(F, f2, f4, f6);
+ __ cmp_s(F, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dF)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fF)) );
+
+ __ cmp_d(UN, f2, f4, f6);
+ __ cmp_s(UN, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUn)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUn)) );
+
+ __ cmp_d(EQ, f2, f4, f6);
+ __ cmp_s(EQ, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dEq)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fEq)) );
+
+ __ cmp_d(UEQ, f2, f4, f6);
+ __ cmp_s(UEQ, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUeq)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUeq)) );
+
+ __ cmp_d(LT, f2, f4, f6);
+ __ cmp_s(LT, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOlt)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOlt)) );
+
+ __ cmp_d(ULT, f2, f4, f6);
+ __ cmp_s(ULT, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUlt)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUlt)) );
+
+ __ cmp_d(LE, f2, f4, f6);
+ __ cmp_s(LE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOle)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOle)) );
+
+ __ cmp_d(ULE, f2, f4, f6);
+ __ cmp_s(ULE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUle)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUle)) );
+
+ __ cmp_d(ORD, f2, f4, f6);
+ __ cmp_s(ORD, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOr)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOr)) );
+
+ __ cmp_d(UNE, f2, f4, f6);
+ __ cmp_s(UNE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUne)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUne)) );
+
+ __ cmp_d(NE, f2, f4, f6);
+ __ cmp_s(NE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dNe)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fNe)) );
+
+ __ 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());
+ uint64_t dTrue = 0xFFFFFFFFFFFFFFFF;
+ uint64_t dFalse = 0x0000000000000000;
+ uint32_t fTrue = 0xFFFFFFFF;
+ uint32_t fFalse = 0x00000000;
+
+ test.dOp1 = 2.0;
+ test.dOp2 = 3.0;
+ test.fOp1 = 2.0;
+ test.fOp2 = 3.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
+
+ test.dOp1 = std::numeric_limits<double>::max();
+ test.dOp2 = std::numeric_limits<double>::min();
+ test.fOp1 = std::numeric_limits<float>::min();
+ test.fOp2 = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fFalse);
+
+ test.dOp1 = -std::numeric_limits<double>::max(); // lowest()
+ test.dOp2 = -std::numeric_limits<double>::max(); // lowest()
+ test.fOp1 = std::numeric_limits<float>::max();
+ test.fOp2 = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
+
+ test.dOp1 = std::numeric_limits<double>::quiet_NaN();
+ test.dOp2 = 0.0;
+ test.fOp1 = std::numeric_limits<float>::quiet_NaN();
+ test.fOp2 = 0.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
+ }
+}
+
+
+TEST(CVT) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float cvt_d_s_in;
+ double cvt_d_s_out;
+ int32_t cvt_d_w_in;
+ double cvt_d_w_out;
+ int64_t cvt_d_l_in;
+ double cvt_d_l_out;
+
+ float cvt_l_s_in;
+ int64_t cvt_l_s_out;
+ double cvt_l_d_in;
+ int64_t cvt_l_d_out;
+
+ double cvt_s_d_in;
+ float cvt_s_d_out;
+ int32_t cvt_s_w_in;
+ float cvt_s_w_out;
+ int64_t cvt_s_l_in;
+ float cvt_s_l_out;
+
+ float cvt_w_s_in;
+ int32_t cvt_w_s_out;
+ double cvt_w_d_in;
+ int32_t cvt_w_d_out;
+ } TestFloat;
+
+ TestFloat test;
+
+ // Save FCSR.
+ __ cfc1(a1, FCSR);
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+
+#define GENERATE_CVT_TEST(x, y, z) \
+ __ y##c1(f0, MemOperand(a0, offsetof(TestFloat, x##_in))); \
+ __ x(f0, f0); \
+ __ nop(); \
+ __ z##c1(f0, MemOperand(a0, offsetof(TestFloat, x##_out)));
+
+ GENERATE_CVT_TEST(cvt_d_s, lw, sd)
+ GENERATE_CVT_TEST(cvt_d_w, lw, sd)
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ GENERATE_CVT_TEST(cvt_d_l, ld, sd)
+ }
+
+ if (IsFp64Mode()) {
+ GENERATE_CVT_TEST(cvt_l_s, lw, sd)
+ GENERATE_CVT_TEST(cvt_l_d, ld, sd)
+ }
+
+ GENERATE_CVT_TEST(cvt_s_d, ld, sw)
+ GENERATE_CVT_TEST(cvt_s_w, lw, sw)
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ GENERATE_CVT_TEST(cvt_s_l, ld, sw)
+ }
+
+ GENERATE_CVT_TEST(cvt_w_s, lw, sw)
+ GENERATE_CVT_TEST(cvt_w_d, ld, sw)
+
+ // 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());
+
+ test.cvt_d_s_in = -0.51;
+ test.cvt_d_w_in = -1;
+ test.cvt_d_l_in = -1;
+ test.cvt_l_s_in = -0.51;
+ test.cvt_l_d_in = -0.51;
+ test.cvt_s_d_in = -0.51;
+ test.cvt_s_w_in = -1;
+ test.cvt_s_l_in = -1;
+ test.cvt_w_s_in = -0.51;
+ test.cvt_w_d_in = -0.51;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ }
+ if (IsFp64Mode()) {
+ CHECK_EQ(test.cvt_l_s_out, -1);
+ CHECK_EQ(test.cvt_l_d_out, -1);
+ }
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ }
+ CHECK_EQ(test.cvt_w_s_out, -1);
+ CHECK_EQ(test.cvt_w_d_out, -1);
+
+
+ test.cvt_d_s_in = 0.49;
+ test.cvt_d_w_in = 1;
+ test.cvt_d_l_in = 1;
+ test.cvt_l_s_in = 0.49;
+ test.cvt_l_d_in = 0.49;
+ test.cvt_s_d_in = 0.49;
+ test.cvt_s_w_in = 1;
+ test.cvt_s_l_in = 1;
+ test.cvt_w_s_in = 0.49;
+ test.cvt_w_d_in = 0.49;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ }
+ if (IsFp64Mode()) {
+ CHECK_EQ(test.cvt_l_s_out, 0);
+ CHECK_EQ(test.cvt_l_d_out, 0);
+ }
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ }
+ CHECK_EQ(test.cvt_w_s_out, 0);
+ CHECK_EQ(test.cvt_w_d_out, 0);
+
+ test.cvt_d_s_in = std::numeric_limits<float>::max();
+ test.cvt_d_w_in = std::numeric_limits<int32_t>::max();
+ test.cvt_d_l_in = std::numeric_limits<int64_t>::max();
+ test.cvt_l_s_in = std::numeric_limits<float>::max();
+ test.cvt_l_d_in = std::numeric_limits<double>::max();
+ test.cvt_s_d_in = std::numeric_limits<double>::max();
+ test.cvt_s_w_in = std::numeric_limits<int32_t>::max();
+ test.cvt_s_l_in = std::numeric_limits<int64_t>::max();
+ test.cvt_w_s_in = std::numeric_limits<float>::max();
+ test.cvt_w_d_in = std::numeric_limits<double>::max();
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ }
+ if (IsFp64Mode()) {
+ CHECK_EQ(test.cvt_l_s_out, std::numeric_limits<int64_t>::max());
+ CHECK_EQ(test.cvt_l_d_out, std::numeric_limits<int64_t>::max());
+ }
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ }
+ CHECK_EQ(test.cvt_w_s_out, std::numeric_limits<int32_t>::max());
+ CHECK_EQ(test.cvt_w_d_out, std::numeric_limits<int32_t>::max());
+
+
+ test.cvt_d_s_in = -std::numeric_limits<float>::max(); // lowest()
+ test.cvt_d_w_in = std::numeric_limits<int32_t>::min(); // lowest()
+ test.cvt_d_l_in = std::numeric_limits<int64_t>::min(); // lowest()
+ test.cvt_l_s_in = -std::numeric_limits<float>::max(); // lowest()
+ test.cvt_l_d_in = -std::numeric_limits<double>::max(); // lowest()
+ test.cvt_s_d_in = -std::numeric_limits<double>::max(); // lowest()
+ test.cvt_s_w_in = std::numeric_limits<int32_t>::min(); // lowest()
+ test.cvt_s_l_in = std::numeric_limits<int64_t>::min(); // lowest()
+ test.cvt_w_s_in = -std::numeric_limits<float>::max(); // lowest()
+ test.cvt_w_d_in = -std::numeric_limits<double>::max(); // lowest()
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ }
+ // The returned value when converting from fixed-point to float-point
+ // is not consistent between board, simulator and specification
+ // in this test case, therefore modifying the test
+ if (IsFp64Mode()) {
+ CHECK(test.cvt_l_s_out == std::numeric_limits<int64_t>::min() ||
+ test.cvt_l_s_out == std::numeric_limits<int64_t>::max());
+ CHECK(test.cvt_l_d_out == std::numeric_limits<int64_t>::min() ||
+ test.cvt_l_d_out == std::numeric_limits<int64_t>::max());
+ }
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ }
+ CHECK(test.cvt_w_s_out == std::numeric_limits<int32_t>::min() ||
+ test.cvt_w_s_out == std::numeric_limits<int32_t>::max());
+ CHECK(test.cvt_w_d_out == std::numeric_limits<int32_t>::min() ||
+ test.cvt_w_d_out == std::numeric_limits<int32_t>::max());
+
+
+ test.cvt_d_s_in = std::numeric_limits<float>::min();
+ test.cvt_d_w_in = std::numeric_limits<int32_t>::min();
+ test.cvt_d_l_in = std::numeric_limits<int64_t>::min();
+ test.cvt_l_s_in = std::numeric_limits<float>::min();
+ test.cvt_l_d_in = std::numeric_limits<double>::min();
+ test.cvt_s_d_in = std::numeric_limits<double>::min();
+ test.cvt_s_w_in = std::numeric_limits<int32_t>::min();
+ test.cvt_s_l_in = std::numeric_limits<int64_t>::min();
+ test.cvt_w_s_in = std::numeric_limits<float>::min();
+ test.cvt_w_d_in = std::numeric_limits<double>::min();
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ }
+ if (IsFp64Mode()) {
+ CHECK_EQ(test.cvt_l_s_out, 0);
+ CHECK_EQ(test.cvt_l_d_out, 0);
+ }
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ }
+ CHECK_EQ(test.cvt_w_s_out, 0);
+ CHECK_EQ(test.cvt_w_d_out, 0);
+}
+
+
+TEST(DIV_FMT) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test {
+ double dOp1;
+ double dOp2;
+ double dRes;
+ float fOp1;
+ float fOp2;
+ float fRes;
+ } Test;
+
+ Test test;
+
+ // Save FCSR.
+ __ cfc1(a1, FCSR);
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, dOp1)) );
+ __ ldc1(f2, MemOperand(a0, offsetof(Test, dOp2)) );
+ __ nop();
+ __ div_d(f6, f4, f2);
+ __ sdc1(f6, MemOperand(a0, offsetof(Test, dRes)) );
+
+ __ lwc1(f4, MemOperand(a0, offsetof(Test, fOp1)) );
+ __ lwc1(f2, MemOperand(a0, offsetof(Test, fOp2)) );
+ __ nop();
+ __ div_s(f6, f4, f2);
+ __ swc1(f6, MemOperand(a0, offsetof(Test, fRes)) );
+
+ // 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());
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+
+ const int test_size = 3;
+
+ double dOp1[test_size] = {
+ 5.0,
+ DBL_MAX,
+ DBL_MAX,
+ };
+ double dOp2[test_size] = {
+ 2.0,
+ 2.0,
+ -DBL_MAX,
+ };
+ double dRes[test_size] = {
+ 2.5,
+ DBL_MAX / 2.0,
+ -1.0,
+ };
+ float fOp1[test_size] = {
+ 5.0,
+ FLT_MAX,
+ FLT_MAX,
+ };
+ float fOp2[test_size] = {
+ 2.0,
+ 2.0,
+ -FLT_MAX,
+ };
+ float fRes[test_size] = {
+ 2.5,
+ FLT_MAX / 2.0,
+ -1.0,
+ };
+
+ for (int i = 0; i < test_size; i++) {
+ test.dOp1 = dOp1[i];
+ test.dOp2 = dOp2[i];
+ test.fOp1 = fOp1[i];
+ test.fOp2 = fOp2[i];
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dRes, dRes[i]);
+ CHECK_EQ(test.fRes, fRes[i]);
+ }
+
+ test.dOp1 = DBL_MAX;
+ test.dOp2 = -0.0;
+ test.fOp1 = FLT_MAX;
+ test.fOp2 = -0.0;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(false, std::isfinite(test.dRes));
+ CHECK_EQ(false, std::isfinite(test.fRes));
+
+ test.dOp1 = 0.0;
+ test.dOp2 = -0.0;
+ test.fOp1 = 0.0;
+ test.fOp2 = -0.0;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(true, std::isnan(test.dRes));
+ CHECK_EQ(true, std::isnan(test.fRes));
+
+ test.dOp1 = std::numeric_limits<double>::quiet_NaN();
+ test.dOp2 = -5.0;
+ test.fOp1 = std::numeric_limits<float>::quiet_NaN();
+ test.fOp2 = -5.0;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(true, std::isnan(test.dRes));
+ CHECK_EQ(true, std::isnan(test.fRes));
+}
+
+
+uint32_t run_align(uint32_t rs_value, uint32_t rt_value, uint8_t bp) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ align(v0, a0, a1, bp);
+ __ 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());
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, rs_value,
+ rt_value,
+ 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_align) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAlign {
+ uint32_t rs_value;
+ uint32_t rt_value;
+ uint8_t bp;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseAlign tc[] = {
+ // rs_value, rt_value, bp, expected_res
+ { 0x11223344, 0xaabbccdd, 0, 0xaabbccdd },
+ { 0x11223344, 0xaabbccdd, 1, 0xbbccdd11 },
+ { 0x11223344, 0xaabbccdd, 2, 0xccdd1122 },
+ { 0x11223344, 0xaabbccdd, 3, 0xdd112233 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAlign);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ CHECK_EQ(tc[i].expected_res, run_align(tc[i].rs_value,
+ tc[i].rt_value, tc[i].bp));
+ }
+ }
+}
+
+uint32_t PC; // The program counter.
+
+uint32_t run_aluipc(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ aluipc(v0, offset);
+ __ 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());
+ PC = (uint32_t) f; // Set the program counter.
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_aluipc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAluipc {
+ int16_t offset;
+ };
+
+ struct TestCaseAluipc tc[] = {
+ // offset
+ { -32768 }, // 0x8000
+ { -1 }, // 0xFFFF
+ { 0 },
+ { 1 },
+ { 32767 }, // 0x7FFF
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAluipc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ PC = 0;
+ uint32_t res = run_aluipc(tc[i].offset);
+ // Now, the program_counter (PC) is set.
+ uint32_t expected_res = ~0x0FFFF & (PC + (tc[i].offset << 16));
+ CHECK_EQ(expected_res, res);
+ }
+ }
+}
+
+
+uint32_t run_auipc(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ auipc(v0, offset);
+ __ 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());
+ PC = (uint32_t) f; // Set the program counter.
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_auipc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAuipc {
+ int16_t offset;
+ };
+
+ struct TestCaseAuipc tc[] = {
+ // offset
+ { -32768 }, // 0x8000
+ { -1 }, // 0xFFFF
+ { 0 },
+ { 1 },
+ { 32767 }, // 0x7FFF
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAuipc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ PC = 0;
+ uint32_t res = run_auipc(tc[i].offset);
+ // Now, the program_counter (PC) is set.
+ uint32_t expected_res = PC + (tc[i].offset << 16);
+ CHECK_EQ(expected_res, res);
+ }
+ }
+}
+
+
+uint32_t run_lwpc(int offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ // 256k instructions; 2^8k
+ // addiu t7, t0, 0xffff; (0x250fffff)
+ // ...
+ // addiu t4, t0, 0x0000; (0x250c0000)
+ uint32_t addiu_start_1 = 0x25000000;
+ for (int32_t i = 0xfffff; i >= 0xc0000; --i) {
+ uint32_t addiu_new = addiu_start_1 + i;
+ __ dd(addiu_new);
+ }
+
+ __ lwpc(t8, offset); // offset 0; 0xef080000 (t8 register)
+ __ mov(v0, t8);
+
+ // 256k instructions; 2^8k
+ // addiu t0, t0, 0x0000; (0x25080000)
+ // ...
+ // addiu t3, t0, 0xffff; (0x250bffff)
+ uint32_t addiu_start_2 = 0x25000000;
+ for (int32_t i = 0x80000; i <= 0xbffff; ++i) {
+ uint32_t addiu_new = addiu_start_2 + i;
+ __ dd(addiu_new);
+ }
+
+ __ 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());
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_lwpc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseLwpc {
+ int offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseLwpc tc[] = {
+ // offset, expected_res
+ { -262144, 0x250fffff }, // offset 0x40000
+ { -4, 0x250c0003 },
+ { -1, 0x250c0000 },
+ { 0, 0xef080000 },
+ { 1, 0x03001025 }, // mov(v0, t8)
+ { 2, 0x25080000 },
+ { 4, 0x25080002 },
+ { 262143, 0x250bfffd }, // offset 0x3ffff
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLwpc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint32_t res = run_lwpc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint32_t run_jic(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label get_program_counter, stop_execution;
+ __ push(ra);
+ __ li(v0, 0);
+ __ li(t1, 0x66);
+
+ __ addiu(v0, v0, 0x1); // <-- offset = -32
+ __ addiu(v0, v0, 0x2);
+ __ addiu(v0, v0, 0x10);
+ __ addiu(v0, v0, 0x20);
+ __ beq(v0, t1, &stop_execution);
+ __ nop();
+
+ __ bal(&get_program_counter); // t0 <- program counter
+ __ nop();
+ __ jic(t0, offset);
+
+ __ addiu(v0, v0, 0x100);
+ __ addiu(v0, v0, 0x200);
+ __ addiu(v0, v0, 0x1000);
+ __ addiu(v0, v0, 0x2000); // <--- offset = 16
+ __ pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&get_program_counter);
+ __ mov(t0, ra);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&stop_execution);
+ __ pop(ra);
+ __ 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());
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_jic) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseJic {
+ // As rt will be used t0 register which will have value of
+ // the program counter for the jic instruction.
+ int16_t offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseJic tc[] = {
+ // offset, expected_result
+ { 16, 0x2033 },
+ { 4, 0x3333 },
+ { -32, 0x66 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJic);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint32_t res = run_jic(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_beqzc(int32_t value, int32_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label stop_execution;
+ __ li(v0, 0);
+ __ li(t1, 0x66);
+ __ push(ra);
+
+ __ addiu(v0, v0, 0x1); // <-- offset = -32
+ __ addiu(v0, v0, 0x2);
+ __ addiu(v0, v0, 0x10);
+ __ addiu(v0, v0, 0x20);
+ __ beq(v0, t1, &stop_execution);
+ __ nop();
+
+ __ beqzc(a0, offset); // BEQZC rs, offset
+
+ __ addiu(v0, v0, 0x1);
+ __ addiu(v0, v0, 0x100);
+ __ addiu(v0, v0, 0x200);
+ __ addiu(v0, v0, 0x1000);
+ __ addiu(v0, v0, 0x2000); // <--- offset = 16
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&stop_execution);
+ __ pop(ra);
+ __ 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());
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, value, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_beqzc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseBeqzc {
+ uint32_t value;
+ int32_t offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseBeqzc tc[] = {
+ // value, offset, expected_res
+ { 0x0, -8, 0x66 },
+ { 0x0, 0, 0x3334 },
+ { 0x0, 1, 0x3333 },
+ { 0xabc, 1, 0x3334 },
+ { 0x0, 4, 0x2033 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBeqzc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint32_t res = run_beqzc(tc[i].value, tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint32_t run_jialc(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label main_block, get_program_counter;
+ __ push(ra);
+ __ li(v0, 0);
+ __ beq(v0, v0, &main_block);
+ __ nop();
+
+ // Block 1
+ __ addiu(v0, v0, 0x1); // <-- offset = -40
+ __ addiu(v0, v0, 0x2);
+ __ jr(ra);
+ __ nop();
+
+ // Block 2
+ __ addiu(v0, v0, 0x10); // <-- offset = -24
+ __ addiu(v0, v0, 0x20);
+ __ jr(ra);
+ __ nop();
+
+ // Block 3 (Main)
+ __ bind(&main_block);
+ __ bal(&get_program_counter); // t0 <- program counter
+ __ nop();
+ __ jialc(t0, offset);
+ __ addiu(v0, v0, 0x4);
+ __ pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ // Block 4
+ __ addiu(v0, v0, 0x100); // <-- offset = 20
+ __ addiu(v0, v0, 0x200);
+ __ jr(ra);
+ __ nop();
+
+ // Block 5
+ __ addiu(v0, v0, 0x1000); // <--- offset = 36
+ __ addiu(v0, v0, 0x2000);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&get_program_counter);
+ __ mov(t0, ra);
+ __ 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());
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_jialc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseJialc {
+ int16_t offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseJialc tc[] = {
+ // offset, expected_res
+ { -40, 0x7 },
+ { -24, 0x34 },
+ { 20, 0x304 },
+ { 36, 0x3004 }
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJialc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint32_t res = run_jialc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_addiupc(int32_t imm19) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ addiupc(v0, imm19);
+ __ 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());
+ PC = (uint32_t) f; // Set the program counter.
+
+ uint32_t rs =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, imm19, 0, 0, 0, 0));
+
+ return rs;
+}
+
+
+TEST(r6_addiupc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAddiupc {
+ int32_t imm19;
+ };
+
+ struct TestCaseAddiupc tc[] = {
+ // imm19
+ { -262144 }, // 0x40000
+ { -1 }, // 0x7FFFF
+ { 0 },
+ { 1 }, // 0x00001
+ { 262143 } // 0x3FFFF
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAddiupc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ PC = 0;
+ uint32_t res = run_addiupc(tc[i].imm19);
+ // Now, the program_counter (PC) is set.
+ uint32_t expected_res = PC + (tc[i].imm19 << 2);
+ CHECK_EQ(expected_res, res);
+ }
+ }
+}
+
+
+int32_t run_bc(int32_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label continue_1, stop_execution;
+ __ push(ra);
+ __ li(v0, 0);
+ __ li(t8, 0);
+ __ li(t9, 2); // A condition for stopping execution.
+
+ uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1
+ for (int32_t i = -100; i <= -11; ++i) {
+ __ dd(instruction_addiu);
+ }
+
+ __ addiu(t8, t8, 1); // -10
+
+ __ beq(t8, t9, &stop_execution); // -9
+ __ nop(); // -8
+ __ beq(t8, t8, &continue_1); // -7
+ __ nop(); // -6
+
+ __ bind(&stop_execution);
+ __ pop(ra); // -5, -4
+ __ jr(ra); // -3
+ __ nop(); // -2
+
+ __ bind(&continue_1);
+ __ bc(offset); // -1
+
+ for (int32_t i = 0; i <= 99; ++i) {
+ __ dd(instruction_addiu);
+ }
+
+ __ pop(ra);
+ __ 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());
+
+ int32_t res =
+ reinterpret_cast<int32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_bc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseBc {
+ int32_t offset;
+ int32_t expected_res;
+ };
+
+ struct TestCaseBc tc[] = {
+ // offset, expected_result
+ { -100, (abs(-100) - 10) * 2 },
+ { -11, (abs(-100) - 10 + 1) },
+ { 0, (abs(-100) - 10 + 1 + 99) },
+ { 1, (abs(-100) - 10 + 99) },
+ { 99, (abs(-100) - 10 + 1) },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ int32_t res = run_bc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+int32_t run_balc(int32_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label continue_1, stop_execution;
+ __ push(ra);
+ __ li(v0, 0);
+ __ li(t8, 0);
+ __ li(t9, 2); // A condition for stopping execution.
+
+ __ beq(t8, t8, &continue_1);
+ __ nop();
+
+ uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1
+ for (int32_t i = -117; i <= -57; ++i) {
+ __ dd(instruction_addiu);
+ }
+ __ jr(ra); // -56
+ __ nop(); // -55
+
+ for (int32_t i = -54; i <= -4; ++i) {
+ __ dd(instruction_addiu);
+ }
+ __ jr(ra); // -3
+ __ nop(); // -2
+
+ __ bind(&continue_1);
+ __ balc(offset); // -1
+
+ __ pop(ra); // 0, 1
+ __ jr(ra); // 2
+ __ nop(); // 3
+
+ for (int32_t i = 4; i <= 44; ++i) {
+ __ dd(instruction_addiu);
+ }
+ __ 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());
+
+ int32_t res =
+ reinterpret_cast<int32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_balc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseBalc {
+ int32_t offset;
+ int32_t expected_res;
+ };
+
+ struct TestCaseBalc tc[] = {
+ // offset, expected_result
+ { -117, 61 },
+ { -54, 51 },
+ { 0, 0 },
+ { 4, 41 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBalc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ int32_t res = run_balc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
#undef __
diff --git a/deps/v8/test/cctest/test-assembler-mips64.cc b/deps/v8/test/cctest/test-assembler-mips64.cc
index 3b422a2716..bb7b05ca76 100644
--- a/deps/v8/test/cctest/test-assembler-mips64.cc
+++ b/deps/v8/test/cctest/test-assembler-mips64.cc
@@ -45,6 +45,7 @@ using namespace v8::internal;
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);
+typedef Object* (*F4)(int64_t x, int64_t y, int64_t p2, int64_t p3, int64_t p4);
// clang-format off
@@ -289,61 +290,61 @@ TEST(MIPS3) {
Label L, C;
// Double precision floating point instructions.
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
__ add_d(f8, f4, f6);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, c)) ); // c = a + b.
+ __ sdc1(f8, MemOperand(a0, offsetof(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(f10, MemOperand(a0, offsetof(T, d)) ); // d = c - (-b).
- __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, b)) ); // b = a.
+ __ sdc1(f4, MemOperand(a0, offsetof(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.
+ __ sdc1(f10, MemOperand(a0, offsetof(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.
+ __ sdc1(f12, MemOperand(a0, offsetof(T, f)) ); // f = e / a = 120.44.
__ sqrt_d(f14, f12);
- __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, g)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(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)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, h)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, i)) );
__ madd_d(f14, f6, f4, f6);
- __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, h)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(T, h)) );
}
// Single precision floating point instructions.
- __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fa)) );
- __ lwc1(f6, MemOperand(a0, OFFSET_OF(T, fb)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fa)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(T, fb)) );
__ add_s(f8, f4, f6);
- __ swc1(f8, MemOperand(a0, OFFSET_OF(T, fc)) ); // fc = fa + fb.
+ __ swc1(f8, MemOperand(a0, offsetof(T, fc)) ); // fc = fa + fb.
__ neg_s(f10, f6); // -fb
__ sub_s(f10, f8, f10);
- __ swc1(f10, MemOperand(a0, OFFSET_OF(T, fd)) ); // fd = fc - (-fb).
+ __ swc1(f10, MemOperand(a0, offsetof(T, fd)) ); // fd = fc - (-fb).
- __ swc1(f4, MemOperand(a0, OFFSET_OF(T, fb)) ); // fb = fa.
+ __ swc1(f4, MemOperand(a0, offsetof(T, fb)) ); // fb = fa.
__ li(t0, 120);
__ mtc1(t0, f14);
__ cvt_s_w(f14, f14); // f14 = 120.0.
__ mul_s(f10, f10, f14);
- __ swc1(f10, MemOperand(a0, OFFSET_OF(T, fe)) ); // fe = fd * 120
+ __ swc1(f10, MemOperand(a0, offsetof(T, fe)) ); // fe = fd * 120
__ div_s(f12, f10, f4);
- __ swc1(f12, MemOperand(a0, OFFSET_OF(T, ff)) ); // ff = fe / fa
+ __ swc1(f12, MemOperand(a0, offsetof(T, ff)) ); // ff = fe / fa
__ sqrt_s(f14, f12);
- __ swc1(f14, MemOperand(a0, OFFSET_OF(T, fg)) );
+ __ swc1(f14, MemOperand(a0, offsetof(T, fg)) );
__ jr(ra);
__ nop();
@@ -412,8 +413,8 @@ TEST(MIPS4) {
Assembler assm(isolate, NULL, 0);
Label L, C;
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)));
- __ ldc1(f5, MemOperand(a0, OFFSET_OF(T, b)));
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)));
+ __ ldc1(f5, MemOperand(a0, offsetof(T, b)));
// Swap f4 and f5, by using 3 integer registers, a4-a6,
// both two 32-bit chunks, and one 64-bit chunk.
@@ -428,16 +429,16 @@ TEST(MIPS4) {
__ 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)));
+ __ sdc1(f4, MemOperand(a0, offsetof(T, a)));
+ __ sdc1(f5, MemOperand(a0, offsetof(T, c)));
// Test sign extension of move operations from coprocessor.
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, d)));
+ __ ldc1(f4, MemOperand(a0, offsetof(T, d)));
__ mfhc1(a4, f4);
__ mfc1(a5, f4);
- __ sd(a4, MemOperand(a0, OFFSET_OF(T, high)));
- __ sd(a5, MemOperand(a0, OFFSET_OF(T, low)));
+ __ sd(a4, MemOperand(a0, offsetof(T, high)));
+ __ sd(a5, MemOperand(a0, offsetof(T, low)));
__ jr(ra);
__ nop();
@@ -480,30 +481,30 @@ TEST(MIPS5) {
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)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
+ __ lw(a4, MemOperand(a0, offsetof(T, i)) );
+ __ lw(a5, MemOperand(a0, offsetof(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)) );
+ __ sw(a6, MemOperand(a0, offsetof(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)) );
+ __ sw(a7, MemOperand(a0, offsetof(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)) );
+ __ sdc1(f0, MemOperand(a0, offsetof(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)) );
+ __ sdc1(f2, MemOperand(a0, offsetof(T, b)) );
__ jr(ra);
__ nop();
@@ -549,31 +550,31 @@ TEST(MIPS6) {
Label L, C;
// Basic word load/store.
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, ui)) );
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, r1)) );
+ __ lw(a4, MemOperand(a0, offsetof(T, ui)) );
+ __ sw(a4, MemOperand(a0, offsetof(T, r1)) );
// lh with positive data.
- __ lh(a5, MemOperand(a0, OFFSET_OF(T, ui)) );
- __ sw(a5, MemOperand(a0, OFFSET_OF(T, r2)) );
+ __ lh(a5, MemOperand(a0, offsetof(T, ui)) );
+ __ sw(a5, MemOperand(a0, offsetof(T, r2)) );
// lh with negative data.
- __ lh(a6, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(a6, MemOperand(a0, OFFSET_OF(T, r3)) );
+ __ lh(a6, MemOperand(a0, offsetof(T, si)) );
+ __ sw(a6, MemOperand(a0, offsetof(T, r3)) );
// lhu with negative data.
- __ lhu(a7, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(a7, MemOperand(a0, OFFSET_OF(T, r4)) );
+ __ lhu(a7, MemOperand(a0, offsetof(T, si)) );
+ __ sw(a7, MemOperand(a0, offsetof(T, r4)) );
// lb with negative data.
- __ lb(t0, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, r5)) );
+ __ lb(t0, MemOperand(a0, offsetof(T, si)) );
+ __ sw(t0, MemOperand(a0, offsetof(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)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, r6)) );
+ __ lhu(t1, MemOperand(a0, offsetof(T, si)) );
+ __ sh(t1, MemOperand(a0, offsetof(T, r6)) );
__ jr(ra);
__ nop();
@@ -619,8 +620,8 @@ TEST(MIPS7) {
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)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
if (kArchVariant != kMips64r6) {
__ c(UN, D, f4, f6);
__ bc1f(&neither_is_nan);
@@ -629,7 +630,7 @@ TEST(MIPS7) {
__ bc1eqz(&neither_is_nan, f2);
}
__ nop();
- __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
+ __ sw(zero_reg, MemOperand(a0, offsetof(T, result)) );
__ Branch(&outa_here);
__ bind(&neither_is_nan);
@@ -643,12 +644,12 @@ TEST(MIPS7) {
}
__ nop();
- __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
+ __ sw(zero_reg, MemOperand(a0, offsetof(T, result)) );
__ Branch(&outa_here);
__ bind(&less_than);
__ Addu(a4, zero_reg, Operand(1));
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, result)) ); // Set true.
+ __ sw(a4, MemOperand(a0, offsetof(T, result)) ); // Set true.
// This test-case should have additional tests.
@@ -707,7 +708,7 @@ TEST(MIPS8) {
MacroAssembler assm(isolate, NULL, 0);
// Basic word load.
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, input)) );
+ __ lw(a4, MemOperand(a0, offsetof(T, input)) );
// ROTR instruction (called through the Ror macro).
__ Ror(a5, a4, 0x0004);
@@ -719,13 +720,13 @@ TEST(MIPS8) {
__ 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)) );
+ __ sw(a5, MemOperand(a0, offsetof(T, result_rotr_4)) );
+ __ sw(a6, MemOperand(a0, offsetof(T, result_rotr_8)) );
+ __ sw(a7, MemOperand(a0, offsetof(T, result_rotr_12)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, result_rotr_16)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, result_rotr_20)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, result_rotr_24)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, result_rotr_28)) );
// ROTRV instruction (called through the Ror macro).
__ li(t3, 0x0004);
@@ -744,13 +745,13 @@ TEST(MIPS8) {
__ 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)) );
+ __ sw(a5, MemOperand(a0, offsetof(T, result_rotrv_4)) );
+ __ sw(a6, MemOperand(a0, offsetof(T, result_rotrv_8)) );
+ __ sw(a7, MemOperand(a0, offsetof(T, result_rotrv_12)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, result_rotrv_16)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, result_rotrv_20)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, result_rotrv_24)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, result_rotrv_28)) );
__ jr(ra);
__ nop();
@@ -838,42 +839,42 @@ TEST(MIPS10) {
// - 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)));
+ __ ldc1(f0, MemOperand(a0, offsetof(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)));
+ __ sw(a4, MemOperand(a0, offsetof(T, dbl_mant)));
+ __ sw(a5, MemOperand(a0, offsetof(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)));
+ __ sw(a4, MemOperand(a0, offsetof(T, long_lo)));
+ __ sw(a5, MemOperand(a0, offsetof(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)));
+ __ sdc1(f1, MemOperand(a0, offsetof(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)));
+ __ lw(a4, MemOperand(a0, offsetof(T, b_long_lo)));
+ __ lw(a5, MemOperand(a0, offsetof(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)));
+ __ sdc1(f10, MemOperand(a0, offsetof(T, b)));
// Convert double b back to long-int.
- __ ldc1(f31, MemOperand(a0, OFFSET_OF(T, b)));
+ __ ldc1(f31, MemOperand(a0, offsetof(T, b)));
__ cvt_l_d(f31, f31);
__ dmfc1(a7, f31);
- __ sd(a7, MemOperand(a0, OFFSET_OF(T, b_long_as_int64)));
+ __ sd(a7, MemOperand(a0, offsetof(T, b_long_as_int64)));
__ jr(ra);
@@ -936,80 +937,80 @@ TEST(MIPS11) {
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(a4, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwl(a4, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a4, MemOperand(a0, offsetof(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(a5, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwl(a5, MemOperand(a0, offsetof(T, mem_init) + 1));
+ __ sw(a5, MemOperand(a0, offsetof(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(a6, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwl(a6, MemOperand(a0, offsetof(T, mem_init) + 2));
+ __ sw(a6, MemOperand(a0, offsetof(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)));
+ __ lw(a7, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwl(a7, MemOperand(a0, offsetof(T, mem_init) + 3));
+ __ sw(a7, MemOperand(a0, offsetof(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(a4, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwr(a4, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a4, MemOperand(a0, offsetof(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(a5, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwr(a5, MemOperand(a0, offsetof(T, mem_init) + 1));
+ __ sw(a5, MemOperand(a0, offsetof(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(a6, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwr(a6, MemOperand(a0, offsetof(T, mem_init) + 2));
+ __ sw(a6, MemOperand(a0, offsetof(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)) );
+ __ lw(a7, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwr(a7, MemOperand(a0, offsetof(T, mem_init) + 3));
+ __ sw(a7, MemOperand(a0, offsetof(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));
+ __ lw(a4, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a4, MemOperand(a0, offsetof(T, swl_0)));
+ __ lw(a4, MemOperand(a0, offsetof(T, reg_init)));
+ __ swl(a4, MemOperand(a0, offsetof(T, swl_0)));
+
+ __ lw(a5, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a5, MemOperand(a0, offsetof(T, swl_1)));
+ __ lw(a5, MemOperand(a0, offsetof(T, reg_init)));
+ __ swl(a5, MemOperand(a0, offsetof(T, swl_1) + 1));
+
+ __ lw(a6, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a6, MemOperand(a0, offsetof(T, swl_2)));
+ __ lw(a6, MemOperand(a0, offsetof(T, reg_init)));
+ __ swl(a6, MemOperand(a0, offsetof(T, swl_2) + 2));
+
+ __ lw(a7, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a7, MemOperand(a0, offsetof(T, swl_3)));
+ __ lw(a7, MemOperand(a0, offsetof(T, reg_init)));
+ __ swl(a7, MemOperand(a0, offsetof(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));
+ __ lw(a4, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a4, MemOperand(a0, offsetof(T, swr_0)));
+ __ lw(a4, MemOperand(a0, offsetof(T, reg_init)));
+ __ swr(a4, MemOperand(a0, offsetof(T, swr_0)));
+
+ __ lw(a5, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a5, MemOperand(a0, offsetof(T, swr_1)));
+ __ lw(a5, MemOperand(a0, offsetof(T, reg_init)));
+ __ swr(a5, MemOperand(a0, offsetof(T, swr_1) + 1));
+
+ __ lw(a6, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a6, MemOperand(a0, offsetof(T, swr_2)));
+ __ lw(a6, MemOperand(a0, offsetof(T, reg_init)));
+ __ swr(a6, MemOperand(a0, offsetof(T, swr_2) + 2));
+
+ __ lw(a7, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a7, MemOperand(a0, offsetof(T, swr_3)));
+ __ lw(a7, MemOperand(a0, offsetof(T, reg_init)));
+ __ swr(a7, MemOperand(a0, offsetof(T, swr_3) + 3));
__ jr(ra);
__ nop();
@@ -1067,8 +1068,8 @@ TEST(MIPS12) {
__ 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)));
+ __ lw(a4, MemOperand(a0, offsetof(T, y)));
+ __ lw(a7, MemOperand(a0, offsetof(T, y4)));
__ addu(a5, a4, a7);
__ subu(t0, a4, a7);
@@ -1086,30 +1087,30 @@ TEST(MIPS12) {
__ push(a7);
__ pop(t0);
__ nop();
- __ sw(a4, MemOperand(fp, OFFSET_OF(T, y)));
- __ lw(a4, MemOperand(fp, OFFSET_OF(T, y)));
+ __ sw(a4, MemOperand(fp, offsetof(T, y)));
+ __ lw(a4, MemOperand(fp, offsetof(T, y)));
__ nop();
- __ sw(a4, MemOperand(fp, OFFSET_OF(T, y)));
- __ lw(a5, MemOperand(fp, OFFSET_OF(T, y)));
+ __ sw(a4, MemOperand(fp, offsetof(T, y)));
+ __ lw(a5, MemOperand(fp, offsetof(T, y)));
__ nop();
__ push(a5);
- __ lw(a5, MemOperand(fp, OFFSET_OF(T, y)));
+ __ lw(a5, MemOperand(fp, offsetof(T, y)));
__ pop(a5);
__ nop();
__ push(a5);
- __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)));
+ __ lw(a6, MemOperand(fp, offsetof(T, y)));
__ pop(a5);
__ nop();
__ push(a5);
- __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)));
+ __ lw(a6, MemOperand(fp, offsetof(T, y)));
__ pop(a6);
__ nop();
__ push(a6);
- __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)));
+ __ lw(a6, MemOperand(fp, offsetof(T, y)));
__ pop(a5);
__ nop();
__ push(a5);
- __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)));
+ __ lw(a6, MemOperand(fp, offsetof(T, y)));
__ pop(a7);
__ nop();
@@ -1154,19 +1155,19 @@ TEST(MIPS13) {
MacroAssembler assm(isolate, NULL, 0);
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, cvt_small_in)));
+ __ sw(a4, MemOperand(a0, offsetof(T, cvt_small_in)));
__ Cvt_d_uw(f10, a4, f22);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out)));
+ __ sdc1(f10, MemOperand(a0, offsetof(T, cvt_small_out)));
__ Trunc_uw_d(f10, f10, f22);
- __ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out)));
+ __ swc1(f10, MemOperand(a0, offsetof(T, trunc_small_out)));
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, cvt_big_in)));
+ __ sw(a4, MemOperand(a0, offsetof(T, cvt_big_in)));
__ Cvt_d_uw(f8, a4, f22);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out)));
+ __ sdc1(f8, MemOperand(a0, offsetof(T, cvt_big_out)));
__ Trunc_uw_d(f8, f8, f22);
- __ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out)));
+ __ swc1(f8, MemOperand(a0, offsetof(T, trunc_big_out)));
__ jr(ra);
__ nop();
@@ -1236,46 +1237,46 @@ TEST(MIPS14) {
// Disable FPU exceptions.
__ ctc1(zero_reg, FCSR);
#define RUN_ROUND_TEST(x) \
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_up_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, round_up_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_up_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, x##_up_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_down_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, round_down_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_down_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, x##_down_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_up_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, neg_round_up_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_up_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, neg_##x##_up_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_down_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, neg_round_down_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_down_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, neg_##x##_down_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err1_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(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))); \
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err1_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err2_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(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))); \
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err2_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err3_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(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))); \
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err3_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err4_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(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)));
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err4_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, x##_invalid_result)));
RUN_ROUND_TEST(round)
RUN_ROUND_TEST(floor)
@@ -1363,48 +1364,48 @@ TEST(MIPS16) {
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)));
+ __ lw(a4, MemOperand(a0, offsetof(T, ui)));
+ __ sw(a4, MemOperand(a0, offsetof(T, r1)));
// Check that the data got zero-extended into 64-bit a4.
- __ sd(a4, MemOperand(a0, OFFSET_OF(T, r2)));
+ __ sd(a4, MemOperand(a0, offsetof(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)));
+ __ lw(a5, MemOperand(a0, offsetof(T, si)));
+ __ sw(a5, MemOperand(a0, offsetof(T, r3)));
// Check that the data got sign-extended into 64-bit a4.
- __ sd(a5, MemOperand(a0, OFFSET_OF(T, r4)));
+ __ sd(a5, MemOperand(a0, offsetof(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)));
+ __ lwu(a6, MemOperand(a0, offsetof(T, si)));
+ __ sw(a6, MemOperand(a0, offsetof(T, r5)));
// Check that the data got zero-extended into 64-bit a4.
- __ sd(a6, MemOperand(a0, OFFSET_OF(T, r6)));
+ __ sd(a6, MemOperand(a0, offsetof(T, r6)));
// lh with positive data.
- __ lh(a5, MemOperand(a0, OFFSET_OF(T, ui)));
- __ sw(a5, MemOperand(a0, OFFSET_OF(T, r2)));
+ __ lh(a5, MemOperand(a0, offsetof(T, ui)));
+ __ sw(a5, MemOperand(a0, offsetof(T, r2)));
// lh with negative data.
- __ lh(a6, MemOperand(a0, OFFSET_OF(T, si)));
- __ sw(a6, MemOperand(a0, OFFSET_OF(T, r3)));
+ __ lh(a6, MemOperand(a0, offsetof(T, si)));
+ __ sw(a6, MemOperand(a0, offsetof(T, r3)));
// lhu with negative data.
- __ lhu(a7, MemOperand(a0, OFFSET_OF(T, si)));
- __ sw(a7, MemOperand(a0, OFFSET_OF(T, r4)));
+ __ lhu(a7, MemOperand(a0, offsetof(T, si)));
+ __ sw(a7, MemOperand(a0, offsetof(T, r4)));
// lb with negative data.
- __ lb(t0, MemOperand(a0, OFFSET_OF(T, si)));
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, r5)));
+ __ lb(t0, MemOperand(a0, offsetof(T, si)));
+ __ sw(t0, MemOperand(a0, offsetof(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)));
+ __ sw(t1, MemOperand(a0, offsetof(T, r6)));
+ __ lhu(t1, MemOperand(a0, offsetof(T, si)));
+ __ sh(t1, MemOperand(a0, offsetof(T, r6)));
__ jr(ra);
__ nop();
@@ -1439,7 +1440,8 @@ TEST(MIPS16) {
}
-TEST(MIPS17) {
+// ----------------------mips32r6 specific tests----------------------
+TEST(seleqz_selnez) {
if (kArchVariant == kMips64r6) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -1455,26 +1457,36 @@ TEST(MIPS17) {
double f;
double g;
double h;
+ float i;
+ float j;
+ float k;
+ float l;
} Test;
Test test;
// Integer part of test.
__ addiu(t1, zero_reg, 1); // t1 = 1
__ seleqz(t3, t1, zero_reg); // t3 = 1
- __ sw(t3, MemOperand(a0, OFFSET_OF(Test, a))); // a = 1
+ __ sw(t3, MemOperand(a0, offsetof(Test, a))); // a = 1
__ seleqz(t2, t1, t1); // t2 = 0
- __ sw(t2, MemOperand(a0, OFFSET_OF(Test, b))); // b = 0
+ __ sw(t2, MemOperand(a0, offsetof(Test, b))); // b = 0
__ selnez(t3, t1, zero_reg); // t3 = 1;
- __ sw(t3, MemOperand(a0, OFFSET_OF(Test, c))); // c = 0
+ __ sw(t3, MemOperand(a0, offsetof(Test, c))); // c = 0
__ selnez(t3, t1, t1); // t3 = 1
- __ sw(t3, MemOperand(a0, OFFSET_OF(Test, d))); // d = 1
+ __ sw(t3, MemOperand(a0, offsetof(Test, d))); // d = 1
// Floating point part of test.
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(Test, e)) ); // src
- __ ldc1(f2, MemOperand(a0, OFFSET_OF(Test, f)) ); // test
- __ seleqz(D, f4, f0, f2);
- __ selnez(D, f6, f0, f2);
- __ sdc1(f4, MemOperand(a0, OFFSET_OF(Test, g)) ); // src
- __ sdc1(f6, MemOperand(a0, OFFSET_OF(Test, h)) ); // src
+ __ ldc1(f0, MemOperand(a0, offsetof(Test, e)) ); // src
+ __ ldc1(f2, MemOperand(a0, offsetof(Test, f)) ); // test
+ __ lwc1(f8, MemOperand(a0, offsetof(Test, i)) ); // src
+ __ lwc1(f10, MemOperand(a0, offsetof(Test, j)) ); // test
+ __ seleqz_d(f4, f0, f2);
+ __ selnez_d(f6, f0, f2);
+ __ seleqz_s(f12, f8, f10);
+ __ selnez_s(f14, f8, f10);
+ __ sdc1(f4, MemOperand(a0, offsetof(Test, g)) ); // src
+ __ sdc1(f6, MemOperand(a0, offsetof(Test, h)) ); // src
+ __ swc1(f12, MemOperand(a0, offsetof(Test, k)) ); // src
+ __ swc1(f14, MemOperand(a0, offsetof(Test, l)) ); // src
__ jr(ra);
__ nop();
CodeDesc desc;
@@ -1493,31 +1505,45 @@ TEST(MIPS17) {
const int test_size = 3;
const int input_size = 5;
- double inputs[input_size] = {0.0, 65.2, -70.32,
+ double inputs_D[input_size] = {0.0, 65.2, -70.32,
18446744073709551621.0, -18446744073709551621.0};
- double outputs[input_size] = {0.0, 65.2, -70.32,
+ double outputs_D[input_size] = {0.0, 65.2, -70.32,
18446744073709551621.0, -18446744073709551621.0};
- double tests[test_size*2] = {2.8, 2.9, -2.8, -2.9,
+ double tests_D[test_size*2] = {2.8, 2.9, -2.8, -2.9,
18446744073709551616.0, 18446744073709555712.0};
- for (int j=0;j < test_size;j+=2) {
- for (int i=0;i < input_size;i++) {
- test.e = inputs[i];
- test.f = tests[j];
+ float inputs_S[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ float outputs_S[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ float tests_S[test_size*2] = {2.9, 2.8, -2.9, -2.8,
+ 18446744073709551616.0, 18446746272732807168.0};
+ for (int j=0; j < test_size; j+=2) {
+ for (int i=0; i < input_size; i++) {
+ test.e = inputs_D[i];
+ test.f = tests_D[j];
+ test.i = inputs_S[i];
+ test.j = tests_S[j];
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.g, outputs[i]);
+ CHECK_EQ(test.g, outputs_D[i]);
CHECK_EQ(test.h, 0);
+ CHECK_EQ(test.k, outputs_S[i]);
+ CHECK_EQ(test.l, 0);
- test.f = tests[j+1];
+ test.f = tests_D[j+1];
+ test.j = tests_S[j+1];
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.g, 0);
- CHECK_EQ(test.h, outputs[i]);
+ CHECK_EQ(test.h, outputs_D[i]);
+ CHECK_EQ(test.k, 0);
+ CHECK_EQ(test.l, outputs_S[i]);
}
}
}
}
-TEST(MIPS18) {
+
+TEST(min_max) {
if (kArchVariant == kMips64r6) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -1529,16 +1555,38 @@ TEST(MIPS18) {
double b;
double c;
double d;
+ float e;
+ float f;
+ float g;
+ float h;
} TestFloat;
TestFloat test;
-
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a)));
- __ ldc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b)));
+ const double dblNaN = std::numeric_limits<double>::quiet_NaN();
+ const float fltNaN = std::numeric_limits<float>::quiet_NaN();
+ const int tableLength = 5;
+ double inputsa[tableLength] = {2.0, 3.0, dblNaN, 3.0, dblNaN};
+ double inputsb[tableLength] = {3.0, 2.0, 3.0, dblNaN, dblNaN};
+ double outputsdmin[tableLength] = {2.0, 2.0, 3.0, 3.0, dblNaN};
+ double outputsdmax[tableLength] = {3.0, 3.0, 3.0, 3.0, dblNaN};
+
+ float inputse[tableLength] = {2.0, 3.0, fltNaN, 3.0, fltNaN};
+ float inputsf[tableLength] = {3.0, 2.0, 3.0, fltNaN, fltNaN};
+ float outputsfmin[tableLength] = {2.0, 2.0, 3.0, 3.0, fltNaN};
+ float outputsfmax[tableLength] = {3.0, 3.0, 3.0, 3.0, fltNaN};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, e)));
+ __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, f)));
__ min_d(f10, f4, f8);
__ max_d(f12, f4, f8);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, c)));
- __ sdc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, d)));
+ __ min_s(f14, f2, f6);
+ __ max_s(f16, f2, f6);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, d)));
+ __ swc1(f14, MemOperand(a0, offsetof(TestFloat, g)));
+ __ swc1(f16, MemOperand(a0, offsetof(TestFloat, h)));
__ jr(ra);
__ nop();
@@ -1547,40 +1595,31 @@ TEST(MIPS18) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
- test.a = 2.0; // a goes to fs
- test.b = 3.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 2.0);
- CHECK_EQ(test.d, 3.0);
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputsa[i];
+ test.b = inputsb[i];
+ test.e = inputse[i];
+ test.f = inputsf[i];
- test.a = 3.0; // a goes to fs
- test.b = 2.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 2.0);
- CHECK_EQ(test.d, 3.0);
-
- test.a = std::numeric_limits<double>::quiet_NaN();
- test.b = 3.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 3.0);
- CHECK_EQ(test.d, 3.0);
-
- test.b = std::numeric_limits<double>::quiet_NaN();
- test.a = 3.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 3.0);
- CHECK_EQ(test.d, 3.0);
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- test.a = std::numeric_limits<double>::quiet_NaN();
- test.b = std::numeric_limits<double>::quiet_NaN();
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- DCHECK(std::isnan(test.c));
- DCHECK(std::isnan(test.d));
+ if (i < tableLength - 1) {
+ CHECK_EQ(test.c, outputsdmin[i]);
+ CHECK_EQ(test.d, outputsdmax[i]);
+ CHECK_EQ(test.g, outputsfmin[i]);
+ CHECK_EQ(test.h, outputsfmax[i]);
+ } else {
+ DCHECK(std::isnan(test.c));
+ DCHECK(std::isnan(test.d));
+ DCHECK(std::isnan(test.g));
+ DCHECK(std::isnan(test.h));
+ }
+ }
}
}
-TEST(MIPS19) {
+TEST(rint_d) {
if (kArchVariant == kMips64r6) {
const int tableLength = 30;
CcTest::InitializeVM();
@@ -1658,11 +1697,190 @@ TEST(MIPS19) {
int fcsr_inputs[4] =
{kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(TestFloat, fcsr)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lw(t0, MemOperand(a0, offsetof(TestFloat, fcsr)) );
__ ctc1(t0, FCSR);
__ rint_d(f8, f4);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b)) );
+ __ sdc1(f8, MemOperand(a0, offsetof(TestFloat, 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());
+
+ for (int j = 0; j < 4; j++) {
+ test.fcsr = fcsr_inputs[j];
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, outputs[j][i]);
+ }
+ }
+ }
+}
+
+
+TEST(sel) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test {
+ double dd;
+ double ds;
+ double dt;
+ float fd;
+ float fs;
+ float ft;
+ } Test;
+
+ Test test;
+ __ ldc1(f0, MemOperand(a0, offsetof(Test, dd)) ); // test
+ __ ldc1(f2, MemOperand(a0, offsetof(Test, ds)) ); // src1
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, dt)) ); // src2
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, fd)) ); // test
+ __ lwc1(f8, MemOperand(a0, offsetof(Test, fs)) ); // src1
+ __ lwc1(f10, MemOperand(a0, offsetof(Test, ft)) ); // src2
+ __ sel_d(f0, f2, f4);
+ __ sel_s(f6, f8, f10);
+ __ sdc1(f0, MemOperand(a0, offsetof(Test, dd)) );
+ __ swc1(f6, MemOperand(a0, offsetof(Test, fd)) );
+ __ 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());
+
+ const int test_size = 3;
+ const int input_size = 5;
+
+ double inputs_dt[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ double inputs_ds[input_size] = {0.1, 69.88, -91.325,
+ 18446744073709551625.0, -18446744073709551625.0};
+ float inputs_ft[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ float inputs_fs[input_size] = {0.1, 69.88, -91.325,
+ 18446744073709551625.0, -18446744073709551625.0};
+ double tests_D[test_size*2] = {2.8, 2.9, -2.8, -2.9,
+ 18446744073709551616.0, 18446744073709555712.0};
+ float tests_S[test_size*2] = {2.9, 2.8, -2.9, -2.8,
+ 18446744073709551616.0, 18446746272732807168.0};
+ for (int j=0; j < test_size; j+=2) {
+ for (int i=0; i < input_size; i++) {
+ test.dt = inputs_dt[i];
+ test.dd = tests_D[j];
+ test.ds = inputs_ds[i];
+ test.ft = inputs_ft[i];
+ test.fd = tests_S[j];
+ test.fs = inputs_fs[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dd, inputs_ds[i]);
+ CHECK_EQ(test.fd, inputs_fs[i]);
+
+ test.dd = tests_D[j+1];
+ test.fd = tests_S[j+1];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dd, inputs_dt[i]);
+ CHECK_EQ(test.fd, inputs_ft[i]);
+ }
+ }
+ }
+}
+
+
+TEST(rint_s) {
+ if (kArchVariant == kMips64r6) {
+ const int tableLength = 30;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float b;
+ int fcsr;
+ }TestFloat;
+
+ TestFloat test;
+ float inputs[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E+38, 6.27463370218383111104242366943E-37,
+ 309485009821345068724781056.89,
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RN[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 0,
+ 309485009821345068724781057.0,
+ 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
+ -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RZ[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 0,
+ 309485009821345068724781057.0,
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RP[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 1,
+ 309485009821345068724781057.0,
+ 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RM[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 0,
+ 309485009821345068724781057.0,
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ int fcsr_inputs[4] =
+ {kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
+ float* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lw(t0, MemOperand(a0, offsetof(TestFloat, fcsr)) );
+ __ cfc1(t1, FCSR);
+ __ ctc1(t0, FCSR);
+ __ rint_s(f8, f4);
+ __ swc1(f8, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ ctc1(t1, FCSR);
__ jr(ra);
__ nop();
@@ -1672,11 +1890,10 @@ TEST(MIPS19) {
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
- for (int j = 0;j < 4;j++) {
+ for (int j = 0; j < 4; j++) {
test.fcsr = fcsr_inputs[j];
- for (int i = 0;i < tableLength;i++) {
+ for (int i = 0; i < tableLength; i++) {
test.a = inputs[i];
- std::cout << j << " " << i << "\n";
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.b, outputs[j][i]);
}
@@ -1685,7 +1902,358 @@ TEST(MIPS19) {
}
-TEST(MIPS20) {
+TEST(mina_maxa) {
+ if (kArchVariant == kMips64r6) {
+ const int tableLength = 12;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ double b;
+ double resd;
+ double resd1;
+ float c;
+ float d;
+ float resf;
+ float resf1;
+ }TestFloat;
+
+ TestFloat test;
+ double inputsa[tableLength] = {
+ 5.3, 4.8, 6.1,
+ 9.8, 9.8, 9.8,
+ -10.0, -8.9, -9.8,
+ -10.0, -8.9, -9.8
+ };
+ double inputsb[tableLength] = {
+ 4.8, 5.3, 6.1,
+ -10.0, -8.9, -9.8,
+ 9.8, 9.8, 9.8,
+ -9.8, -11.2, -9.8
+ };
+ double resd[tableLength] = {
+ 4.8, 4.8, 6.1,
+ 9.8, -8.9, 9.8,
+ 9.8, -8.9, 9.8,
+ -9.8, -8.9, -9.8
+ };
+ double resd1[tableLength] = {
+ 5.3, 5.3, 6.1,
+ -10.0, 9.8, 9.8,
+ -10.0, 9.8, 9.8,
+ -10.0, -11.2, -9.8
+ };
+ float inputsc[tableLength] = {
+ 5.3, 4.8, 6.1,
+ 9.8, 9.8, 9.8,
+ -10.0, -8.9, -9.8,
+ -10.0, -8.9, -9.8
+ };
+ float inputsd[tableLength] = {
+ 4.8, 5.3, 6.1,
+ -10.0, -8.9, -9.8,
+ 9.8, 9.8, 9.8,
+ -9.8, -11.2, -9.8
+ };
+ float resf[tableLength] = {
+ 4.8, 4.8, 6.1,
+ 9.8, -8.9, 9.8,
+ 9.8, -8.9, 9.8,
+ -9.8, -8.9, -9.8
+ };
+ float resf1[tableLength] = {
+ 5.3, 5.3, 6.1,
+ -10.0, 9.8, 9.8,
+ -10.0, 9.8, 9.8,
+ -10.0, -11.2, -9.8
+ };
+
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ lwc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ lwc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ mina_d(f6, f2, f4);
+ __ mina_s(f12, f8, f10);
+ __ maxa_d(f14, f2, f4);
+ __ maxa_s(f16, f8, f10);
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, resf)) );
+ __ sdc1(f6, MemOperand(a0, offsetof(TestFloat, resd)) );
+ __ swc1(f16, MemOperand(a0, offsetof(TestFloat, resf1)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(TestFloat, resd1)) );
+ __ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputsa[i];
+ test.b = inputsb[i];
+ test.c = inputsc[i];
+ test.d = inputsd[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+
+ CHECK_EQ(test.resd, resd[i]);
+ CHECK_EQ(test.resf, resf[i]);
+ CHECK_EQ(test.resd1, resd1[i]);
+ CHECK_EQ(test.resf1, resf1[i]);
+ }
+ }
+}
+
+
+
+// ----------------------mips32r2 specific tests----------------------
+TEST(trunc_l) {
+ if (kArchVariant == kMips64r2) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c; // a trunc result
+ int64_t d; // b trunc result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ trunc_l_d(f8, f4);
+ __ trunc_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+ }
+}
+
+
+TEST(movz_movn) {
+ if (kArchVariant == kMips64r2) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ int64_t rt;
+ double a;
+ double b;
+ double bold;
+ double b1;
+ double bold1;
+ float c;
+ float d;
+ float dold;
+ float d1;
+ float dold1;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ double inputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ float outputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+ double outputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ lw(t0, MemOperand(a0, offsetof(TestFloat, rt)) );
+ __ li(t1, 0x0);
+ __ mtc1(t1, f12);
+ __ mtc1(t1, f10);
+ __ mtc1(t1, f16);
+ __ mtc1(t1, f14);
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, bold)) );
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, dold)) );
+ __ sdc1(f16, MemOperand(a0, offsetof(TestFloat, bold1)) );
+ __ swc1(f14, MemOperand(a0, offsetof(TestFloat, dold1)) );
+ __ movz_s(f10, f6, t0);
+ __ movz_d(f12, f2, t0);
+ __ movn_s(f14, f6, t0);
+ __ movn_d(f16, f2, t0);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ swc1(f14, MemOperand(a0, offsetof(TestFloat, d1)) );
+ __ sdc1(f16, MemOperand(a0, offsetof(TestFloat, b1)) );
+ __ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.c = inputs_S[i];
+
+ test.rt = 1;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, test.bold);
+ CHECK_EQ(test.d, test.dold);
+ CHECK_EQ(test.b1, outputs_D[i]);
+ CHECK_EQ(test.d1, outputs_S[i]);
+
+ test.rt = 0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, outputs_D[i]);
+ CHECK_EQ(test.d, outputs_S[i]);
+ CHECK_EQ(test.b1, test.bold1);
+ CHECK_EQ(test.d1, test.dold1);
+ }
+ }
+}
+
+
+TEST(movt_movd) {
+ if (kArchVariant == kMips64r2) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ typedef struct test_float {
+ double srcd;
+ double dstd;
+ double dstdold;
+ double dstd1;
+ double dstdold1;
+ float srcf;
+ float dstf;
+ float dstfold;
+ float dstf1;
+ float dstfold1;
+ int32_t cc;
+ int32_t fcsr;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 5.3, -5.3, 20.8, -2.9
+ };
+ double inputs_S[tableLength] = {
+ 4.88, 4.8, -4.8, -0.29
+ };
+
+ float outputs_S[tableLength] = {
+ 4.88, 4.8, -4.8, -0.29
+ };
+ double outputs_D[tableLength] = {
+ 5.3, -5.3, 20.8, -2.9
+ };
+ int condition_flags[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+
+ for (int i = 0; i < tableLength; i++) {
+ test.srcd = inputs_D[i];
+ test.srcf = inputs_S[i];
+
+ for (int j = 0; j< 8; j++) {
+ test.cc = condition_flags[j];
+ if (test.cc == 0) {
+ test.fcsr = 1 << 23;
+ } else {
+ test.fcsr = 1 << (24+condition_flags[j]);
+ }
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, srcd)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, srcf)) );
+ __ lw(t1, MemOperand(a0, offsetof(TestFloat, fcsr)) );
+ __ cfc1(t0, FCSR);
+ __ ctc1(t1, FCSR);
+ __ li(t2, 0x0);
+ __ mtc1(t2, f12);
+ __ mtc1(t2, f10);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstdold)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstfold)) );
+ __ movt_s(f12, f4, test.cc);
+ __ movt_d(f10, f2, test.cc);
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstf)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstd)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstdold1)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstfold1)) );
+ __ movf_s(f12, f4, test.cc);
+ __ movf_d(f10, f2, test.cc);
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstf1)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstd1)) );
+ __ ctc1(t0, 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());
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dstf, outputs_S[i]);
+ CHECK_EQ(test.dstd, outputs_D[i]);
+ CHECK_EQ(test.dstf1, test.dstfold1);
+ CHECK_EQ(test.dstd1, test.dstdold1);
+ test.fcsr = 0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dstf, test.dstfold);
+ CHECK_EQ(test.dstd, test.dstdold);
+ CHECK_EQ(test.dstf1, outputs_S[i]);
+ CHECK_EQ(test.dstd1, outputs_D[i]);
+ }
+ }
+ }
+}
+
+
+
+// ----------------------tests for all archs--------------------------
+TEST(cvt_w_d) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
@@ -1736,12 +2304,12 @@ TEST(MIPS20) {
int fcsr_inputs[4] =
{kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, a)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(Test, fcsr)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lw(t0, MemOperand(a0, offsetof(Test, fcsr)) );
__ cfc1(t1, FCSR);
__ ctc1(t0, FCSR);
__ cvt_w_d(f8, f4);
- __ swc1(f8, MemOperand(a0, OFFSET_OF(Test, b)) );
+ __ swc1(f8, MemOperand(a0, offsetof(Test, b)) );
__ ctc1(t1, FCSR);
__ jr(ra);
__ nop();
@@ -1751,9 +2319,9 @@ TEST(MIPS20) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
- for (int j = 0;j < 4;j++) {
+ for (int j = 0; j < 4; j++) {
test.fcsr = fcsr_inputs[j];
- for (int i = 0;i < tableLength;i++) {
+ for (int i = 0; i < tableLength; i++) {
test.a = inputs[i];
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.b, outputs[j][i]);
@@ -1762,111 +2330,736 @@ TEST(MIPS20) {
}
-TEST(MIPS21) {
- if (kArchVariant == kMips64r6) {
- const int tableLength = 30;
+TEST(trunc_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a trunc result
+ int32_t d; // b trunc result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ trunc_w_d(f8, f4);
+ __ trunc_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(round_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a trunc result
+ int32_t d; // b trunc result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
+ -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ round_w_d(f8, f4);
+ __ round_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(round_l) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0);
-
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
typedef struct test_float {
double a;
- double b;
- int fcsr;
- }TestFloat;
+ float b;
+ int64_t c;
+ int64_t d;
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
+ -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ round_l_d(f8, f4);
+ __ round_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ std::cout<< i<< "\n";
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
- TestFloat test;
- double inputs[tableLength] = {18446744073709551617.0,
- 4503599627370496.0, -4503599627370496.0,
- 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
- 1.7976931348623157E308, 6.27463370218383111104242366943E-307,
- 309485009821345068724781056.89,
+
+TEST(sub) {
+ const int tableLength = 12;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float b;
+ float resultS;
+ double c;
+ double d;
+ double resultD;
+ }TestFloat;
+
+ TestFloat test;
+ double inputfs_D[tableLength] = {
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9
+ };
+ double inputft_D[tableLength] = {
+ 4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
+ -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
+ };
+ double outputs_D[tableLength] = {
+ 0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
+ 10.1, 10.1, 5.8, -0.5, 0.5, 0.0
+ };
+ float inputfs_S[tableLength] = {
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9
+ };
+ float inputft_S[tableLength] = {
+ 4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
+ -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
+ };
+ float outputs_S[tableLength] = {
+ 0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
+ 10.1, 10.1, 5.8, -0.5, 0.5, 0.0
+ };
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ ldc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ sub_s(f6, f2, f4);
+ __ sub_d(f12, f8, f10);
+ __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputfs_S[i];
+ test.b = inputft_S[i];
+ test.c = inputfs_D[i];
+ test.d = inputft_D[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resultS, outputs_S[i]);
+ CHECK_EQ(test.resultD, outputs_D[i]);
+ }
+}
+
+
+TEST(sqrt_rsqrt_recip) {
+ const int tableLength = 4;
+ const double deltaDouble = 2E-15;
+ const float deltaFloat = 2E-7;
+ const float sqrt2_s = sqrt(2);
+ const double sqrt2_d = sqrt(2);
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float resultS;
+ float resultS1;
+ float resultS2;
+ double c;
+ double resultD;
+ double resultD1;
+ double resultD2;
+ }TestFloat;
+ TestFloat test;
+
+ double inputs_D[tableLength] = {
+ 0.0L, 4.0L, 2.0L, 4e-28L
+ };
+
+ double outputs_D[tableLength] = {
+ 0.0L, 2.0L, sqrt2_d, 2e-14L
+ };
+ float inputs_S[tableLength] = {
+ 0.0, 4.0, 2.0, 4e-28
+ };
+
+ float outputs_S[tableLength] = {
+ 0.0, 2.0, sqrt2_s, 2e-14
+ };
+
+
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ sqrt_s(f6, f2);
+ __ sqrt_d(f12, f8);
+ __ rsqrt_d(f14, f8);
+ __ rsqrt_s(f16, f2);
+ __ recip_d(f18, f8);
+ __ recip_s(f20, f2);
+ __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ swc1(f16, MemOperand(a0, offsetof(TestFloat, resultS1)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(TestFloat, resultD1)) );
+ __ swc1(f20, MemOperand(a0, offsetof(TestFloat, resultS2)) );
+ __ sdc1(f18, MemOperand(a0, offsetof(TestFloat, resultD2)) );
+ __ 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());
+
+ for (int i = 0; i < tableLength; i++) {
+ float f1;
+ double d1;
+ test.a = inputs_S[i];
+ test.c = inputs_D[i];
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+
+ CHECK_EQ(test.resultS, outputs_S[i]);
+ CHECK_EQ(test.resultD, outputs_D[i]);
+
+ if (i != 0) {
+ f1 = test.resultS1 - 1.0F/outputs_S[i];
+ f1 = (f1 < 0) ? f1 : -f1;
+ CHECK(f1 <= deltaFloat);
+ d1 = test.resultD1 - 1.0L/outputs_D[i];
+ d1 = (d1 < 0) ? d1 : -d1;
+ CHECK(d1 <= deltaDouble);
+ f1 = test.resultS2 - 1.0F/inputs_S[i];
+ f1 = (f1 < 0) ? f1 : -f1;
+ CHECK(f1 <= deltaFloat);
+ d1 = test.resultD2 - 1.0L/inputs_D[i];
+ d1 = (d1 < 0) ? d1 : -d1;
+ CHECK(d1 <= deltaDouble);
+ } else {
+ CHECK_EQ(test.resultS1, 1.0F/outputs_S[i]);
+ CHECK_EQ(test.resultD1, 1.0L/outputs_D[i]);
+ CHECK_EQ(test.resultS2, 1.0F/inputs_S[i]);
+ CHECK_EQ(test.resultD2, 1.0L/inputs_D[i]);
+ }
+ }
+}
+
+
+TEST(neg) {
+ const int tableLength = 2;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float resultS;
+ double c;
+ double resultD;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 4.0, -2.0
+ };
+
+ double outputs_D[tableLength] = {
+ -4.0, 2.0
+ };
+ float inputs_S[tableLength] = {
+ 4.0, -2.0
+ };
+
+ float outputs_S[tableLength] = {
+ -4.0, 2.0
+ };
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ neg_s(f6, f2);
+ __ neg_d(f12, f8);
+ __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_S[i];
+ test.c = inputs_D[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resultS, outputs_S[i]);
+ CHECK_EQ(test.resultD, outputs_D[i]);
+ }
+}
+
+
+
+TEST(mul) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float b;
+ float resultS;
+ double c;
+ double d;
+ double resultD;
+ }TestFloat;
+
+ TestFloat test;
+ double inputfs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ double inputft_D[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ float inputfs_S[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ float inputft_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ mul_s(f10, f2, f4);
+ __ mul_d(f12, f6, f8);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputfs_S[i];
+ test.b = inputft_S[i];
+ test.c = inputfs_D[i];
+ test.d = inputft_D[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resultS, inputfs_S[i]*inputft_S[i]);
+ CHECK_EQ(test.resultD, inputfs_D[i]*inputft_D[i]);
+ }
+}
+
+
+TEST(mov) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ double b;
+ float c;
+ float d;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ double inputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ float outputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+ double outputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ mov_s(f18, f6);
+ __ mov_d(f20, f2);
+ __ swc1(f18, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ sdc1(f20, MemOperand(a0, offsetof(TestFloat, 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.c = inputs_S[i];
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, outputs_D[i]);
+ CHECK_EQ(test.d, outputs_S[i]);
+ }
+}
+
+
+TEST(floor_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a floor result
+ int32_t d; // b floor result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
-2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
- 37778931862957161709568.0, 37778931862957161709569.0,
- 37778931862957161709580.0, 37778931862957161709581.0,
- 37778931862957161709582.0, 37778931862957161709583.0,
- 37778931862957161709584.0, 37778931862957161709585.0,
- 37778931862957161709586.0, 37778931862957161709587.0};
- double outputs_RN[tableLength] = {18446744073709551617.0,
- 4503599627370496.0, -4503599627370496.0,
- 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
- 1.7976931348623157E308, 0,
- 309485009821345068724781057.0,
- 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
- -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
- 37778931862957161709568.0, 37778931862957161709569.0,
- 37778931862957161709580.0, 37778931862957161709581.0,
- 37778931862957161709582.0, 37778931862957161709583.0,
- 37778931862957161709584.0, 37778931862957161709585.0,
- 37778931862957161709586.0, 37778931862957161709587.0};
- double outputs_RZ[tableLength] = {18446744073709551617.0,
- 4503599627370496.0, -4503599627370496.0,
- 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
- 1.7976931348623157E308, 0,
- 309485009821345068724781057.0,
- 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
- -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
- 37778931862957161709568.0, 37778931862957161709569.0,
- 37778931862957161709580.0, 37778931862957161709581.0,
- 37778931862957161709582.0, 37778931862957161709583.0,
- 37778931862957161709584.0, 37778931862957161709585.0,
- 37778931862957161709586.0, 37778931862957161709587.0};
- double outputs_RP[tableLength] = {18446744073709551617.0,
- 4503599627370496.0, -4503599627370496.0,
- 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
- 1.7976931348623157E308, 1,
- 309485009821345068724781057.0,
- 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
- -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
- 37778931862957161709568.0, 37778931862957161709569.0,
- 37778931862957161709580.0, 37778931862957161709581.0,
- 37778931862957161709582.0, 37778931862957161709583.0,
- 37778931862957161709584.0, 37778931862957161709585.0,
- 37778931862957161709586.0, 37778931862957161709587.0};
- double outputs_RM[tableLength] = {18446744073709551617.0,
- 4503599627370496.0, -4503599627370496.0,
- 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
- 1.7976931348623157E308, 0,
- 309485009821345068724781057.0,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
-3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
- 37778931862957161709568.0, 37778931862957161709569.0,
- 37778931862957161709580.0, 37778931862957161709581.0,
- 37778931862957161709582.0, 37778931862957161709583.0,
- 37778931862957161709584.0, 37778931862957161709585.0,
- 37778931862957161709586.0, 37778931862957161709587.0};
- int fcsr_inputs[4] =
- {kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
- double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(TestFloat, fcsr)) );
- __ cfc1(t1, FCSR);
- __ ctc1(t0, FCSR);
- __ rint_d(f8, f4);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b)) );
- __ ctc1(t1, FCSR);
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ floor_w_d(f8, f4);
+ __ floor_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(floor_l) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c;
+ int64_t d;
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ floor_l_d(f8, f4);
+ __ floor_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
__ jr(ra);
__ nop();
-
+ Test test;
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());
- for (int j = 0;j < 4;j++) {
- test.fcsr = fcsr_inputs[j];
- for (int i = 0;i < tableLength;i++) {
- test.a = inputs[i];
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.b, outputs[j][i]);
- }
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
}
+}
+
+
+TEST(ceil_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a floor result
+ int32_t d; // b floor result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ ceil_w_d(f8, f4);
+ __ ceil_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
}
}
+TEST(ceil_l) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c;
+ int64_t d;
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ ceil_l_d(f8, f4);
+ __ ceil_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ 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());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
TEST(jump_tables1) {
@@ -1930,8 +3123,9 @@ TEST(jump_tables1) {
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
for (int i = 0; i < kNumCases; ++i) {
- int res = reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, i, 0, 0, 0, 0));
- ::printf("f(%d) = %d\n", i, res);
+ int64_t res = reinterpret_cast<int64_t>(
+ CALL_GENERATED_CODE(f, i, 0, 0, 0, 0));
+ ::printf("f(%d) = %" PRId64 "\n", i, res);
CHECK_EQ(values[i], static_cast<int>(res));
}
}
@@ -2002,8 +3196,9 @@ TEST(jump_tables2) {
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
for (int i = 0; i < kNumCases; ++i) {
- int res = reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, i, 0, 0, 0, 0));
- ::printf("f(%d) = %d\n", i, res);
+ int64_t res = reinterpret_cast<int64_t>(
+ CALL_GENERATED_CODE(f, i, 0, 0, 0, 0));
+ ::printf("f(%d) = %" PRId64 "\n", i, res);
CHECK_EQ(values[i], res);
}
}
@@ -2095,4 +3290,2080 @@ TEST(jump_tables3) {
}
+TEST(BITSWAP) {
+ // Test BITSWAP
+ if (kArchVariant == kMips64r6) {
+ 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;
+ } T;
+ T t;
+
+ Assembler assm(isolate, NULL, 0);
+
+ __ ld(a4, MemOperand(a0, offsetof(T, r1)));
+ __ nop();
+ __ bitswap(a6, a4);
+ __ sd(a6, MemOperand(a0, offsetof(T, r1)));
+
+ __ ld(a4, MemOperand(a0, offsetof(T, r2)));
+ __ nop();
+ __ bitswap(a6, a4);
+ __ sd(a6, MemOperand(a0, offsetof(T, r2)));
+
+ __ ld(a4, MemOperand(a0, offsetof(T, r3)));
+ __ nop();
+ __ bitswap(a6, a4);
+ __ sd(a6, MemOperand(a0, offsetof(T, r3)));
+
+ __ ld(a4, MemOperand(a0, offsetof(T, r4)));
+ __ nop();
+ __ bitswap(a6, a4);
+ __ sd(a6, MemOperand(a0, offsetof(T, r4)));
+
+ __ ld(a4, MemOperand(a0, offsetof(T, r5)));
+ __ nop();
+ __ dbitswap(a6, a4);
+ __ sd(a6, MemOperand(a0, offsetof(T, r5)));
+
+ __ ld(a4, MemOperand(a0, offsetof(T, r6)));
+ __ nop();
+ __ dbitswap(a6, a4);
+ __ sd(a6, MemOperand(a0, offsetof(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.r1 = 0x00102100781A15C3;
+ t.r2 = 0x001021008B71FCDE;
+ t.r3 = 0xFF8017FF781A15C3;
+ t.r4 = 0xFF8017FF8B71FCDE;
+ t.r5 = 0x10C021098B71FCDE;
+ t.r6 = 0xFB8017FF781A15C3;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(static_cast<int64_t>(0x000000001E58A8C3L), t.r1);
+ CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFD18E3F7BL), t.r2);
+ CHECK_EQ(static_cast<int64_t>(0x000000001E58A8C3L), t.r3);
+ CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFD18E3F7BL), t.r4);
+ CHECK_EQ(static_cast<int64_t>(0x08038490D18E3F7BL), t.r5);
+ CHECK_EQ(static_cast<int64_t>(0xDF01E8FF1E58A8C3L), t.r6);
+ }
+}
+
+
+TEST(class_fmt) {
+ if (kArchVariant == kMips64r6) {
+ // Test CLASS.fmt instruction.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ double dSignalingNan;
+ double dQuietNan;
+ double dNegInf;
+ double dNegNorm;
+ double dNegSubnorm;
+ double dNegZero;
+ double dPosInf;
+ double dPosNorm;
+ double dPosSubnorm;
+ double dPosZero;
+ float fSignalingNan;
+ float fQuietNan;
+ float fNegInf;
+ float fNegNorm;
+ float fNegSubnorm;
+ float fNegZero;
+ float fPosInf;
+ float fPosNorm;
+ float fPosSubnorm;
+ float fPosZero; } 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);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dSignalingNan)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dSignalingNan)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dQuietNan)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dQuietNan)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegInf)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegInf)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegNorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegNorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegSubnorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegSubnorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegZero)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegZero)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosInf)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosInf)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosNorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosNorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosSubnorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosSubnorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosZero)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosZero)));
+
+ // Testing instruction CLASS.S
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fSignalingNan)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fSignalingNan)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fQuietNan)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fQuietNan)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegInf)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegInf)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegNorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegNorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegSubnorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegSubnorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegZero)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegZero)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosInf)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosInf)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosNorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosNorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosSubnorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosSubnorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosZero)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosZero)));
+
+ __ 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());
+
+ // Double test values.
+ t.dSignalingNan = std::numeric_limits<double>::signaling_NaN();
+ t.dQuietNan = std::numeric_limits<double>::quiet_NaN();
+ t.dNegInf = -1.0 / 0.0;
+ t.dNegNorm = -5.0;
+ t.dNegSubnorm = -DBL_MIN / 2.0;
+ t.dNegZero = -0.0;
+ t.dPosInf = 2.0 / 0.0;
+ t.dPosNorm = 275.35;
+ t.dPosSubnorm = DBL_MIN / 2.0;
+ t.dPosZero = +0.0;
+ // Float test values
+
+ t.fSignalingNan = std::numeric_limits<float>::signaling_NaN();
+ t.fQuietNan = std::numeric_limits<float>::quiet_NaN();
+ t.fNegInf = -0.5/0.0;
+ t.fNegNorm = -FLT_MIN;
+ t.fNegSubnorm = -FLT_MIN / 1.5;
+ t.fNegZero = -0.0;
+ t.fPosInf = 100000.0 / 0.0;
+ t.fPosNorm = FLT_MAX;
+ t.fPosSubnorm = FLT_MIN / 20.0;
+ t.fPosZero = +0.0;
+
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+ // Expected double results.
+ CHECK_EQ(bit_cast<int64_t>(t.dNegInf), 0x004);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegNorm), 0x008);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegSubnorm), 0x010);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegZero), 0x020);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosInf), 0x040);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosNorm), 0x080);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosSubnorm), 0x100);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosZero), 0x200);
+
+ // Expected float results.
+ CHECK_EQ(bit_cast<int32_t>(t.fNegInf), 0x004);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegNorm), 0x008);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegSubnorm), 0x010);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegZero), 0x020);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosInf), 0x040);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosNorm), 0x080);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosSubnorm), 0x100);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosZero), 0x200);
+ }
+}
+
+
+TEST(ABS) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ int64_t fir;
+ double a;
+ float b;
+ double fcsr;
+ } TestFloat;
+
+ TestFloat test;
+
+ // Save FIR.
+ __ cfc1(a1, FCSR);
+ __ sd(a1, MemOperand(a0, offsetof(TestFloat, fcsr)));
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
+ __ abs_d(f10, f4);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, a)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)));
+ __ abs_s(f10, f4);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, b)));
+
+ // 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());
+ test.a = -2.0;
+ test.b = -2.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, 2.0);
+ CHECK_EQ(test.b, 2.0);
+
+ test.a = 2.0;
+ test.b = 2.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, 2.0);
+ CHECK_EQ(test.b, 2.0);
+
+ // Testing biggest positive number
+ test.a = std::numeric_limits<double>::max();
+ test.b = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::max());
+ CHECK_EQ(test.b, std::numeric_limits<float>::max());
+
+ // Testing smallest negative number
+ test.a = -std::numeric_limits<double>::max(); // lowest()
+ test.b = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::max());
+ CHECK_EQ(test.b, std::numeric_limits<float>::max());
+
+ // Testing smallest positive number
+ test.a = -std::numeric_limits<double>::min();
+ test.b = -std::numeric_limits<float>::min();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::min());
+ CHECK_EQ(test.b, std::numeric_limits<float>::min());
+
+ // Testing infinity
+ test.a = -std::numeric_limits<double>::max()
+ / std::numeric_limits<double>::min();
+ test.b = -std::numeric_limits<float>::max()
+ / std::numeric_limits<float>::min();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::max()
+ / std::numeric_limits<double>::min());
+ CHECK_EQ(test.b, std::numeric_limits<float>::max()
+ / std::numeric_limits<float>::min());
+
+ test.a = std::numeric_limits<double>::quiet_NaN();
+ test.b = std::numeric_limits<float>::quiet_NaN();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isnan(test.a), true);
+ CHECK_EQ(std::isnan(test.b), true);
+
+ test.a = std::numeric_limits<double>::signaling_NaN();
+ test.b = std::numeric_limits<float>::signaling_NaN();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isnan(test.a), true);
+ CHECK_EQ(std::isnan(test.b), true);
+}
+
+
+TEST(ADD_FMT) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ double b;
+ double c;
+ float fa;
+ float fb;
+ float fc;
+ } TestFloat;
+
+ TestFloat test;
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
+ __ add_d(f10, f8, f4);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, fa)));
+ __ lwc1(f8, MemOperand(a0, offsetof(TestFloat, fb)));
+ __ add_s(f10, f8, f4);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, fc)));
+
+ __ 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());
+ test.a = 2.0;
+ test.b = 3.0;
+ test.fa = 2.0;
+ test.fb = 3.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, 5.0);
+ CHECK_EQ(test.fc, 5.0);
+
+ test.a = std::numeric_limits<double>::max();
+ test.b = -std::numeric_limits<double>::max(); // lowest()
+ test.fa = std::numeric_limits<float>::max();
+ test.fb = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, 0.0);
+ CHECK_EQ(test.fc, 0.0);
+
+ test.a = std::numeric_limits<double>::max();
+ test.b = std::numeric_limits<double>::max();
+ test.fa = std::numeric_limits<float>::max();
+ test.fb = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isfinite(test.c), false);
+ CHECK_EQ(std::isfinite(test.fc), false);
+
+ test.a = 5.0;
+ test.b = std::numeric_limits<double>::signaling_NaN();
+ test.fa = 5.0;
+ test.fb = std::numeric_limits<float>::signaling_NaN();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isnan(test.c), true);
+ CHECK_EQ(std::isnan(test.fc), true);
+}
+
+
+TEST(C_COND_FMT) {
+ if (kArchVariant == kMips64r2) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double dOp1;
+ double dOp2;
+ uint32_t dF;
+ uint32_t dUn;
+ uint32_t dEq;
+ uint32_t dUeq;
+ uint32_t dOlt;
+ uint32_t dUlt;
+ uint32_t dOle;
+ uint32_t dUle;
+ float fOp1;
+ float fOp2;
+ uint32_t fF;
+ uint32_t fUn;
+ uint32_t fEq;
+ uint32_t fUeq;
+ uint32_t fOlt;
+ uint32_t fUlt;
+ uint32_t fOle;
+ uint32_t fUle;
+ } TestFloat;
+
+ TestFloat test;
+
+ __ li(t1, 1);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, dOp1)));
+ __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, dOp2)));
+
+ __ lwc1(f14, MemOperand(a0, offsetof(TestFloat, fOp1)));
+ __ lwc1(f16, MemOperand(a0, offsetof(TestFloat, fOp2)));
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(F, f4, f6, 0);
+ __ c_s(F, f14, f16, 2);
+ __ movt(t2, t1, 0);
+ __ movt(t3, t1, 2);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dF)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fF)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(UN, f4, f6, 2);
+ __ c_s(UN, f14, f16, 4);
+ __ movt(t2, t1, 2);
+ __ movt(t3, t1, 4);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUn)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUn)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(EQ, f4, f6, 4);
+ __ c_s(EQ, f14, f16, 6);
+ __ movt(t2, t1, 4);
+ __ movt(t3, t1, 6);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dEq)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fEq)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(UEQ, f4, f6, 6);
+ __ c_s(UEQ, f14, f16, 0);
+ __ movt(t2, t1, 6);
+ __ movt(t3, t1, 0);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUeq)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUeq)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(OLT, f4, f6, 0);
+ __ c_s(OLT, f14, f16, 2);
+ __ movt(t2, t1, 0);
+ __ movt(t3, t1, 2);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dOlt)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fOlt)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(ULT, f4, f6, 2);
+ __ c_s(ULT, f14, f16, 4);
+ __ movt(t2, t1, 2);
+ __ movt(t3, t1, 4);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUlt)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUlt)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(OLE, f4, f6, 4);
+ __ c_s(OLE, f14, f16, 6);
+ __ movt(t2, t1, 4);
+ __ movt(t3, t1, 6);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dOle)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fOle)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(ULE, f4, f6, 6);
+ __ c_s(ULE, f14, f16, 0);
+ __ movt(t2, t1, 6);
+ __ movt(t3, t1, 0);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUle)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUle)) );
+
+ __ 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());
+ test.dOp1 = 2.0;
+ test.dOp2 = 3.0;
+ test.fOp1 = 2.0;
+ test.fOp2 = 3.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 0U);
+ CHECK_EQ(test.dEq, 0U);
+ CHECK_EQ(test.dUeq, 0U);
+ CHECK_EQ(test.dOlt, 1U);
+ CHECK_EQ(test.dUlt, 1U);
+ CHECK_EQ(test.dOle, 1U);
+ CHECK_EQ(test.dUle, 1U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 0U);
+ CHECK_EQ(test.fEq, 0U);
+ CHECK_EQ(test.fUeq, 0U);
+ CHECK_EQ(test.fOlt, 1U);
+ CHECK_EQ(test.fUlt, 1U);
+ CHECK_EQ(test.fOle, 1U);
+ CHECK_EQ(test.fUle, 1U);
+
+ test.dOp1 = std::numeric_limits<double>::max();
+ test.dOp2 = std::numeric_limits<double>::min();
+ test.fOp1 = std::numeric_limits<float>::min();
+ test.fOp2 = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 0U);
+ CHECK_EQ(test.dEq, 0U);
+ CHECK_EQ(test.dUeq, 0U);
+ CHECK_EQ(test.dOlt, 0U);
+ CHECK_EQ(test.dUlt, 0U);
+ CHECK_EQ(test.dOle, 0U);
+ CHECK_EQ(test.dUle, 0U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 0U);
+ CHECK_EQ(test.fEq, 0U);
+ CHECK_EQ(test.fUeq, 0U);
+ CHECK_EQ(test.fOlt, 0U);
+ CHECK_EQ(test.fUlt, 0U);
+ CHECK_EQ(test.fOle, 0U);
+ CHECK_EQ(test.fUle, 0U);
+
+ test.dOp1 = -std::numeric_limits<double>::max(); // lowest()
+ test.dOp2 = -std::numeric_limits<double>::max(); // lowest()
+ test.fOp1 = std::numeric_limits<float>::max();
+ test.fOp2 = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 0U);
+ CHECK_EQ(test.dEq, 1U);
+ CHECK_EQ(test.dUeq, 1U);
+ CHECK_EQ(test.dOlt, 0U);
+ CHECK_EQ(test.dUlt, 0U);
+ CHECK_EQ(test.dOle, 1U);
+ CHECK_EQ(test.dUle, 1U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 0U);
+ CHECK_EQ(test.fEq, 1U);
+ CHECK_EQ(test.fUeq, 1U);
+ CHECK_EQ(test.fOlt, 0U);
+ CHECK_EQ(test.fUlt, 0U);
+ CHECK_EQ(test.fOle, 1U);
+ CHECK_EQ(test.fUle, 1U);
+
+ test.dOp1 = std::numeric_limits<double>::quiet_NaN();
+ test.dOp2 = 0.0;
+ test.fOp1 = std::numeric_limits<float>::quiet_NaN();
+ test.fOp2 = 0.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 1U);
+ CHECK_EQ(test.dEq, 0U);
+ CHECK_EQ(test.dUeq, 1U);
+ CHECK_EQ(test.dOlt, 0U);
+ CHECK_EQ(test.dUlt, 1U);
+ CHECK_EQ(test.dOle, 0U);
+ CHECK_EQ(test.dUle, 1U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 1U);
+ CHECK_EQ(test.fEq, 0U);
+ CHECK_EQ(test.fUeq, 1U);
+ CHECK_EQ(test.fOlt, 0U);
+ CHECK_EQ(test.fUlt, 1U);
+ CHECK_EQ(test.fOle, 0U);
+ CHECK_EQ(test.fUle, 1U);
+ }
+}
+
+
+TEST(CMP_COND_FMT) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double dOp1;
+ double dOp2;
+ double dF;
+ double dUn;
+ double dEq;
+ double dUeq;
+ double dOlt;
+ double dUlt;
+ double dOle;
+ double dUle;
+ double dOr;
+ double dUne;
+ double dNe;
+ float fOp1;
+ float fOp2;
+ float fF;
+ float fUn;
+ float fEq;
+ float fUeq;
+ float fOlt;
+ float fUlt;
+ float fOle;
+ float fUle;
+ float fOr;
+ float fUne;
+ float fNe;
+ } TestFloat;
+
+ TestFloat test;
+
+ __ li(t1, 1);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, dOp1)));
+ __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, dOp2)));
+
+ __ lwc1(f14, MemOperand(a0, offsetof(TestFloat, fOp1)));
+ __ lwc1(f16, MemOperand(a0, offsetof(TestFloat, fOp2)));
+
+ __ cmp_d(F, f2, f4, f6);
+ __ cmp_s(F, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dF)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fF)) );
+
+ __ cmp_d(UN, f2, f4, f6);
+ __ cmp_s(UN, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUn)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUn)) );
+
+ __ cmp_d(EQ, f2, f4, f6);
+ __ cmp_s(EQ, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dEq)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fEq)) );
+
+ __ cmp_d(UEQ, f2, f4, f6);
+ __ cmp_s(UEQ, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUeq)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUeq)) );
+
+ __ cmp_d(LT, f2, f4, f6);
+ __ cmp_s(LT, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOlt)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOlt)) );
+
+ __ cmp_d(ULT, f2, f4, f6);
+ __ cmp_s(ULT, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUlt)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUlt)) );
+
+ __ cmp_d(LE, f2, f4, f6);
+ __ cmp_s(LE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOle)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOle)) );
+
+ __ cmp_d(ULE, f2, f4, f6);
+ __ cmp_s(ULE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUle)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUle)) );
+
+ __ cmp_d(ORD, f2, f4, f6);
+ __ cmp_s(ORD, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOr)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOr)) );
+
+ __ cmp_d(UNE, f2, f4, f6);
+ __ cmp_s(UNE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUne)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUne)) );
+
+ __ cmp_d(NE, f2, f4, f6);
+ __ cmp_s(NE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dNe)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fNe)) );
+
+ __ 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());
+ uint64_t dTrue = 0xFFFFFFFFFFFFFFFF;
+ uint64_t dFalse = 0x0000000000000000;
+ uint32_t fTrue = 0xFFFFFFFF;
+ uint32_t fFalse = 0x00000000;
+
+ test.dOp1 = 2.0;
+ test.dOp2 = 3.0;
+ test.fOp1 = 2.0;
+ test.fOp2 = 3.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
+
+ test.dOp1 = std::numeric_limits<double>::max();
+ test.dOp2 = std::numeric_limits<double>::min();
+ test.fOp1 = std::numeric_limits<float>::min();
+ test.fOp2 = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fFalse);
+
+ test.dOp1 = -std::numeric_limits<double>::max(); // lowest()
+ test.dOp2 = -std::numeric_limits<double>::max(); // lowest()
+ test.fOp1 = std::numeric_limits<float>::max();
+ test.fOp2 = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
+
+ test.dOp1 = std::numeric_limits<double>::quiet_NaN();
+ test.dOp2 = 0.0;
+ test.fOp1 = std::numeric_limits<float>::quiet_NaN();
+ test.fOp2 = 0.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
+ }
+}
+
+
+TEST(CVT) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float cvt_d_s_in;
+ double cvt_d_s_out;
+ int32_t cvt_d_w_in;
+ double cvt_d_w_out;
+ int64_t cvt_d_l_in;
+ double cvt_d_l_out;
+
+ float cvt_l_s_in;
+ int64_t cvt_l_s_out;
+ double cvt_l_d_in;
+ int64_t cvt_l_d_out;
+
+ double cvt_s_d_in;
+ float cvt_s_d_out;
+ int32_t cvt_s_w_in;
+ float cvt_s_w_out;
+ int64_t cvt_s_l_in;
+ float cvt_s_l_out;
+
+ float cvt_w_s_in;
+ int32_t cvt_w_s_out;
+ double cvt_w_d_in;
+ int32_t cvt_w_d_out;
+ } TestFloat;
+
+ TestFloat test;
+
+ // Save FCSR.
+ __ cfc1(a1, FCSR);
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+
+#define GENERATE_CVT_TEST(x, y, z) \
+ __ y##c1(f0, MemOperand(a0, offsetof(TestFloat, x##_in))); \
+ __ x(f0, f0); \
+ __ nop(); \
+ __ z##c1(f0, MemOperand(a0, offsetof(TestFloat, x##_out)));
+
+ GENERATE_CVT_TEST(cvt_d_s, lw, sd)
+ GENERATE_CVT_TEST(cvt_d_w, lw, sd)
+ GENERATE_CVT_TEST(cvt_d_l, ld, sd)
+
+ GENERATE_CVT_TEST(cvt_l_s, lw, sd)
+ GENERATE_CVT_TEST(cvt_l_d, ld, sd)
+
+ GENERATE_CVT_TEST(cvt_s_d, ld, sw)
+ GENERATE_CVT_TEST(cvt_s_w, lw, sw)
+ GENERATE_CVT_TEST(cvt_s_l, ld, sw)
+
+ GENERATE_CVT_TEST(cvt_w_s, lw, sw)
+ GENERATE_CVT_TEST(cvt_w_d, ld, sw)
+
+ // 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());
+
+ test.cvt_d_s_in = -0.51;
+ test.cvt_d_w_in = -1;
+ test.cvt_d_l_in = -1;
+ test.cvt_l_s_in = -0.51;
+ test.cvt_l_d_in = -0.51;
+ test.cvt_s_d_in = -0.51;
+ test.cvt_s_w_in = -1;
+ test.cvt_s_l_in = -1;
+ test.cvt_w_s_in = -0.51;
+ test.cvt_w_d_in = -0.51;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ CHECK_EQ(test.cvt_l_s_out, -1);
+ CHECK_EQ(test.cvt_l_d_out, -1);
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ CHECK_EQ(test.cvt_w_s_out, -1);
+ CHECK_EQ(test.cvt_w_d_out, -1);
+
+
+ test.cvt_d_s_in = 0.49;
+ test.cvt_d_w_in = 1;
+ test.cvt_d_l_in = 1;
+ test.cvt_l_s_in = 0.49;
+ test.cvt_l_d_in = 0.49;
+ test.cvt_s_d_in = 0.49;
+ test.cvt_s_w_in = 1;
+ test.cvt_s_l_in = 1;
+ test.cvt_w_s_in = 0.49;
+ test.cvt_w_d_in = 0.49;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ CHECK_EQ(test.cvt_l_s_out, 0);
+ CHECK_EQ(test.cvt_l_d_out, 0);
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ CHECK_EQ(test.cvt_w_s_out, 0);
+ CHECK_EQ(test.cvt_w_d_out, 0);
+
+ test.cvt_d_s_in = std::numeric_limits<float>::max();
+ test.cvt_d_w_in = std::numeric_limits<int32_t>::max();
+ test.cvt_d_l_in = std::numeric_limits<int64_t>::max();
+ test.cvt_l_s_in = std::numeric_limits<float>::max();
+ test.cvt_l_d_in = std::numeric_limits<double>::max();
+ test.cvt_s_d_in = std::numeric_limits<double>::max();
+ test.cvt_s_w_in = std::numeric_limits<int32_t>::max();
+ test.cvt_s_l_in = std::numeric_limits<int64_t>::max();
+ test.cvt_w_s_in = std::numeric_limits<float>::max();
+ test.cvt_w_d_in = std::numeric_limits<double>::max();
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ CHECK_EQ(test.cvt_l_s_out, std::numeric_limits<int64_t>::max());
+ CHECK_EQ(test.cvt_l_d_out, std::numeric_limits<int64_t>::max());
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ CHECK_EQ(test.cvt_w_s_out, std::numeric_limits<int32_t>::max());
+ CHECK_EQ(test.cvt_w_d_out, std::numeric_limits<int32_t>::max());
+
+
+ test.cvt_d_s_in = -std::numeric_limits<float>::max(); // lowest()
+ test.cvt_d_w_in = std::numeric_limits<int32_t>::min(); // lowest()
+ test.cvt_d_l_in = std::numeric_limits<int64_t>::min(); // lowest()
+ test.cvt_l_s_in = -std::numeric_limits<float>::max(); // lowest()
+ test.cvt_l_d_in = -std::numeric_limits<double>::max(); // lowest()
+ test.cvt_s_d_in = -std::numeric_limits<double>::max(); // lowest()
+ test.cvt_s_w_in = std::numeric_limits<int32_t>::min(); // lowest()
+ test.cvt_s_l_in = std::numeric_limits<int64_t>::min(); // lowest()
+ test.cvt_w_s_in = -std::numeric_limits<float>::max(); // lowest()
+ test.cvt_w_d_in = -std::numeric_limits<double>::max(); // lowest()
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ // The returned value when converting from fixed-point to float-point
+ // is not consistent between board, simulator and specification
+ // in this test case, therefore modifying the test
+ CHECK(test.cvt_l_s_out == std::numeric_limits<int64_t>::min() ||
+ test.cvt_l_s_out == std::numeric_limits<int64_t>::max());
+ CHECK(test.cvt_l_d_out == std::numeric_limits<int64_t>::min() ||
+ test.cvt_l_d_out == std::numeric_limits<int64_t>::max());
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ CHECK(test.cvt_w_s_out == std::numeric_limits<int32_t>::min() ||
+ test.cvt_w_s_out == std::numeric_limits<int32_t>::max());
+ CHECK(test.cvt_w_d_out == std::numeric_limits<int32_t>::min() ||
+ test.cvt_w_d_out == std::numeric_limits<int32_t>::max());
+
+
+ test.cvt_d_s_in = std::numeric_limits<float>::min();
+ test.cvt_d_w_in = std::numeric_limits<int32_t>::min();
+ test.cvt_d_l_in = std::numeric_limits<int64_t>::min();
+ test.cvt_l_s_in = std::numeric_limits<float>::min();
+ test.cvt_l_d_in = std::numeric_limits<double>::min();
+ test.cvt_s_d_in = std::numeric_limits<double>::min();
+ test.cvt_s_w_in = std::numeric_limits<int32_t>::min();
+ test.cvt_s_l_in = std::numeric_limits<int64_t>::min();
+ test.cvt_w_s_in = std::numeric_limits<float>::min();
+ test.cvt_w_d_in = std::numeric_limits<double>::min();
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ CHECK_EQ(test.cvt_l_s_out, 0);
+ CHECK_EQ(test.cvt_l_d_out, 0);
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ CHECK_EQ(test.cvt_w_s_out, 0);
+ CHECK_EQ(test.cvt_w_d_out, 0);
+}
+
+
+TEST(DIV_FMT) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test {
+ double dOp1;
+ double dOp2;
+ double dRes;
+ float fOp1;
+ float fOp2;
+ float fRes;
+ } Test;
+
+ Test test;
+
+ // Save FCSR.
+ __ cfc1(a1, FCSR);
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, dOp1)) );
+ __ ldc1(f2, MemOperand(a0, offsetof(Test, dOp2)) );
+ __ nop();
+ __ div_d(f6, f4, f2);
+ __ sdc1(f6, MemOperand(a0, offsetof(Test, dRes)) );
+
+ __ lwc1(f4, MemOperand(a0, offsetof(Test, fOp1)) );
+ __ lwc1(f2, MemOperand(a0, offsetof(Test, fOp2)) );
+ __ nop();
+ __ div_s(f6, f4, f2);
+ __ swc1(f6, MemOperand(a0, offsetof(Test, fRes)) );
+
+ // 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());
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+
+ const int test_size = 3;
+
+ double dOp1[test_size] = {
+ 5.0,
+ DBL_MAX,
+ DBL_MAX,
+ };
+ double dOp2[test_size] = {
+ 2.0,
+ 2.0,
+ -DBL_MAX,
+ };
+ double dRes[test_size] = {
+ 2.5,
+ DBL_MAX / 2.0,
+ -1.0,
+ };
+ float fOp1[test_size] = {
+ 5.0,
+ FLT_MAX,
+ FLT_MAX,
+ };
+ float fOp2[test_size] = {
+ 2.0,
+ 2.0,
+ -FLT_MAX,
+ };
+ float fRes[test_size] = {
+ 2.5,
+ FLT_MAX / 2.0,
+ -1.0,
+ };
+
+ for (int i = 0; i < test_size; i++) {
+ test.dOp1 = dOp1[i];
+ test.dOp2 = dOp2[i];
+ test.fOp1 = fOp1[i];
+ test.fOp2 = fOp2[i];
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dRes, dRes[i]);
+ CHECK_EQ(test.fRes, fRes[i]);
+ }
+
+ test.dOp1 = DBL_MAX;
+ test.dOp2 = -0.0;
+ test.fOp1 = FLT_MAX;
+ test.fOp2 = -0.0;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(false, std::isfinite(test.dRes));
+ CHECK_EQ(false, std::isfinite(test.fRes));
+
+ test.dOp1 = 0.0;
+ test.dOp2 = -0.0;
+ test.fOp1 = 0.0;
+ test.fOp2 = -0.0;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(true, std::isnan(test.dRes));
+ CHECK_EQ(true, std::isnan(test.fRes));
+
+ test.dOp1 = std::numeric_limits<double>::quiet_NaN();
+ test.dOp2 = -5.0;
+ test.fOp1 = std::numeric_limits<float>::quiet_NaN();
+ test.fOp2 = -5.0;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(true, std::isnan(test.dRes));
+ CHECK_EQ(true, std::isnan(test.fRes));
+}
+
+
+uint64_t run_align(uint64_t rs_value, uint64_t rt_value, uint8_t bp) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ align(v0, a0, a1, bp);
+ __ 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());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs_value,
+ rt_value,
+ 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_align) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAlign {
+ uint64_t rs_value;
+ uint64_t rt_value;
+ uint8_t bp;
+ uint64_t expected_res;
+ };
+
+ struct TestCaseAlign tc[] = {
+ // rs_value, rt_value, bp, expected_res
+ { 0x11223344, 0xaabbccdd, 0, 0xffffffffaabbccdd },
+ { 0x11223344, 0xaabbccdd, 1, 0xffffffffbbccdd11 },
+ { 0x11223344, 0xaabbccdd, 2, 0xffffffffccdd1122 },
+ { 0x11223344, 0xaabbccdd, 3, 0xffffffffdd112233 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAlign);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ CHECK_EQ(tc[i].expected_res, run_align(tc[i].rs_value,
+ tc[i].rt_value,
+ tc[i].bp));
+ }
+ }
+}
+
+
+uint64_t run_dalign(uint64_t rs_value, uint64_t rt_value, uint8_t bp) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ dalign(v0, a0, a1, bp);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F4 f = FUNCTION_CAST<F4>(code->entry());
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs_value,
+ rt_value,
+ 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_dalign) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseDalign {
+ uint64_t rs_value;
+ uint64_t rt_value;
+ uint8_t bp;
+ uint64_t expected_res;
+ };
+
+ struct TestCaseDalign tc[] = {
+ // rs_value, rt_value, bp, expected_res
+ { 0x1122334455667700, 0xaabbccddeeff8899, 0, 0xaabbccddeeff8899 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 1, 0xbbccddeeff889911 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 2, 0xccddeeff88991122 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 3, 0xddeeff8899112233 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 4, 0xeeff889911223344 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 5, 0xff88991122334455 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 6, 0x8899112233445566 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 7, 0x9911223344556677 }
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDalign);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ CHECK_EQ(tc[i].expected_res, run_dalign(tc[i].rs_value,
+ tc[i].rt_value,
+ tc[i].bp));
+ }
+ }
+}
+
+
+uint64_t PC; // The program counter.
+
+uint64_t run_aluipc(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ aluipc(v0, offset);
+ __ 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());
+ PC = (uint64_t) f; // Set the program counter.
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_aluipc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAluipc {
+ int16_t offset;
+ };
+
+ struct TestCaseAluipc tc[] = {
+ // offset
+ { -32768 }, // 0x8000
+ { -1 }, // 0xFFFF
+ { 0 },
+ { 1 },
+ { 32767 }, // 0x7FFF
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAluipc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ PC = 0;
+ uint64_t res = run_aluipc(tc[i].offset);
+ // Now, the program_counter (PC) is set.
+ uint64_t expected_res = ~0x0FFFF & (PC + (tc[i].offset << 16));
+ CHECK_EQ(expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_auipc(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ auipc(v0, offset);
+ __ 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());
+ PC = (uint64_t) f; // Set the program counter.
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_auipc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAuipc {
+ int16_t offset;
+ };
+
+ struct TestCaseAuipc tc[] = {
+ // offset
+ { -32768 }, // 0x8000
+ { -1 }, // 0xFFFF
+ { 0 },
+ { 1 },
+ { 32767 }, // 0x7FFF
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAuipc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ PC = 0;
+ uint64_t res = run_auipc(tc[i].offset);
+ // Now, the program_counter (PC) is set.
+ uint64_t expected_res = PC + (tc[i].offset << 16);
+ CHECK_EQ(expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_lwpc(int offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ // 256k instructions; 2^8k
+ // addiu t3, a4, 0xffff; (0x250fffff)
+ // ...
+ // addiu t0, a4, 0x0000; (0x250c0000)
+ uint32_t addiu_start_1 = 0x25000000;
+ for (int32_t i = 0xfffff; i >= 0xc0000; --i) {
+ uint32_t addiu_new = addiu_start_1 + i;
+ __ dd(addiu_new);
+ }
+
+ __ lwpc(t8, offset); // offset 0; 0xef080000 (t8 register)
+ __ mov(v0, t8);
+
+ // 256k instructions; 2^8k
+ // addiu a4, a4, 0x0000; (0x25080000)
+ // ...
+ // addiu a7, a4, 0xffff; (0x250bffff)
+ uint32_t addiu_start_2 = 0x25000000;
+ for (int32_t i = 0x80000; i <= 0xbffff; ++i) {
+ uint32_t addiu_new = addiu_start_2 + i;
+ __ dd(addiu_new);
+ }
+
+ __ 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());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_lwpc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseLwpc {
+ int offset;
+ uint64_t expected_res;
+ };
+
+ struct TestCaseLwpc tc[] = {
+ // offset, expected_res
+ { -262144, 0x250fffff }, // offset 0x40000
+ { -4, 0x250c0003 },
+ { -1, 0x250c0000 },
+ { 0, 0xffffffffef080000 },
+ { 1, 0x03001025 }, // mov(v0, t8)
+ { 2, 0x25080000 },
+ { 4, 0x25080002 },
+ { 262143, 0x250bfffd }, // offset 0x3ffff
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLwpc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_lwpc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_lwupc(int offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ // 256k instructions; 2^8k
+ // addiu t3, a4, 0xffff; (0x250fffff)
+ // ...
+ // addiu t0, a4, 0x0000; (0x250c0000)
+ uint32_t addiu_start_1 = 0x25000000;
+ for (int32_t i = 0xfffff; i >= 0xc0000; --i) {
+ uint32_t addiu_new = addiu_start_1 + i;
+ __ dd(addiu_new);
+ }
+
+ __ lwupc(t8, offset); // offset 0; 0xef080000 (t8 register)
+ __ mov(v0, t8);
+
+ // 256k instructions; 2^8k
+ // addiu a4, a4, 0x0000; (0x25080000)
+ // ...
+ // addiu a7, a4, 0xffff; (0x250bffff)
+ uint32_t addiu_start_2 = 0x25000000;
+ for (int32_t i = 0x80000; i <= 0xbffff; ++i) {
+ uint32_t addiu_new = addiu_start_2 + i;
+ __ dd(addiu_new);
+ }
+
+ __ 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());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_lwupc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseLwupc {
+ int offset;
+ uint64_t expected_res;
+ };
+
+ struct TestCaseLwupc tc[] = {
+ // offset, expected_res
+ { -262144, 0x250fffff }, // offset 0x40000
+ { -4, 0x250c0003 },
+ { -1, 0x250c0000 },
+ { 0, 0xef100000 },
+ { 1, 0x03001025 }, // mov(v0, t8)
+ { 2, 0x25080000 },
+ { 4, 0x25080002 },
+ { 262143, 0x250bfffd }, // offset 0x3ffff
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLwupc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_lwupc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_jic(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label get_program_counter, stop_execution;
+ __ push(ra);
+ __ li(v0, 0);
+ __ li(t1, 0x66);
+
+ __ addiu(v0, v0, 0x1); // <-- offset = -32
+ __ addiu(v0, v0, 0x2);
+ __ addiu(v0, v0, 0x10);
+ __ addiu(v0, v0, 0x20);
+ __ beq(v0, t1, &stop_execution);
+ __ nop();
+
+ __ bal(&get_program_counter); // t0 <- program counter
+ __ nop();
+ __ jic(t0, offset);
+
+ __ addiu(v0, v0, 0x100);
+ __ addiu(v0, v0, 0x200);
+ __ addiu(v0, v0, 0x1000);
+ __ addiu(v0, v0, 0x2000); // <--- offset = 16
+ __ pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&get_program_counter);
+ __ mov(t0, ra);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&stop_execution);
+ __ pop(ra);
+ __ 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());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_jic) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseJic {
+ // As rt will be used t0 register which will have value of
+ // the program counter for the jic instruction.
+ int16_t offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseJic tc[] = {
+ // offset, expected_result
+ { 16, 0x2033 },
+ { 4, 0x3333 },
+ { -32, 0x66 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJic);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_jic(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_beqzc(int32_t value, int32_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label stop_execution;
+ __ li(v0, 0);
+ __ li(t1, 0x66);
+
+ __ addiu(v0, v0, 0x1); // <-- offset = -8
+ __ addiu(v0, v0, 0x2);
+ __ addiu(v0, v0, 0x10);
+ __ addiu(v0, v0, 0x20);
+ __ beq(v0, t1, &stop_execution);
+ __ nop();
+
+ __ beqzc(a0, offset);
+
+ __ addiu(v0, v0, 0x1);
+ __ addiu(v0, v0, 0x100);
+ __ addiu(v0, v0, 0x200);
+ __ addiu(v0, v0, 0x1000);
+ __ addiu(v0, v0, 0x2000); // <--- offset = 4
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&stop_execution);
+ __ 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());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, value, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_beqzc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseBeqzc {
+ uint32_t value;
+ int32_t offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseBeqzc tc[] = {
+ // value, offset, expected_res
+ { 0x0, -8, 0x66 },
+ { 0x0, 0, 0x3334 },
+ { 0x0, 1, 0x3333 },
+ { 0xabc, 1, 0x3334 },
+ { 0x0, 4, 0x2033 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBeqzc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_beqzc(tc[i].value, tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_jialc(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label main_block, get_program_counter;
+ __ push(ra);
+ __ li(v0, 0);
+ __ beq(v0, v0, &main_block);
+ __ nop();
+
+ // Block 1
+ __ addiu(v0, v0, 0x1); // <-- offset = -40
+ __ addiu(v0, v0, 0x2);
+ __ jr(ra);
+ __ nop();
+
+ // Block 2
+ __ addiu(v0, v0, 0x10); // <-- offset = -24
+ __ addiu(v0, v0, 0x20);
+ __ jr(ra);
+ __ nop();
+
+ // Block 3 (Main)
+ __ bind(&main_block);
+ __ bal(&get_program_counter); // t0 <- program counter
+ __ nop();
+ __ jialc(t0, offset);
+ __ addiu(v0, v0, 0x4);
+ __ pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ // Block 4
+ __ addiu(v0, v0, 0x100); // <-- offset = 20
+ __ addiu(v0, v0, 0x200);
+ __ jr(ra);
+ __ nop();
+
+ // Block 5
+ __ addiu(v0, v0, 0x1000); // <--- offset = 36
+ __ addiu(v0, v0, 0x2000);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&get_program_counter);
+ __ mov(t0, ra);
+ __ 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());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_jialc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseJialc {
+ // As rt will be used t0 register which will have value of
+ // the program counter for the jialc instruction.
+ int16_t offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseJialc tc[] = {
+ // offset, expected_res
+ { -40, 0x7 },
+ { -24, 0x34 },
+ { 20, 0x304 },
+ { 36, 0x3004 }
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJialc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_jialc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_addiupc(int32_t imm19) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ addiupc(v0, imm19);
+ __ 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());
+ PC = (uint64_t) f; // Set the program counter.
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_addiupc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAddiupc {
+ int32_t imm19;
+ };
+
+ struct TestCaseAddiupc tc[] = {
+ // imm19
+ { -262144 }, // 0x40000
+ { -1 }, // 0x7FFFF
+ { 0 },
+ { 1 }, // 0x00001
+ { 262143 } // 0x3FFFF
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAddiupc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ PC = 0;
+ uint64_t res = run_addiupc(tc[i].imm19);
+ // Now, the program_counter (PC) is set.
+ uint64_t expected_res = PC + (tc[i].imm19 << 2);
+ CHECK_EQ(expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_ldpc(int offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ // 256k instructions; 2 * 2^7k = 2^8k
+ // addiu t3, a4, 0xffff; (0x250fffff)
+ // ...
+ // addiu t0, a4, 0x0000; (0x250c0000)
+ uint32_t addiu_start_1 = 0x25000000;
+ for (int32_t i = 0xfffff; i >= 0xc0000; --i) {
+ uint32_t addiu_new = addiu_start_1 + i;
+ __ dd(addiu_new);
+ }
+
+ __ ldpc(t8, offset); // offset 0; 0xef080000 (t8 register)
+ __ mov(v0, t8);
+
+ // 256k instructions; 2 * 2^7k = 2^8k
+ // addiu a4, a4, 0x0000; (0x25080000)
+ // ...
+ // addiu a7, a4, 0xffff; (0x250bffff)
+ uint32_t addiu_start_2 = 0x25000000;
+ for (int32_t i = 0x80000; i <= 0xbffff; ++i) {
+ uint32_t addiu_new = addiu_start_2 + i;
+ __ dd(addiu_new);
+ }
+
+ __ 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());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_ldpc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseLdpc {
+ int offset;
+ uint64_t expected_res;
+ };
+
+ struct TestCaseLdpc tc[] = {
+ // offset, expected_res
+ { -131072, 0x250ffffe250fffff },
+ { -4, 0x250c0006250c0007 },
+ { -1, 0x250c0000250c0001 },
+ { 0, 0x03001025ef180000 },
+ { 1, 0x2508000125080000 },
+ { 4, 0x2508000725080006 },
+ { 131071, 0x250bfffd250bfffc },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLdpc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_ldpc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+int64_t run_bc(int32_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label continue_1, stop_execution;
+ __ push(ra);
+ __ li(v0, 0);
+ __ li(t8, 0);
+ __ li(t9, 2); // Condition for the stopping execution.
+
+ uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1
+ for (int32_t i = -100; i <= -11; ++i) {
+ __ dd(instruction_addiu);
+ }
+
+ __ addiu(t8, t8, 1); // -10
+
+ __ beq(t8, t9, &stop_execution); // -9
+ __ nop(); // -8
+ __ beq(t8, t8, &continue_1); // -7
+ __ nop(); // -6
+
+ __ bind(&stop_execution);
+ __ pop(ra); // -5, -4
+ __ jr(ra); // -3
+ __ nop(); // -2
+
+ __ bind(&continue_1);
+ __ bc(offset); // -1
+
+ for (int32_t i = 0; i <= 99; ++i) {
+ __ dd(instruction_addiu);
+ }
+
+ __ pop(ra);
+ __ 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, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_bc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseBc {
+ int32_t offset;
+ int64_t expected_res;
+ };
+
+ struct TestCaseBc tc[] = {
+ // offset, expected_result
+ { -100, (abs(-100) - 10) * 2 },
+ { -11, (abs(-100) - 10 + 1) },
+ { 0, (abs(-100) - 10 + 1 + 99) },
+ { 1, (abs(-100) - 10 + 99) },
+ { 99, (abs(-100) - 10 + 1) },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ int64_t res = run_bc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+int64_t run_balc(int32_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label continue_1, stop_execution;
+ __ push(ra);
+ __ li(v0, 0);
+ __ li(t8, 0);
+ __ li(t9, 2); // Condition for stopping execution.
+
+ __ beq(t8, t8, &continue_1);
+ __ nop();
+
+ uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1
+ for (int32_t i = -117; i <= -57; ++i) {
+ __ dd(instruction_addiu);
+ }
+ __ jr(ra); // -56
+ __ nop(); // -55
+
+ for (int32_t i = -54; i <= -4; ++i) {
+ __ dd(instruction_addiu);
+ }
+ __ jr(ra); // -3
+ __ nop(); // -2
+
+ __ bind(&continue_1);
+ __ balc(offset); // -1
+
+ __ pop(ra); // 0, 1
+ __ jr(ra); // 2
+ __ nop(); // 3
+
+ for (int32_t i = 4; i <= 44; ++i) {
+ __ dd(instruction_addiu);
+ }
+ __ 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, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_balc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseBalc {
+ int32_t offset;
+ int64_t expected_res;
+ };
+
+ struct TestCaseBalc tc[] = {
+ // offset, expected_result
+ { -117, 61 },
+ { -54, 51 },
+ { 0, 0 },
+ { 4, 41 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBalc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ int64_t res = run_balc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
#undef __
diff --git a/deps/v8/test/cctest/test-assembler-ppc.cc b/deps/v8/test/cctest/test-assembler-ppc.cc
index 4a2e7d3983..b2dca6a9fc 100644
--- a/deps/v8/test/cctest/test-assembler-ppc.cc
+++ b/deps/v8/test/cctest/test-assembler-ppc.cc
@@ -194,21 +194,21 @@ TEST(3) {
__ mr(r4, r3);
// modify field int i of struct
- __ lwz(r3, MemOperand(r4, OFFSET_OF(T, i)));
+ __ lwz(r3, MemOperand(r4, offsetof(T, i)));
__ srwi(r5, r3, Operand(1));
- __ stw(r5, MemOperand(r4, OFFSET_OF(T, i)));
+ __ stw(r5, MemOperand(r4, offsetof(T, i)));
// modify field char c of struct
- __ lbz(r5, MemOperand(r4, OFFSET_OF(T, c)));
+ __ lbz(r5, MemOperand(r4, offsetof(T, c)));
__ add(r3, r5, r3);
__ slwi(r5, r5, Operand(2));
- __ stb(r5, MemOperand(r4, OFFSET_OF(T, c)));
+ __ stb(r5, MemOperand(r4, offsetof(T, c)));
// modify field int16_t s of struct
- __ lhz(r5, MemOperand(r4, OFFSET_OF(T, s)));
+ __ lhz(r5, MemOperand(r4, offsetof(T, s)));
__ add(r3, r5, r3);
__ srwi(r5, r5, Operand(3));
- __ sth(r5, MemOperand(r4, OFFSET_OF(T, s)));
+ __ sth(r5, MemOperand(r4, offsetof(T, s)));
// restore frame
#if V8_TARGET_ARCH_PPC64
@@ -278,59 +278,59 @@ TEST(4) {
__ sub(fp, ip, Operand(4));
__ mov(r4, Operand(r0));
- __ vldr(d6, r4, OFFSET_OF(T, a));
- __ vldr(d7, r4, OFFSET_OF(T, b));
+ __ vldr(d6, r4, offsetof(T, a));
+ __ vldr(d7, r4, offsetof(T, b));
__ vadd(d5, d6, d7);
- __ vstr(d5, r4, OFFSET_OF(T, c));
+ __ vstr(d5, r4, offsetof(T, c));
__ vmov(r2, r3, d5);
__ vmov(d4, r2, r3);
- __ vstr(d4, r4, OFFSET_OF(T, b));
+ __ vstr(d4, r4, offsetof(T, b));
// Load t.x and t.y, switch values, and store back to the struct.
- __ vldr(s0, r4, OFFSET_OF(T, x));
- __ vldr(s31, r4, OFFSET_OF(T, y));
+ __ vldr(s0, r4, offsetof(T, x));
+ __ vldr(s31, r4, offsetof(T, y));
__ vmov(s16, s0);
__ vmov(s0, s31);
__ vmov(s31, s16);
- __ vstr(s0, r4, OFFSET_OF(T, x));
- __ vstr(s31, r4, OFFSET_OF(T, y));
+ __ vstr(s0, r4, offsetof(T, x));
+ __ vstr(s31, r4, offsetof(T, y));
// Move a literal into a register that can be encoded in the instruction.
__ vmov(d4, 1.0);
- __ vstr(d4, r4, OFFSET_OF(T, e));
+ __ vstr(d4, r4, offsetof(T, e));
// Move a literal into a register that requires 64 bits to encode.
// 0x3ff0000010000000 = 1.000000059604644775390625
__ vmov(d4, 1.000000059604644775390625);
- __ vstr(d4, r4, OFFSET_OF(T, d));
+ __ vstr(d4, r4, offsetof(T, d));
// Convert from floating point to integer.
__ vmov(d4, 2.0);
__ vcvt_s32_f64(s31, d4);
- __ vstr(s31, r4, OFFSET_OF(T, i));
+ __ vstr(s31, r4, offsetof(T, i));
// Convert from integer to floating point.
__ mov(lr, Operand(42));
__ vmov(s31, lr);
__ vcvt_f64_s32(d4, s31);
- __ vstr(d4, r4, OFFSET_OF(T, f));
+ __ vstr(d4, r4, offsetof(T, f));
// Test vabs.
- __ vldr(d1, r4, OFFSET_OF(T, g));
+ __ vldr(d1, r4, offsetof(T, g));
__ vabs(d0, d1);
- __ vstr(d0, r4, OFFSET_OF(T, g));
- __ vldr(d2, r4, OFFSET_OF(T, h));
+ __ vstr(d0, r4, offsetof(T, g));
+ __ vldr(d2, r4, offsetof(T, h));
__ vabs(d0, d2);
- __ vstr(d0, r4, OFFSET_OF(T, h));
+ __ vstr(d0, r4, offsetof(T, h));
// Test vneg.
- __ vldr(d1, r4, OFFSET_OF(T, m));
+ __ vldr(d1, r4, offsetof(T, m));
__ vneg(d0, d1);
- __ vstr(d0, r4, OFFSET_OF(T, m));
- __ vldr(d1, r4, OFFSET_OF(T, n));
+ __ vstr(d0, r4, offsetof(T, m));
+ __ vldr(d1, r4, offsetof(T, n));
__ vneg(d0, d1);
- __ vstr(d0, r4, OFFSET_OF(T, n));
+ __ vstr(d0, r4, offsetof(T, n));
__ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
@@ -677,19 +677,19 @@ TEST(8) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
- __ addi(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ addi(r4, r0, Operand(offsetof(D, a)));
__ vldm(ia_w, r4, d0, d3);
__ vldm(ia_w, r4, d4, d7);
- __ addi(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ addi(r4, r0, Operand(offsetof(D, a)));
__ vstm(ia_w, r4, d6, d7);
__ vstm(ia_w, r4, d0, d5);
- __ addi(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ addi(r4, r1, Operand(offsetof(F, a)));
__ vldm(ia_w, r4, s0, s3);
__ vldm(ia_w, r4, s4, s7);
- __ addi(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ addi(r4, r1, Operand(offsetof(F, a)));
__ vstm(ia_w, r4, s6, s7);
__ vstm(ia_w, r4, s0, s5);
@@ -789,22 +789,22 @@ TEST(9) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
- __ addi(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ addi(r4, r0, Operand(offsetof(D, a)));
__ vldm(ia, r4, d0, d3);
__ addi(r4, r4, Operand(4 * 8));
__ vldm(ia, r4, d4, d7);
- __ addi(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ addi(r4, r0, Operand(offsetof(D, a)));
__ vstm(ia, r4, d6, d7);
__ addi(r4, r4, Operand(2 * 8));
__ vstm(ia, r4, d0, d5);
- __ addi(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ addi(r4, r1, Operand(offsetof(F, a)));
__ vldm(ia, r4, s0, s3);
__ addi(r4, r4, Operand(4 * 4));
__ vldm(ia, r4, s4, s7);
- __ addi(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ addi(r4, r1, Operand(offsetof(F, a)));
__ vstm(ia, r4, s6, s7);
__ addi(r4, r4, Operand(2 * 4));
__ vstm(ia, r4, s0, s5);
@@ -905,19 +905,19 @@ TEST(10) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
- __ addi(r4, r0, Operand(OFFSET_OF(D, h) + 8));
+ __ addi(r4, r0, Operand(offsetof(D, h) + 8));
__ vldm(db_w, r4, d4, d7);
__ vldm(db_w, r4, d0, d3);
- __ addi(r4, r0, Operand(OFFSET_OF(D, h) + 8));
+ __ addi(r4, r0, Operand(offsetof(D, h) + 8));
__ vstm(db_w, r4, d0, d5);
__ vstm(db_w, r4, d6, d7);
- __ addi(r4, r1, Operand(OFFSET_OF(F, h) + 4));
+ __ addi(r4, r1, Operand(offsetof(F, h) + 4));
__ vldm(db_w, r4, s4, s7);
__ vldm(db_w, r4, s0, s3);
- __ addi(r4, r1, Operand(OFFSET_OF(F, h) + 4));
+ __ addi(r4, r1, Operand(offsetof(F, h) + 4));
__ vstm(db_w, r4, s0, s5);
__ vstm(db_w, r4, s6, s7);
@@ -996,28 +996,28 @@ TEST(11) {
Assembler assm(isolate, NULL, 0);
// Test HeapObject untagging.
- __ ldr(r1, MemOperand(r0, OFFSET_OF(I, a)));
+ __ ldr(r1, MemOperand(r0, offsetof(I, a)));
__ mov(r1, Operand(r1, ASR, 1), SetCC);
__ adc(r1, r1, Operand(r1), LeaveCC, cs);
- __ str(r1, MemOperand(r0, OFFSET_OF(I, a)));
+ __ str(r1, MemOperand(r0, offsetof(I, a)));
- __ ldr(r2, MemOperand(r0, OFFSET_OF(I, b)));
+ __ ldr(r2, MemOperand(r0, offsetof(I, b)));
__ mov(r2, Operand(r2, ASR, 1), SetCC);
__ adc(r2, r2, Operand(r2), LeaveCC, cs);
- __ str(r2, MemOperand(r0, OFFSET_OF(I, b)));
+ __ str(r2, MemOperand(r0, offsetof(I, b)));
// Test corner cases.
__ mov(r1, Operand(0xffffffff));
__ mov(r2, Operand::Zero());
__ mov(r3, Operand(r1, ASR, 1), SetCC); // Set the carry.
__ adc(r3, r1, Operand(r2));
- __ str(r3, MemOperand(r0, OFFSET_OF(I, c)));
+ __ str(r3, MemOperand(r0, offsetof(I, c)));
__ mov(r1, Operand(0xffffffff));
__ mov(r2, Operand::Zero());
__ mov(r3, Operand(r2, ASR, 1), SetCC); // Unset the carry.
__ adc(r3, r1, Operand(r2));
- __ str(r3, MemOperand(r0, OFFSET_OF(I, d)));
+ __ str(r3, MemOperand(r0, offsetof(I, d)));
__ mov(pc, Operand(lr));
diff --git a/deps/v8/test/cctest/test-code-stubs-arm64.cc b/deps/v8/test/cctest/test-code-stubs-arm64.cc
index 6d5b0f49be..8b38b96600 100644
--- a/deps/v8/test/cctest/test-code-stubs-arm64.cc
+++ b/deps/v8/test/cctest/test-code-stubs-arm64.cc
@@ -142,8 +142,8 @@ int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func,
Simulator::CallArgument(from),
Simulator::CallArgument::End()
};
- return Simulator::current(Isolate::Current())->CallInt64(
- FUNCTION_ADDR(func), args);
+ return static_cast<int32_t>(Simulator::current(Isolate::Current())
+ ->CallInt64(FUNCTION_ADDR(func), args));
#else
return (*func)(from);
#endif
diff --git a/deps/v8/test/cctest/test-code-stubs-mips64.cc b/deps/v8/test/cctest/test-code-stubs-mips64.cc
index 1f7df380e1..9f146f65fd 100644
--- a/deps/v8/test/cctest/test-code-stubs-mips64.cc
+++ b/deps/v8/test/cctest/test-code-stubs-mips64.cc
@@ -144,7 +144,8 @@ 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());
+ return static_cast<int32_t>(
+ Simulator::current(Isolate::Current())->get_register(v0.code()));
#else
return (*func)(from);
#endif
diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc
index ed8b1c6d99..3b25480a4a 100644
--- a/deps/v8/test/cctest/test-compiler.cc
+++ b/deps/v8/test/cctest/test-compiler.cc
@@ -60,8 +60,8 @@ static Handle<JSFunction> Compile(const char* source) {
Handle<String> source_code = isolate->factory()->NewStringFromUtf8(
CStrVector(source)).ToHandleChecked();
Handle<SharedFunctionInfo> shared_function = Compiler::CompileScript(
- source_code, Handle<String>(), 0, 0, false, false, Handle<Object>(),
- Handle<Context>(isolate->native_context()), NULL, NULL,
+ source_code, Handle<String>(), 0, 0, v8::ScriptOriginOptions(),
+ Handle<Object>(), Handle<Context>(isolate->native_context()), NULL, NULL,
v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE, false);
return isolate->factory()->NewFunctionFromSharedFunctionInfo(
shared_function, isolate->native_context());
@@ -362,7 +362,7 @@ TEST(FeedbackVectorUnaffectedByScopeChanges) {
// Now a feedback vector is allocated.
CHECK(f->shared()->is_compiled());
int expected_slots = 0;
- int expected_ic_slots = FLAG_vector_ics ? 2 : 1;
+ int expected_ic_slots = 2;
CHECK_EQ(expected_slots, f->shared()->feedback_vector()->Slots());
CHECK_EQ(expected_ic_slots, f->shared()->feedback_vector()->ICSlots());
}
@@ -370,40 +370,92 @@ TEST(FeedbackVectorUnaffectedByScopeChanges) {
// Test that optimized code for different closures is actually shared
// immediately by the FastNewClosureStub when run in the same context.
-TEST(OptimizedCodeSharing) {
- // Skip test if --cache-optimized-code is not activated by default because
- // FastNewClosureStub that is baked into the snapshot is incorrect.
- if (!FLAG_cache_optimized_code) return;
+TEST(OptimizedCodeSharing1) {
FLAG_stress_compaction = false;
FLAG_allow_natives_syntax = true;
+ FLAG_cache_optimized_code = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
for (int i = 0; i < 10; i++) {
LocalContext env;
env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"),
v8::Integer::New(CcTest::isolate(), i));
- CompileRun("function MakeClosure() {"
- " return function() { return x; };"
- "}"
- "var closure0 = MakeClosure();"
- "%DebugPrint(closure0());"
- "%OptimizeFunctionOnNextCall(closure0);"
- "%DebugPrint(closure0());"
- "var closure1 = MakeClosure();"
- "var closure2 = MakeClosure();");
+ CompileRun(
+ "function MakeClosure() {"
+ " return function() { return x; };"
+ "}"
+ "var closure0 = MakeClosure();"
+ "%DebugPrint(closure0());"
+ "%OptimizeFunctionOnNextCall(closure0);"
+ "%DebugPrint(closure0());"
+ "var closure1 = MakeClosure();"
+ "var closure2 = MakeClosure();");
Handle<JSFunction> fun1 = v8::Utils::OpenHandle(
*v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure1"))));
Handle<JSFunction> fun2 = v8::Utils::OpenHandle(
*v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure2"))));
- CHECK(fun1->IsOptimized()
- || !CcTest::i_isolate()->use_crankshaft() || !fun1->IsOptimizable());
- CHECK(fun2->IsOptimized()
- || !CcTest::i_isolate()->use_crankshaft() || !fun2->IsOptimizable());
+ CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
+ CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
CHECK_EQ(fun1->code(), fun2->code());
}
}
+// Test that optimized code for different closures is actually shared
+// immediately by the FastNewClosureStub when run different contexts.
+TEST(OptimizedCodeSharing2) {
+ if (FLAG_stress_compaction) return;
+ FLAG_allow_natives_syntax = true;
+ FLAG_cache_optimized_code = true;
+ FLAG_turbo_cache_shared_code = true;
+ const char* flag = "--turbo-filter=*";
+ FlagList::SetFlagsFromString(flag, StrLength(flag));
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Script> script = v8_compile(
+ "function MakeClosure() {"
+ " return function() { return x; };"
+ "}");
+ Handle<Code> reference_code;
+ {
+ LocalContext env;
+ env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"),
+ v8::Integer::New(CcTest::isolate(), 23));
+ script->GetUnboundScript()->BindToCurrentContext()->Run();
+ CompileRun(
+ "var closure0 = MakeClosure();"
+ "%DebugPrint(closure0());"
+ "%OptimizeFunctionOnNextCall(closure0);"
+ "%DebugPrint(closure0());");
+ Handle<JSFunction> fun0 = v8::Utils::OpenHandle(
+ *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure0"))));
+ CHECK(fun0->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
+ reference_code = handle(fun0->code());
+ }
+ for (int i = 0; i < 10; i++) {
+ LocalContext env;
+ env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"),
+ v8::Integer::New(CcTest::isolate(), i));
+ script->GetUnboundScript()->BindToCurrentContext()->Run();
+ CompileRun(
+ "var closure0 = MakeClosure();"
+ "%DebugPrint(closure0());"
+ "%OptimizeFunctionOnNextCall(closure0);"
+ "%DebugPrint(closure0());"
+ "var closure1 = MakeClosure();"
+ "var closure2 = MakeClosure();");
+ Handle<JSFunction> fun1 = v8::Utils::OpenHandle(
+ *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure1"))));
+ Handle<JSFunction> fun2 = v8::Utils::OpenHandle(
+ *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure2"))));
+ CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
+ CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
+ CHECK_EQ(*reference_code, fun1->code());
+ CHECK_EQ(*reference_code, fun2->code());
+ }
+}
+
+
TEST(CompileFunctionInContext) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -533,6 +585,9 @@ static void CheckCodeForUnsafeLiteral(Handle<JSFunction> f) {
int decode_size =
Min(f->code()->instruction_size(),
static_cast<int>(f->code()->back_edge_table_offset()));
+ if (FLAG_enable_embedded_constant_pool) {
+ decode_size = Min(decode_size, f->code()->constant_pool_offset());
+ }
Address end = pc + decode_size;
v8::internal::EmbeddedVector<char, 128> decode_buffer;
diff --git a/deps/v8/test/cctest/test-constantpool.cc b/deps/v8/test/cctest/test-constantpool.cc
index 4592074742..ce3abb0edb 100644
--- a/deps/v8/test/cctest/test-constantpool.cc
+++ b/deps/v8/test/cctest/test-constantpool.cc
@@ -1,337 +1,247 @@
-// 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.
-
-// Test constant pool array code.
+// Copyright 2015 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.
+
+// Test embedded constant pool builder code.
#include "src/v8.h"
-#include "src/factory.h"
-#include "src/objects.h"
+#include "src/assembler.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() {};");
- i::Handle<i::JSFunction> fun = v8::Utils::OpenHandle(
- *v8::Local<v8::Function>::Cast(
- (*context)->Global()->Get(v8_str("foo"))));
- return fun->code();
-}
+const ConstantPoolEntry::Type kPtrType = ConstantPoolEntry::INTPTR;
+const ConstantPoolEntry::Type kDblType = ConstantPoolEntry::DOUBLE;
+const ConstantPoolEntry::Access kRegAccess = ConstantPoolEntry::REGULAR;
+const ConstantPoolEntry::Access kOvflAccess = ConstantPoolEntry::OVERFLOWED;
+const int kReachBits = 6; // Use reach of 64-bytes to test overflow.
+const int kReach = 1 << kReachBits;
-TEST(ConstantPoolSmall) {
- LocalContext context;
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- v8::HandleScope scope(context->GetIsolate());
- // Check construction.
- ConstantPoolArray::NumberOfEntries small(3, 1, 2, 1);
- Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(small);
+TEST(ConstantPoolPointers) {
+ ConstantPoolBuilder builder(kReachBits, kReachBits);
+ const int kRegularCount = kReach / kPointerSize;
+ ConstantPoolEntry::Access access;
+ int pos = 0;
+ intptr_t value = 0;
+ bool sharing_ok = true;
- 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(builder.IsEmpty());
+ while (builder.NextAccess(kPtrType) == kRegAccess) {
+ access = builder.AddEntry(pos++, value++, sharing_ok);
+ CHECK_EQ(access, kRegAccess);
}
- 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, IMMUTABLE, TENURED);
- Code* code = DummyCode(&context);
- array->set(0, big_number);
- array->set(1, 0.5);
- array->set(2, 3e-24);
- array->set(3, code->entry());
- array->set(4, code);
- array->set(5, *object);
- array->set(6, 50);
- 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));
+ CHECK(!builder.IsEmpty());
+ CHECK_EQ(pos, kRegularCount);
+
+ access = builder.AddEntry(pos, value, sharing_ok);
+ CHECK_EQ(access, kOvflAccess);
}
-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));
- }
+TEST(ConstantPoolDoubles) {
+ ConstantPoolBuilder builder(kReachBits, kReachBits);
+ const int kRegularCount = kReach / kDoubleSize;
+ ConstantPoolEntry::Access access;
+ int pos = 0;
+ double value = 0.0;
- // 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(builder.IsEmpty());
+ while (builder.NextAccess(kDblType) == kRegAccess) {
+ access = builder.AddEntry(pos++, value);
+ value += 0.5;
+ CHECK_EQ(access, kRegAccess);
}
+ CHECK(!builder.IsEmpty());
+ CHECK_EQ(pos, kRegularCount);
- // 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);
- }
- }
+ access = builder.AddEntry(pos, value);
+ CHECK_EQ(access, kOvflAccess);
+}
- 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));
+
+TEST(ConstantPoolMixedTypes) {
+ ConstantPoolBuilder builder(kReachBits, kReachBits);
+ const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
+ ((kPointerSize < kDoubleSize) ? 1 : 0));
+ ConstantPoolEntry::Type type = kPtrType;
+ ConstantPoolEntry::Access access;
+ int pos = 0;
+ intptr_t ptrValue = 0;
+ double dblValue = 0.0;
+ bool sharing_ok = true;
+
+ CHECK(builder.IsEmpty());
+ while (builder.NextAccess(type) == kRegAccess) {
+ if (type == kPtrType) {
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ type = kDblType;
} else {
- CHECK(i <= array->last_index(ConstantPoolArray::INT32, kExtended));
- CHECK_EQ(extended_section_int32, array->get_int32_entry(i));
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ type = kPtrType;
}
+ CHECK_EQ(access, kRegAccess);
}
+ CHECK(!builder.IsEmpty());
+ CHECK_EQ(pos, kRegularCount);
+
+ access = builder.AddEntry(pos++, ptrValue, sharing_ok);
+ CHECK_EQ(access, kOvflAccess);
+ access = builder.AddEntry(pos, dblValue);
+ CHECK_EQ(access, kOvflAccess);
}
-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());
+TEST(ConstantPoolMixedReach) {
+ const int ptrReachBits = kReachBits + 2;
+ const int ptrReach = 1 << ptrReachBits;
+ const int dblReachBits = kReachBits;
+ const int dblReach = kReach;
+ const int dblRegularCount =
+ Min(dblReach / kDoubleSize, ptrReach / (kDoubleSize + kPointerSize));
+ const int ptrRegularCount =
+ ((ptrReach - (dblRegularCount * (kDoubleSize + kPointerSize))) /
+ kPointerSize) +
+ dblRegularCount;
+ ConstantPoolBuilder builder(ptrReachBits, dblReachBits);
+ ConstantPoolEntry::Access access;
+ int pos = 0;
+ intptr_t ptrValue = 0;
+ double dblValue = 0.0;
+ bool sharing_ok = true;
+ int ptrCount = 0;
+ int dblCount = 0;
+
+ CHECK(builder.IsEmpty());
+ while (builder.NextAccess(kDblType) == kRegAccess) {
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ dblCount++;
+ CHECK_EQ(access, kRegAccess);
+
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ ptrCount++;
+ CHECK_EQ(access, kRegAccess);
}
- CHECK_EQ(count, i);
-}
+ CHECK(!builder.IsEmpty());
+ CHECK_EQ(dblCount, dblRegularCount);
+ while (ptrCount < ptrRegularCount) {
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ CHECK_EQ(access, kOvflAccess);
-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);
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ ptrCount++;
+ CHECK_EQ(access, kRegAccess);
+ }
+ CHECK_EQ(builder.NextAccess(kPtrType), kOvflAccess);
- 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);
+ access = builder.AddEntry(pos++, ptrValue, sharing_ok);
+ CHECK_EQ(access, kOvflAccess);
+ access = builder.AddEntry(pos, dblValue);
+ CHECK_EQ(access, kOvflAccess);
}
-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(ConstantPoolSharing) {
+ ConstantPoolBuilder builder(kReachBits, kReachBits);
+ const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
+ ((kPointerSize < kDoubleSize) ? 1 : 0));
+ ConstantPoolEntry::Access access;
+ CHECK(builder.IsEmpty());
-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);
-
- // 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));
+ ConstantPoolEntry::Type type = kPtrType;
+ int pos = 0;
+ intptr_t ptrValue = 0;
+ double dblValue = 0.0;
+ bool sharing_ok = true;
+ while (builder.NextAccess(type) == kRegAccess) {
+ if (type == kPtrType) {
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ type = kDblType;
+ } else {
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ type = kPtrType;
+ }
+ CHECK_EQ(access, kRegAccess);
+ }
+ CHECK(!builder.IsEmpty());
+ CHECK_EQ(pos, kRegularCount);
+
+ type = kPtrType;
+ ptrValue = 0;
+ dblValue = 0.0;
+ while (pos < kRegularCount * 2) {
+ if (type == kPtrType) {
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ type = kDblType;
+ } else {
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ type = kPtrType;
+ }
+ CHECK_EQ(access, kRegAccess);
+ }
+
+ access = builder.AddEntry(pos++, ptrValue, sharing_ok);
+ CHECK_EQ(access, kOvflAccess);
+ access = builder.AddEntry(pos, dblValue);
+ CHECK_EQ(access, kOvflAccess);
}
-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_space()->anchor()->next_page();
- {
- HandleScope scope(isolate);
- int dummy_array_size = Page::kMaxRegularHeapObjectSize - 92 * KB;
- Handle<HeapObject> temp =
- factory->NewFixedDoubleArray(dummy_array_size / kDoubleSize, TENURED);
- CHECK(heap->InOldSpace(temp->address()));
- Handle<HeapObject> heap_ptr =
- factory->NewHeapNumber(5.0, IMMUTABLE, TENURED);
- CHECK(heap->InOldSpace(heap_ptr->address()));
- CHECK(!first_page->Contains(heap_ptr->address()));
- array->set(0, *heap_ptr);
- array->set(1, *heap_ptr);
- }
+TEST(ConstantPoolNoSharing) {
+ ConstantPoolBuilder builder(kReachBits, kReachBits);
+ const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
+ ((kPointerSize < kDoubleSize) ? 1 : 0));
+ ConstantPoolEntry::Access access;
- // 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));
+ CHECK(builder.IsEmpty());
- // Force compacting garbage collection.
- CHECK(FLAG_always_compact);
- heap->CollectAllGarbage();
+ ConstantPoolEntry::Type type = kPtrType;
+ int pos = 0;
+ intptr_t ptrValue = 0;
+ double dblValue = 0.0;
+ bool sharing_ok = false;
+ while (builder.NextAccess(type) == kRegAccess) {
+ if (type == kPtrType) {
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ type = kDblType;
+ } else {
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ type = kPtrType;
+ }
+ CHECK_EQ(access, kRegAccess);
+ }
+ CHECK(!builder.IsEmpty());
+ CHECK_EQ(pos, kRegularCount);
+
+ type = kPtrType;
+ ptrValue = 0;
+ dblValue = 0.0;
+ sharing_ok = true;
+ while (pos < kRegularCount * 2) {
+ if (type == kPtrType) {
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ type = kDblType;
+ CHECK_EQ(access, kOvflAccess);
+ } else {
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ type = kPtrType;
+ CHECK_EQ(access, kRegAccess);
+ }
+ }
- CHECK_NE(old_ptr, *object);
- CHECK_EQ(*object, array->get_heap_ptr_entry(0));
- CHECK_EQ(*object, array->get_heap_ptr_entry(1));
+ access = builder.AddEntry(pos++, ptrValue, sharing_ok);
+ CHECK_EQ(access, kOvflAccess);
+ access = builder.AddEntry(pos, dblValue);
+ CHECK_EQ(access, kOvflAccess);
}
diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index 2f6cf6e9a2..a6ffdca179 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -115,8 +115,9 @@ class DebugLocalContext {
v8::Utils::OpenHandle(*context_->Global())));
Handle<v8::internal::String> debug_string =
factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("debug"));
- v8::internal::Runtime::DefineObjectProperty(global, debug_string,
- handle(debug_context->global_proxy(), isolate), DONT_ENUM).Check();
+ v8::internal::JSObject::SetOwnPropertyIgnoreAttributes(
+ global, debug_string, handle(debug_context->global_proxy()), DONT_ENUM)
+ .Check();
}
private:
@@ -211,7 +212,7 @@ static int SetScriptBreakPointByIdFromJS(v8::Isolate* isolate, int script_id,
}
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
v8::Handle<v8::String> str =
v8::String::NewFromUtf8(isolate, buffer.start());
v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run();
@@ -240,7 +241,7 @@ static int SetScriptBreakPointByNameFromJS(v8::Isolate* isolate,
}
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
v8::Handle<v8::String> str =
v8::String::NewFromUtf8(isolate, buffer.start());
v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run();
@@ -425,7 +426,8 @@ void CheckDebuggerUnloaded(bool check_functions) {
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
// Check that the debugger has been fully unloaded.
@@ -443,6 +445,7 @@ void CheckDebugBreakFunction(DebugLocalContext* env,
const char* source, const char* name,
int position, v8::internal::RelocInfo::Mode mode,
Code* debug_break) {
+ EnableDebugger();
i::Debug* debug = CcTest::i_isolate()->debug();
// Create function and set the break point.
@@ -486,6 +489,8 @@ void CheckDebugBreakFunction(DebugLocalContext* env,
i::RelocInfo rinfo = location.rinfo();
CHECK(!rinfo.IsPatchedReturnSequence());
}
+
+ DisableDebugger();
}
@@ -964,92 +969,6 @@ static void MessageCallbackCount(v8::Handle<v8::Message> message,
// --- T h e A c t u a l T e s t s
-
-// Test that the debug break function is the expected one for different kinds
-// of break locations.
-TEST(DebugStub) {
- using ::v8::internal::Builtins;
- using ::v8::internal::Isolate;
- DebugLocalContext env;
- v8::HandleScope scope(env->GetIsolate());
-
- CheckDebugBreakFunction(&env,
- "function f1(){}", "f1",
- 0,
- v8::internal::RelocInfo::JS_RETURN,
- NULL);
- CheckDebugBreakFunction(&env,
- "function f2(){x=1;}", "f2",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
- CcTest::i_isolate()->builtins()->builtin(
- Builtins::kStoreIC_DebugBreak));
- CheckDebugBreakFunction(&env,
- "function f3(){var a=x;}", "f3",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
- CcTest::i_isolate()->builtins()->builtin(
- Builtins::kLoadIC_DebugBreak));
-
-// TODO(1240753): Make the test architecture independent or split
-// parts of the debugger into architecture dependent files. This
-// part currently disabled as it is not portable between IA32/ARM.
-// Currently on ICs for keyed store/load on ARM.
-#if !defined (__arm__) && !defined(__thumb__)
- CheckDebugBreakFunction(
- &env,
- "function f4(){var index='propertyName'; var a={}; a[index] = 'x';}",
- "f4",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
- CcTest::i_isolate()->builtins()->builtin(
- Builtins::kKeyedStoreIC_DebugBreak));
- CheckDebugBreakFunction(
- &env,
- "function f5(){var index='propertyName'; var a={}; return a[index];}",
- "f5",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
- CcTest::i_isolate()->builtins()->builtin(
- Builtins::kKeyedLoadIC_DebugBreak));
-#endif
-
- CheckDebugBreakFunction(
- &env,
- "function f6(a){return a==null;}",
- "f6",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
- CcTest::i_isolate()->builtins()->builtin(
- Builtins::kCompareNilIC_DebugBreak));
-
- // Check the debug break code stubs for call ICs with different number of
- // parameters.
- // TODO(verwaest): XXX update test.
- // Handle<Code> debug_break_0 = v8::internal::ComputeCallDebugBreak(0);
- // Handle<Code> debug_break_1 = v8::internal::ComputeCallDebugBreak(1);
- // Handle<Code> debug_break_4 = v8::internal::ComputeCallDebugBreak(4);
-
- // CheckDebugBreakFunction(&env,
- // "function f4_0(){x();}", "f4_0",
- // 0,
- // v8::internal::RelocInfo::CODE_TARGET,
- // *debug_break_0);
-
- // CheckDebugBreakFunction(&env,
- // "function f4_1(){x(1);}", "f4_1",
- // 0,
- // v8::internal::RelocInfo::CODE_TARGET,
- // *debug_break_1);
-
- // CheckDebugBreakFunction(&env,
- // "function f4_4(){x(1,2,3,4);}", "f4_4",
- // 0,
- // v8::internal::RelocInfo::CODE_TARGET,
- // *debug_break_4);
-}
-
-
// Test that the debug info in the VM is in sync with the functions being
// debugged.
TEST(DebugInfo) {
@@ -1064,6 +983,7 @@ TEST(DebugInfo) {
CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
CHECK(!HasDebugInfo(foo));
CHECK(!HasDebugInfo(bar));
+ EnableDebugger();
// One function (foo) is debugged.
int bp1 = SetBreakPoint(foo, 0);
CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length());
@@ -1081,6 +1001,7 @@ TEST(DebugInfo) {
CHECK(HasDebugInfo(bar));
// No functions are debugged.
ClearBreakPoint(bp2);
+ DisableDebugger();
CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
CHECK(!HasDebugInfo(foo));
CHECK(!HasDebugInfo(bar));
@@ -2288,11 +2209,12 @@ TEST(RemoveBreakPointInBreak) {
v8::Local<v8::Function> foo =
CompileFunction(&env, "function foo(){a=1;}", "foo");
- debug_event_remove_break_point = SetBreakPoint(foo, 0);
// Register the debug event listener pasing the function
v8::Debug::SetDebugEventListener(DebugEventRemoveBreakPoint, foo);
+ debug_event_remove_break_point = SetBreakPoint(foo, 0);
+
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
@@ -2348,7 +2270,7 @@ TEST(DebuggerStatementBreakpoint) {
v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")));
- // The debugger statement triggers breakpint hit
+ // The debugger statement triggers breakpoint hit
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
@@ -2779,11 +2701,11 @@ TEST(DebugStepLinear) {
// Run foo to allow it to get optimized.
CompileRun("a=0; b=0; c=0; foo();");
- SetBreakPoint(foo, 3);
-
// Register a debug event listener which steps and counts.
v8::Debug::SetDebugEventListener(DebugEventStep);
+ SetBreakPoint(foo, 3);
+
step_action = StepIn;
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -3272,6 +3194,13 @@ TEST(DebugStepDoWhile) {
v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
SetBreakPoint(foo, 8); // "var a = 0;"
+ // Looping 0 times.
+ 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(4, break_point_hit_count);
+
// Looping 10 times.
step_action = StepIn;
break_point_hit_count = 0;
@@ -3314,19 +3243,26 @@ TEST(DebugStepFor) {
SetBreakPoint(foo, 8); // "a = 1;"
+ // Looping 0 times.
+ 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(4, 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(45, break_point_hit_count);
+ CHECK_EQ(34, 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(405, break_point_hit_count);
+ CHECK_EQ(304, break_point_hit_count);
// Get rid of the debug event listener.
v8::Debug::SetDebugEventListener(NULL);
@@ -3541,14 +3477,14 @@ TEST(DebugConditional) {
step_action = StepIn;
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
- CHECK_EQ(5, break_point_hit_count);
+ CHECK_EQ(4, break_point_hit_count);
step_action = StepIn;
break_point_hit_count = 0;
const int argc = 1;
v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) };
foo->Call(env->Global(), argc, argv_true);
- CHECK_EQ(5, break_point_hit_count);
+ CHECK_EQ(4, break_point_hit_count);
// Get rid of the debug event listener.
v8::Debug::SetDebugEventListener(NULL);
@@ -3823,6 +3759,48 @@ TEST(DebugStepFunctionCall) {
}
+// Test that step in works with Function.call.apply.
+TEST(DebugStepFunctionCallApply) {
+ DebugLocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ // Create a function for testing stepping.
+ v8::Local<v8::Function> foo =
+ CompileFunction(&env,
+ "function bar() { }"
+ "function foo(){ debugger;"
+ " Function.call.apply(bar);"
+ " Function.call.apply(Function.call, "
+ "[Function.call, bar]);"
+ "}",
+ "foo");
+
+ // Register a debug event listener which steps and counts.
+ v8::Debug::SetDebugEventListener(DebugEventStep);
+ step_action = StepIn;
+
+ break_point_hit_count = 0;
+ foo->Call(env->Global(), 0, NULL);
+ CHECK_EQ(5, break_point_hit_count);
+
+ v8::Debug::SetDebugEventListener(NULL);
+ CheckDebuggerUnloaded();
+
+ // Register a debug event listener which just counts.
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+
+ break_point_hit_count = 0;
+ foo->Call(env->Global(), 0, NULL);
+
+ // Without stepping only the debugger statement is hit.
+ CHECK_EQ(1, break_point_hit_count);
+
+ v8::Debug::SetDebugEventListener(NULL);
+ CheckDebuggerUnloaded();
+}
+
+
// Tests that breakpoint will be hit if it's set in script.
TEST(PauseInScript) {
DebugLocalContext env;
@@ -3856,6 +3834,13 @@ TEST(PauseInScript) {
}
+static void DebugEventCounterCheck(int caught, int uncaught, int message) {
+ CHECK_EQ(caught, exception_hit_count);
+ CHECK_EQ(uncaught, uncaught_exception_hit_count);
+ CHECK_EQ(message, message_callback_count);
+}
+
+
// Test break on exceptions. For each exception break combination the number
// of debug event exception callbacks and message callbacks are collected. The
// number of debug event exception callbacks are used to check that the
@@ -3875,6 +3860,15 @@ TEST(BreakOnException) {
"caught");
v8::Local<v8::Function> notCaught =
CompileFunction(&env, "function notCaught(){throws();}", "notCaught");
+ v8::Local<v8::Function> notCaughtFinally = CompileFunction(
+ &env, "function notCaughtFinally(){try{throws();}finally{}}",
+ "notCaughtFinally");
+ // In this edge case, even though this finally does not propagate the
+ // exception, the debugger considers this uncaught, since we want to break
+ // at the first throw for the general case where finally implicitly rethrows.
+ v8::Local<v8::Function> edgeCaseFinally = CompileFunction(
+ &env, "function caughtFinally(){L:try{throws();}finally{break L;}}",
+ "caughtFinally");
v8::V8::AddMessageListener(MessageCallbackCount);
v8::Debug::SetDebugEventListener(DebugEventCounter);
@@ -3883,117 +3877,117 @@ TEST(BreakOnException) {
DebugEventCounterClear();
MessageCallbackCountClear();
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(0, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(0, 0, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(0, 0, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(0, 0, 2);
// No break on exception
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnException(false, false);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(0, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(0, 0, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(0, 0, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(0, 0, 2);
// Break on uncaught exception
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnException(false, true);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(0, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(1, exception_hit_count);
- CHECK_EQ(1, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(1, 1, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(2, 2, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(3, 3, 2);
// Break on exception and uncaught exception
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnException(true, true);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(1, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(1, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(2, exception_hit_count);
- CHECK_EQ(1, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(2, 1, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(3, 2, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(4, 3, 2);
// Break on exception
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnException(true, false);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(1, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(1, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(2, exception_hit_count);
- CHECK_EQ(1, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(2, 1, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(3, 2, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(4, 3, 2);
// No break on exception using JavaScript
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, false);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(0, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(0, 0, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(0, 0, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(0, 0, 2);
// Break on uncaught exception using JavaScript
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, true);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(0, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(1, exception_hit_count);
- CHECK_EQ(1, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(1, 1, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(2, 2, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(3, 3, 2);
// Break on exception and uncaught exception using JavaScript
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, true);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(1, exception_hit_count);
- CHECK_EQ(0, message_callback_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
+ DebugEventCounterCheck(1, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(2, exception_hit_count);
- CHECK_EQ(1, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(2, 1, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(3, 2, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(4, 3, 2);
// Break on exception using JavaScript
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, false);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(1, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(1, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(2, exception_hit_count);
- CHECK_EQ(1, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(2, 1, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(3, 2, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(4, 3, 2);
v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
@@ -4001,6 +3995,35 @@ TEST(BreakOnException) {
}
+static void try_finally_original_message(v8::Handle<v8::Message> message,
+ v8::Handle<v8::Value> data) {
+ CHECK_EQ(2, message->GetLineNumber());
+ CHECK_EQ(2, message->GetStartColumn());
+ message_callback_count++;
+}
+
+
+TEST(TryFinallyOriginalMessage) {
+ // Test that the debugger plays nicely with the pending message.
+ message_callback_count = 0;
+ DebugEventCounterClear();
+ v8::V8::AddMessageListener(try_finally_original_message);
+ v8::Debug::SetDebugEventListener(DebugEventCounter);
+ ChangeBreakOnException(true, true);
+ DebugLocalContext env;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ CompileRun(
+ "try {\n"
+ " throw 1;\n"
+ "} finally {\n"
+ "}\n");
+ DebugEventCounterCheck(1, 1, 1);
+ v8::Debug::SetDebugEventListener(NULL);
+ v8::V8::RemoveMessageListeners(try_finally_original_message);
+}
+
+
TEST(EvalJSInDebugEventListenerOnNativeReThrownException) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -4023,7 +4046,7 @@ TEST(EvalJSInDebugEventListenerOnNativeReThrownException) {
// ReThrow native error
{
- v8::TryCatch tryCatch;
+ v8::TryCatch tryCatch(env->GetIsolate());
env->GetIsolate()->ThrowException(v8::Exception::TypeError(
v8::String::NewFromUtf8(env->GetIsolate(), "Type error")));
CHECK(tryCatch.HasCaught());
@@ -5532,11 +5555,6 @@ TEST(RecursiveBreakpointsGlobal) {
}
-static void DummyDebugEventListener(
- const v8::Debug::EventDetails& event_details) {
-}
-
-
TEST(SetDebugEventListenerOnUninitializedVM) {
v8::Debug::SetDebugEventListener(DummyDebugEventListener);
}
@@ -5602,7 +5620,7 @@ static void CheckDataParameter(
CHECK(v8::Debug::Call(debugger_call_with_data, data)->IsString());
for (int i = 0; i < 3; i++) {
- v8::TryCatch catcher;
+ v8::TryCatch catcher(args.GetIsolate());
CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty());
CHECK(catcher.HasCaught());
CHECK(catcher.Exception()->IsString());
@@ -5910,7 +5928,7 @@ TEST(DebugGetLoadedScripts) {
v8::String::NewExternal(env->GetIsolate(), &source_ext_str);
v8::Handle<v8::Script> evil_script(v8::Script::Compile(source));
// "use" evil_script to make the compiler happy.
- (void) evil_script;
+ USE(evil_script);
Handle<i::ExternalTwoByteString> i_source(
i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source)));
// This situation can happen if source was an external string disposed
@@ -5919,12 +5937,23 @@ TEST(DebugGetLoadedScripts) {
bool allow_natives_syntax = i::FLAG_allow_natives_syntax;
i::FLAG_allow_natives_syntax = true;
- CompileRun(
- "var scripts = %DebugGetLoadedScripts();"
- "var count = scripts.length;"
- "for (var i = 0; i < count; ++i) {"
- " scripts[i].line_ends;"
- "}");
+ EnableDebugger();
+ v8::MaybeLocal<v8::Value> result =
+ CompileRun(env.context(),
+ "var scripts = %DebugGetLoadedScripts();"
+ "var count = scripts.length;"
+ "for (var i = 0; i < count; ++i) {"
+ " var lines = scripts[i].lineCount();"
+ " if (lines < 1) throw 'lineCount';"
+ " var last = -1;"
+ " for (var j = 0; j < lines; ++j) {"
+ " var end = scripts[i].lineEnd(j);"
+ " if (last >= end) throw 'lineEnd';"
+ " last = end;"
+ " }"
+ "}");
+ CHECK(!result.IsEmpty());
+ DisableDebugger();
// Must not crash while accessing line_ends.
i::FLAG_allow_natives_syntax = allow_natives_syntax;
@@ -6492,6 +6521,8 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) {
const char* script = "function f() {};";
const char* resource_name = "test_resource";
+ v8::Debug::SetMessageHandler(AfterCompileMessageHandler);
+
// Set a couple of provisional breakpoint on lines out of the script lines
// range.
int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name,
@@ -6500,7 +6531,6 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) {
SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, 5, 5);
after_compile_message_count = 0;
- v8::Debug::SetMessageHandler(AfterCompileMessageHandler);
v8::ScriptOrigin origin(
v8::String::NewFromUtf8(env->GetIsolate(), resource_name),
@@ -6925,6 +6955,13 @@ TEST(DebugContextIsPreservedBetweenAccesses) {
}
+TEST(NoDebugContextWhenDebuggerDisabled) {
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Context> context = v8::Debug::GetDebugContext();
+ CHECK(context.IsEmpty());
+}
+
+
static v8::Handle<v8::Value> expected_callback_data;
static void DebugEventContextChecker(const v8::Debug::EventDetails& details) {
CHECK(details.GetEventContext() == expected_context);
@@ -7260,7 +7297,7 @@ static void DebugEventStepNext(
static void RunScriptInANewCFrame(const char* source) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
CompileRun(source);
CHECK(try_catch.HasCaught());
}
@@ -7440,7 +7477,7 @@ TEST(DebugBreakOffThreadTerminate) {
v8::Debug::SetDebugEventListener(DebugBreakTriggerTerminate);
TerminationThread terminator(isolate);
terminator.Start();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(env->GetIsolate());
v8::Debug::DebugBreak(isolate);
CompileRun("while (true);");
CHECK(try_catch.HasTerminated());
@@ -7456,7 +7493,7 @@ static void DebugEventExpectNoException(
static void TryCatchWrappedThrowCallback(
const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
CompileRun("throw 'rejection';");
CHECK(try_catch.HasCaught());
}
diff --git a/deps/v8/test/cctest/test-decls.cc b/deps/v8/test/cctest/test-decls.cc
index f3dc777102..347ca9a6bc 100644
--- a/deps/v8/test/cctest/test-decls.cc
+++ b/deps/v8/test/cctest/test-decls.cc
@@ -130,6 +130,10 @@ void DeclarationContext::InitializeIfNeeded() {
context_.Reset(isolate, context);
context->Enter();
is_initialized_ = true;
+ // Reset counts. Bootstrapping might have called into the interceptor.
+ get_count_ = 0;
+ set_count_ = 0;
+ query_count_ = 0;
PostInitializeContext(context);
}
@@ -143,7 +147,7 @@ void DeclarationContext::Check(const char* source,
// to avoid that.
CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE);
HandleScope scope(CcTest::isolate());
- TryCatch catcher;
+ TryCatch catcher(CcTest::isolate());
catcher.SetVerbose(true);
Local<Script> script =
Script::Compile(String::NewFromUtf8(CcTest::isolate(), source));
@@ -567,7 +571,7 @@ class SimpleContext {
Expectations expectations,
v8::Handle<Value> value = Local<Value>()) {
HandleScope scope(context_->GetIsolate());
- TryCatch catcher;
+ TryCatch catcher(context_->GetIsolate());
catcher.SetVerbose(true);
Local<Script> script =
Script::Compile(String::NewFromUtf8(context_->GetIsolate(), source));
diff --git a/deps/v8/test/cctest/test-deoptimization.cc b/deps/v8/test/cctest/test-deoptimization.cc
index 674291524d..1d512e0a75 100644
--- a/deps/v8/test/cctest/test-deoptimization.cc
+++ b/deps/v8/test/cctest/test-deoptimization.cc
@@ -112,8 +112,6 @@ static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
TEST(DeoptimizeSimple) {
- i::FLAG_turbo_deoptimization = true;
-
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -152,8 +150,6 @@ TEST(DeoptimizeSimple) {
TEST(DeoptimizeSimpleWithArguments) {
- i::FLAG_turbo_deoptimization = true;
-
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -193,8 +189,6 @@ TEST(DeoptimizeSimpleWithArguments) {
TEST(DeoptimizeSimpleNested) {
- i::FLAG_turbo_deoptimization = true;
-
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -220,7 +214,6 @@ TEST(DeoptimizeSimpleNested) {
TEST(DeoptimizeRecursive) {
- i::FLAG_turbo_deoptimization = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -248,7 +241,6 @@ TEST(DeoptimizeRecursive) {
TEST(DeoptimizeMultiple) {
- i::FLAG_turbo_deoptimization = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -277,7 +269,6 @@ TEST(DeoptimizeMultiple) {
TEST(DeoptimizeConstructor) {
- i::FLAG_turbo_deoptimization = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -316,7 +307,6 @@ TEST(DeoptimizeConstructor) {
TEST(DeoptimizeConstructorMultiple) {
- i::FLAG_turbo_deoptimization = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -346,7 +336,6 @@ TEST(DeoptimizeConstructorMultiple) {
UNINITIALIZED_TEST(DeoptimizeBinaryOperationADDString) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
AllowNativesSyntaxNoInlining options;
v8::Isolate::CreateParams create_params;
@@ -451,7 +440,6 @@ static void TestDeoptimizeBinaryOpHelper(LocalContext* env,
UNINITIALIZED_TEST(DeoptimizeBinaryOperationADD) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -474,7 +462,6 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationADD) {
UNINITIALIZED_TEST(DeoptimizeBinaryOperationSUB) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -497,7 +484,6 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationSUB) {
UNINITIALIZED_TEST(DeoptimizeBinaryOperationMUL) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -520,7 +506,6 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationMUL) {
UNINITIALIZED_TEST(DeoptimizeBinaryOperationDIV) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -543,7 +528,6 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationDIV) {
UNINITIALIZED_TEST(DeoptimizeBinaryOperationMOD) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -566,7 +550,6 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationMOD) {
UNINITIALIZED_TEST(DeoptimizeCompare) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -623,7 +606,6 @@ UNINITIALIZED_TEST(DeoptimizeCompare) {
UNINITIALIZED_TEST(DeoptimizeLoadICStoreIC) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -716,7 +698,6 @@ UNINITIALIZED_TEST(DeoptimizeLoadICStoreIC) {
UNINITIALIZED_TEST(DeoptimizeLoadICStoreICNested) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
diff --git a/deps/v8/test/cctest/test-disasm-arm64.cc b/deps/v8/test/cctest/test-disasm-arm64.cc
index 208f1f5afb..b3b50acf9d 100644
--- a/deps/v8/test/cctest/test-disasm-arm64.cc
+++ b/deps/v8/test/cctest/test-disasm-arm64.cc
@@ -83,10 +83,11 @@ using namespace v8::internal;
abort(); \
}
-#define CLEANUP() \
- delete disasm; \
- delete decoder; \
- delete assm
+#define CLEANUP() \
+ delete disasm; \
+ delete decoder; \
+ delete assm; \
+ free(buf)
static bool vm_initialized = false;
diff --git a/deps/v8/test/cctest/test-disasm-mips.cc b/deps/v8/test/cctest/test-disasm-mips.cc
index b66554e55e..c04cd23bf5 100644
--- a/deps/v8/test/cctest/test-disasm-mips.cc
+++ b/deps/v8/test/cctest/test-disasm-mips.cc
@@ -92,6 +92,45 @@ if (failure) { \
}
+#define COMPARE_PC_REL_COMPACT(asm_, compare_string, offset) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ char str_with_address[100]; \
+ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
+ compare_string, progcounter + 4 + (offset << 2)); \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
+ }
+
+
+#define COMPARE_PC_REL(asm_, compare_string, offset) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ char str_with_address[100]; \
+ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
+ compare_string, progcounter + (offset << 2)); \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
+ }
+
+
+#define COMPARE_PC_JUMP(asm_, compare_string, target) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ char str_with_address[100]; \
+ int instr_index = target >> 2; \
+ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
+ compare_string, reinterpret_cast<byte *>( \
+ ((uint32_t)(progcounter + 1) & ~0xfffffff) | \
+ (instr_index << 2))); \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
+ }
+
+
TEST(Type0) {
SET_UP();
@@ -199,39 +238,241 @@ TEST(Type0) {
COMPARE(modu(v0, v1, a0),
"006410db modu 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_PC_REL_COMPACT(bovc(a0, a0, static_cast<int16_t>(0)),
+ "20840000 bovc a0, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, static_cast<int16_t>(0)),
+ "20a40000 bovc a1, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, 32767),
+ "20a47fff bovc a1, a0, 32767", 32767);
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, -32768),
+ "20a48000 bovc a1, a0, -32768", -32768);
+
+ COMPARE_PC_REL_COMPACT(bnvc(a0, a0, static_cast<int16_t>(0)),
+ "60840000 bnvc a0, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bnvc(a1, a0, static_cast<int16_t>(0)),
+ "60a40000 bnvc a1, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bnvc(a1, a0, 32767),
+ "60a47fff bnvc a1, a0, 32767", 32767);
+ COMPARE_PC_REL_COMPACT(bnvc(a1, a0, -32768),
+ "60a48000 bnvc a1, a0, -32768", -32768);
+
+ COMPARE_PC_REL_COMPACT(beqzc(a0, -1048576),
+ "d8900000 beqzc a0, -1048576", -1048576);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, -1), "d89fffff beqzc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 0), "d8800000 beqzc a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 1), "d8800001 beqzc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 1048575),
+ "d88fffff beqzc a0, 1048575", 1048575);
+
+ COMPARE_PC_REL_COMPACT(bnezc(a0, 0), "f8800000 bnezc a0, 0x0", 0);
+ COMPARE_PC_REL_COMPACT(bnezc(a0, 0xfffff), // 0x0fffff == 1048575.
+ "f88fffff bnezc a0, 0xfffff", 1048575);
+ COMPARE_PC_REL_COMPACT(bnezc(a0, 0x100000), // 0x100000 == -1048576.
+ "f8900000 bnezc a0, 0x100000", -1048576);
+
+ COMPARE_PC_REL_COMPACT(bc(-33554432), "ca000000 bc -33554432",
+ -33554432);
+ COMPARE_PC_REL_COMPACT(bc(-1), "cbffffff bc -1", -1);
+ COMPARE_PC_REL_COMPACT(bc(0), "c8000000 bc 0", 0);
+ COMPARE_PC_REL_COMPACT(bc(1), "c8000001 bc 1", 1);
+ COMPARE_PC_REL_COMPACT(bc(33554431), "c9ffffff bc 33554431",
+ 33554431);
+
+ COMPARE_PC_REL_COMPACT(balc(-33554432), "ea000000 balc -33554432",
+ -33554432);
+ COMPARE_PC_REL_COMPACT(balc(-1), "ebffffff balc -1", -1);
+ COMPARE_PC_REL_COMPACT(balc(0), "e8000000 balc 0", 0);
+ COMPARE_PC_REL_COMPACT(balc(1), "e8000001 balc 1", 1);
+ COMPARE_PC_REL_COMPACT(balc(33554431), "e9ffffff balc 33554431",
+ 33554431);
+
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -32768),
+ "18858000 bgeuc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -1),
+ "1885ffff bgeuc a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 1),
+ "18850001 bgeuc a0, a1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 32767),
+ "18857fff bgeuc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, -32768),
+ "18848000 bgezalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, -1), "1884ffff bgezalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, 1), "18840001 bgezalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, 32767),
+ "18847fff bgezalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(blezalc(a0, -32768),
+ "18048000 blezalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(blezalc(a0, -1), "1804ffff blezalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(blezalc(a0, 1), "18040001 blezalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(blezalc(a0, 32767),
+ "18047fff blezalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, -32768),
+ "1c858000 bltuc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, -1),
+ "1c85ffff bltuc a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, 1), "1c850001 bltuc a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, 32767),
+ "1c857fff bltuc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, -32768),
+ "1c848000 bltzalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, -1), "1c84ffff bltzalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, 1), "1c840001 bltzalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, 32767),
+ "1c847fff bltzalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, -32768),
+ "1c048000 bgtzalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, -1), "1c04ffff bgtzalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, 1), "1c040001 bgtzalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, 32767),
+ "1c047fff bgtzalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgezc(a0, -32768),
+ "58848000 bgezc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgezc(a0, -1), "5884ffff bgezc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgezc(a0, 1), "58840001 bgezc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgezc(a0, 32767),
+ "58847fff bgezc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, -32768),
+ "58858000 bgec a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, -1),
+ "5885ffff bgec a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, 1), "58850001 bgec a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, 32767),
+ "58857fff bgec a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(blezc(a0, -32768),
+ "58048000 blezc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(blezc(a0, -1), "5804ffff blezc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(blezc(a0, 1), "58040001 blezc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(blezc(a0, 32767),
+ "58047fff blezc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltzc(a0, -32768),
+ "5c848000 bltzc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltzc(a0, -1), "5c84ffff bltzc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltzc(a0, 1), "5c840001 bltzc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bltzc(a0, 32767),
+ "5c847fff bltzc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, -32768),
+ "5c858000 bltc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, -1),
+ "5c85ffff bltc a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, 1), "5c850001 bltc a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, 32767),
+ "5c857fff bltc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, -32768),
+ "5c048000 bgtzc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, -1), "5c04ffff bgtzc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, 1), "5c040001 bgtzc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, 32767),
+ "5c047fff bgtzc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bc1eqz(-32768, f1),
+ "45218000 bc1eqz f1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bc1eqz(-1, f1), "4521ffff bc1eqz f1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bc1eqz(1, f1), "45210001 bc1eqz f1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bc1eqz(32767, f1),
+ "45217fff bc1eqz f1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bc1nez(-32768, f1),
+ "45a18000 bc1nez f1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bc1nez(-1, f1), "45a1ffff bc1nez f1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bc1nez(1, f1), "45a10001 bc1nez f1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bc1nez(32767, f1),
+ "45a17fff bc1nez f1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, -1), "20a4ffff bovc a1, a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bovc(a0, a0, 1), "20840001 bovc a0, a0, 1",
+ 1);
+
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, -32768),
+ "20858000 beqc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, -1), "2085ffff beqc a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, 1), "20850001 beqc a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, 32767),
+ "20857fff beqc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, -32768),
+ "60858000 bnec a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, -1), "6085ffff bnec a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, 1), "60850001 bnec a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, 32767),
+ "60857fff bnec a0, a1, 32767", 32767);
}
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, -32768),
+ "14858000 bne a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, -1), "1485ffff bne a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, 1), "14850001 bne a0, a1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, 32767),
+ "14857fff bne a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, -32768),
+ "10858000 beq a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, -1), "1085ffff beq a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, 1), "10850001 beq a0, a1, 1", 1);
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, 32767),
+ "10857fff beq a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltz(a0, -32768), "04808000 bltz a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(bltz(a0, -1), "0480ffff bltz a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltz(a0, 1), "04800001 bltz a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bltz(a0, 32767), "04807fff bltz a0, 32767",
+ 32767);
+
+ COMPARE_PC_REL_COMPACT(bgez(a0, -32768), "04818000 bgez a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(bgez(a0, -1), "0481ffff bgez a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgez(a0, 1), "04810001 bgez a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgez(a0, 32767), "04817fff bgez a0, 32767",
+ 32767);
+
+ COMPARE_PC_REL_COMPACT(blez(a0, -32768), "18808000 blez a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(blez(a0, -1), "1880ffff blez a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(blez(a0, 1), "18800001 blez a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(blez(a0, 32767), "18807fff blez a0, 32767",
+ 32767);
+
+ COMPARE_PC_REL_COMPACT(bgtz(a0, -32768), "1c808000 bgtz a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(bgtz(a0, -1), "1c80ffff bgtz a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgtz(a0, 1), "1c800001 bgtz a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgtz(a0, 32767), "1c807fff bgtz a0, 32767",
+ 32767);
+
+ COMPARE_PC_JUMP(j(0x4), "08000001 j 0x4", 0x4);
+ COMPARE_PC_JUMP(j(0xffffffc), "0bffffff j 0xffffffc", 0xffffffc);
+
+ COMPARE_PC_JUMP(jal(0x4), "0c000001 jal 0x4", 0x4);
+ COMPARE_PC_JUMP(jal(0xffffffc), "0fffffff jal 0xffffffc",
+ 0xffffffc);
+
COMPARE(addiu(a0, a1, 0x0),
"24a40000 addiu a0, a1, 0");
COMPARE(addiu(s0, s1, 32767),
@@ -506,7 +747,7 @@ TEST(Type0) {
}
}
- if (IsMipsArchVariant(kMips32r2)) {
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
COMPARE(ins_(a0, a1, 31, 1),
"7ca4ffc4 ins a0, a1, 31, 1");
COMPARE(ins_(s6, s7, 30, 2),
@@ -520,26 +761,280 @@ TEST(Type0) {
COMPARE(ext_(v0, v1, 0, 32),
"7c62f800 ext v0, v1, 0, 32");
}
+ COMPARE(add_s(f4, f6, f8), "46083100 add.s f4, f6, f8");
+ COMPARE(add_d(f12, f14, f16), "46307300 add.d f12, f14, f16");
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(bitswap(a0, a1), "7c052020 bitswap a0, a1");
+ COMPARE(bitswap(t8, s0), "7c10c020 bitswap t8, s0");
+ }
+
+ COMPARE(abs_s(f6, f8), "46004185 abs.s f6, f8");
+ COMPARE(abs_d(f10, f12), "46206285 abs.d f10, f12");
+
+ COMPARE(div_s(f2, f4, f6), "46062083 div.s f2, f4, f6");
+ COMPARE(div_d(f2, f4, f6), "46262083 div.d f2, f4, f6");
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(align(v0, a0, a1, 0), "7c851220 align v0, a0, a1, 0");
+ COMPARE(align(v0, a0, a1, 1), "7c851260 align v0, a0, a1, 1");
+ COMPARE(align(v0, a0, a1, 2), "7c8512a0 align v0, a0, a1, 2");
+ COMPARE(align(v0, a0, a1, 3), "7c8512e0 align v0, a0, a1, 3");
+ }
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(aluipc(v0, 0), "ec5f0000 aluipc v0, 0");
+ COMPARE(aluipc(v0, 1), "ec5f0001 aluipc v0, 1");
+ COMPARE(aluipc(v0, 32767), "ec5f7fff aluipc v0, 32767");
+ COMPARE(aluipc(v0, -32768), "ec5f8000 aluipc v0, -32768");
+ COMPARE(aluipc(v0, -1), "ec5fffff aluipc v0, -1");
+ }
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(auipc(t8, 0), "ef1e0000 auipc t8, 0");
+ COMPARE(auipc(t8, 1), "ef1e0001 auipc t8, 1");
+ COMPARE(auipc(t8, 32767), "ef1e7fff auipc t8, 32767");
+ COMPARE(auipc(t8, -32768), "ef1e8000 auipc t8, -32768");
+ COMPARE(auipc(t8, -1), "ef1effff auipc t8, -1");
+ }
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(lwpc(t1, 0), "ed280000 lwpc t1, 0");
+ COMPARE(lwpc(t1, 4), "ed280004 lwpc t1, 4");
+ COMPARE(lwpc(t1, -4), "ed2ffffc lwpc t1, -4");
+ }
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(jic(t0, -32768), "d8088000 jic t0, -32768");
+ COMPARE(jic(t0, -1), "d808ffff jic t0, -1");
+ COMPARE(jic(t0, 0), "d8080000 jic t0, 0");
+ COMPARE(jic(t0, 4), "d8080004 jic t0, 4");
+ COMPARE(jic(t0, 32767), "d8087fff jic t0, 32767");
+ }
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(addiupc(a0, 262143), "ec83ffff addiupc a0, 262143");
+ COMPARE(addiupc(a0, -1), "ec87ffff addiupc a0, -1");
+ COMPARE(addiupc(v0, 0), "ec400000 addiupc v0, 0");
+ COMPARE(addiupc(s1, 1), "ee200001 addiupc s1, 1");
+ COMPARE(addiupc(a0, -262144), "ec840000 addiupc a0, -262144");
+ }
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(jialc(a0, -32768), "f8048000 jialc a0, 0x8000");
+ COMPARE(jialc(a0, -1), "f804ffff jialc a0, 0xffff");
+ COMPARE(jialc(v0, 0), "f8020000 jialc v0, 0x0");
+ COMPARE(jialc(s1, 1), "f8110001 jialc s1, 0x1");
+ COMPARE(jialc(a0, 32767), "f8047fff jialc a0, 0x7fff");
+ }
VERIFY_RUN();
}
-// Tests only seleqz, selnez, seleqz.fmt and selnez.fmt
TEST(Type1) {
+ SET_UP();
if (IsMipsArchVariant(kMips32r6)) {
- SET_UP();
COMPARE(seleqz(a0, a1, a2), "00a62035 seleqz a0, a1, a2");
COMPARE(selnez(a0, a1, a2), "00a62037 selnez a0, a1, a2");
- COMPARE(seleqz(D, f3, f4, f5), "462520d4 seleqz.d f3, f4, f5");
- COMPARE(selnez(D, f3, f4, f5), "462520d7 selnez.d f3, f4, f5");
+ COMPARE(seleqz_d(f3, f4, f5), "462520d4 seleqz.d f3, f4, f5");
+ COMPARE(selnez_d(f3, f4, f5), "462520d7 selnez.d f3, f4, f5");
+ COMPARE(seleqz_s(f3, f4, f5), "460520d4 seleqz.s f3, f4, f5");
+ COMPARE(selnez_s(f3, f4, f5), "460520d7 selnez.s f3, f4, f5");
COMPARE(min_d(f3, f4, f5), "462520dc min.d f3, f4, f5");
COMPARE(max_d(f3, f4, f5), "462520de max.d f3, f4, f5");
+
+ COMPARE(sel_s(f3, f4, f5), "460520d0 sel.s f3, f4, f5");
+ COMPARE(sel_d(f3, f4, f5), "462520d0 sel.d f3, f4, f5");
+
COMPARE(rint_d(f8, f6), "4620321a rint.d f8, f6");
+ COMPARE(rint_s(f8, f6), "4600321a rint.s f8, f6");
+
+ COMPARE(min_s(f3, f4, f5), "460520dc min.s f3, f4, f5");
+ COMPARE(max_s(f3, f4, f5), "460520de max.s f3, f4, f5");
+
+ COMPARE(mina_d(f3, f4, f5), "462520dd mina.d f3, f4, f5");
+ COMPARE(mina_s(f3, f4, f5), "460520dd mina.s f3, f4, f5");
+
+ COMPARE(maxa_d(f3, f4, f5), "462520df maxa.d f3, f4, f5");
+ COMPARE(maxa_s(f3, f4, f5), "460520df maxa.s f3, f4, f5");
+ }
+
+ COMPARE(trunc_w_d(f8, f6), "4620320d trunc.w.d f8, f6");
+ COMPARE(trunc_w_s(f8, f6), "4600320d trunc.w.s f8, f6");
+
+ COMPARE(round_w_s(f8, f6), "4600320c round.w.s f8, f6");
+ COMPARE(round_w_d(f8, f6), "4620320c round.w.d f8, f6");
+
+ COMPARE(round_l_s(f8, f6), "46003208 round.l.s f8, f6");
+ COMPARE(round_l_d(f8, f6), "46203208 round.l.d f8, f6");
+
+ COMPARE(floor_w_s(f8, f6), "4600320f floor.w.s f8, f6");
+ COMPARE(floor_w_d(f8, f6), "4620320f floor.w.d f8, f6");
+
+ COMPARE(floor_l_s(f8, f6), "4600320b floor.l.s f8, f6");
+ COMPARE(floor_l_d(f8, f6), "4620320b floor.l.d f8, f6");
+
+ COMPARE(ceil_w_s(f8, f6), "4600320e ceil.w.s f8, f6");
+ COMPARE(ceil_w_d(f8, f6), "4620320e ceil.w.d f8, f6");
+
+ COMPARE(ceil_l_s(f8, f6), "4600320a ceil.l.s f8, f6");
+ COMPARE(ceil_l_d(f8, f6), "4620320a ceil.l.d f8, f6");
+
+ COMPARE(sub_s(f10, f8, f6), "46064281 sub.s f10, f8, f6");
+ COMPARE(sub_d(f10, f8, f6), "46264281 sub.d f10, f8, f6");
+
+ COMPARE(sqrt_s(f8, f6), "46003204 sqrt.s f8, f6");
+ COMPARE(sqrt_d(f8, f6), "46203204 sqrt.d f8, f6");
+
+ COMPARE(neg_s(f8, f6), "46003207 neg.s f8, f6");
+ COMPARE(neg_d(f8, f6), "46203207 neg.d f8, f6");
+
+ COMPARE(mul_s(f8, f6, f4), "46043202 mul.s f8, f6, f4");
+ COMPARE(mul_d(f8, f6, f4), "46243202 mul.d f8, f6, f4");
+
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ COMPARE(rsqrt_s(f8, f6), "46003216 rsqrt.s f8, f6");
+ COMPARE(rsqrt_d(f8, f6), "46203216 rsqrt.d f8, f6");
+
+ COMPARE(recip_s(f8, f6), "46003215 recip.s f8, f6");
+ COMPARE(recip_d(f8, f6), "46203215 recip.d f8, f6");
+ }
+
+ COMPARE(mov_s(f6, f4), "46002186 mov.s f6, f4");
+ COMPARE(mov_d(f6, f4), "46202186 mov.d f6, f4");
+
+ if (IsMipsArchVariant(kMips32r2)) {
+ COMPARE(trunc_l_d(f8, f6), "46203209 trunc.l.d f8, f6");
+ COMPARE(trunc_l_s(f8, f6), "46003209 trunc.l.s f8, f6");
+
+ COMPARE(movz_s(f6, f4, t0), "46082192 movz.s f6, f4, t0");
+ COMPARE(movz_d(f6, f4, t0), "46282192 movz.d f6, f4, t0");
+
+ COMPARE(movt_s(f6, f4, 4), "46112191 movt.s f6, f4, cc(1)");
+ COMPARE(movt_d(f6, f4, 4), "46312191 movt.d f6, f4, cc(1)");
+
+ COMPARE(movf_s(f6, f4, 4), "46102191 movf.s f6, f4, cc(1)");
+ COMPARE(movf_d(f6, f4, 4), "46302191 movf.d f6, f4, cc(1)");
+
+ COMPARE(movn_s(f6, f4, t0), "46082193 movn.s f6, f4, t0");
+ COMPARE(movn_d(f6, f4, t0), "46282193 movn.d f6, f4, t0");
+ }
+ VERIFY_RUN();
+}
+
+
+TEST(Type2) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ SET_UP();
+
+ COMPARE(class_s(f3, f4), "460020db class.s f3, f4");
+ COMPARE(class_d(f2, f3), "4620189b class.d f2, f3");
+
+ VERIFY_RUN();
+ }
+}
+
+
+TEST(C_FMT_DISASM) {
+ if (IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kMips32r2)) {
+ SET_UP();
+
+ COMPARE(c_s(F, f8, f10, 0), "460a4030 c.f.s f8, f10, cc(0)");
+ COMPARE(c_d(F, f8, f10, 0), "462a4030 c.f.d f8, f10, cc(0)");
+
+ COMPARE(c_s(UN, f8, f10, 2), "460a4231 c.un.s f8, f10, cc(2)");
+ COMPARE(c_d(UN, f8, f10, 2), "462a4231 c.un.d f8, f10, cc(2)");
+
+ COMPARE(c_s(EQ, f8, f10, 4), "460a4432 c.eq.s f8, f10, cc(4)");
+ COMPARE(c_d(EQ, f8, f10, 4), "462a4432 c.eq.d f8, f10, cc(4)");
+
+ COMPARE(c_s(UEQ, f8, f10, 6), "460a4633 c.ueq.s f8, f10, cc(6)");
+ COMPARE(c_d(UEQ, f8, f10, 6), "462a4633 c.ueq.d f8, f10, cc(6)");
+
+ COMPARE(c_s(OLT, f8, f10, 0), "460a4034 c.olt.s f8, f10, cc(0)");
+ COMPARE(c_d(OLT, f8, f10, 0), "462a4034 c.olt.d f8, f10, cc(0)");
+
+ COMPARE(c_s(ULT, f8, f10, 2), "460a4235 c.ult.s f8, f10, cc(2)");
+ COMPARE(c_d(ULT, f8, f10, 2), "462a4235 c.ult.d f8, f10, cc(2)");
+
+ COMPARE(c_s(OLE, f8, f10, 4), "460a4436 c.ole.s f8, f10, cc(4)");
+ COMPARE(c_d(OLE, f8, f10, 4), "462a4436 c.ole.d f8, f10, cc(4)");
+
+ COMPARE(c_s(ULE, f8, f10, 6), "460a4637 c.ule.s f8, f10, cc(6)");
+ COMPARE(c_d(ULE, f8, f10, 6), "462a4637 c.ule.d f8, f10, cc(6)");
VERIFY_RUN();
}
}
+
+
+TEST(COND_FMT_DISASM) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ SET_UP();
+
+ COMPARE(cmp_s(F, f6, f8, f10), "468a4180 cmp.af.s f6, f8, f10");
+ COMPARE(cmp_d(F, f6, f8, f10), "46aa4180 cmp.af.d f6, f8, f10");
+
+ COMPARE(cmp_s(UN, f6, f8, f10), "468a4181 cmp.un.s f6, f8, f10");
+ COMPARE(cmp_d(UN, f6, f8, f10), "46aa4181 cmp.un.d f6, f8, f10");
+
+ COMPARE(cmp_s(EQ, f6, f8, f10), "468a4182 cmp.eq.s f6, f8, f10");
+ COMPARE(cmp_d(EQ, f6, f8, f10), "46aa4182 cmp.eq.d f6, f8, f10");
+
+ COMPARE(cmp_s(UEQ, f6, f8, f10), "468a4183 cmp.ueq.s f6, f8, f10");
+ COMPARE(cmp_d(UEQ, f6, f8, f10), "46aa4183 cmp.ueq.d f6, f8, f10");
+
+ COMPARE(cmp_s(LT, f6, f8, f10), "468a4184 cmp.lt.s f6, f8, f10");
+ COMPARE(cmp_d(LT, f6, f8, f10), "46aa4184 cmp.lt.d f6, f8, f10");
+
+ COMPARE(cmp_s(ULT, f6, f8, f10), "468a4185 cmp.ult.s f6, f8, f10");
+ COMPARE(cmp_d(ULT, f6, f8, f10), "46aa4185 cmp.ult.d f6, f8, f10");
+
+ COMPARE(cmp_s(LE, f6, f8, f10), "468a4186 cmp.le.s f6, f8, f10");
+ COMPARE(cmp_d(LE, f6, f8, f10), "46aa4186 cmp.le.d f6, f8, f10");
+
+ COMPARE(cmp_s(ULE, f6, f8, f10), "468a4187 cmp.ule.s f6, f8, f10");
+ COMPARE(cmp_d(ULE, f6, f8, f10), "46aa4187 cmp.ule.d f6, f8, f10");
+
+ COMPARE(cmp_s(ORD, f6, f8, f10), "468a4191 cmp.or.s f6, f8, f10");
+ COMPARE(cmp_d(ORD, f6, f8, f10), "46aa4191 cmp.or.d f6, f8, f10");
+
+ COMPARE(cmp_s(UNE, f6, f8, f10), "468a4192 cmp.une.s f6, f8, f10");
+ COMPARE(cmp_d(UNE, f6, f8, f10), "46aa4192 cmp.une.d f6, f8, f10");
+
+ COMPARE(cmp_s(NE, f6, f8, f10), "468a4193 cmp.ne.s f6, f8, f10");
+ COMPARE(cmp_d(NE, f6, f8, f10), "46aa4193 cmp.ne.d f6, f8, f10");
+
+ VERIFY_RUN();
+ }
+}
+
+
+TEST(CVT_DISSASM) {
+ SET_UP();
+ COMPARE(cvt_d_s(f22, f24), "4600c5a1 cvt.d.s f22, f24");
+ COMPARE(cvt_d_w(f22, f24), "4680c5a1 cvt.d.w f22, f24");
+ if (IsMipsArchVariant(kMips32r6) || IsMipsArchVariant(kMips32r2)) {
+ COMPARE(cvt_d_l(f22, f24), "46a0c5a1 cvt.d.l f22, f24");
+ }
+
+ if (IsMipsArchVariant(kMips32r6) || IsMipsArchVariant(kMips32r2)) {
+ COMPARE(cvt_l_s(f22, f24), "4600c5a5 cvt.l.s f22, f24");
+ COMPARE(cvt_l_d(f22, f24), "4620c5a5 cvt.l.d f22, f24");
+ }
+
+ COMPARE(cvt_s_d(f22, f24), "4620c5a0 cvt.s.d f22, f24");
+ COMPARE(cvt_s_w(f22, f24), "4680c5a0 cvt.s.w f22, f24");
+ if (IsMipsArchVariant(kMips32r6) || IsMipsArchVariant(kMips32r2)) {
+ COMPARE(cvt_s_l(f22, f24), "46a0c5a0 cvt.s.l f22, f24");
+ }
+
+ COMPARE(cvt_s_d(f22, f24), "4620c5a0 cvt.s.d f22, f24");
+ COMPARE(cvt_s_w(f22, f24), "4680c5a0 cvt.s.w f22, f24");
+
+ VERIFY_RUN();
+}
diff --git a/deps/v8/test/cctest/test-disasm-mips64.cc b/deps/v8/test/cctest/test-disasm-mips64.cc
index 492265b2e7..225a1e7f0b 100644
--- a/deps/v8/test/cctest/test-disasm-mips64.cc
+++ b/deps/v8/test/cctest/test-disasm-mips64.cc
@@ -92,6 +92,45 @@ if (failure) { \
}
+#define COMPARE_PC_REL_COMPACT(asm_, compare_string, offset) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ char str_with_address[100]; \
+ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
+ compare_string, progcounter + 4 + (offset << 2)); \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
+ }
+
+
+#define COMPARE_PC_REL(asm_, compare_string, offset) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ char str_with_address[100]; \
+ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
+ compare_string, progcounter + (offset << 2)); \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
+ }
+
+
+#define COMPARE_PC_JUMP(asm_, compare_string, target) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ char str_with_address[100]; \
+ int instr_index = target >> 2; \
+ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
+ compare_string, reinterpret_cast<byte *>( \
+ ((uint64_t)(progcounter + 1) & ~0xfffffff) | \
+ (instr_index << 2))); \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
+ }
+
+
TEST(Type0) {
SET_UP();
@@ -279,38 +318,6 @@ TEST(Type0) {
"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),
@@ -669,23 +676,551 @@ TEST(Type0) {
COMPARE(ext_(v0, v1, 0, 32),
"7c62f800 ext v0, v1, 0, 32");
+ COMPARE(add_s(f4, f6, f8), "46083100 add.s f4, f6, f8");
+ COMPARE(add_d(f12, f14, f16), "46307300 add.d f12, f14, f16");
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(bitswap(a0, a1), "7c052020 bitswap a0, a1");
+ COMPARE(bitswap(t8, s0), "7c10c020 bitswap t8, s0");
+ COMPARE(dbitswap(a0, a1), "7c052024 dbitswap a0, a1");
+ COMPARE(dbitswap(t8, s0), "7c10c024 dbitswap t8, s0");
+ }
+
+ COMPARE(abs_s(f6, f8), "46004185 abs.s f6, f8");
+ COMPARE(abs_d(f10, f12), "46206285 abs.d f10, f12");
+
+ COMPARE(div_s(f2, f4, f6), "46062083 div.s f2, f4, f6");
+ COMPARE(div_d(f2, f4, f6), "46262083 div.d f2, f4, f6");
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(align(v0, a0, a1, 0), "7c851220 align v0, a0, a1, 0");
+ COMPARE(align(v0, a0, a1, 1), "7c851260 align v0, a0, a1, 1");
+ COMPARE(align(v0, a0, a1, 2), "7c8512a0 align v0, a0, a1, 2");
+ COMPARE(align(v0, a0, a1, 3), "7c8512e0 align v0, a0, a1, 3");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(dalign(v0, a0, a1, 0), "7c851224 dalign v0, a0, a1, 0");
+ COMPARE(dalign(v0, a0, a1, 1), "7c851264 dalign v0, a0, a1, 1");
+ COMPARE(dalign(v0, a0, a1, 2), "7c8512a4 dalign v0, a0, a1, 2");
+ COMPARE(dalign(v0, a0, a1, 3), "7c8512e4 dalign v0, a0, a1, 3");
+ COMPARE(dalign(v0, a0, a1, 4), "7c851324 dalign v0, a0, a1, 4");
+ COMPARE(dalign(v0, a0, a1, 5), "7c851364 dalign v0, a0, a1, 5");
+ COMPARE(dalign(v0, a0, a1, 6), "7c8513a4 dalign v0, a0, a1, 6");
+ COMPARE(dalign(v0, a0, a1, 7), "7c8513e4 dalign v0, a0, a1, 7");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(aluipc(v0, 0), "ec5f0000 aluipc v0, 0");
+ COMPARE(aluipc(v0, 1), "ec5f0001 aluipc v0, 1");
+ COMPARE(aluipc(v0, 32767), "ec5f7fff aluipc v0, 32767");
+ COMPARE(aluipc(v0, -32768), "ec5f8000 aluipc v0, -32768");
+ COMPARE(aluipc(v0, -1), "ec5fffff aluipc v0, -1");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(auipc(t8, 0), "ef1e0000 auipc t8, 0");
+ COMPARE(auipc(t8, 1), "ef1e0001 auipc t8, 1");
+ COMPARE(auipc(t8, 32767), "ef1e7fff auipc t8, 32767");
+ COMPARE(auipc(t8, -32768), "ef1e8000 auipc t8, -32768");
+ COMPARE(auipc(t8, -1), "ef1effff auipc t8, -1");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(lwpc(a5, 0), "ed280000 lwpc a5, 0");
+ COMPARE(lwpc(a5, 4), "ed280004 lwpc a5, 4");
+ COMPARE(lwpc(a5, -4), "ed2ffffc lwpc a5, -4");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(lwupc(a0, -262144), "ec940000 lwupc a0, -262144");
+ COMPARE(lwupc(a0, -1), "ec97ffff lwupc a0, -1");
+ COMPARE(lwupc(a0, 0), "ec900000 lwupc a0, 0");
+ COMPARE(lwupc(a0, 1), "ec900001 lwupc a0, 1");
+ COMPARE(lwupc(a0, 262143), "ec93ffff lwupc a0, 262143");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(jic(t0, 16), "d80c0010 jic t0, 16");
+ COMPARE(jic(t0, 4), "d80c0004 jic t0, 4");
+ COMPARE(jic(t0, -32), "d80cffe0 jic t0, -32");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 16), "d8800010 beqzc a0, 0x10",
+ 16);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 4), "d8800004 beqzc a0, 0x4", 4);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, -32),
+ "d89fffe0 beqzc a0, 0x1fffe0", -32);
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(ldpc(v0, 256), "ec580100 ldpc v0, 256");
+ COMPARE(ldpc(a0, -1), "ec9bffff ldpc a0, -1");
+ COMPARE(ldpc(a1, 0), "ecb80000 ldpc a1, 0");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(addiupc(a0, 262143), "ec83ffff addiupc a0, 262143");
+ COMPARE(addiupc(a0, -1), "ec87ffff addiupc a0, -1");
+ COMPARE(addiupc(v0, 0), "ec400000 addiupc v0, 0");
+ COMPARE(addiupc(s1, 1), "ee200001 addiupc s1, 1");
+ COMPARE(addiupc(a0, -262144), "ec840000 addiupc a0, -262144");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(jialc(a0, -32768), "f8048000 jialc a0, 0x8000");
+ COMPARE(jialc(a0, -1), "f804ffff jialc a0, 0xffff");
+ COMPARE(jialc(v0, 0), "f8020000 jialc v0, 0x0");
+ COMPARE(jialc(s1, 1), "f8110001 jialc s1, 0x1");
+ COMPARE(jialc(a0, 32767), "f8047fff jialc a0, 0x7fff");
+ }
+
VERIFY_RUN();
}
TEST(Type1) {
+ SET_UP();
if (kArchVariant == kMips64r6) {
- SET_UP();
COMPARE(seleqz(a0, a1, a2), "00a62035 seleqz a0, a1, a2");
COMPARE(selnez(a0, a1, a2), "00a62037 selnez a0, a1, a2");
COMPARE(seleqz(D, f3, f4, f5), "462520d4 seleqz.d f3, f4, f5");
COMPARE(selnez(D, f3, f4, f5), "462520d7 selnez.d f3, f4, f5");
+ COMPARE(seleqz(S, f3, f4, f5), "460520d4 seleqz.s f3, f4, f5");
+ COMPARE(selnez(S, f3, f4, f5), "460520d7 selnez.s f3, f4, f5");
COMPARE(min_d(f3, f4, f5), "462520dc min.d f3, f4, f5");
COMPARE(max_d(f3, f4, f5), "462520de max.d f3, f4, f5");
+
+ COMPARE(sel(S, f3, f4, f5), "460520d0 sel.s f3, f4, f5");
+ COMPARE(sel(D, f3, f4, f5), "462520d0 sel.d f3, f4, f5");
+
COMPARE(rint_d(f8, f6), "4620321a rint.d f8, f6");
+
+ COMPARE(min_s(f3, f4, f5), "460520dc min.s f3, f4, f5");
+ COMPARE(max_s(f3, f4, f5), "460520de max.s f3, f4, f5");
+
+ COMPARE(rint(S, f8, f6), "4600321a rint.s f8, f6");
+
+ COMPARE(mina_d(f3, f4, f5), "462520dd mina.d f3, f4, f5");
+ COMPARE(mina_s(f3, f4, f5), "460520dd mina.s f3, f4, f5");
+
+ COMPARE(maxa_d(f3, f4, f5), "462520df maxa.d f3, f4, f5");
+ COMPARE(maxa_s(f3, f4, f5), "460520df maxa.s f3, f4, f5");
+ }
+ COMPARE(trunc_w_d(f8, f6), "4620320d trunc.w.d f8, f6");
+ COMPARE(trunc_w_s(f8, f6), "4600320d trunc.w.s f8, f6");
+
+ COMPARE(round_w_s(f8, f6), "4600320c round.w.s f8, f6");
+ COMPARE(round_w_d(f8, f6), "4620320c round.w.d f8, f6");
+
+ COMPARE(round_l_s(f8, f6), "46003208 round.l.s f8, f6");
+ COMPARE(round_l_d(f8, f6), "46203208 round.l.d f8, f6");
+
+ COMPARE(floor_w_s(f8, f6), "4600320f floor.w.s f8, f6");
+ COMPARE(floor_w_d(f8, f6), "4620320f floor.w.d f8, f6");
+
+ COMPARE(floor_l_s(f8, f6), "4600320b floor.l.s f8, f6");
+ COMPARE(floor_l_d(f8, f6), "4620320b floor.l.d f8, f6");
+
+ COMPARE(ceil_w_s(f8, f6), "4600320e ceil.w.s f8, f6");
+ COMPARE(ceil_w_d(f8, f6), "4620320e ceil.w.d f8, f6");
+
+ COMPARE(ceil_l_s(f8, f6), "4600320a ceil.l.s f8, f6");
+ COMPARE(ceil_l_d(f8, f6), "4620320a ceil.l.d f8, f6");
+
+ COMPARE(sub_s(f10, f8, f6), "46064281 sub.s f10, f8, f6");
+ COMPARE(sub_d(f10, f8, f6), "46264281 sub.d f10, f8, f6");
+
+ COMPARE(sqrt_s(f8, f6), "46003204 sqrt.s f8, f6");
+ COMPARE(sqrt_d(f8, f6), "46203204 sqrt.d f8, f6");
+
+ COMPARE(neg_s(f8, f6), "46003207 neg.s f8, f6");
+ COMPARE(neg_d(f8, f6), "46203207 neg.d f8, f6");
+
+ COMPARE(mul_s(f8, f6, f4), "46043202 mul.s f8, f6, f4");
+ COMPARE(mul_d(f8, f6, f4), "46243202 mul.d f8, f6, f4");
+
+ COMPARE(rsqrt_s(f8, f6), "46003216 rsqrt.s f8, f6");
+ COMPARE(rsqrt_d(f8, f6), "46203216 rsqrt.d f8, f6");
+
+ COMPARE(recip_s(f8, f6), "46003215 recip.s f8, f6");
+ COMPARE(recip_d(f8, f6), "46203215 recip.d f8, f6");
+
+ COMPARE(mov_s(f6, f4), "46002186 mov.s f6, f4");
+ COMPARE(mov_d(f6, f4), "46202186 mov.d f6, f4");
+ if (kArchVariant == kMips64r2) {
+ COMPARE(trunc_l_d(f8, f6), "46203209 trunc.l.d f8, f6");
+ COMPARE(trunc_l_s(f8, f6), "46003209 trunc.l.s f8, f6");
+
+ COMPARE(movz_s(f6, f4, t0), "460c2192 movz.s f6, f4, t0");
+ COMPARE(movz_d(f6, f4, t0), "462c2192 movz.d f6, f4, t0");
+
+ COMPARE(movt_s(f6, f4, 4), "46112191 movt.s f6, f4, cc(1)");
+ COMPARE(movt_d(f6, f4, 4), "46312191 movt.d f6, f4, cc(1)");
+
+ COMPARE(movf_s(f6, f4, 4), "46102191 movf.s f6, f4, cc(1)");
+ COMPARE(movf_d(f6, f4, 4), "46302191 movf.d f6, f4, cc(1)");
+
+ COMPARE(movn_s(f6, f4, t0), "460c2193 movn.s f6, f4, t0");
+ COMPARE(movn_d(f6, f4, t0), "462c2193 movn.d f6, f4, t0");
+ }
+ VERIFY_RUN();
+}
+
+
+TEST(Type2) {
+ if (kArchVariant == kMips64r6) {
+ SET_UP();
+
+ COMPARE(class_s(f3, f4), "460020db class.s f3, f4");
+ COMPARE(class_d(f2, f3), "4620189b class.d f2, f3");
+
VERIFY_RUN();
}
}
+
+
+TEST(Type3) {
+ SET_UP();
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE_PC_REL_COMPACT(bovc(a0, a0, static_cast<int16_t>(0)),
+ "20840000 bovc a0, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, static_cast<int16_t>(0)),
+ "20a40000 bovc a1, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, 32767),
+ "20a47fff bovc a1, a0, 32767", 32767);
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, -32768),
+ "20a48000 bovc a1, a0, -32768", -32768);
+
+ COMPARE_PC_REL_COMPACT(bnvc(a0, a0, static_cast<int16_t>(0)),
+ "60840000 bnvc a0, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bnvc(a1, a0, static_cast<int16_t>(0)),
+ "60a40000 bnvc a1, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bnvc(a1, a0, 32767),
+ "60a47fff bnvc a1, a0, 32767", 32767);
+ COMPARE_PC_REL_COMPACT(bnvc(a1, a0, -32768),
+ "60a48000 bnvc a1, a0, -32768", -32768);
+
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 0), "d8800000 beqzc a0, 0x0", 0);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 0xfffff), // 0x0fffff == 1048575.
+ "d88fffff beqzc a0, 0xfffff", 1048575);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 0x100000), // 0x100000 == -1048576.
+ "d8900000 beqzc a0, 0x100000", -1048576);
+
+ COMPARE_PC_REL_COMPACT(bnezc(a0, 0), "f8800000 bnezc a0, 0x0", 0);
+ COMPARE_PC_REL_COMPACT(bnezc(a0, 0xfffff), // 0x0fffff == 1048575.
+ "f88fffff bnezc a0, 0xfffff", 1048575);
+ COMPARE_PC_REL_COMPACT(bnezc(a0, 0x100000), // 0x100000 == -1048576.
+ "f8900000 bnezc a0, 0x100000", -1048576);
+
+ COMPARE_PC_REL_COMPACT(bc(-33554432), "ca000000 bc -33554432",
+ -33554432);
+ COMPARE_PC_REL_COMPACT(bc(-1), "cbffffff bc -1", -1);
+ COMPARE_PC_REL_COMPACT(bc(0), "c8000000 bc 0", 0);
+ COMPARE_PC_REL_COMPACT(bc(1), "c8000001 bc 1", 1);
+ COMPARE_PC_REL_COMPACT(bc(33554431), "c9ffffff bc 33554431",
+ 33554431);
+
+ COMPARE_PC_REL_COMPACT(balc(-33554432), "ea000000 balc -33554432",
+ -33554432);
+ COMPARE_PC_REL_COMPACT(balc(-1), "ebffffff balc -1", -1);
+ COMPARE_PC_REL_COMPACT(balc(0), "e8000000 balc 0", 0);
+ COMPARE_PC_REL_COMPACT(balc(1), "e8000001 balc 1", 1);
+ COMPARE_PC_REL_COMPACT(balc(33554431), "e9ffffff balc 33554431",
+ 33554431);
+
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -32768),
+ "18858000 bgeuc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -1),
+ "1885ffff bgeuc a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 1),
+ "18850001 bgeuc a0, a1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 32767),
+ "18857fff bgeuc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, -32768),
+ "18848000 bgezalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, -1), "1884ffff bgezalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, 1), "18840001 bgezalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, 32767),
+ "18847fff bgezalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(blezalc(a0, -32768),
+ "18048000 blezalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(blezalc(a0, -1), "1804ffff blezalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(blezalc(a0, 1), "18040001 blezalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(blezalc(a0, 32767),
+ "18047fff blezalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, -32768),
+ "1c858000 bltuc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, -1),
+ "1c85ffff bltuc a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, 1), "1c850001 bltuc a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, 32767),
+ "1c857fff bltuc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, -32768),
+ "1c848000 bltzalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, -1), "1c84ffff bltzalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, 1), "1c840001 bltzalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, 32767),
+ "1c847fff bltzalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, -32768),
+ "1c048000 bgtzalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, -1), "1c04ffff bgtzalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, 1), "1c040001 bgtzalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, 32767),
+ "1c047fff bgtzalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgezc(a0, -32768),
+ "58848000 bgezc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgezc(a0, -1), "5884ffff bgezc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgezc(a0, 1), "58840001 bgezc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgezc(a0, 32767),
+ "58847fff bgezc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, -32768),
+ "58858000 bgec a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, -1),
+ "5885ffff bgec a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, 1), "58850001 bgec a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, 32767),
+ "58857fff bgec a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(blezc(a0, -32768),
+ "58048000 blezc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(blezc(a0, -1), "5804ffff blezc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(blezc(a0, 1), "58040001 blezc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(blezc(a0, 32767),
+ "58047fff blezc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltzc(a0, -32768),
+ "5c848000 bltzc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltzc(a0, -1), "5c84ffff bltzc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltzc(a0, 1), "5c840001 bltzc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bltzc(a0, 32767),
+ "5c847fff bltzc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, -32768),
+ "5c858000 bltc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, -1),
+ "5c85ffff bltc a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, 1), "5c850001 bltc a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, 32767),
+ "5c857fff bltc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, -32768),
+ "5c048000 bgtzc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, -1), "5c04ffff bgtzc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, 1), "5c040001 bgtzc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, 32767),
+ "5c047fff bgtzc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bc1eqz(-32768, f1),
+ "45218000 bc1eqz f1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bc1eqz(-1, f1), "4521ffff bc1eqz f1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bc1eqz(1, f1), "45210001 bc1eqz f1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bc1eqz(32767, f1),
+ "45217fff bc1eqz f1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bc1nez(-32768, f1),
+ "45a18000 bc1nez f1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bc1nez(-1, f1), "45a1ffff bc1nez f1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bc1nez(1, f1), "45a10001 bc1nez f1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bc1nez(32767, f1),
+ "45a17fff bc1nez f1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, -1), "20a4ffff bovc a1, a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bovc(a0, a0, 1), "20840001 bovc a0, a0, 1",
+ 1);
+
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, -32768),
+ "20858000 beqc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, -1), "2085ffff beqc a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, 1), "20850001 beqc a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, 32767),
+ "20857fff beqc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, -32768),
+ "60858000 bnec a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, -1), "6085ffff bnec a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, 1), "60850001 bnec a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, 32767),
+ "60857fff bnec a0, a1, 32767", 32767);
+ }
+
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, -32768),
+ "14858000 bne a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, -1), "1485ffff bne a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, 1), "14850001 bne a0, a1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, 32767),
+ "14857fff bne a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, -32768),
+ "10858000 beq a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, -1), "1085ffff beq a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, 1), "10850001 beq a0, a1, 1", 1);
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, 32767),
+ "10857fff beq a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltz(a0, -32768), "04808000 bltz a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(bltz(a0, -1), "0480ffff bltz a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltz(a0, 1), "04800001 bltz a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bltz(a0, 32767), "04807fff bltz a0, 32767",
+ 32767);
+
+ COMPARE_PC_REL_COMPACT(bgez(a0, -32768), "04818000 bgez a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(bgez(a0, -1), "0481ffff bgez a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgez(a0, 1), "04810001 bgez a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgez(a0, 32767), "04817fff bgez a0, 32767",
+ 32767);
+
+ COMPARE_PC_REL_COMPACT(blez(a0, -32768), "18808000 blez a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(blez(a0, -1), "1880ffff blez a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(blez(a0, 1), "18800001 blez a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(blez(a0, 32767), "18807fff blez a0, 32767",
+ 32767);
+
+ COMPARE_PC_REL_COMPACT(bgtz(a0, -32768), "1c808000 bgtz a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(bgtz(a0, -1), "1c80ffff bgtz a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgtz(a0, 1), "1c800001 bgtz a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgtz(a0, 32767), "1c807fff bgtz a0, 32767",
+ 32767);
+
+ COMPARE_PC_JUMP(j(0x4), "08000001 j 0x4", 0x4);
+ COMPARE_PC_JUMP(j(0xffffffc), "0bffffff j 0xffffffc", 0xffffffc);
+
+ COMPARE_PC_JUMP(jal(0x4), "0c000001 jal 0x4", 0x4);
+ COMPARE_PC_JUMP(jal(0xffffffc), "0fffffff jal 0xffffffc",
+ 0xffffffc);
+
+ VERIFY_RUN();
+}
+
+
+TEST(C_FMT_DISASM) {
+ if (kArchVariant == kMips64r2) {
+ SET_UP();
+
+ COMPARE(c_s(F, f8, f10, 0), "460a4030 c.f.s f8, f10, cc(0)");
+ COMPARE(c_d(F, f8, f10, 0), "462a4030 c.f.d f8, f10, cc(0)");
+
+ COMPARE(c_s(UN, f8, f10, 2), "460a4231 c.un.s f8, f10, cc(2)");
+ COMPARE(c_d(UN, f8, f10, 2), "462a4231 c.un.d f8, f10, cc(2)");
+
+ COMPARE(c_s(EQ, f8, f10, 4), "460a4432 c.eq.s f8, f10, cc(4)");
+ COMPARE(c_d(EQ, f8, f10, 4), "462a4432 c.eq.d f8, f10, cc(4)");
+
+ COMPARE(c_s(UEQ, f8, f10, 6), "460a4633 c.ueq.s f8, f10, cc(6)");
+ COMPARE(c_d(UEQ, f8, f10, 6), "462a4633 c.ueq.d f8, f10, cc(6)");
+
+ COMPARE(c_s(OLT, f8, f10, 0), "460a4034 c.olt.s f8, f10, cc(0)");
+ COMPARE(c_d(OLT, f8, f10, 0), "462a4034 c.olt.d f8, f10, cc(0)");
+
+ COMPARE(c_s(ULT, f8, f10, 2), "460a4235 c.ult.s f8, f10, cc(2)");
+ COMPARE(c_d(ULT, f8, f10, 2), "462a4235 c.ult.d f8, f10, cc(2)");
+
+ COMPARE(c_s(OLE, f8, f10, 4), "460a4436 c.ole.s f8, f10, cc(4)");
+ COMPARE(c_d(OLE, f8, f10, 4), "462a4436 c.ole.d f8, f10, cc(4)");
+
+ COMPARE(c_s(ULE, f8, f10, 6), "460a4637 c.ule.s f8, f10, cc(6)");
+ COMPARE(c_d(ULE, f8, f10, 6), "462a4637 c.ule.d f8, f10, cc(6)");
+
+ VERIFY_RUN();
+ }
+}
+
+
+TEST(COND_FMT_DISASM) {
+ if (kArchVariant == kMips64r6) {
+ SET_UP();
+
+ COMPARE(cmp_s(F, f6, f8, f10), "468a4180 cmp.af.s f6, f8, f10");
+ COMPARE(cmp_d(F, f6, f8, f10), "46aa4180 cmp.af.d f6, f8, f10");
+
+ COMPARE(cmp_s(UN, f6, f8, f10), "468a4181 cmp.un.s f6, f8, f10");
+ COMPARE(cmp_d(UN, f6, f8, f10), "46aa4181 cmp.un.d f6, f8, f10");
+
+ COMPARE(cmp_s(EQ, f6, f8, f10), "468a4182 cmp.eq.s f6, f8, f10");
+ COMPARE(cmp_d(EQ, f6, f8, f10), "46aa4182 cmp.eq.d f6, f8, f10");
+
+ COMPARE(cmp_s(UEQ, f6, f8, f10), "468a4183 cmp.ueq.s f6, f8, f10");
+ COMPARE(cmp_d(UEQ, f6, f8, f10), "46aa4183 cmp.ueq.d f6, f8, f10");
+
+ COMPARE(cmp_s(LT, f6, f8, f10), "468a4184 cmp.lt.s f6, f8, f10");
+ COMPARE(cmp_d(LT, f6, f8, f10), "46aa4184 cmp.lt.d f6, f8, f10");
+
+ COMPARE(cmp_s(ULT, f6, f8, f10), "468a4185 cmp.ult.s f6, f8, f10");
+ COMPARE(cmp_d(ULT, f6, f8, f10), "46aa4185 cmp.ult.d f6, f8, f10");
+
+ COMPARE(cmp_s(LE, f6, f8, f10), "468a4186 cmp.le.s f6, f8, f10");
+ COMPARE(cmp_d(LE, f6, f8, f10), "46aa4186 cmp.le.d f6, f8, f10");
+
+ COMPARE(cmp_s(ULE, f6, f8, f10), "468a4187 cmp.ule.s f6, f8, f10");
+ COMPARE(cmp_d(ULE, f6, f8, f10), "46aa4187 cmp.ule.d f6, f8, f10");
+
+ COMPARE(cmp_s(ORD, f6, f8, f10), "468a4191 cmp.or.s f6, f8, f10");
+ COMPARE(cmp_d(ORD, f6, f8, f10), "46aa4191 cmp.or.d f6, f8, f10");
+
+ COMPARE(cmp_s(UNE, f6, f8, f10), "468a4192 cmp.une.s f6, f8, f10");
+ COMPARE(cmp_d(UNE, f6, f8, f10), "46aa4192 cmp.une.d f6, f8, f10");
+
+ COMPARE(cmp_s(NE, f6, f8, f10), "468a4193 cmp.ne.s f6, f8, f10");
+ COMPARE(cmp_d(NE, f6, f8, f10), "46aa4193 cmp.ne.d f6, f8, f10");
+
+ VERIFY_RUN();
+ }
+}
+
+
+TEST(CVT_DISSASM) {
+ SET_UP();
+ COMPARE(cvt_d_s(f22, f24), "4600c5a1 cvt.d.s f22, f24");
+ COMPARE(cvt_d_w(f22, f24), "4680c5a1 cvt.d.w f22, f24");
+ if (kArchVariant == kMips64r6 || kArchVariant == kMips64r2) {
+ COMPARE(cvt_d_l(f22, f24), "46a0c5a1 cvt.d.l f22, f24");
+ }
+
+ if (kArchVariant == kMips64r6 || kArchVariant == kMips64r2) {
+ COMPARE(cvt_l_s(f22, f24), "4600c5a5 cvt.l.s f22, f24");
+ COMPARE(cvt_l_d(f22, f24), "4620c5a5 cvt.l.d f22, f24");
+ }
+
+ COMPARE(cvt_s_d(f22, f24), "4620c5a0 cvt.s.d f22, f24");
+ COMPARE(cvt_s_w(f22, f24), "4680c5a0 cvt.s.w f22, f24");
+ if (kArchVariant == kMips64r6 || kArchVariant == kMips64r2) {
+ COMPARE(cvt_s_l(f22, f24), "46a0c5a0 cvt.s.l f22, f24");
+ }
+
+ COMPARE(cvt_s_d(f22, f24), "4620c5a0 cvt.s.d f22, f24");
+ COMPARE(cvt_s_w(f22, f24), "4680c5a0 cvt.s.w f22, f24");
+
+ VERIFY_RUN();
+}
diff --git a/deps/v8/test/cctest/test-extra.js b/deps/v8/test/cctest/test-extra.js
new file mode 100644
index 0000000000..829ddee01a
--- /dev/null
+++ b/deps/v8/test/cctest/test-extra.js
@@ -0,0 +1,14 @@
+// Copyright 2015 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 (global, exports) {
+ 'use strict';
+ exports.testExtraShouldReturnFive = function () {
+ return 5;
+ };
+
+ exports.testExtraShouldCallToRuntime = function() {
+ return exports.runtime(3);
+ };
+})
diff --git a/deps/v8/test/cctest/test-feedback-vector.cc b/deps/v8/test/cctest/test-feedback-vector.cc
index e94de7b552..cf8a730fb7 100644
--- a/deps/v8/test/cctest/test-feedback-vector.cc
+++ b/deps/v8/test/cctest/test-feedback-vector.cc
@@ -46,19 +46,13 @@ TEST(VectorStructure) {
CHECK_EQ(1, vector->ICSlots());
ZoneFeedbackVectorSpec spec(zone, 3, 5);
- if (FLAG_vector_ics) {
- for (int i = 0; i < 5; i++) spec.SetKind(i, Code::CALL_IC);
- }
+ for (int i = 0; i < 5; i++) spec.SetKind(i, Code::CALL_IC);
vector = factory->NewTypeFeedbackVector(&spec);
CHECK_EQ(3, vector->Slots());
CHECK_EQ(5, vector->ICSlots());
int metadata_length = vector->ic_metadata_length();
- if (!FLAG_vector_ics) {
- CHECK_EQ(0, metadata_length);
- } else {
- CHECK(metadata_length > 0);
- }
+ CHECK(metadata_length > 0);
int index = vector->GetIndex(FeedbackVectorSlot(0));
@@ -79,11 +73,6 @@ TEST(VectorStructure) {
TEST(VectorICMetadata) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- if (!FLAG_vector_ics) {
- // If FLAG_vector_ics is false, we only store CALL_ICs in the vector, so
- // there is no need for metadata to describe the slots.
- return;
- }
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
Zone* zone = isolate->runtime_zone();
@@ -259,7 +248,7 @@ TEST(VectorCallICStates) {
TEST(VectorLoadICStates) {
- if (i::FLAG_always_opt || !i::FLAG_vector_ics) return;
+ if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
@@ -313,7 +302,7 @@ TEST(VectorLoadICStates) {
TEST(VectorLoadICSlotSharing) {
- if (i::FLAG_always_opt || !i::FLAG_vector_ics) return;
+ if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
@@ -322,7 +311,7 @@ TEST(VectorLoadICSlotSharing) {
// Function f has 3 LoadICs, one for each o, but the ICs share the same
// feedback vector IC slot.
CompileRun(
- "var o = 10;"
+ "o = 10;"
"function f() {"
" var x = o + 10;"
" return o + x + o;"
@@ -341,7 +330,7 @@ TEST(VectorLoadICSlotSharing) {
TEST(VectorLoadICOnSmi) {
- if (i::FLAG_always_opt || !i::FLAG_vector_ics) return;
+ if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
diff --git a/deps/v8/test/cctest/test-fuzz-arm64.cc b/deps/v8/test/cctest/test-fuzz-arm64.cc
index ada609fe78..8f6651a6a9 100644
--- a/deps/v8/test/cctest/test-fuzz-arm64.cc
+++ b/deps/v8/test/cctest/test-fuzz-arm64.cc
@@ -43,7 +43,7 @@ TEST(FUZZ_decoder) {
Instruction buffer[kInstructionSize];
for (int i = 0; i < instruction_count; i++) {
- uint32_t instr = mrand48();
+ uint32_t instr = static_cast<uint32_t>(mrand48());
buffer->SetInstructionBits(instr);
decoder.Decode(buffer);
}
@@ -64,7 +64,7 @@ TEST(FUZZ_disasm) {
decoder.AppendVisitor(&disasm);
for (int i = 0; i < instruction_count; i++) {
- uint32_t instr = mrand48();
+ uint32_t instr = static_cast<uint32_t>(mrand48());
buffer->SetInstructionBits(instr);
decoder.Decode(buffer);
}
diff --git a/deps/v8/test/cctest/test-global-object.cc b/deps/v8/test/cctest/test-global-object.cc
index b0ed29daf1..9cc755e4e1 100644
--- a/deps/v8/test/cctest/test-global-object.cc
+++ b/deps/v8/test/cctest/test-global-object.cc
@@ -29,15 +29,13 @@
#include "test/cctest/cctest.h"
-using namespace v8;
-
// This test fails if properties on the prototype of the global object appear
// as declared globals.
TEST(StrictUndeclaredGlobalVariable) {
- HandleScope scope(CcTest::isolate());
+ v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::String> var_name = v8_str("x");
LocalContext context;
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
v8::Local<v8::Script> script = v8_compile("\"use strict\"; x = 42;");
v8::Handle<v8::Object> proto = v8::Object::New(CcTest::isolate());
v8::Handle<v8::Object> global =
diff --git a/deps/v8/test/cctest/test-hashing.cc b/deps/v8/test/cctest/test-hashing.cc
index c8ae4f30e5..9e5de2e05a 100644
--- a/deps/v8/test/cctest/test-hashing.cc
+++ b/deps/v8/test/cctest/test-hashing.cc
@@ -131,7 +131,7 @@ void check(uint32_t key) {
#endif
uint32_t runtime_hash = ComputeIntegerHash(key, isolate->heap()->HashSeed());
- CHECK(runtime_hash == codegen_hash);
+ CHECK_EQ(runtime_hash, codegen_hash);
}
diff --git a/deps/v8/test/cctest/test-hashmap.cc b/deps/v8/test/cctest/test-hashmap.cc
index fb56225fb4..b45d6c7183 100644
--- a/deps/v8/test/cctest/test-hashmap.cc
+++ b/deps/v8/test/cctest/test-hashmap.cc
@@ -171,7 +171,7 @@ void TestSet(IntKeyHash hash, int size) {
}
-TEST(Set) {
+TEST(HashSet) {
TestSet(Hash, 100);
TestSet(CollisionHash, 50);
}
diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc
index f0a6ad5d26..d85310225a 100644
--- a/deps/v8/test/cctest/test-heap.cc
+++ b/deps/v8/test/cctest/test-heap.cc
@@ -59,6 +59,7 @@ TEST(HeapMaps) {
Heap* heap = CcTest::heap();
CheckMap(heap->meta_map(), MAP_TYPE, Map::kSize);
CheckMap(heap->heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize);
+ CheckMap(heap->float32x4_map(), FLOAT32X4_TYPE, Float32x4::kSize);
CheckMap(heap->fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel);
CheckMap(heap->string_map(), STRING_TYPE, kVariableSizeSentinel);
}
@@ -213,6 +214,60 @@ TEST(HeapObjects) {
}
+template <typename T, typename LANE_TYPE, int LANES>
+static void CheckSimdLanes(T* value) {
+ // Get the original values, and check that all lanes can be set to new values
+ // without disturbing the other lanes.
+ LANE_TYPE lane_values[LANES];
+ for (int i = 0; i < LANES; i++) {
+ lane_values[i] = value->get_lane(i);
+ }
+ for (int i = 0; i < LANES; i++) {
+ lane_values[i] += 1;
+ value->set_lane(i, lane_values[i]);
+ for (int j = 0; j < LANES; j++) {
+ CHECK_EQ(lane_values[j], value->get_lane(j));
+ }
+ }
+}
+
+
+TEST(SimdObjects) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ Factory* factory = isolate->factory();
+
+ HandleScope sc(isolate);
+
+ Handle<Object> value = factory->NewFloat32x4(1, 2, 3, 4);
+ CHECK(value->IsFloat32x4());
+ CHECK(value->BooleanValue()); // SIMD values map to true.
+
+ Float32x4* float32x4 = *Handle<Float32x4>::cast(value);
+ CheckSimdLanes<Float32x4, float, 4>(float32x4);
+
+ // Check ToString for SIMD values.
+ // TODO(bbudge): Switch to Check* style function to test ToString().
+ value = factory->NewFloat32x4(1, 2, 3, 4);
+ float32x4 = *Handle<Float32x4>::cast(value);
+ std::ostringstream os;
+ float32x4->Float32x4Print(os);
+ CHECK_EQ("1, 2, 3, 4", os.str());
+
+ // Check unusual lane values.
+ float32x4->set_lane(0, 0);
+ CHECK_EQ(0, float32x4->get_lane(0));
+ float32x4->set_lane(1, -0.0);
+ CHECK_EQ(-0.0, float32x4->get_lane(1));
+ float quiet_NaN = std::numeric_limits<float>::quiet_NaN();
+ float signaling_NaN = std::numeric_limits<float>::signaling_NaN();
+ float32x4->set_lane(2, quiet_NaN);
+ CHECK(std::isnan(float32x4->get_lane(2)));
+ float32x4->set_lane(3, signaling_NaN);
+ CHECK(std::isnan(float32x4->get_lane(3)));
+}
+
+
TEST(Tagging) {
CcTest::InitializeVM();
int request = 24;
@@ -730,29 +785,27 @@ TEST(JSArray) {
JSArray::Initialize(array, 0);
// Set array length to 0.
- JSArray::SetElementsLength(array, handle(Smi::FromInt(0), isolate)).Check();
+ JSArray::SetLength(array, 0);
CHECK_EQ(Smi::FromInt(0), array->length());
// Must be in fast mode.
CHECK(array->HasFastSmiOrObjectElements());
// array[length] = name.
- JSReceiver::SetElement(array, 0, name, NONE, SLOPPY).Check();
+ JSReceiver::SetElement(array, 0, name, SLOPPY).Check();
CHECK_EQ(Smi::FromInt(1), array->length());
element = i::Object::GetElement(isolate, array, 0).ToHandleChecked();
CHECK_EQ(*element, *name);
// Set array length with larger than smi value.
- Handle<Object> length =
- factory->NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1);
- JSArray::SetElementsLength(array, length).Check();
+ JSArray::SetLength(array, static_cast<uint32_t>(Smi::kMaxValue) + 1);
uint32_t int_length = 0;
- CHECK(length->ToArrayIndex(&int_length));
- CHECK_EQ(*length, array->length());
+ CHECK(array->length()->ToArrayIndex(&int_length));
+ CHECK_EQ(static_cast<uint32_t>(Smi::kMaxValue) + 1, int_length);
CHECK(array->HasDictionaryElements()); // Must be in slow mode.
// array[length] = name.
- JSReceiver::SetElement(array, int_length, name, NONE, SLOPPY).Check();
+ JSReceiver::SetElement(array, int_length, name, SLOPPY).Check();
uint32_t new_int_length = 0;
CHECK(array->length()->ToArrayIndex(&new_int_length));
CHECK_EQ(static_cast<double>(int_length), new_int_length - 1);
@@ -783,8 +836,8 @@ TEST(JSObjectCopy) {
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();
+ JSReceiver::SetElement(obj, 0, first, SLOPPY).Check();
+ JSReceiver::SetElement(obj, 1, second, SLOPPY).Check();
// Make the clone.
Handle<Object> value1, value2;
@@ -809,8 +862,8 @@ TEST(JSObjectCopy) {
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();
+ JSReceiver::SetElement(clone, 0, second, SLOPPY).Check();
+ JSReceiver::SetElement(clone, 1, first, SLOPPY).Check();
value1 = Object::GetElement(isolate, obj, 1).ToHandleChecked();
value2 = Object::GetElement(isolate, clone, 0).ToHandleChecked();
@@ -896,9 +949,8 @@ TEST(Iteration) {
// Allocate a JS array to OLD_SPACE and NEW_SPACE
objs[next_objs_index++] = factory->NewJSArray(10);
- objs[next_objs_index++] = factory->NewJSArray(10,
- FAST_HOLEY_ELEMENTS,
- TENURED);
+ objs[next_objs_index++] =
+ factory->NewJSArray(10, FAST_HOLEY_ELEMENTS, Strength::WEAK, TENURED);
// Allocate a small string to OLD_DATA_SPACE and NEW_SPACE
objs[next_objs_index++] = factory->NewStringFromStaticChars("abcdefghij");
@@ -1142,7 +1194,7 @@ TEST(TestCodeFlushingPreAged) {
TEST(TestCodeFlushingIncremental) {
// If we do not flush code this test is invalid.
- if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return;
+ if (!FLAG_flush_code) return;
i::FLAG_allow_natives_syntax = true;
i::FLAG_optimize_for_size = false;
CcTest::InitializeVM();
@@ -1211,7 +1263,7 @@ TEST(TestCodeFlushingIncremental) {
TEST(TestCodeFlushingIncrementalScavenge) {
// If we do not flush code this test is invalid.
- if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return;
+ if (!FLAG_flush_code) return;
i::FLAG_allow_natives_syntax = true;
i::FLAG_optimize_for_size = false;
CcTest::InitializeVM();
@@ -1280,7 +1332,7 @@ TEST(TestCodeFlushingIncrementalScavenge) {
TEST(TestCodeFlushingIncrementalAbort) {
// If we do not flush code this test is invalid.
- if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return;
+ if (!FLAG_flush_code) return;
i::FLAG_allow_natives_syntax = true;
i::FLAG_optimize_for_size = false;
CcTest::InitializeVM();
@@ -1328,8 +1380,10 @@ TEST(TestCodeFlushingIncrementalAbort) {
// disabled.
int position = 0;
Handle<Object> breakpoint_object(Smi::FromInt(0), isolate);
+ EnableDebugger();
isolate->debug()->SetBreakPoint(function, breakpoint_object, &position);
isolate->debug()->ClearAllBreakPoints();
+ DisableDebugger();
// Force optimization now that code flushing is disabled.
{ v8::HandleScope scope(CcTest::isolate());
@@ -1346,8 +1400,7 @@ TEST(TestCodeFlushingIncrementalAbort) {
TEST(CompilationCacheCachingBehavior) {
// If we do not flush code, or have the compilation cache turned off, this
// test is invalid.
- if (!FLAG_flush_code || !FLAG_flush_code_incrementally ||
- !FLAG_compilation_cache) {
+ if (!FLAG_flush_code || !FLAG_compilation_cache) {
return;
}
CcTest::InitializeVM();
@@ -1377,7 +1430,8 @@ TEST(CompilationCacheCachingBehavior) {
// On first compilation, only a hash is inserted in the code cache. We can't
// find that value.
MaybeHandle<SharedFunctionInfo> info = compilation_cache->LookupScript(
- source, Handle<Object>(), 0, 0, false, true, native_context,
+ source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(false, true, false), native_context,
language_mode);
CHECK(info.is_null());
@@ -1388,16 +1442,20 @@ TEST(CompilationCacheCachingBehavior) {
// On second compilation, the hash is replaced by a real cache entry mapping
// the source to the shared function info containing the code.
- info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false,
- true, native_context, language_mode);
+ info = compilation_cache->LookupScript(
+ source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(false, true, false), native_context,
+ language_mode);
CHECK(!info.is_null());
heap->CollectAllGarbage();
// On second compilation, the hash is replaced by a real cache entry mapping
// the source to the shared function info containing the code.
- info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false,
- true, native_context, language_mode);
+ info = compilation_cache->LookupScript(
+ source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(false, true, false), native_context,
+ language_mode);
CHECK(!info.is_null());
while (!info.ToHandleChecked()->code()->IsOld()) {
@@ -1406,8 +1464,10 @@ TEST(CompilationCacheCachingBehavior) {
heap->CollectAllGarbage();
// Ensure code aging cleared the entry from the cache.
- info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false,
- true, native_context, language_mode);
+ info = compilation_cache->LookupScript(
+ source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(false, true, false), native_context,
+ language_mode);
CHECK(info.is_null());
{
@@ -1417,8 +1477,10 @@ TEST(CompilationCacheCachingBehavior) {
// On first compilation, only a hash is inserted in the code cache. We can't
// find that value.
- info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false,
- true, native_context, language_mode);
+ info = compilation_cache->LookupScript(
+ source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(false, true, false), native_context,
+ language_mode);
CHECK(info.is_null());
for (int i = 0; i < CompilationCacheTable::kHashGenerations; i++) {
@@ -1432,8 +1494,10 @@ TEST(CompilationCacheCachingBehavior) {
// If we aged the cache before caching the script, ensure that we didn't cache
// on next compilation.
- info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false,
- true, native_context, language_mode);
+ info = compilation_cache->LookupScript(
+ source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(false, true, false), native_context,
+ language_mode);
CHECK(info.is_null());
}
@@ -1682,13 +1746,13 @@ TEST(TestSizeOfRegExpCode) {
// Adjust source below and this check to match
// RegExpImple::kRegExpTooLargeToOptimize.
- DCHECK_EQ(i::RegExpImpl::kRegExpTooLargeToOptimize, 10 * KB);
+ DCHECK_EQ(i::RegExpImpl::kRegExpTooLargeToOptimize, 20 * KB);
// Compile a regexp that is much larger if we are using regexp optimizations.
CompileRun(
"var reg_exp_source = '(?:a|bc|def|ghij|klmno|pqrstu)';"
"var half_size_reg_exp;"
- "while (reg_exp_source.length < 10 * 1024) {"
+ "while (reg_exp_source.length < 20 * 1024) {"
" half_size_reg_exp = reg_exp_source;"
" reg_exp_source = reg_exp_source + reg_exp_source;"
"}"
@@ -1719,7 +1783,11 @@ TEST(TestSizeOfRegExpCode) {
int size_of_regexp_code = size_with_regexp - initial_size;
- CHECK_LE(size_of_regexp_code, 1 * MB);
+ // On some platforms the debug-code flag causes huge amounts of regexp code
+ // to be emitted, breaking this test.
+ if (!FLAG_debug_code) {
+ CHECK_LE(size_of_regexp_code, 1 * MB);
+ }
// Small regexp is half the size, but compiles to more than twice the code
// due to the optimization steps.
@@ -1773,6 +1841,271 @@ TEST(TestSizeOfObjects) {
}
+TEST(TestAlignmentCalculations) {
+ // Maximum fill amounts are consistent.
+ int maximum_double_misalignment = kDoubleSize - kPointerSize;
+ int maximum_simd128_misalignment = kSimd128Size - kPointerSize;
+ int max_word_fill = Heap::GetMaximumFillToAlign(kWordAligned);
+ CHECK_EQ(0, max_word_fill);
+ int max_double_fill = Heap::GetMaximumFillToAlign(kDoubleAligned);
+ CHECK_EQ(maximum_double_misalignment, max_double_fill);
+ int max_double_unaligned_fill = Heap::GetMaximumFillToAlign(kDoubleUnaligned);
+ CHECK_EQ(maximum_double_misalignment, max_double_unaligned_fill);
+ int max_simd128_unaligned_fill =
+ Heap::GetMaximumFillToAlign(kSimd128Unaligned);
+ CHECK_EQ(maximum_simd128_misalignment, max_simd128_unaligned_fill);
+
+ Address base = reinterpret_cast<Address>(NULL);
+ int fill = 0;
+
+ // Word alignment never requires fill.
+ fill = Heap::GetFillToAlign(base, kWordAligned);
+ CHECK_EQ(0, fill);
+ fill = Heap::GetFillToAlign(base + kPointerSize, kWordAligned);
+ CHECK_EQ(0, fill);
+
+ // No fill is required when address is double aligned.
+ fill = Heap::GetFillToAlign(base, kDoubleAligned);
+ CHECK_EQ(0, fill);
+ // Fill is required if address is not double aligned.
+ fill = Heap::GetFillToAlign(base + kPointerSize, kDoubleAligned);
+ CHECK_EQ(maximum_double_misalignment, fill);
+ // kDoubleUnaligned has the opposite fill amounts.
+ fill = Heap::GetFillToAlign(base, kDoubleUnaligned);
+ CHECK_EQ(maximum_double_misalignment, fill);
+ fill = Heap::GetFillToAlign(base + kPointerSize, kDoubleUnaligned);
+ CHECK_EQ(0, fill);
+
+ // 128 bit SIMD types have 2 or 4 possible alignments, depending on platform.
+ fill = Heap::GetFillToAlign(base, kSimd128Unaligned);
+ CHECK_EQ((3 * kPointerSize) & kSimd128AlignmentMask, fill);
+ fill = Heap::GetFillToAlign(base + kPointerSize, kSimd128Unaligned);
+ CHECK_EQ((2 * kPointerSize) & kSimd128AlignmentMask, fill);
+ fill = Heap::GetFillToAlign(base + 2 * kPointerSize, kSimd128Unaligned);
+ CHECK_EQ(kPointerSize, fill);
+ fill = Heap::GetFillToAlign(base + 3 * kPointerSize, kSimd128Unaligned);
+ CHECK_EQ(0, fill);
+}
+
+
+static HeapObject* NewSpaceAllocateAligned(int size,
+ AllocationAlignment alignment) {
+ Heap* heap = CcTest::heap();
+ AllocationResult allocation =
+ heap->new_space()->AllocateRawAligned(size, alignment);
+ HeapObject* obj = NULL;
+ allocation.To(&obj);
+ heap->CreateFillerObjectAt(obj->address(), size);
+ return obj;
+}
+
+
+// Get new space allocation into the desired alignment.
+static Address AlignNewSpace(AllocationAlignment alignment, int offset) {
+ Address* top_addr = CcTest::heap()->new_space()->allocation_top_address();
+ int fill = Heap::GetFillToAlign(*top_addr, alignment);
+ if (fill) {
+ NewSpaceAllocateAligned(fill + offset, kWordAligned);
+ }
+ return *top_addr;
+}
+
+
+TEST(TestAlignedAllocation) {
+ // Double misalignment is 4 on 32-bit platforms, 0 on 64-bit ones.
+ const intptr_t double_misalignment = kDoubleSize - kPointerSize;
+ Address* top_addr = CcTest::heap()->new_space()->allocation_top_address();
+ Address start;
+ HeapObject* obj;
+ HeapObject* filler;
+ if (double_misalignment) {
+ // Allocate a pointer sized object that must be double aligned at an
+ // aligned address.
+ start = AlignNewSpace(kDoubleAligned, 0);
+ obj = NewSpaceAllocateAligned(kPointerSize, kDoubleAligned);
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment));
+ // There is no filler.
+ CHECK_EQ(kPointerSize, *top_addr - start);
+
+ // Allocate a second pointer sized object that must be double aligned at an
+ // unaligned address.
+ start = AlignNewSpace(kDoubleAligned, kPointerSize);
+ obj = NewSpaceAllocateAligned(kPointerSize, kDoubleAligned);
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment));
+ // There is a filler object before the object.
+ filler = HeapObject::FromAddress(start);
+ CHECK(obj != filler && filler->IsFiller() &&
+ filler->Size() == kPointerSize);
+ CHECK_EQ(kPointerSize + double_misalignment, *top_addr - start);
+
+ // Similarly for kDoubleUnaligned.
+ start = AlignNewSpace(kDoubleUnaligned, 0);
+ obj = NewSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
+ CHECK_EQ(kPointerSize, *top_addr - start);
+ start = AlignNewSpace(kDoubleUnaligned, kPointerSize);
+ obj = NewSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
+ // There is a filler object before the object.
+ filler = HeapObject::FromAddress(start);
+ CHECK(obj != filler && filler->IsFiller() &&
+ filler->Size() == kPointerSize);
+ CHECK_EQ(kPointerSize + double_misalignment, *top_addr - start);
+ }
+
+ // Now test SIMD alignment. There are 2 or 4 possible alignments, depending
+ // on platform.
+ start = AlignNewSpace(kSimd128Unaligned, 0);
+ obj = NewSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There is no filler.
+ CHECK_EQ(kPointerSize, *top_addr - start);
+ start = AlignNewSpace(kSimd128Unaligned, kPointerSize);
+ obj = NewSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There is a filler object before the object.
+ filler = HeapObject::FromAddress(start);
+ CHECK(obj != filler && filler->IsFiller() &&
+ filler->Size() == kSimd128Size - kPointerSize);
+ CHECK_EQ(kPointerSize + kSimd128Size - kPointerSize, *top_addr - start);
+
+ if (double_misalignment) {
+ // Test the 2 other alignments possible on 32 bit platforms.
+ start = AlignNewSpace(kSimd128Unaligned, 2 * kPointerSize);
+ obj = NewSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There is a filler object before the object.
+ filler = HeapObject::FromAddress(start);
+ CHECK(obj != filler && filler->IsFiller() &&
+ filler->Size() == 2 * kPointerSize);
+ CHECK_EQ(kPointerSize + 2 * kPointerSize, *top_addr - start);
+ start = AlignNewSpace(kSimd128Unaligned, 3 * kPointerSize);
+ obj = NewSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There is a filler object before the object.
+ filler = HeapObject::FromAddress(start);
+ CHECK(obj != filler && filler->IsFiller() &&
+ filler->Size() == kPointerSize);
+ CHECK_EQ(kPointerSize + kPointerSize, *top_addr - start);
+ }
+}
+
+
+static HeapObject* OldSpaceAllocateAligned(int size,
+ AllocationAlignment alignment) {
+ Heap* heap = CcTest::heap();
+ AllocationResult allocation =
+ heap->old_space()->AllocateRawAligned(size, alignment);
+ HeapObject* obj = NULL;
+ allocation.To(&obj);
+ heap->CreateFillerObjectAt(obj->address(), size);
+ return obj;
+}
+
+
+// Get old space allocation into the desired alignment.
+static Address AlignOldSpace(AllocationAlignment alignment, int offset) {
+ Address* top_addr = CcTest::heap()->old_space()->allocation_top_address();
+ int fill = Heap::GetFillToAlign(*top_addr, alignment);
+ int allocation = fill + offset;
+ if (allocation) {
+ OldSpaceAllocateAligned(allocation, kWordAligned);
+ }
+ Address top = *top_addr;
+ // Now force the remaining allocation onto the free list.
+ CcTest::heap()->old_space()->EmptyAllocationInfo();
+ return top;
+}
+
+
+// Test the case where allocation must be done from the free list, so filler
+// may precede or follow the object.
+TEST(TestAlignedOverAllocation) {
+ // Double misalignment is 4 on 32-bit platforms, 0 on 64-bit ones.
+ const intptr_t double_misalignment = kDoubleSize - kPointerSize;
+ Address start;
+ HeapObject* obj;
+ HeapObject* filler1;
+ HeapObject* filler2;
+ if (double_misalignment) {
+ start = AlignOldSpace(kDoubleAligned, 0);
+ obj = OldSpaceAllocateAligned(kPointerSize, kDoubleAligned);
+ // The object is aligned, and a filler object is created after.
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment));
+ filler1 = HeapObject::FromAddress(start + kPointerSize);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kPointerSize);
+ // Try the opposite alignment case.
+ start = AlignOldSpace(kDoubleAligned, kPointerSize);
+ obj = OldSpaceAllocateAligned(kPointerSize, kDoubleAligned);
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment));
+ filler1 = HeapObject::FromAddress(start);
+ CHECK(obj != filler1);
+ CHECK(filler1->IsFiller());
+ CHECK(filler1->Size() == kPointerSize);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kPointerSize);
+
+ // Similarly for kDoubleUnaligned.
+ start = AlignOldSpace(kDoubleUnaligned, 0);
+ obj = OldSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
+ // The object is aligned, and a filler object is created after.
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
+ filler1 = HeapObject::FromAddress(start + kPointerSize);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kPointerSize);
+ // Try the opposite alignment case.
+ start = AlignOldSpace(kDoubleUnaligned, kPointerSize);
+ obj = OldSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
+ filler1 = HeapObject::FromAddress(start);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kPointerSize);
+ }
+
+ // Now test SIMD alignment. There are 2 or 4 possible alignments, depending
+ // on platform.
+ start = AlignOldSpace(kSimd128Unaligned, 0);
+ obj = OldSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There is a filler object after the object.
+ filler1 = HeapObject::FromAddress(start + kPointerSize);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kSimd128Size - kPointerSize);
+ start = AlignOldSpace(kSimd128Unaligned, kPointerSize);
+ obj = OldSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There is a filler object before the object.
+ filler1 = HeapObject::FromAddress(start);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kSimd128Size - kPointerSize);
+
+ if (double_misalignment) {
+ // Test the 2 other alignments possible on 32 bit platforms.
+ start = AlignOldSpace(kSimd128Unaligned, 2 * kPointerSize);
+ obj = OldSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There are filler objects before and after the object.
+ filler1 = HeapObject::FromAddress(start);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == 2 * kPointerSize);
+ filler2 = HeapObject::FromAddress(start + 3 * kPointerSize);
+ CHECK(obj != filler2 && filler2->IsFiller() &&
+ filler2->Size() == kPointerSize);
+ start = AlignOldSpace(kSimd128Unaligned, 3 * kPointerSize);
+ obj = OldSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There are filler objects before and after the object.
+ filler1 = HeapObject::FromAddress(start);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kPointerSize);
+ filler2 = HeapObject::FromAddress(start + 2 * kPointerSize);
+ CHECK(obj != filler2 && filler2->IsFiller() &&
+ filler2->Size() == 2 * kPointerSize);
+ }
+}
+
+
TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
CcTest::InitializeVM();
HeapIterator iterator(CcTest::heap());
@@ -2118,7 +2451,7 @@ TEST(InstanceOfStubWriteBarrier) {
IncrementalMarking* marking = CcTest::heap()->incremental_marking();
marking->Abort();
- marking->Start();
+ marking->Start(Heap::kNoGCFlags);
Handle<JSFunction> f =
v8::Utils::OpenHandle(
@@ -2191,7 +2524,8 @@ TEST(PrototypeTransitionClearing) {
TransitionArray::GetPrototypeTransitions(baseObject->map());
for (int i = initialTransitions; i < initialTransitions + transitions; i++) {
int j = TransitionArray::kProtoTransitionHeaderSize + i;
- CHECK(trans->get(j)->IsMap());
+ CHECK(trans->get(j)->IsWeakCell());
+ CHECK(WeakCell::cast(trans->get(j))->value()->IsMap());
}
// Make sure next prototype is placed on an old-space evacuation candidate.
@@ -2200,7 +2534,8 @@ TEST(PrototypeTransitionClearing) {
{
AlwaysAllocateScope always_allocate(isolate);
SimulateFullSpace(space);
- prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED);
+ prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS,
+ Strength::WEAK, TENURED);
}
// Add a prototype on an evacuation candidate and verify that transition
@@ -2244,7 +2579,7 @@ TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) {
IncrementalMarking* marking = CcTest::heap()->incremental_marking();
marking->Abort();
- marking->Start();
+ marking->Start(Heap::kNoGCFlags);
// The following calls will increment CcTest::heap()->global_ic_age().
CcTest::isolate()->ContextDisposedNotification();
SimulateIncrementalMarking(CcTest::heap());
@@ -2302,7 +2637,7 @@ TEST(IdleNotificationFinishMarking) {
SimulateFullSpace(CcTest::heap()->old_space());
IncrementalMarking* marking = CcTest::heap()->incremental_marking();
marking->Abort();
- marking->Start();
+ marking->Start(Heap::kNoGCFlags);
CHECK_EQ(CcTest::heap()->gc_count(), 0);
@@ -3071,7 +3406,6 @@ TEST(TransitionArraySimpleToFull) {
TEST(Regress2143a) {
- i::FLAG_collect_maps = true;
i::FLAG_incremental_marking = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -3111,7 +3445,6 @@ TEST(Regress2143a) {
TEST(Regress2143b) {
- i::FLAG_collect_maps = true;
i::FLAG_incremental_marking = true;
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
@@ -3203,6 +3536,31 @@ TEST(ReleaseOverReservedPages) {
CHECK_EQ(1, old_space->CountTotalPages());
}
+static int forced_gc_counter = 0;
+
+void MockUseCounterCallback(v8::Isolate* isolate,
+ v8::Isolate::UseCounterFeature feature) {
+ isolate->GetCallingContext();
+ if (feature == v8::Isolate::kForcedGC) {
+ forced_gc_counter++;
+ }
+}
+
+
+TEST(CountForcedGC) {
+ i::FLAG_expose_gc = true;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ v8::HandleScope scope(CcTest::isolate());
+
+ isolate->SetUseCounterCallback(MockUseCounterCallback);
+
+ forced_gc_counter = 0;
+ const char* source = "gc();";
+ CompileRun(source);
+ CHECK_GT(forced_gc_counter, 0);
+}
+
TEST(Regress2237) {
i::FLAG_stress_compaction = false;
@@ -3255,41 +3613,6 @@ TEST(PrintSharedFunctionInfo) {
#endif // OBJECT_PRINT
-TEST(Regress2211) {
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
-
- v8::Handle<v8::String> value = v8_str("val string");
- Smi* hash = Smi::FromInt(321);
- Factory* factory = CcTest::i_isolate()->factory();
-
- for (int i = 0; i < 2; i++) {
- // Store identity hash first and common hidden property second.
- v8::Handle<v8::Object> obj = v8::Object::New(CcTest::isolate());
- Handle<JSObject> internal_obj = v8::Utils::OpenHandle(*obj);
- CHECK(internal_obj->HasFastProperties());
-
- // In the first iteration, set hidden value first and identity hash second.
- // In the second iteration, reverse the order.
- if (i == 0) obj->SetHiddenValue(v8_str("key string"), value);
- JSObject::SetIdentityHash(internal_obj, handle(hash, CcTest::i_isolate()));
- if (i == 1) obj->SetHiddenValue(v8_str("key string"), value);
-
- // Check values.
- CHECK_EQ(hash,
- internal_obj->GetHiddenProperty(factory->identity_hash_string()));
- CHECK(value->Equals(obj->GetHiddenValue(v8_str("key string"))));
-
- // Check size.
- FieldIndex index = FieldIndex::ForDescriptor(internal_obj->map(), 0);
- ObjectHashTable* hashtable = ObjectHashTable::cast(
- internal_obj->RawFastPropertyAt(index));
- // HashTable header (5) and 4 initial entries (8).
- CHECK_LE(hashtable->SizeFor(hashtable->length()), 13 * kPointerSize);
- }
-}
-
-
TEST(IncrementalMarkingPreservesMonomorphicCallIC) {
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
@@ -3447,23 +3770,15 @@ TEST(IncrementalMarkingPreservesMonomorphicIC) {
CcTest::global()->Get(v8_str("f"))));
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorIC(f, 0, MONOMORPHIC);
- CHECK(ic_before->ic_state() == DEFAULT);
- } else {
- CHECK(ic_before->ic_state() == MONOMORPHIC);
- }
+ CheckVectorIC(f, 0, MONOMORPHIC);
+ CHECK(ic_before->ic_state() == DEFAULT);
SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage();
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorIC(f, 0, MONOMORPHIC);
- CHECK(ic_after->ic_state() == DEFAULT);
- } else {
- CHECK(ic_after->ic_state() == MONOMORPHIC);
- }
+ CheckVectorIC(f, 0, MONOMORPHIC);
+ CHECK(ic_after->ic_state() == DEFAULT);
}
@@ -3487,12 +3802,8 @@ TEST(IncrementalMarkingClearsMonomorphicIC) {
*v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorIC(f, 0, MONOMORPHIC);
- CHECK(ic_before->ic_state() == DEFAULT);
- } else {
- CHECK(ic_before->ic_state() == MONOMORPHIC);
- }
+ CheckVectorIC(f, 0, MONOMORPHIC);
+ CHECK(ic_before->ic_state() == DEFAULT);
// Fire context dispose notification.
CcTest::isolate()->ContextDisposedNotification();
@@ -3500,12 +3811,8 @@ TEST(IncrementalMarkingClearsMonomorphicIC) {
CcTest::heap()->CollectAllGarbage();
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorICCleared(f, 0);
- CHECK(ic_after->ic_state() == DEFAULT);
- } else {
- CHECK(IC::IsCleared(ic_after));
- }
+ CheckVectorICCleared(f, 0);
+ CHECK(ic_after->ic_state() == DEFAULT);
}
@@ -3536,24 +3843,16 @@ TEST(IncrementalMarkingPreservesPolymorphicIC) {
*v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorIC(f, 0, POLYMORPHIC);
- CHECK(ic_before->ic_state() == DEFAULT);
- } else {
- CHECK(ic_before->ic_state() == POLYMORPHIC);
- }
+ CheckVectorIC(f, 0, POLYMORPHIC);
+ CHECK(ic_before->ic_state() == DEFAULT);
// Fire context dispose notification.
SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage();
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorIC(f, 0, POLYMORPHIC);
- CHECK(ic_after->ic_state() == DEFAULT);
- } else {
- CHECK(ic_after->ic_state() == POLYMORPHIC);
- }
+ CheckVectorIC(f, 0, POLYMORPHIC);
+ CHECK(ic_after->ic_state() == DEFAULT);
}
@@ -3584,25 +3883,16 @@ TEST(IncrementalMarkingClearsPolymorphicIC) {
*v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorIC(f, 0, POLYMORPHIC);
- CHECK(ic_before->ic_state() == DEFAULT);
- } else {
- CHECK(ic_before->ic_state() == POLYMORPHIC);
- }
+ CheckVectorIC(f, 0, POLYMORPHIC);
+ CHECK(ic_before->ic_state() == DEFAULT);
// Fire context dispose notification.
CcTest::isolate()->ContextDisposedNotification();
SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage();
- Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorICCleared(f, 0);
- CHECK(ic_before->ic_state() == DEFAULT);
- } else {
- CHECK(IC::IsCleared(ic_after));
- }
+ CheckVectorICCleared(f, 0);
+ CHECK(ic_before->ic_state() == DEFAULT);
}
@@ -3718,7 +4008,6 @@ UNINITIALIZED_TEST(ReleaseStackTraceData) {
TEST(Regress159140) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_flush_code_incrementally = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
@@ -3780,7 +4069,6 @@ TEST(Regress159140) {
TEST(Regress165495) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_flush_code_incrementally = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
@@ -3828,7 +4116,6 @@ TEST(Regress165495) {
TEST(Regress169209) {
i::FLAG_stress_compaction = false;
i::FLAG_allow_natives_syntax = true;
- i::FLAG_flush_code_incrementally = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -3944,9 +4231,8 @@ TEST(Regress169928) {
JSArray::kSize + AllocationMemento::kSize +
kPointerSize);
- Handle<JSArray> array = factory->NewJSArrayWithElements(array_data,
- FAST_SMI_ELEMENTS,
- NOT_TENURED);
+ Handle<JSArray> array =
+ factory->NewJSArrayWithElements(array_data, FAST_SMI_ELEMENTS);
CHECK_EQ(Smi::FromInt(2), array->length());
CHECK(array->HasFastSmiOrObjectElements());
@@ -3954,8 +4240,9 @@ TEST(Regress169928) {
// We need filler the size of AllocationMemento object, plus an extra
// fill pointer value.
HeapObject* obj = NULL;
- AllocationResult allocation = CcTest::heap()->new_space()->AllocateRaw(
- AllocationMemento::kSize + kPointerSize);
+ AllocationResult allocation =
+ CcTest::heap()->new_space()->AllocateRawUnaligned(
+ AllocationMemento::kSize + kPointerSize);
CHECK(allocation.To(&obj));
Address addr_obj = obj->address();
CcTest::heap()->CreateFillerObjectAt(
@@ -3977,7 +4264,6 @@ TEST(Regress168801) {
i::FLAG_always_compact = true;
i::FLAG_cache_optimized_code = false;
i::FLAG_allow_natives_syntax = true;
- i::FLAG_flush_code_incrementally = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
@@ -4034,7 +4320,6 @@ TEST(Regress173458) {
i::FLAG_always_compact = true;
i::FLAG_cache_optimized_code = false;
i::FLAG_allow_natives_syntax = true;
- i::FLAG_flush_code_incrementally = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
@@ -4119,7 +4404,7 @@ TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) {
"};"
"f(10 * 1024 * 1024);");
IncrementalMarking* marking = CcTest::heap()->incremental_marking();
- if (marking->IsStopped()) marking->Start();
+ if (marking->IsStopped()) marking->Start(Heap::kNoGCFlags);
// This big step should be sufficient to mark the whole array.
marking->Step(100 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
DCHECK(marking->IsComplete() ||
@@ -4390,7 +4675,6 @@ static int GetCodeChainLength(Code* code) {
TEST(NextCodeLinkIsWeak) {
i::FLAG_always_opt = false;
i::FLAG_allow_natives_syntax = true;
- i::FLAG_turbo_deoptimization = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
v8::internal::Heap* heap = CcTest::heap();
@@ -4705,9 +4989,8 @@ Handle<JSFunction> GetFunctionByName(Isolate* isolate, const char* name) {
void CheckIC(Code* code, Code::Kind kind, SharedFunctionInfo* shared,
int ic_slot, InlineCacheState state) {
- if (FLAG_vector_ics &&
- (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC ||
- kind == Code::CALL_IC)) {
+ if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC ||
+ kind == Code::CALL_IC) {
TypeFeedbackVector* vector = shared->feedback_vector();
FeedbackVectorICSlot slot(ic_slot);
if (kind == Code::LOAD_IC) {
@@ -4849,7 +5132,7 @@ TEST(WeakCellsWithIncrementalMarking) {
Handle<WeakCell> weak_cell = factory->NewWeakCell(value);
CHECK(weak_cell->value()->IsFixedArray());
IncrementalMarking* marking = heap->incremental_marking();
- if (marking->IsStopped()) marking->Start();
+ if (marking->IsStopped()) marking->Start(Heap::kNoGCFlags);
marking->Step(128, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
heap->CollectGarbage(NEW_SPACE);
CHECK(weak_cell->value()->IsFixedArray());
@@ -5117,7 +5400,7 @@ TEST(Regress388880) {
// that would cause crash.
IncrementalMarking* marking = CcTest::heap()->incremental_marking();
marking->Abort();
- marking->Start();
+ marking->Start(Heap::kNoGCFlags);
CHECK(marking->IsMarking());
// Now everything is set up for crashing in JSObject::MigrateFastToFast()
@@ -5143,7 +5426,7 @@ TEST(Regress3631) {
"}"
"weak_map");
if (marking->IsStopped()) {
- marking->Start();
+ marking->Start(Heap::kNoGCFlags);
}
// Incrementally mark the backing store.
Handle<JSObject> obj =
@@ -5319,7 +5602,7 @@ static void TestRightTrimFixedTypedArray(i::ExternalArrayType type,
Heap* heap = isolate->heap();
Handle<FixedTypedArrayBase> array =
- factory->NewFixedTypedArray(initial_length, type);
+ factory->NewFixedTypedArray(initial_length, type, true);
int old_size = array->size();
heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(*array,
elements_to_trim);
@@ -5369,7 +5652,7 @@ TEST(WeakFixedArray) {
Handle<HeapNumber> number = CcTest::i_isolate()->factory()->NewHeapNumber(1);
Handle<WeakFixedArray> array = WeakFixedArray::Add(Handle<Object>(), number);
array->Remove(number);
- array->Compact();
+ array->Compact<WeakFixedArray::NullCallback>();
WeakFixedArray::Add(array, number);
}
@@ -5379,7 +5662,7 @@ TEST(PreprocessStackTrace) {
FLAG_gc_interval = -1;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
CompileRun("throw new Error();");
CHECK(try_catch.HasCaught());
Isolate* isolate = CcTest::i_isolate();
@@ -5405,3 +5688,370 @@ TEST(PreprocessStackTrace) {
CHECK(!element->IsCode());
}
}
+
+
+static bool utils_has_been_collected = false;
+
+static void UtilsHasBeenCollected(
+ const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
+ utils_has_been_collected = true;
+ data.GetParameter()->Reset();
+}
+
+
+TEST(BootstrappingExports) {
+ FLAG_expose_natives_as = "natives";
+ CcTest::InitializeVM();
+ v8::Isolate* isolate = CcTest::isolate();
+
+ if (Snapshot::HaveASnapshotToStartFrom(CcTest::i_isolate())) return;
+
+ utils_has_been_collected = false;
+
+ v8::Persistent<v8::Object> utils;
+
+ {
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::Object> natives =
+ CcTest::global()->Get(v8_str("natives"))->ToObject(isolate);
+ utils.Reset(isolate, natives->Get(v8_str("utils"))->ToObject(isolate));
+ natives->Delete(v8_str("utils"));
+ }
+
+ utils.SetWeak(&utils, UtilsHasBeenCollected,
+ v8::WeakCallbackType::kParameter);
+
+ CcTest::heap()->CollectAllAvailableGarbage("fire weak callbacks");
+
+ CHECK(utils_has_been_collected);
+}
+
+
+TEST(Regress1878) {
+ FLAG_allow_natives_syntax = true;
+ CcTest::InitializeVM();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::Function> constructor =
+ v8::Utils::ToLocal(CcTest::i_isolate()->internal_array_function());
+ CcTest::global()->Set(v8_str("InternalArray"), constructor);
+
+ v8::TryCatch try_catch(isolate);
+
+ CompileRun(
+ "var a = Array();"
+ "for (var i = 0; i < 1000; i++) {"
+ " var ai = new InternalArray(10000);"
+ " if (%HaveSameMap(ai, a)) throw Error();"
+ " if (!%HasFastObjectElements(ai)) throw Error();"
+ "}"
+ "for (var i = 0; i < 1000; i++) {"
+ " var ai = new InternalArray(10000);"
+ " if (%HaveSameMap(ai, a)) throw Error();"
+ " if (!%HasFastObjectElements(ai)) throw Error();"
+ "}");
+
+ CHECK(!try_catch.HasCaught());
+}
+
+
+void AllocateInSpace(Isolate* isolate, size_t bytes, AllocationSpace space) {
+ CHECK(bytes >= FixedArray::kHeaderSize);
+ CHECK(bytes % kPointerSize == 0);
+ Factory* factory = isolate->factory();
+ HandleScope scope(isolate);
+ AlwaysAllocateScope always_allocate(isolate);
+ int elements =
+ static_cast<int>((bytes - FixedArray::kHeaderSize) / kPointerSize);
+ Handle<FixedArray> array = factory->NewFixedArray(
+ elements, space == NEW_SPACE ? NOT_TENURED : TENURED);
+ CHECK((space == NEW_SPACE) == isolate->heap()->InNewSpace(*array));
+ CHECK_EQ(bytes, static_cast<size_t>(array->Size()));
+}
+
+
+TEST(NewSpaceAllocationCounter) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ size_t counter1 = heap->NewSpaceAllocationCounter();
+ heap->CollectGarbage(NEW_SPACE);
+ const size_t kSize = 1024;
+ AllocateInSpace(isolate, kSize, NEW_SPACE);
+ size_t counter2 = heap->NewSpaceAllocationCounter();
+ CHECK_EQ(kSize, counter2 - counter1);
+ heap->CollectGarbage(NEW_SPACE);
+ size_t counter3 = heap->NewSpaceAllocationCounter();
+ CHECK_EQ(0U, counter3 - counter2);
+ // Test counter overflow.
+ size_t max_counter = -1;
+ heap->set_new_space_allocation_counter(max_counter - 10 * kSize);
+ size_t start = heap->NewSpaceAllocationCounter();
+ for (int i = 0; i < 20; i++) {
+ AllocateInSpace(isolate, kSize, NEW_SPACE);
+ size_t counter = heap->NewSpaceAllocationCounter();
+ CHECK_EQ(kSize, counter - start);
+ start = counter;
+ }
+}
+
+
+TEST(OldSpaceAllocationCounter) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ size_t counter1 = heap->OldGenerationAllocationCounter();
+ heap->CollectGarbage(NEW_SPACE);
+ heap->CollectGarbage(NEW_SPACE);
+ const size_t kSize = 1024;
+ AllocateInSpace(isolate, kSize, OLD_SPACE);
+ size_t counter2 = heap->OldGenerationAllocationCounter();
+ // TODO(ulan): replace all CHECK_LE with CHECK_EQ after v8:4148 is fixed.
+ CHECK_LE(kSize, counter2 - counter1);
+ heap->CollectGarbage(NEW_SPACE);
+ size_t counter3 = heap->OldGenerationAllocationCounter();
+ CHECK_EQ(0u, counter3 - counter2);
+ AllocateInSpace(isolate, kSize, OLD_SPACE);
+ heap->CollectGarbage(OLD_SPACE);
+ size_t counter4 = heap->OldGenerationAllocationCounter();
+ CHECK_LE(kSize, counter4 - counter3);
+ // Test counter overflow.
+ size_t max_counter = -1;
+ heap->set_old_generation_allocation_counter(max_counter - 10 * kSize);
+ size_t start = heap->OldGenerationAllocationCounter();
+ for (int i = 0; i < 20; i++) {
+ AllocateInSpace(isolate, kSize, OLD_SPACE);
+ size_t counter = heap->OldGenerationAllocationCounter();
+ CHECK_LE(kSize, counter - start);
+ start = counter;
+ }
+}
+
+
+TEST(NewSpaceAllocationThroughput) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ GCTracer* tracer = heap->tracer();
+ int time1 = 100;
+ size_t counter1 = 1000;
+ tracer->SampleAllocation(time1, counter1, 0);
+ int time2 = 200;
+ size_t counter2 = 2000;
+ tracer->SampleAllocation(time2, counter2, 0);
+ size_t throughput =
+ tracer->NewSpaceAllocationThroughputInBytesPerMillisecond();
+ CHECK_EQ((counter2 - counter1) / (time2 - time1), throughput);
+ int time3 = 1000;
+ size_t counter3 = 30000;
+ tracer->SampleAllocation(time3, counter3, 0);
+ throughput = tracer->NewSpaceAllocationThroughputInBytesPerMillisecond();
+ CHECK_EQ((counter3 - counter1) / (time3 - time1), throughput);
+}
+
+
+TEST(NewSpaceAllocationThroughput2) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ GCTracer* tracer = heap->tracer();
+ int time1 = 100;
+ size_t counter1 = 1000;
+ tracer->SampleAllocation(time1, counter1, 0);
+ int time2 = 200;
+ size_t counter2 = 2000;
+ tracer->SampleAllocation(time2, counter2, 0);
+ size_t throughput =
+ tracer->NewSpaceAllocationThroughputInBytesPerMillisecond(100);
+ CHECK_EQ((counter2 - counter1) / (time2 - time1), throughput);
+ int time3 = 1000;
+ size_t counter3 = 30000;
+ tracer->SampleAllocation(time3, counter3, 0);
+ throughput = tracer->NewSpaceAllocationThroughputInBytesPerMillisecond(100);
+ CHECK_EQ((counter3 - counter1) / (time3 - time1), throughput);
+}
+
+
+static void CheckLeak(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ Isolate* isolate = CcTest::i_isolate();
+ Object* message =
+ *reinterpret_cast<Object**>(isolate->pending_message_obj_address());
+ CHECK(message->IsTheHole());
+}
+
+
+TEST(MessageObjectLeak) {
+ CcTest::InitializeVM();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
+ global->Set(v8::String::NewFromUtf8(isolate, "check"),
+ v8::FunctionTemplate::New(isolate, CheckLeak));
+ v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global);
+ v8::Context::Scope cscope(context);
+
+ const char* test =
+ "try {"
+ " throw 'message 1';"
+ "} catch (e) {"
+ "}"
+ "check();"
+ "L: try {"
+ " throw 'message 2';"
+ "} finally {"
+ " break L;"
+ "}"
+ "check();";
+ CompileRun(test);
+
+ const char* flag = "--turbo-filter=*";
+ FlagList::SetFlagsFromString(flag, StrLength(flag));
+ FLAG_always_opt = true;
+ FLAG_turbo_try_catch = true;
+ FLAG_turbo_try_finally = true;
+
+ CompileRun(test);
+}
+
+
+static void CheckEqualSharedFunctionInfos(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ Handle<Object> obj1 = v8::Utils::OpenHandle(*args[0]);
+ Handle<Object> obj2 = v8::Utils::OpenHandle(*args[1]);
+ Handle<JSFunction> fun1 = Handle<JSFunction>::cast(obj1);
+ Handle<JSFunction> fun2 = Handle<JSFunction>::cast(obj2);
+ CHECK(fun1->shared() == fun2->shared());
+}
+
+
+static void RemoveCodeAndGC(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ Isolate* isolate = CcTest::i_isolate();
+ Handle<Object> obj = v8::Utils::OpenHandle(*args[0]);
+ Handle<JSFunction> fun = Handle<JSFunction>::cast(obj);
+ fun->ReplaceCode(*isolate->builtins()->CompileLazy());
+ fun->shared()->ReplaceCode(*isolate->builtins()->CompileLazy());
+ isolate->heap()->CollectAllAvailableGarbage("remove code and gc");
+}
+
+
+TEST(CanonicalSharedFunctionInfo) {
+ CcTest::InitializeVM();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
+ global->Set(isolate, "check", v8::FunctionTemplate::New(
+ isolate, CheckEqualSharedFunctionInfos));
+ global->Set(isolate, "remove",
+ v8::FunctionTemplate::New(isolate, RemoveCodeAndGC));
+ v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global);
+ v8::Context::Scope cscope(context);
+ CompileRun(
+ "function f() { return function g() {}; }"
+ "var g1 = f();"
+ "remove(f);"
+ "var g2 = f();"
+ "check(g1, g2);");
+
+ CompileRun(
+ "function f() { return (function() { return function g() {}; })(); }"
+ "var g1 = f();"
+ "remove(f);"
+ "var g2 = f();"
+ "check(g1, g2);");
+}
+
+
+TEST(OldGenerationAllocationThroughput) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ GCTracer* tracer = heap->tracer();
+ int time1 = 100;
+ size_t counter1 = 1000;
+ tracer->SampleAllocation(time1, 0, counter1);
+ int time2 = 200;
+ size_t counter2 = 2000;
+ tracer->SampleAllocation(time2, 0, counter2);
+ size_t throughput =
+ tracer->OldGenerationAllocationThroughputInBytesPerMillisecond(100);
+ CHECK_EQ((counter2 - counter1) / (time2 - time1), throughput);
+ int time3 = 1000;
+ size_t counter3 = 30000;
+ tracer->SampleAllocation(time3, 0, counter3);
+ throughput =
+ tracer->OldGenerationAllocationThroughputInBytesPerMillisecond(100);
+ CHECK_EQ((counter3 - counter1) / (time3 - time1), throughput);
+}
+
+
+TEST(AllocationThroughput) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ GCTracer* tracer = heap->tracer();
+ int time1 = 100;
+ size_t counter1 = 1000;
+ tracer->SampleAllocation(time1, counter1, counter1);
+ int time2 = 200;
+ size_t counter2 = 2000;
+ tracer->SampleAllocation(time2, counter2, counter2);
+ size_t throughput = tracer->AllocationThroughputInBytesPerMillisecond(100);
+ CHECK_EQ(2 * (counter2 - counter1) / (time2 - time1), throughput);
+ int time3 = 1000;
+ size_t counter3 = 30000;
+ tracer->SampleAllocation(time3, counter3, counter3);
+ throughput = tracer->AllocationThroughputInBytesPerMillisecond(100);
+ CHECK_EQ(2 * (counter3 - counter1) / (time3 - time1), throughput);
+}
+
+
+TEST(SlotsBufferObjectSlotsRemoval) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ Factory* factory = isolate->factory();
+
+ SlotsBuffer* buffer = new SlotsBuffer(NULL);
+ void* fake_object[1];
+
+ Handle<FixedArray> array = factory->NewFixedArray(2, TENURED);
+ CHECK(heap->old_space()->Contains(*array));
+ array->set(0, reinterpret_cast<Object*>(fake_object), SKIP_WRITE_BARRIER);
+
+ // Firstly, let's test the regular slots buffer entry.
+ buffer->Add(HeapObject::RawField(*array, FixedArray::kHeaderSize));
+ DCHECK(reinterpret_cast<void*>(buffer->Get(0)) ==
+ HeapObject::RawField(*array, FixedArray::kHeaderSize));
+ SlotsBuffer::RemoveObjectSlots(CcTest::i_isolate()->heap(), buffer,
+ array->address(),
+ array->address() + array->Size());
+ DCHECK(reinterpret_cast<void*>(buffer->Get(0)) ==
+ HeapObject::RawField(heap->empty_fixed_array(),
+ FixedArrayBase::kLengthOffset));
+
+ // Secondly, let's test the typed slots buffer entry.
+ SlotsBuffer::AddTo(NULL, &buffer, SlotsBuffer::EMBEDDED_OBJECT_SLOT,
+ array->address() + FixedArray::kHeaderSize,
+ SlotsBuffer::FAIL_ON_OVERFLOW);
+ DCHECK(reinterpret_cast<void*>(buffer->Get(1)) ==
+ reinterpret_cast<Object**>(SlotsBuffer::EMBEDDED_OBJECT_SLOT));
+ DCHECK(reinterpret_cast<void*>(buffer->Get(2)) ==
+ HeapObject::RawField(*array, FixedArray::kHeaderSize));
+ SlotsBuffer::RemoveObjectSlots(CcTest::i_isolate()->heap(), buffer,
+ array->address(),
+ array->address() + array->Size());
+ DCHECK(reinterpret_cast<void*>(buffer->Get(1)) ==
+ HeapObject::RawField(heap->empty_fixed_array(),
+ FixedArrayBase::kLengthOffset));
+ DCHECK(reinterpret_cast<void*>(buffer->Get(2)) ==
+ HeapObject::RawField(heap->empty_fixed_array(),
+ FixedArrayBase::kLengthOffset));
+ delete buffer;
+}
diff --git a/deps/v8/test/cctest/test-hydrogen-types.cc b/deps/v8/test/cctest/test-hydrogen-types.cc
index 0ac53bde09..93fdf7b32d 100644
--- a/deps/v8/test/cctest/test-hydrogen-types.cc
+++ b/deps/v8/test/cctest/test-hydrogen-types.cc
@@ -8,7 +8,6 @@
using namespace v8::internal;
-
static const HType kTypes[] = {
#define DECLARE_TYPE(Name, mask) HType::Name(),
HTYPE_LIST(DECLARE_TYPE)
diff --git a/deps/v8/test/cctest/test-log.cc b/deps/v8/test/cctest/test-log.cc
index 90245b7882..0938a9ede2 100644
--- a/deps/v8/test/cctest/test-log.cc
+++ b/deps/v8/test/cctest/test-log.cc
@@ -482,7 +482,7 @@ TEST(EquivalenceOfLoggingAndTraversal) {
i::Vector<const char> source = TestSources::GetScriptsSource();
v8::Handle<v8::String> source_str = v8::String::NewFromUtf8(
isolate, source.start(), v8::String::kNormalString, source.length());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
v8::Handle<v8::Script> script = CompileWithOrigin(source_str, "");
if (script.IsEmpty()) {
v8::String::Utf8Value exception(try_catch.Exception());
diff --git a/deps/v8/test/cctest/test-microtask-delivery.cc b/deps/v8/test/cctest/test-microtask-delivery.cc
index 601290cf3a..5befdfba9f 100644
--- a/deps/v8/test/cctest/test-microtask-delivery.cc
+++ b/deps/v8/test/cctest/test-microtask-delivery.cc
@@ -29,7 +29,6 @@
#include "test/cctest/cctest.h"
-using namespace v8;
namespace i = v8::internal;
namespace {
@@ -38,7 +37,7 @@ class HarmonyIsolate {
HarmonyIsolate() {
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
- isolate_ = Isolate::New(create_params);
+ isolate_ = v8::Isolate::New(create_params);
isolate_->Enter();
}
@@ -47,17 +46,17 @@ class HarmonyIsolate {
isolate_->Dispose();
}
- Isolate* GetIsolate() const { return isolate_; }
+ v8::Isolate* GetIsolate() const { return isolate_; }
private:
- Isolate* isolate_;
+ v8::Isolate* isolate_;
};
}
TEST(MicrotaskDeliverySimple) {
HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
+ v8::HandleScope scope(isolate.GetIsolate());
LocalContext context(isolate.GetIsolate());
CompileRun(
"var ordering = [];"
@@ -95,16 +94,16 @@ TEST(MicrotaskDeliverySimple) {
TEST(MicrotaskPerIsolateState) {
HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
+ v8::HandleScope scope(isolate.GetIsolate());
LocalContext context1(isolate.GetIsolate());
isolate.GetIsolate()->SetAutorunMicrotasks(false);
CompileRun(
"var obj = { calls: 0 };");
- Handle<Value> obj = CompileRun("obj");
+ v8::Handle<v8::Value> obj = CompileRun("obj");
{
LocalContext context2(isolate.GetIsolate());
- context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
- obj);
+ context2->Global()->Set(
+ v8::String::NewFromUtf8(isolate.GetIsolate(), "obj"), obj);
CompileRun(
"var resolver = {};"
"new Promise(function(resolve) {"
@@ -118,8 +117,8 @@ TEST(MicrotaskPerIsolateState) {
}
{
LocalContext context3(isolate.GetIsolate());
- context3->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
- obj);
+ context3->Global()->Set(
+ v8::String::NewFromUtf8(isolate.GetIsolate(), "obj"), obj);
CompileRun(
"var foo = { id: 1 };"
"Object.observe(foo, function() {"
@@ -129,8 +128,8 @@ TEST(MicrotaskPerIsolateState) {
}
{
LocalContext context4(isolate.GetIsolate());
- context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
- obj);
+ context4->Global()->Set(
+ v8::String::NewFromUtf8(isolate.GetIsolate(), "obj"), obj);
isolate.GetIsolate()->RunMicrotasks();
CHECK_EQ(2, CompileRun("obj.calls")->Int32Value());
}
diff --git a/deps/v8/test/cctest/test-migrations.cc b/deps/v8/test/cctest/test-migrations.cc
index 14bdcea3c6..0cefd54ceb 100644
--- a/deps/v8/test/cctest/test-migrations.cc
+++ b/deps/v8/test/cctest/test-migrations.cc
@@ -503,8 +503,7 @@ TEST(ReconfigureAccessorToNonExistingDataFieldHeavy) {
CHECK(obj->map()->instance_descriptors()->GetValue(0)->IsAccessorPair());
Handle<Object> value(Smi::FromInt(42), isolate);
- JSObject::SetOwnPropertyIgnoreAttributes(
- obj, foo_str, value, NONE, JSObject::DONT_FORCE_FIELD).ToHandleChecked();
+ JSObject::SetOwnPropertyIgnoreAttributes(obj, foo_str, value, NONE).Check();
// Check that the property contains |value|.
CHECK_EQ(1, obj->map()->NumberOfOwnDescriptors());
diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc
index 58a5955685..cbb79b16da 100644
--- a/deps/v8/test/cctest/test-parsing.cc
+++ b/deps/v8/test/cctest/test-parsing.cc
@@ -73,7 +73,6 @@ TEST(ScanKeywords) {
i::Scanner scanner(&unicode_cache);
// The scanner should parse Harmony keywords for this test.
scanner.SetHarmonyModules(true);
- scanner.SetHarmonyClasses(true);
scanner.Initialize(&stream);
CHECK_EQ(key_token.token, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next());
@@ -277,7 +276,7 @@ TEST(PreparseFunctionDataIsUsed) {
for (unsigned i = 0; i < arraysize(good_code); i++) {
v8::ScriptCompiler::Source good_source(v8_str(good_code[i]));
v8::ScriptCompiler::Compile(isolate, &good_source,
- v8::ScriptCompiler::kProduceDataToCache);
+ v8::ScriptCompiler::kProduceParserCache);
const v8::ScriptCompiler::CachedData* cached_data =
good_source.GetCachedData();
@@ -291,7 +290,9 @@ TEST(PreparseFunctionDataIsUsed) {
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();
+ v8::ScriptCompiler::Compile(isolate, &bad_source,
+ v8::ScriptCompiler::kConsumeParserCache)
+ ->Run();
CHECK(result->IsInt32());
CHECK_EQ(25, result->Int32Value());
}
@@ -976,10 +977,10 @@ TEST(ScopeUsesArgumentsSuperThis) {
SUPER_PROPERTY = 1 << 1,
THIS = 1 << 2,
INNER_ARGUMENTS = 1 << 3,
- INNER_SUPER_PROPERTY = 1 << 4,
- INNER_THIS = 1 << 5
+ EVAL = 1 << 4
};
+ // clang-format off
static const struct {
const char* body;
int expected;
@@ -992,8 +993,8 @@ TEST(ScopeUsesArgumentsSuperThis) {
{"return this + arguments[0]", ARGUMENTS | THIS},
{"return this + arguments[0] + super.x",
ARGUMENTS | SUPER_PROPERTY | THIS},
- {"return x => this + x", INNER_THIS},
- {"return x => super.f() + x", INNER_SUPER_PROPERTY},
+ {"return x => this + x", THIS},
+ {"return x => super.f() + x", SUPER_PROPERTY},
{"this.foo = 42;", THIS},
{"this.foo();", THIS},
{"if (foo()) { this.f() }", THIS},
@@ -1006,9 +1007,7 @@ TEST(ScopeUsesArgumentsSuperThis) {
{"while (true) { while (true) { while (true) return this } }", THIS},
{"while (true) { while (true) { while (true) return super.f() } }",
SUPER_PROPERTY},
- {"if (1) { return () => { while (true) new this() } }", INNER_THIS},
- // Note that propagation of the inner_uses_this() value does not
- // cross boundaries of normal functions onto parent scopes.
+ {"if (1) { return () => { while (true) new this() } }", THIS},
{"return function (x) { return this + x }", NONE},
{"return { m(x) { return super.m() + x } }", NONE},
{"var x = function () { this.foo = 42 };", NONE},
@@ -1019,17 +1018,22 @@ TEST(ScopeUsesArgumentsSuperThis) {
{"return { m(x) { return () => super.m() } }", NONE},
// Flags must be correctly set when using block scoping.
{"\"use strict\"; while (true) { let x; this, arguments; }",
- INNER_ARGUMENTS | INNER_THIS},
+ INNER_ARGUMENTS | THIS},
{"\"use strict\"; while (true) { let x; this, super.f(), arguments; }",
- INNER_ARGUMENTS | INNER_SUPER_PROPERTY | INNER_THIS},
- {"\"use strict\"; if (foo()) { let x; this.f() }", INNER_THIS},
- {"\"use strict\"; if (foo()) { let x; super.f() }",
- INNER_SUPER_PROPERTY},
+ INNER_ARGUMENTS | SUPER_PROPERTY | THIS},
+ {"\"use strict\"; if (foo()) { let x; this.f() }", THIS},
+ {"\"use strict\"; if (foo()) { let x; super.f() }", SUPER_PROPERTY},
{"\"use strict\"; if (1) {"
" let x; return { m() { return this + super.m() + arguments } }"
"}",
NONE},
+ {"eval(42)", EVAL},
+ {"if (1) { eval(42) }", EVAL},
+ {"eval('super.x')", EVAL},
+ {"eval('this.x')", EVAL},
+ {"eval('arguments')", EVAL},
};
+ // clang-format on
i::Isolate* isolate = CcTest::i_isolate();
i::Factory* factory = isolate->factory();
@@ -1045,7 +1049,6 @@ TEST(ScopeUsesArgumentsSuperThis) {
for (unsigned i = 0; i < arraysize(source_data); ++i) {
// Super property is only allowed in constructor and method.
if (((source_data[i].expected & SUPER_PROPERTY) ||
- (source_data[i].expected & INNER_SUPER_PROPERTY) ||
(source_data[i].expected == NONE)) && j != 2) {
continue;
}
@@ -1063,8 +1066,6 @@ TEST(ScopeUsesArgumentsSuperThis) {
i::ParseInfo info(&zone, script);
i::Parser parser(&info);
parser.set_allow_harmony_arrow_functions(true);
- parser.set_allow_harmony_classes(true);
- parser.set_allow_harmony_object_literals(true);
parser.set_allow_harmony_sloppy(true);
info.set_global();
CHECK(parser.Parse(&info));
@@ -1086,18 +1087,71 @@ TEST(ScopeUsesArgumentsSuperThis) {
scope->uses_arguments());
CHECK_EQ((source_data[i].expected & SUPER_PROPERTY) != 0,
scope->uses_super_property());
- CHECK_EQ((source_data[i].expected & THIS) != 0, scope->uses_this());
+ if ((source_data[i].expected & THIS) != 0) {
+ // Currently the is_used() flag is conservative; all variables in a
+ // script scope are marked as used.
+ CHECK(scope->LookupThis()->is_used());
+ }
CHECK_EQ((source_data[i].expected & INNER_ARGUMENTS) != 0,
scope->inner_uses_arguments());
- CHECK_EQ((source_data[i].expected & INNER_SUPER_PROPERTY) != 0,
- scope->inner_uses_super_property());
- CHECK_EQ((source_data[i].expected & INNER_THIS) != 0,
- scope->inner_uses_this());
+ CHECK_EQ((source_data[i].expected & EVAL) != 0, scope->calls_eval());
}
}
}
+static void CheckParsesToNumber(const char* source, bool with_dot) {
+ v8::V8::Initialize();
+ HandleAndZoneScope handles;
+
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::Factory* factory = isolate->factory();
+
+ std::string full_source = "function f() { return ";
+ full_source += source;
+ full_source += "; }";
+
+ i::Handle<i::String> source_code =
+ factory->NewStringFromUtf8(i::CStrVector(full_source.c_str()))
+ .ToHandleChecked();
+
+ i::Handle<i::Script> script = factory->NewScript(source_code);
+
+ i::ParseInfo info(handles.main_zone(), script);
+ i::Parser parser(&info);
+ parser.set_allow_harmony_arrow_functions(true);
+ parser.set_allow_harmony_sloppy(true);
+ info.set_global();
+ info.set_lazy(false);
+ info.set_allow_lazy_parsing(false);
+ info.set_toplevel(true);
+
+ i::CompilationInfo compilation_info(&info);
+ CHECK(i::Compiler::ParseAndAnalyze(&info));
+
+ CHECK(info.scope()->declarations()->length() == 1);
+ i::FunctionLiteral* fun =
+ info.scope()->declarations()->at(0)->AsFunctionDeclaration()->fun();
+ CHECK(fun->body()->length() == 1);
+ CHECK(fun->body()->at(0)->IsReturnStatement());
+ i::ReturnStatement* ret = fun->body()->at(0)->AsReturnStatement();
+ CHECK(ret->expression()->IsLiteral());
+ i::Literal* lit = ret->expression()->AsLiteral();
+ const i::AstValue* val = lit->raw_value();
+ CHECK(with_dot == val->ContainsDot());
+}
+
+
+TEST(ParseNumbers) {
+ CheckParsesToNumber("1.34", true);
+ CheckParsesToNumber("134", false);
+ CheckParsesToNumber("134e44", false);
+ CheckParsesToNumber("134.e44", true);
+ CheckParsesToNumber("134.44e44", true);
+ CheckParsesToNumber(".44", true);
+}
+
+
TEST(ScopePositions) {
// Test the parser for correctly setting the start and end positions
// of a scope. We check the scope positions of exactly one scope
@@ -1348,40 +1402,24 @@ const char* ReadString(unsigned* start) {
i::Handle<i::String> FormatMessage(i::Vector<unsigned> data) {
i::Isolate* isolate = CcTest::i_isolate();
- i::Factory* factory = isolate->factory();
- const char* message =
- ReadString(&data[i::PreparseDataConstants::kMessageTextPos]);
- i::Handle<i::String> format = v8::Utils::OpenHandle(
- *v8::String::NewFromUtf8(CcTest::isolate(), message));
+ int message = data[i::PreparseDataConstants::kMessageTemplatePos];
int arg_count = data[i::PreparseDataConstants::kMessageArgCountPos];
- const char* arg = NULL;
- i::Handle<i::JSArray> args_array;
+ i::Handle<i::Object> arg_object;
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();
+ const char* arg =
+ ReadString(&data[i::PreparseDataConstants::kMessageArgPos]);
+ arg_object =
+ v8::Utils::OpenHandle(*v8::String::NewFromUtf8(CcTest::isolate(), arg));
+ i::DeleteArray(arg);
} else {
CHECK_EQ(0, arg_count);
- args_array = factory->NewJSArray(0);
+ arg_object = isolate->factory()->undefined_value();
}
- i::Handle<i::JSObject> builtins(isolate->js_builtins_object());
- i::Handle<i::Object> format_fun =
- i::Object::GetProperty(isolate, builtins, "$formatMessage")
- .ToHandleChecked();
- i::Handle<i::Object> arg_handles[] = { format, args_array };
- i::Handle<i::Object> result = i::Execution::Call(
- isolate, format_fun, builtins, 2, arg_handles).ToHandleChecked();
- CHECK(result->IsString());
- i::DeleteArray(message);
- i::DeleteArray(arg);
data.Dispose();
- return i::Handle<i::String>::cast(result);
+ return i::MessageTemplate::FormatMessage(isolate, message, arg_object);
}
@@ -1390,15 +1428,16 @@ enum ParserFlag {
kAllowNatives,
kAllowHarmonyModules,
kAllowHarmonyArrowFunctions,
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonyRestParameters,
kAllowHarmonySloppy,
kAllowHarmonyUnicode,
kAllowHarmonyComputedPropertyNames,
kAllowHarmonySpreadCalls,
kAllowHarmonyDestructuring,
- kAllowStrongMode
+ kAllowHarmonySpreadArrays,
+ kAllowHarmonyNewTarget,
+ kAllowStrongMode,
+ kNoLegacyConst
};
@@ -1414,11 +1453,8 @@ void SetParserFlags(i::ParserBase<Traits>* parser,
parser->set_allow_lazy(flags.Contains(kAllowLazy));
parser->set_allow_natives(flags.Contains(kAllowNatives));
parser->set_allow_harmony_modules(flags.Contains(kAllowHarmonyModules));
- parser->set_allow_harmony_object_literals(
- flags.Contains(kAllowHarmonyObjectLiterals));
parser->set_allow_harmony_arrow_functions(
flags.Contains(kAllowHarmonyArrowFunctions));
- parser->set_allow_harmony_classes(flags.Contains(kAllowHarmonyClasses));
parser->set_allow_harmony_rest_params(
flags.Contains(kAllowHarmonyRestParameters));
parser->set_allow_harmony_spreadcalls(
@@ -1429,7 +1465,11 @@ void SetParserFlags(i::ParserBase<Traits>* parser,
flags.Contains(kAllowHarmonyComputedPropertyNames));
parser->set_allow_harmony_destructuring(
flags.Contains(kAllowHarmonyDestructuring));
+ parser->set_allow_harmony_spread_arrays(
+ flags.Contains(kAllowHarmonySpreadArrays));
+ parser->set_allow_harmony_new_target(flags.Contains(kAllowHarmonyNewTarget));
parser->set_allow_strong_mode(flags.Contains(kAllowStrongMode));
+ parser->set_allow_legacy_const(!flags.Contains(kNoLegacyConst));
}
@@ -1702,7 +1742,7 @@ TEST(StrictOctal) {
v8::HandleScope scope(CcTest::isolate());
v8::Context::Scope context_scope(
v8::Context::New(CcTest::isolate()));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
const char* script =
"\"use strict\"; \n"
"a = function() { \n"
@@ -1982,8 +2022,7 @@ TEST(NoErrorsFutureStrictReservedWords) {
RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags));
- static const ParserFlag classes_flags[] = {kAllowHarmonyArrowFunctions,
- kAllowHarmonyClasses};
+ static const ParserFlag classes_flags[] = {kAllowHarmonyArrowFunctions};
RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
classes_flags, arraysize(classes_flags));
}
@@ -2996,10 +3035,7 @@ TEST(NoErrorsDeclsInCase) {
nullptr
};
- static const ParserFlag always_flags[] = {kAllowHarmonyClasses};
-
- RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, statement_data, kSuccess);
}
@@ -3579,6 +3615,10 @@ TEST(ErrorsArrowFunctions) {
"(foo ? bar : baz) => {}",
"(a, foo ? bar : baz) => {}",
"(foo ? bar : baz, a) => {}",
+ "(a.b, c) => {}",
+ "(c, a.b) => {}",
+ "(a['b'], c) => {}",
+ "(c, a['b']) => {}",
NULL
};
@@ -3727,8 +3767,6 @@ TEST(SuperNoErrors) {
static const ParserFlag always_flags[] = {
kAllowHarmonyArrowFunctions,
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
@@ -3759,11 +3797,7 @@ TEST(SuperErrors) {
NULL
};
- static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
- kAllowHarmonySloppy
- };
+ static const ParserFlag always_flags[] = {kAllowHarmonySloppy};
RunParserSyncTest(context_data, expression_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
}
@@ -3779,12 +3813,8 @@ TEST(SuperCall) {
NULL
};
- static const ParserFlag always_flags[] = {
- kAllowHarmonyArrowFunctions,
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
- kAllowHarmonySloppy
- };
+ static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions,
+ kAllowHarmonySloppy};
RunParserSyncTest(context_data, success_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags));
@@ -3834,12 +3864,8 @@ TEST(SuperNewNoErrors) {
NULL
};
- static const ParserFlag always_flags[] = {
- kAllowHarmonyArrowFunctions,
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
- kAllowHarmonySloppy
- };
+ static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions,
+ kAllowHarmonySloppy};
RunParserSyncTest(context_data, expression_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags));
}
@@ -3872,12 +3898,8 @@ TEST(SuperNewErrors) {
NULL
};
- static const ParserFlag always_flags[] = {
- kAllowHarmonyArrowFunctions,
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
- kAllowHarmonySloppy
- };
+ static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions,
+ kAllowHarmonySloppy};
RunParserSyncTest(context_data, statement_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
}
@@ -3918,8 +3940,6 @@ TEST(SuperErrorsNonMethods) {
};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, statement_data, kError, NULL, 0,
@@ -3943,9 +3963,7 @@ TEST(NoErrorsMethodDefinition) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, object_literal_body_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, object_literal_body_data, kSuccess);
}
@@ -4019,9 +4037,7 @@ TEST(MethodDefinitionNames) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, name_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, name_data, kSuccess);
}
@@ -4040,9 +4056,7 @@ TEST(MethodDefinitionStrictFormalParamereters) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, params_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, params_data, kError);
}
@@ -4061,15 +4075,11 @@ TEST(MethodDefinitionEvalArguments) {
"arguments",
NULL};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
-
// Fail in strict mode
- RunParserSyncTest(strict_context_data, data, kError, NULL, 0, always_flags,
- arraysize(always_flags));
+ RunParserSyncTest(strict_context_data, data, kError);
// OK in sloppy mode
- RunParserSyncTest(sloppy_context_data, data, kSuccess, NULL, 0, always_flags,
- arraysize(always_flags));
+ RunParserSyncTest(sloppy_context_data, data, kSuccess);
}
@@ -4088,12 +4098,9 @@ TEST(MethodDefinitionDuplicateEvalArguments) {
"arguments, a, arguments",
NULL};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
-
// In strict mode, the error is using "eval" or "arguments" as parameter names
// In sloppy mode, the error is that eval / arguments are duplicated
- RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
- arraysize(always_flags));
+ RunParserSyncTest(context_data, data, kError);
}
@@ -4127,9 +4134,7 @@ TEST(MethodDefinitionDuplicateProperty) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, params_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, params_data, kSuccess);
}
@@ -4151,8 +4156,7 @@ TEST(ClassExpressionNoErrors) {
"class name extends class base {} {}",
NULL};
- static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses, kAllowHarmonySloppy};
+ static const ParserFlag always_flags[] = {kAllowHarmonySloppy};
RunParserSyncTest(context_data, class_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags));
}
@@ -4171,9 +4175,7 @@ TEST(ClassDeclarationNoErrors) {
"class name extends class base {} {}",
NULL};
- static const ParserFlag always_flags[] = {kAllowHarmonyClasses};
- RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, statement_data, kSuccess);
}
@@ -4215,8 +4217,6 @@ TEST(ClassBodyNoErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
@@ -4274,8 +4274,6 @@ TEST(ClassPropertyNameNoErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, name_data, kSuccess, NULL, 0,
@@ -4306,8 +4304,6 @@ TEST(ClassExpressionErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_data, kError, NULL, 0,
@@ -4344,7 +4340,6 @@ TEST(ClassDeclarationErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_data, kError, NULL, 0,
@@ -4374,8 +4369,6 @@ TEST(ClassNameErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_name, kError, NULL, 0,
@@ -4408,8 +4401,6 @@ TEST(ClassGetterParamNameErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_name, kError, NULL, 0,
@@ -4437,8 +4428,6 @@ TEST(ClassStaticPrototypeErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
@@ -4465,8 +4454,6 @@ TEST(ClassSpecialConstructorErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
@@ -4488,8 +4475,6 @@ TEST(ClassConstructorNoErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
@@ -4507,8 +4492,6 @@ TEST(ClassMultipleConstructorErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
@@ -4530,8 +4513,6 @@ TEST(ClassMultiplePropertyNamesNoErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
@@ -4551,8 +4532,6 @@ TEST(ClassesAreStrictErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
@@ -4605,9 +4584,7 @@ TEST(ObjectLiteralPropertyShorthandKeywordsError) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, name_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, name_data, kError);
}
@@ -4628,14 +4605,11 @@ TEST(ObjectLiteralPropertyShorthandStrictKeywords) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, name_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, name_data, kSuccess);
const char* context_strict_data[][2] = {{"'use strict'; ({", "});"},
{NULL, NULL}};
- RunParserSyncTest(context_strict_data, name_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_strict_data, name_data, kError);
}
@@ -4657,9 +4631,7 @@ TEST(ObjectLiteralPropertyShorthandError) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, name_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, name_data, kError);
}
@@ -4672,9 +4644,7 @@ TEST(ObjectLiteralPropertyShorthandYieldInGeneratorError) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, name_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, name_data, kError);
}
@@ -5136,6 +5106,24 @@ TEST(ParseRestParametersErrors) {
}
+TEST(RestParameterInSetterMethodError) {
+ const char* context_data[][2] = {
+ {"'use strict';({ set prop(", ") {} }).prop = 1;"},
+ {"'use strict';(class { static set prop(", ") {} }).prop = 1;"},
+ {"'use strict';(new (class { set prop(", ") {} })).prop = 1;"},
+ {"({ set prop(", ") {} }).prop = 1;"},
+ {"(class { static set prop(", ") {} }).prop = 1;"},
+ {"(new (class { set prop(", ") {} })).prop = 1;"},
+ {nullptr, nullptr}};
+ const char* data[] = {"...a", "...arguments", "...eval", nullptr};
+
+ static const ParserFlag always_flags[] = {kAllowHarmonyRestParameters,
+ kAllowHarmonySloppy};
+ RunParserSyncTest(context_data, data, kError, nullptr, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
TEST(RestParametersEvalArguments) {
const char* strict_context_data[][2] =
{{"'use strict';(function(",
@@ -5253,18 +5241,15 @@ TEST(LexicalScopingSloppyMode) {
"(class C {})",
"(class C extends D {})",
NULL};
- static const ParserFlag always_true_flags[] = {kAllowHarmonyClasses};
static const ParserFlag always_false_flags[] = {kAllowHarmonySloppy};
- RunParserSyncTest(context_data, bad_data, kError, NULL, 0,
- always_true_flags, arraysize(always_true_flags),
+ RunParserSyncTest(context_data, bad_data, kError, NULL, 0, NULL, 0,
always_false_flags, arraysize(always_false_flags));
const char* good_data[] = {
"let = 1;",
"for(let = 1;;){}",
NULL};
- RunParserSyncTest(context_data, good_data, kSuccess, NULL, 0,
- always_true_flags, arraysize(always_true_flags),
+ RunParserSyncTest(context_data, good_data, kSuccess, NULL, 0, NULL, 0,
always_false_flags, arraysize(always_false_flags));
}
@@ -5286,9 +5271,7 @@ TEST(ComputedPropertyName) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
kAllowHarmonyComputedPropertyNames,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy,
};
RunParserSyncTest(context_data, error_data, kError, NULL, 0,
@@ -5317,9 +5300,7 @@ TEST(ComputedPropertyNameShorthandError) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
kAllowHarmonyComputedPropertyNames,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy,
};
RunParserSyncTest(context_data, error_data, kError, NULL, 0,
@@ -5387,7 +5368,6 @@ TEST(BasicImportExportParsing) {
i::Zone zone;
i::ParseInfo info(&zone, script);
i::Parser parser(&info);
- parser.set_allow_harmony_classes(true);
parser.set_allow_harmony_modules(true);
info.set_module();
if (!parser.Parse(&info)) {
@@ -5414,7 +5394,6 @@ TEST(BasicImportExportParsing) {
i::Zone zone;
i::ParseInfo info(&zone, script);
i::Parser parser(&info);
- parser.set_allow_harmony_classes(true);
parser.set_allow_harmony_modules(true);
info.set_global();
CHECK(!parser.Parse(&info));
@@ -5504,7 +5483,6 @@ TEST(ImportExportParsingErrors) {
i::Zone zone;
i::ParseInfo info(&zone, script);
i::Parser parser(&info);
- parser.set_allow_harmony_classes(true);
parser.set_allow_harmony_modules(true);
info.set_module();
CHECK(!parser.Parse(&info));
@@ -5617,7 +5595,6 @@ TEST(DuplicateProtoNoError) {
static const ParserFlag always_flags[] = {
kAllowHarmonyComputedPropertyNames,
- kAllowHarmonyObjectLiterals,
};
RunParserSyncTest(context_data, error_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags));
@@ -5645,8 +5622,7 @@ TEST(DeclarationsError) {
"class C {}",
NULL};
- static const ParserFlag always_flags[] = {kAllowHarmonyClasses,
- kAllowStrongMode};
+ static const ParserFlag always_flags[] = {kAllowStrongMode};
RunParserSyncTest(context_data, statement_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
}
@@ -5730,8 +5706,7 @@ TEST(PropertyNameEvalArguments) {
NULL};
- static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses, kAllowHarmonyObjectLiterals, kAllowStrongMode};
+ static const ParserFlag always_flags[] = {kAllowStrongMode};
RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags));
}
@@ -5915,10 +5890,8 @@ TEST(StrongConstructorThis) {
"class C { constructor() { label: 0; this.a = 0; this.b = 6; } }",
NULL};
- static const ParserFlag always_flags[] = {
- kAllowStrongMode, kAllowHarmonyClasses, kAllowHarmonyObjectLiterals,
- kAllowHarmonyArrowFunctions
- };
+ static const ParserFlag always_flags[] = {kAllowStrongMode,
+ kAllowHarmonyArrowFunctions};
RunParserSyncTest(sloppy_context_data, error_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
RunParserSyncTest(strict_context_data, error_data, kSuccess, NULL, 0,
@@ -5971,10 +5944,8 @@ TEST(StrongConstructorSuper) {
"class C extends Object { constructor() { 3; super(3); this.x = 0; } }",
NULL};
- static const ParserFlag always_flags[] = {
- kAllowStrongMode, kAllowHarmonyClasses, kAllowHarmonyObjectLiterals,
- kAllowHarmonyArrowFunctions
- };
+ static const ParserFlag always_flags[] = {kAllowStrongMode,
+ kAllowHarmonyArrowFunctions};
RunParserSyncTest(sloppy_context_data, error_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
RunParserSyncTest(strict_context_data, error_data, kSuccess, NULL, 0,
@@ -6019,9 +5990,7 @@ TEST(StrongConstructorReturns) {
"class C extends Array { constructor() { super(); this.a = 9; return } }",
NULL};
- static const ParserFlag always_flags[] = {
- kAllowStrongMode, kAllowHarmonyClasses, kAllowHarmonyObjectLiterals
- };
+ static const ParserFlag always_flags[] = {kAllowStrongMode};
RunParserSyncTest(sloppy_context_data, error_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
RunParserSyncTest(strict_context_data, error_data, kSuccess, NULL, 0,
@@ -6219,7 +6188,7 @@ TEST(StrongModeFreeVariablesDeclaredByPreviousScript) {
v8::V8::Initialize();
v8::HandleScope scope(CcTest::isolate());
v8::Context::Scope context_scope(v8::Context::New(CcTest::isolate()));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
// Introduce a bunch of variables, in all language modes.
const char* script1 =
@@ -6278,7 +6247,7 @@ TEST(StrongModeFreeVariablesDeclaredByLanguage) {
v8::V8::Initialize();
v8::HandleScope scope(CcTest::isolate());
v8::Context::Scope context_scope(v8::Context::New(CcTest::isolate()));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
const char* script1 =
"\"use strong\"; \n"
@@ -6294,7 +6263,7 @@ TEST(StrongModeFreeVariablesDeclaredInGlobalPrototype) {
v8::V8::Initialize();
v8::HandleScope scope(CcTest::isolate());
v8::Context::Scope context_scope(v8::Context::New(CcTest::isolate()));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
const char* script1 = "this.__proto__.my_var = 0;\n";
CompileRun(v8_str(script1));
@@ -6313,7 +6282,7 @@ TEST(StrongModeFreeVariablesNotDeclared) {
v8::V8::Initialize();
v8::HandleScope scope(CcTest::isolate());
v8::Context::Scope context_scope(v8::Context::New(CcTest::isolate()));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
// Test that referencing unintroduced variables in sloppy mode is ok.
const char* script1 =
@@ -6330,7 +6299,7 @@ TEST(StrongModeFreeVariablesNotDeclared) {
"if (false) { \n"
" not_there2; \n"
"} \n";
- v8::TryCatch try_catch2;
+ v8::TryCatch try_catch2(CcTest::isolate());
v8::Script::Compile(v8_str(script2));
CHECK(try_catch2.HasCaught());
v8::String::Utf8Value exception(try_catch2.Exception());
@@ -6351,7 +6320,7 @@ TEST(StrongModeFreeVariablesNotDeclared) {
" not_there3; \n"
" } \n"
"})(); \n";
- v8::TryCatch try_catch2;
+ v8::TryCatch try_catch2(CcTest::isolate());
v8::Script::Compile(v8_str(script3));
CHECK(try_catch2.HasCaught());
v8::String::Utf8Value exception(try_catch2.Exception());
@@ -6366,30 +6335,59 @@ TEST(StrongModeFreeVariablesNotDeclared) {
TEST(DestructuringPositiveTests) {
i::FLAG_harmony_destructuring = true;
+ i::FLAG_harmony_arrow_functions = true;
+ i::FLAG_harmony_computed_property_names = true;
const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
{"var ", " = {};"},
{"'use strict'; const ", " = {};"},
+ {"function f(", ") {}"},
+ {"function f(argument1, ", ") {}"},
+ {"var f = (", ") => {};"},
+ {"var f = (argument1,", ") => {};"},
{NULL, NULL}};
// clang-format off
const char* data[] = {
"a",
"{ x : y }",
+ "{ x : y = 1 }",
"[a]",
+ "[a = 1]",
"[a,b,c]",
+ "[a, b = 42, c]",
"{ x : x, y : y }",
+ "{ x : x = 1, y : y }",
+ "{ x : x, y : y = 42 }",
"[]",
"{}",
"[{x:x, y:y}, [a,b,c]]",
+ "[{x:x = 1, y:y = 2}, [a = 3, b = 4, c = 5]]",
+ "{x}",
+ "{x, y}",
+ "{x = 42, y = 15}",
"[a,,b]",
"{42 : x}",
+ "{42 : x = 42}",
"{42e-2 : x}",
+ "{42e-2 : x = 42}",
+ "{x : y, x : z}",
"{'hi' : x}",
+ "{'hi' : x = 42}",
"{var: x}",
+ "{var: x = 42}",
+ "{[x] : z}",
+ "{[1+1] : z}",
+ "{[foo()] : z}",
+ "{}",
+ "[...rest]",
+ "[a,b,...rest]",
+ "[a,,...rest]",
NULL};
// clang-format on
- static const ParserFlag always_flags[] = {kAllowHarmonyDestructuring};
+ static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames,
+ kAllowHarmonyArrowFunctions,
+ kAllowHarmonyDestructuring};
RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
arraysize(always_flags));
}
@@ -6397,12 +6395,21 @@ TEST(DestructuringPositiveTests) {
TEST(DestructuringNegativeTests) {
i::FLAG_harmony_destructuring = true;
- static const ParserFlag always_flags[] = {kAllowHarmonyDestructuring};
+ i::FLAG_harmony_arrow_functions = true;
+ i::FLAG_harmony_computed_property_names = true;
+ static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames,
+ kAllowHarmonyArrowFunctions,
+ kAllowHarmonyDestructuring};
{ // All modes.
const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
{"var ", " = {};"},
{"'use strict'; const ", " = {};"},
+ {"function f(", ") {}"},
+ {"function f(argument1, ", ") {}"},
+ {"var f = (", ") => {};"},
+ {"var f = ", " => {};"},
+ {"var f = (argument1,", ") => {};"},
{NULL, NULL}};
// clang-format off
@@ -6435,7 +6442,6 @@ TEST(DestructuringNegativeTests) {
"a >>> a",
"function a() {}",
"a`bcd`",
- "x => x",
"this",
"null",
"true",
@@ -6443,25 +6449,61 @@ TEST(DestructuringNegativeTests) {
"1",
"'abc'",
"class {}",
- "() => x",
"{+2 : x}",
"{-2 : x}",
"var",
"[var]",
"{x : {y : var}}",
+ "{x : x = a+}",
+ "{x : x = (a+)}",
+ "{x : x += a}",
+ "{m() {} = 0}",
+ "{[1+1]}",
+ "[...rest, x]",
+ "[a,b,...rest, x]",
+ "[a,,...rest, x]",
+ "[...rest,]",
+ "[a,b,...rest,]",
+ "[a,,...rest,]",
+ "[...rest,...rest1]",
+ "[a,b,...rest,...rest1]",
+ "[a,,..rest,...rest1]",
NULL};
// clang-format on
RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
arraysize(always_flags));
}
- { // Strict mode.
+ { // All modes.
const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
+ {"var ", " = {};"},
{"'use strict'; const ", " = {};"},
+ {"function f(", ") {}"},
+ {"function f(argument1, ", ") {}"},
+ {"var f = (", ") => {};"},
+ {"var f = (argument1,", ") => {};"},
{NULL, NULL}};
// clang-format off
const char* data[] = {
+ "x => x",
+ "() => x",
+ NULL};
+ // clang-format on
+ RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+ }
+
+ { // Strict mode.
+ const char* context_data[][2] = {
+ {"'use strict'; let ", " = {};"},
+ {"'use strict'; const ", " = {};"},
+ {"'use strict'; function f(", ") {}"},
+ {"'use strict'; function f(argument1, ", ") {}"},
+ {NULL, NULL}};
+
+ // clang-format off
+ const char* data[] = {
"[eval]",
"{ a : arguments }",
"[public]",
@@ -6490,3 +6532,261 @@ TEST(DestructuringNegativeTests) {
arraysize(always_flags));
}
}
+
+
+TEST(DestructuringDisallowPatternsInForVarIn) {
+ i::FLAG_harmony_destructuring = true;
+ static const ParserFlag always_flags[] = {kAllowHarmonyDestructuring};
+ const char* context_data[][2] = {
+ {"", ""}, {"function f() {", "}"}, {NULL, NULL}};
+ // clang-format off
+ const char* error_data[] = {
+ "for (let x = {} in null);",
+ "for (let x = {} of null);",
+ NULL};
+ // clang-format on
+ RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+
+ // clang-format off
+ const char* success_data[] = {
+ "for (var x = {} in null);",
+ NULL};
+ // clang-format on
+ RunParserSyncTest(context_data, success_data, kSuccess, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(DestructuringDuplicateParams) {
+ i::FLAG_harmony_destructuring = true;
+ i::FLAG_harmony_arrow_functions = true;
+ i::FLAG_harmony_computed_property_names = true;
+ static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames,
+ kAllowHarmonyArrowFunctions,
+ kAllowHarmonyDestructuring};
+ const char* context_data[][2] = {{"'use strict';", ""},
+ {"function outer() { 'use strict';", "}"},
+ {nullptr, nullptr}};
+
+
+ // clang-format off
+ const char* error_data[] = {
+ "function f(x,x){}",
+ "function f(x, {x : x}){}",
+ "function f(x, {x}){}",
+ "function f({x,x}) {}",
+ "function f([x,x]) {}",
+ "function f(x, [y,{z:x}]) {}",
+ "function f([x,{y:x}]) {}",
+ // non-simple parameter list causes duplicates to be errors in sloppy mode.
+ "function f(x, x, {a}) {}",
+ nullptr};
+ // clang-format on
+ RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(DestructuringDuplicateParamsSloppy) {
+ i::FLAG_harmony_destructuring = true;
+ i::FLAG_harmony_arrow_functions = true;
+ i::FLAG_harmony_computed_property_names = true;
+ static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames,
+ kAllowHarmonyArrowFunctions,
+ kAllowHarmonyDestructuring};
+ const char* context_data[][2] = {
+ {"", ""}, {"function outer() {", "}"}, {nullptr, nullptr}};
+
+
+ // clang-format off
+ const char* error_data[] = {
+ // non-simple parameter list causes duplicates to be errors in sloppy mode.
+ "function f(x, {x : x}){}",
+ "function f(x, {x}){}",
+ "function f({x,x}) {}",
+ "function f(x, x, {a}) {}",
+ nullptr};
+ // clang-format on
+ RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(DestructuringDisallowPatternsInSingleParamArrows) {
+ i::FLAG_harmony_destructuring = true;
+ i::FLAG_harmony_arrow_functions = true;
+ i::FLAG_harmony_computed_property_names = true;
+ static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames,
+ kAllowHarmonyArrowFunctions,
+ kAllowHarmonyDestructuring};
+ const char* context_data[][2] = {{"'use strict';", ""},
+ {"function outer() { 'use strict';", "}"},
+ {"", ""},
+ {"function outer() { ", "}"},
+ {nullptr, nullptr}};
+
+ // clang-format off
+ const char* error_data[] = {
+ "var f = {x} => {};",
+ "var f = {x,y} => {};",
+ nullptr};
+ // clang-format on
+ RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(DestructuringDisallowPatternsInRestParams) {
+ i::FLAG_harmony_destructuring = true;
+ i::FLAG_harmony_arrow_functions = true;
+ i::FLAG_harmony_rest_parameters = true;
+ i::FLAG_harmony_computed_property_names = true;
+ static const ParserFlag always_flags[] = {
+ kAllowHarmonyComputedPropertyNames, kAllowHarmonyArrowFunctions,
+ kAllowHarmonyRestParameters, kAllowHarmonyDestructuring};
+ const char* context_data[][2] = {{"'use strict';", ""},
+ {"function outer() { 'use strict';", "}"},
+ {"", ""},
+ {"function outer() { ", "}"},
+ {nullptr, nullptr}};
+
+ // clang-format off
+ const char* error_data[] = {
+ "function(...{}) {}",
+ "function(...{x}) {}",
+ "function(...[x]) {}",
+ "(...{}) => {}",
+ "(...{x}) => {}",
+ "(...[x]) => {}",
+ nullptr};
+ // clang-format on
+ RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(SpreadArray) {
+ i::FLAG_harmony_spread_arrays = true;
+
+ const char* context_data[][2] = {
+ {"'use strict';", ""}, {"", ""}, {NULL, NULL}};
+
+ // clang-format off
+ const char* data[] = {
+ "[...a]",
+ "[a, ...b]",
+ "[...a,]",
+ "[...a, ,]",
+ "[, ...a]",
+ "[...a, ...b]",
+ "[...a, , ...b]",
+ "[...[...a]]",
+ "[, ...a]",
+ "[, , ...a]",
+ NULL};
+ // clang-format on
+ static const ParserFlag always_flags[] = {kAllowHarmonySpreadArrays};
+ RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(SpreadArrayError) {
+ i::FLAG_harmony_spread_arrays = true;
+
+ const char* context_data[][2] = {
+ {"'use strict';", ""}, {"", ""}, {NULL, NULL}};
+
+ // clang-format off
+ const char* data[] = {
+ "[...]",
+ "[a, ...]",
+ "[..., ]",
+ "[..., ...]",
+ "[ (...a)]",
+ NULL};
+ // clang-format on
+ static const ParserFlag always_flags[] = {kAllowHarmonySpreadArrays};
+ RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(NewTarget) {
+ // clang-format off
+ const char* good_context_data[][2] = {
+ {"function f() {", "}"},
+ {"'use strict'; function f() {", "}"},
+ {"var f = function() {", "}"},
+ {"'use strict'; var f = function() {", "}"},
+ {"({m: function() {", "}})"},
+ {"'use strict'; ({m: function() {", "}})"},
+ {"({m() {", "}})"},
+ {"'use strict'; ({m() {", "}})"},
+ {"({get x() {", "}})"},
+ {"'use strict'; ({get x() {", "}})"},
+ {"({set x(_) {", "}})"},
+ {"'use strict'; ({set x(_) {", "}})"},
+ {"class C {m() {", "}}"},
+ {"class C {get x() {", "}}"},
+ {"class C {set x(_) {", "}}"},
+ {NULL}
+ };
+
+ const char* bad_context_data[][2] = {
+ {"", ""},
+ {"'use strict';", ""},
+ {NULL}
+ };
+
+ const char* data[] = {
+ "new.target",
+ "{ new.target }",
+ "() => { new.target }",
+ "() => new.target",
+ "if (1) { new.target }",
+ "if (1) {} else { new.target }",
+ "while (0) { new.target }",
+ "do { new.target } while (0)",
+ NULL
+ };
+
+ static const ParserFlag always_flags[] = {
+ kAllowHarmonyArrowFunctions,
+ kAllowHarmonyNewTarget,
+ kAllowHarmonySloppy,
+ };
+ // clang-format on
+
+ RunParserSyncTest(good_context_data, data, kSuccess, NULL, 0, always_flags,
+ arraysize(always_flags));
+ RunParserSyncTest(bad_context_data, data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(LegacyConst) {
+ // clang-format off
+ const char* context_data[][2] = {
+ {"", ""},
+ {"{", "}"},
+ {NULL, NULL}
+ };
+
+ const char* data[] = {
+ "const x",
+ "const x = 1",
+ "for (const x = 1; x < 1; x++) {}",
+ "for (const x in {}) {}",
+ "for (const x of []) {}",
+ NULL
+ };
+ // clang-format on
+
+ static const ParserFlag always_flags[] = {kNoLegacyConst};
+
+ RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+ RunParserSyncTest(context_data, data, kSuccess);
+}
diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc
index 0a2c7a5625..221761487c 100644
--- a/deps/v8/test/cctest/test-profile-generator.cc
+++ b/deps/v8/test/cctest/test-profile-generator.cc
@@ -681,14 +681,13 @@ TEST(BailoutReason) {
CHECK_EQ(0, iprofiler->GetProfilesCount());
v8::Handle<v8::Script> script =
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
- "function TryCatch() {\n"
- " try {\n"
- " startProfiling();\n"
- " } catch (e) { };\n"
+ "function Debugger() {\n"
+ " debugger;\n"
+ " startProfiling();\n"
"}\n"
"function TryFinally() {\n"
" try {\n"
- " TryCatch();\n"
+ " Debugger();\n"
" } finally { };\n"
"}\n"
"TryFinally();\n"
@@ -703,8 +702,8 @@ TEST(BailoutReason) {
// The tree should look like this:
// (root)
// ""
- // kTryFinally
- // kTryCatch
+ // kTryFinallyStatement
+ // kDebuggerStatement
current = PickChild(current, "");
CHECK(const_cast<v8::CpuProfileNode*>(current));
@@ -712,7 +711,7 @@ TEST(BailoutReason) {
CHECK(const_cast<v8::CpuProfileNode*>(current));
CHECK(!strcmp("TryFinallyStatement", current->GetBailoutReason()));
- current = PickChild(current, "TryCatch");
+ current = PickChild(current, "Debugger");
CHECK(const_cast<v8::CpuProfileNode*>(current));
- CHECK(!strcmp("TryCatchStatement", current->GetBailoutReason()));
+ CHECK(!strcmp("DebuggerStatement", current->GetBailoutReason()));
}
diff --git a/deps/v8/test/cctest/test-reloc-info.cc b/deps/v8/test/cctest/test-reloc-info.cc
index a238c3a7d8..829fd24f4d 100644
--- a/deps/v8/test/cctest/test-reloc-info.cc
+++ b/deps/v8/test/cctest/test-reloc-info.cc
@@ -66,8 +66,8 @@ TEST(Positions) {
writer.Finish();
relocation_info_size = static_cast<int>(buffer_end - writer.pos());
- CodeDesc desc = { buffer.get(), buffer_size, code_size,
- relocation_info_size, NULL };
+ CodeDesc desc = {buffer.get(), buffer_size, code_size, relocation_info_size,
+ 0, NULL};
// Read only (non-statement) positions.
{
@@ -120,4 +120,5 @@ TEST(Positions) {
}
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc
index 938178efb9..0bae94e219 100644
--- a/deps/v8/test/cctest/test-serialize.cc
+++ b/deps/v8/test/cctest/test-serialize.cc
@@ -493,7 +493,7 @@ UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
&outdated_contexts).ToHandleChecked();
CHECK(root->IsContext());
CHECK(Handle<Context>::cast(root)->global_proxy() == *global_proxy);
- CHECK_EQ(1, outdated_contexts->length());
+ CHECK_EQ(2, outdated_contexts->length());
}
Handle<Object> root2;
@@ -628,13 +628,13 @@ UNINITIALIZED_DEPENDENT_TEST(CustomContextDeserialization,
root =
deserializer.DeserializePartial(isolate, global_proxy,
&outdated_contexts).ToHandleChecked();
- CHECK_EQ(2, outdated_contexts->length());
+ CHECK_EQ(3, outdated_contexts->length());
CHECK(root->IsContext());
Handle<Context> context = Handle<Context>::cast(root);
CHECK(context->global_proxy() == *global_proxy);
Handle<String> o = isolate->factory()->NewStringFromAsciiChecked("o");
Handle<JSObject> global_object(context->global_object(), isolate);
- Handle<Object> property = JSObject::GetDataProperty(global_object, o);
+ Handle<Object> property = JSReceiver::GetDataProperty(global_object, o);
CHECK(property.is_identical_to(global_proxy));
v8::Handle<v8::Context> v8_context = v8::Utils::ToLocal(context);
@@ -859,7 +859,7 @@ static Handle<SharedFunctionInfo> CompileScript(
Isolate* isolate, Handle<String> source, Handle<String> name,
ScriptData** cached_data, v8::ScriptCompiler::CompileOptions options) {
return Compiler::CompileScript(
- source, name, 0, 0, false, false, Handle<Object>(),
+ source, name, 0, 0, v8::ScriptOriginOptions(), Handle<Object>(),
Handle<Context>(isolate->native_context()), NULL, cached_data, options,
NOT_NATIVES_CODE, false);
}
@@ -938,7 +938,7 @@ TEST(CodeCachePromotedToCompilationCache) {
isolate, src, src, &cache, v8::ScriptCompiler::kConsumeCodeCache);
CHECK(isolate->compilation_cache()
- ->LookupScript(src, src, 0, 0, false, false,
+ ->LookupScript(src, src, 0, 0, v8::ScriptOriginOptions(),
isolate->native_context(), SLOPPY)
.ToHandleChecked()
.is_identical_to(copy));
@@ -1098,11 +1098,11 @@ TEST(SerializeToplevelLargeStrings) {
Execution::Call(isolate, copy_fun, global, 0, NULL).ToHandleChecked();
CHECK_EQ(6 * 1999999, Handle<String>::cast(copy_result)->length());
- Handle<Object> property = JSObject::GetDataProperty(
+ Handle<Object> property = JSReceiver::GetDataProperty(
isolate->global_object(), f->NewStringFromAsciiChecked("s"));
CHECK(isolate->heap()->InSpace(HeapObject::cast(*property), LO_SPACE));
- property = JSObject::GetDataProperty(isolate->global_object(),
- f->NewStringFromAsciiChecked("t"));
+ property = JSReceiver::GetDataProperty(isolate->global_object(),
+ f->NewStringFromAsciiChecked("t"));
CHECK(isolate->heap()->InSpace(HeapObject::cast(*property), LO_SPACE));
// Make sure we do not serialize too much, e.g. include the source string.
CHECK_LT(cache->length(), 13000000);
@@ -1595,7 +1595,6 @@ TEST(SerializeInternalReference) {
return;
#endif
// Disable experimental natives that are loaded after deserialization.
- FLAG_turbo_deoptimization = false;
FLAG_context_specialization = false;
FLAG_always_opt = true;
const char* flag = "--turbo-filter=foo";
@@ -1659,6 +1658,31 @@ TEST(SerializeInternalReference) {
}
+TEST(Regress503552) {
+ // Test that the code serializer can deal with weak cells that form a linked
+ // list during incremental marking.
+
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+
+ HandleScope scope(isolate);
+ Handle<String> source = isolate->factory()->NewStringFromAsciiChecked(
+ "function f() {} function g() {}");
+ ScriptData* script_data = NULL;
+ Handle<SharedFunctionInfo> shared = Compiler::CompileScript(
+ source, Handle<String>(), 0, 0, v8::ScriptOriginOptions(),
+ Handle<Object>(), Handle<Context>(isolate->native_context()), NULL,
+ &script_data, v8::ScriptCompiler::kProduceCodeCache, NOT_NATIVES_CODE,
+ false);
+ delete script_data;
+
+ SimulateIncrementalMarking(isolate->heap());
+
+ script_data = CodeSerializer::Serialize(isolate, shared, source);
+ delete script_data;
+}
+
+
TEST(SerializationMemoryStats) {
FLAG_profile_deserialization = true;
FLAG_always_opt = false;
diff --git a/deps/v8/test/cctest/test-spaces.cc b/deps/v8/test/cctest/test-spaces.cc
index 9d22327831..3f5e437223 100644
--- a/deps/v8/test/cctest/test-spaces.cc
+++ b/deps/v8/test/cctest/test-spaces.cc
@@ -145,7 +145,8 @@ class TestCodeRangeScope {
DISALLOW_COPY_AND_ASSIGN(TestCodeRangeScope);
};
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
static void VerifyMemoryChunk(Isolate* isolate,
@@ -358,8 +359,9 @@ TEST(NewSpace) {
CHECK(new_space.HasBeenSetUp());
while (new_space.Available() >= Page::kMaxRegularHeapObjectSize) {
- Object* obj = new_space.AllocateRaw(
- Page::kMaxRegularHeapObjectSize).ToObjectChecked();
+ Object* obj =
+ new_space.AllocateRawUnaligned(Page::kMaxRegularHeapObjectSize)
+ .ToObjectChecked();
CHECK(new_space.Contains(HeapObject::cast(obj)));
}
@@ -384,7 +386,7 @@ TEST(OldSpace) {
CHECK(s->SetUp());
while (s->Available() > 0) {
- s->AllocateRaw(Page::kMaxRegularHeapObjectSize).ToObjectChecked();
+ s->AllocateRawUnaligned(Page::kMaxRegularHeapObjectSize).ToObjectChecked();
}
s->TearDown();
@@ -437,6 +439,9 @@ TEST(SizeOfFirstPageIsLargeEnough) {
if (!isolate->snapshot_available()) return;
if (Snapshot::EmbedsScript(isolate)) return;
+ // If this test fails due to enabling experimental natives that are not part
+ // of the snapshot, we may need to adjust CalculateFirstPageSizes.
+
// 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.
@@ -485,7 +490,8 @@ UNINITIALIZED_TEST(NewSpaceGrowsToTargetCapacity) {
// Try to allocate out of the new space. A new page should be added and
// the
// allocation should succeed.
- v8::internal::AllocationResult allocation = new_space->AllocateRaw(80);
+ v8::internal::AllocationResult allocation =
+ new_space->AllocateRawUnaligned(80);
CHECK(!allocation.IsRetry());
CHECK(new_space->CommittedMemory() == 2 * Page::kPageSize);
diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc
index 1713e91662..d8d7c96871 100644
--- a/deps/v8/test/cctest/test-strings.cc
+++ b/deps/v8/test/cctest/test-strings.cc
@@ -1222,7 +1222,7 @@ UNINITIALIZED_TEST(OneByteArrayJoin) {
// summing the lengths of the strings (as Smis) overflows and wraps.
LocalContext context(isolate);
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(CompileRun(
"var two_14 = Math.pow(2, 14);"
"var two_17 = Math.pow(2, 17);"
diff --git a/deps/v8/test/cctest/test-thread-termination.cc b/deps/v8/test/cctest/test-thread-termination.cc
index 250e9a344a..c0cc1cb8d1 100644
--- a/deps/v8/test/cctest/test-thread-termination.cc
+++ b/deps/v8/test/cctest/test-thread-termination.cc
@@ -61,7 +61,7 @@ void Loop(const v8::FunctionCallbackInfo<v8::Value>& args) {
void DoLoop(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(),
"function f() {"
@@ -86,7 +86,7 @@ void DoLoop(const v8::FunctionCallbackInfo<v8::Value>& args) {
void DoLoopNoCall(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(),
"var term = true;"
@@ -217,7 +217,7 @@ void TerminateOrReturnObject(const v8::FunctionCallbackInfo<v8::Value>& args) {
void LoopGetProperty(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
v8::Script::Compile(
v8::String::NewFromUtf8(args.GetIsolate(),
@@ -275,7 +275,7 @@ v8::Persistent<v8::String> reenter_script_1;
v8::Persistent<v8::String> reenter_script_2;
void ReenterAfterTermination(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
v8::Isolate* isolate = args.GetIsolate();
CHECK(!v8::V8::IsExecutionTerminating(isolate));
v8::Local<v8::String> script =
@@ -328,7 +328,7 @@ TEST(TerminateAndReenterFromThreadItself) {
void DoLoopCancelTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
CHECK(!v8::V8::IsExecutionTerminating());
v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(),
"var term = true;"
@@ -426,7 +426,7 @@ TEST(PostponeTerminateException) {
v8::Context::New(CcTest::isolate(), NULL, global);
v8::Context::Scope context_scope(context);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
static const char* terminate_and_loop =
"terminate(); for (var i = 0; i < 10000; i++);";
@@ -504,7 +504,7 @@ TEST(TerminationInInnerTryCall) {
v8::Context::New(CcTest::isolate(), NULL, global_template);
v8::Context::Scope context_scope(context);
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun("inner_try_call_terminate()");
CHECK(try_catch.HasTerminated());
}
@@ -522,7 +522,7 @@ TEST(TerminateAndTryCall) {
v8::Handle<v8::Context> context = v8::Context::New(isolate, NULL, global);
v8::Context::Scope context_scope(context);
CHECK(!v8::V8::IsExecutionTerminating(isolate));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(!v8::V8::IsExecutionTerminating(isolate));
// Terminate execution has been triggered inside TryCall, but re-requested
// to trigger later.
diff --git a/deps/v8/test/cctest/test-threads.cc b/deps/v8/test/cctest/test-threads.cc
index e192bc1559..5f2cdae2a2 100644
--- a/deps/v8/test/cctest/test-threads.cc
+++ b/deps/v8/test/cctest/test-threads.cc
@@ -32,12 +32,7 @@
#include "src/isolate.h"
-enum Turn {
- FILL_CACHE,
- CLEAN_CACHE,
- SECOND_TIME_FILL_CACHE,
- DONE
-};
+enum Turn { FILL_CACHE, CLEAN_CACHE, SECOND_TIME_FILL_CACHE, CACHE_DONE };
static Turn turn = FILL_CACHE;
@@ -76,7 +71,7 @@ class ThreadA : public v8::base::Thread {
// Rerun the script.
CHECK(script->Run()->IsTrue());
- turn = DONE;
+ turn = CACHE_DONE;
}
};
@@ -116,7 +111,7 @@ TEST(JSFunctionResultCachesInTwoThreads) {
threadA.Join();
threadB.Join();
- CHECK_EQ(DONE, turn);
+ CHECK_EQ(CACHE_DONE, turn);
}
class ThreadIdValidationThread : public v8::base::Thread {
diff --git a/deps/v8/test/cctest/test-typedarrays.cc b/deps/v8/test/cctest/test-typedarrays.cc
index d371673b9e..394f6194fd 100644
--- a/deps/v8/test/cctest/test-typedarrays.cc
+++ b/deps/v8/test/cctest/test-typedarrays.cc
@@ -48,7 +48,7 @@ TEST(CopyContentsArray) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
CompileRun("var a = new Uint8Array([0, 1, 2, 3]);");
- TestArrayBufferViewContents(env, true);
+ TestArrayBufferViewContents(env, false);
}
diff --git a/deps/v8/test/cctest/test-types.cc b/deps/v8/test/cctest/test-types.cc
index 295cef6d36..fe07093077 100644
--- a/deps/v8/test/cctest/test-types.cc
+++ b/deps/v8/test/cctest/test-types.cc
@@ -1020,15 +1020,10 @@ struct Tests : Rep {
CheckSub(T.Proxy, T.Receiver);
CheckSub(T.OtherObject, T.Object);
CheckSub(T.Undetectable, T.Object);
- CheckSub(T.DetectableObject, T.Object);
- CheckSub(T.GlobalObject, T.DetectableObject);
- CheckSub(T.OtherObject, T.DetectableObject);
- CheckSub(T.GlobalObject, T.Object);
- CheckSub(T.GlobalObject, T.Receiver);
+ CheckSub(T.OtherObject, T.Object);
CheckUnordered(T.Object, T.Proxy);
- CheckUnordered(T.GlobalObject, T.OtherObject);
- CheckUnordered(T.DetectableObject, T.Undetectable);
+ CheckUnordered(T.OtherObject, T.Undetectable);
// Subtyping between concrete structural types
@@ -1350,7 +1345,6 @@ struct Tests : Rep {
CheckDisjoint(T.InternalizedString, T.Symbol);
CheckOverlap(T.Object, T.Receiver);
CheckOverlap(T.OtherObject, T.Object);
- CheckOverlap(T.GlobalObject, T.Object);
CheckOverlap(T.Proxy, T.Receiver);
CheckDisjoint(T.Object, T.Proxy);
@@ -1505,6 +1499,7 @@ struct Tests : Rep {
void Union3() {
// Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3))
for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
+ HandleScope scope(isolate);
for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
for (TypeIterator it3 = it2; it3 != T.types.end(); ++it3) {
TypeHandle type1 = *it1;
@@ -1757,6 +1752,7 @@ struct Tests : Rep {
// Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3))
for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
+ HandleScope scope(isolate);
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;
@@ -1963,66 +1959,6 @@ struct Tests : Rep {
}
}
}
-
- void GlobalObjectType() {
- i::Handle<i::Context> context1 = v8::Utils::OpenHandle(
- *v8::Context::New(reinterpret_cast<v8::Isolate*>(isolate)));
- Handle<i::GlobalObject> global_object1(context1->global_object());
- TypeHandle GlobalObjectConstant1 =
- Type::Constant(global_object1, Rep::ToRegion(&zone, isolate));
-
- i::Handle<i::Context> context2 = v8::Utils::OpenHandle(
- *v8::Context::New(reinterpret_cast<v8::Isolate*>(isolate)));
- Handle<i::GlobalObject> global_object2(context2->global_object());
- TypeHandle GlobalObjectConstant2 =
- Type::Constant(global_object2, Rep::ToRegion(&zone, isolate));
-
- CheckSub(GlobalObjectConstant1, T.DetectableObject);
- CheckSub(GlobalObjectConstant2, T.DetectableObject);
- CheckSub(GlobalObjectConstant1, T.GlobalObject);
- CheckSub(GlobalObjectConstant2, T.GlobalObject);
- CheckSub(GlobalObjectConstant1, T.Object);
- CheckSub(GlobalObjectConstant2, T.Object);
-
- CheckUnordered(T.GlobalObject, T.OtherObject);
- CheckUnordered(GlobalObjectConstant1, T.OtherObject);
- CheckUnordered(GlobalObjectConstant2, T.OtherObject);
- CheckUnordered(GlobalObjectConstant1, GlobalObjectConstant2);
-
- CheckDisjoint(T.GlobalObject, T.ObjectClass);
- CheckDisjoint(GlobalObjectConstant1, T.ObjectClass);
- CheckDisjoint(GlobalObjectConstant2, T.ArrayClass);
-
- CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.GlobalObject);
- CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), GlobalObjectConstant1);
- CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), GlobalObjectConstant2);
-
- CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.GlobalObject);
- CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass),
- GlobalObjectConstant1);
- CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass),
- GlobalObjectConstant2);
-
- CheckUnordered(T.Union(T.ObjectClass, T.String), T.GlobalObject);
-
- CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass),
- T.Union(T.GlobalObject, T.Object));
-
- CheckDisjoint(T.Union(GlobalObjectConstant1, T.ArrayClass),
- GlobalObjectConstant2);
-
- CheckEqual(T.Union(T.Union(T.Number, GlobalObjectConstant1),
- T.Union(T.SignedSmall, T.GlobalObject)),
- T.Union(T.Number, T.GlobalObject));
-
- CheckEqual(T.Semantic(T.Intersect(T.ObjectClass, T.GlobalObject)), T.None);
-
- CHECK(!T.Intersect(T.ArrayClass, GlobalObjectConstant2)->IsInhabited());
-
- CheckEqual(T.Intersect(T.Union(T.Number, T.OtherObject),
- T.Union(T.Signed32, T.GlobalObject)),
- T.Signed32);
- }
};
typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
@@ -2197,9 +2133,3 @@ TEST(HTypeFromType_zone) { ZoneTests().HTypeFromType(); }
TEST(HTypeFromType_heap) { HeapTests().HTypeFromType(); }
-
-
-TEST(GlobalObjectType_zone) { ZoneTests().GlobalObjectType(); }
-
-
-TEST(GlobalObjectType_heap) { HeapTests().GlobalObjectType(); }
diff --git a/deps/v8/test/cctest/test-unboxed-doubles.cc b/deps/v8/test/cctest/test-unboxed-doubles.cc
index 89f58a62e4..4746e47322 100644
--- a/deps/v8/test/cctest/test-unboxed-doubles.cc
+++ b/deps/v8/test/cctest/test-unboxed-doubles.cc
@@ -1035,7 +1035,7 @@ TEST(DoScavenge) {
CcTest::heap()->CollectGarbage(i::NEW_SPACE);
// Create temp object in the new space.
- Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, NOT_TENURED);
+ Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS);
CHECK(isolate->heap()->new_space()->Contains(*temp));
// Construct a double value that looks like a pointer to the new space object
@@ -1088,7 +1088,8 @@ TEST(DoScavengeWithIncrementalWriteBarrier) {
AlwaysAllocateScope always_allocate(isolate);
// Make sure |obj_value| is placed on an old-space evacuation candidate.
SimulateFullSpace(old_space);
- obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED);
+ obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS,
+ Strength::WEAK, TENURED);
ec_page = Page::FromAddress(obj_value->address());
}
@@ -1373,7 +1374,7 @@ TEST(StoreBufferScanOnScavenge) {
CHECK(isolate->heap()->old_space()->Contains(*obj));
// Create temp object in the new space.
- Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, NOT_TENURED);
+ Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS);
CHECK(isolate->heap()->new_space()->Contains(*temp));
// Construct a double value that looks like a pointer to the new space object
@@ -1572,7 +1573,8 @@ static void TestIncrementalWriteBarrier(Handle<Map> map, Handle<Map> new_map,
// Make sure |obj_value| is placed on an old-space evacuation candidate.
SimulateFullSpace(old_space);
- obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED);
+ obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS,
+ Strength::WEAK, TENURED);
ec_page = Page::FromAddress(obj_value->address());
CHECK_NE(ec_page, Page::FromAddress(obj->address()));
}
diff --git a/deps/v8/test/cctest/test-utils-arm64.h b/deps/v8/test/cctest/test-utils-arm64.h
index d00ad5e78c..a091bf3932 100644
--- a/deps/v8/test/cctest/test-utils-arm64.h
+++ b/deps/v8/test/cctest/test-utils-arm64.h
@@ -96,13 +96,13 @@ class RegisterDump {
return dump_.sp_;
}
- inline int64_t wspreg() const {
+ inline int32_t wspreg() const {
DCHECK(SPRegAliasesMatch());
- return dump_.wsp_;
+ return static_cast<int32_t>(dump_.wsp_);
}
// Flags accessors.
- inline uint64_t flags_nzcv() const {
+ inline uint32_t flags_nzcv() const {
DCHECK(IsComplete());
DCHECK((dump_.flags_ & ~Flags_mask) == 0);
return dump_.flags_ & Flags_mask;
diff --git a/deps/v8/test/cctest/test-version.cc b/deps/v8/test/cctest/test-version.cc
index 7de4467d6b..50fca16871 100644
--- a/deps/v8/test/cctest/test-version.cc
+++ b/deps/v8/test/cctest/test-version.cc
@@ -46,7 +46,8 @@ void SetVersion(int major, int minor, int build, int patch,
Version::soname_ = soname;
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
static void CheckVersion(int major, int minor, int build,
diff --git a/deps/v8/test/cctest/test-weakmaps.cc b/deps/v8/test/cctest/test-weakmaps.cc
index 64d2876887..31b812e287 100644
--- a/deps/v8/test/cctest/test-weakmaps.cc
+++ b/deps/v8/test/cctest/test-weakmaps.cc
@@ -34,7 +34,6 @@
using namespace v8::internal;
-
static Isolate* GetIsolateFrom(LocalContext* context) {
return reinterpret_cast<Isolate*>((*context)->GetIsolate());
}
@@ -89,8 +88,10 @@ TEST(Weakness) {
Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
Handle<JSObject> object = factory->NewJSObjectFromMap(map);
Handle<Smi> smi(Smi::FromInt(23), isolate);
- Runtime::WeakCollectionSet(weakmap, key, object);
- Runtime::WeakCollectionSet(weakmap, object, smi);
+ int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
+ Runtime::WeakCollectionSet(weakmap, key, object, hash);
+ int32_t object_hash = Object::GetOrCreateHash(isolate, object)->value();
+ Runtime::WeakCollectionSet(weakmap, object, smi, object_hash);
}
CHECK_EQ(2, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
@@ -145,7 +146,8 @@ TEST(Shrinking) {
for (int i = 0; i < 32; i++) {
Handle<JSObject> object = factory->NewJSObjectFromMap(map);
Handle<Smi> smi(Smi::FromInt(i), isolate);
- Runtime::WeakCollectionSet(weakmap, object, smi);
+ int32_t object_hash = Object::GetOrCreateHash(isolate, object)->value();
+ Runtime::WeakCollectionSet(weakmap, object, smi, object_hash);
}
}
@@ -193,7 +195,8 @@ TEST(Regress2060a) {
Handle<JSObject> object = factory->NewJSObject(function, TENURED);
CHECK(!heap->InNewSpace(object->address()));
CHECK(!first_page->Contains(object->address()));
- Runtime::WeakCollectionSet(weakmap, key, object);
+ int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
+ Runtime::WeakCollectionSet(weakmap, key, object, hash);
}
}
@@ -235,7 +238,8 @@ TEST(Regress2060b) {
Handle<JSWeakMap> weakmap = AllocateJSWeakMap(isolate);
for (int i = 0; i < 32; i++) {
Handle<Smi> smi(Smi::FromInt(i), isolate);
- Runtime::WeakCollectionSet(weakmap, keys[i], smi);
+ int32_t hash = Object::GetOrCreateHash(isolate, keys[i])->value();
+ Runtime::WeakCollectionSet(weakmap, keys[i], smi, hash);
}
// Force compacting garbage collection. The subsequent collections are used
diff --git a/deps/v8/test/cctest/test-weaksets.cc b/deps/v8/test/cctest/test-weaksets.cc
index dbb7311e83..3595af288f 100644
--- a/deps/v8/test/cctest/test-weaksets.cc
+++ b/deps/v8/test/cctest/test-weaksets.cc
@@ -34,7 +34,6 @@
using namespace v8::internal;
-
static Isolate* GetIsolateFrom(LocalContext* context) {
return reinterpret_cast<Isolate*>((*context)->GetIsolate());
}
@@ -90,7 +89,8 @@ TEST(WeakSet_Weakness) {
{
HandleScope scope(isolate);
Handle<Smi> smi(Smi::FromInt(23), isolate);
- Runtime::WeakCollectionSet(weakset, key, smi);
+ int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
+ Runtime::WeakCollectionSet(weakset, key, smi, hash);
}
CHECK_EQ(1, ObjectHashTable::cast(weakset->table())->NumberOfElements());
@@ -145,7 +145,8 @@ TEST(WeakSet_Shrinking) {
for (int i = 0; i < 32; i++) {
Handle<JSObject> object = factory->NewJSObjectFromMap(map);
Handle<Smi> smi(Smi::FromInt(i), isolate);
- Runtime::WeakCollectionSet(weakset, object, smi);
+ int32_t hash = Object::GetOrCreateHash(isolate, object)->value();
+ Runtime::WeakCollectionSet(weakset, object, smi, hash);
}
}
@@ -193,7 +194,8 @@ TEST(WeakSet_Regress2060a) {
Handle<JSObject> object = factory->NewJSObject(function, TENURED);
CHECK(!heap->InNewSpace(object->address()));
CHECK(!first_page->Contains(object->address()));
- Runtime::WeakCollectionSet(weakset, key, object);
+ int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
+ Runtime::WeakCollectionSet(weakset, key, object, hash);
}
}
@@ -235,7 +237,8 @@ TEST(WeakSet_Regress2060b) {
Handle<JSWeakSet> weakset = AllocateJSWeakSet(isolate);
for (int i = 0; i < 32; i++) {
Handle<Smi> smi(Smi::FromInt(i), isolate);
- Runtime::WeakCollectionSet(weakset, keys[i], smi);
+ int32_t hash = Object::GetOrCreateHash(isolate, keys[i])->value();
+ Runtime::WeakCollectionSet(weakset, keys[i], smi, hash);
}
// Force compacting garbage collection. The subsequent collections are used
diff --git a/deps/v8/test/cctest/trace-extension.cc b/deps/v8/test/cctest/trace-extension.cc
index a95532f931..e7f097f86f 100644
--- a/deps/v8/test/cctest/trace-extension.cc
+++ b/deps/v8/test/cctest/trace-extension.cc
@@ -151,4 +151,5 @@ void TraceExtension::JSEntrySPLevel2(
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/js-perf-test/Exceptions/run.js b/deps/v8/test/js-perf-test/Exceptions/run.js
new file mode 100644
index 0000000000..31153b5047
--- /dev/null
+++ b/deps/v8/test/js-perf-test/Exceptions/run.js
@@ -0,0 +1,26 @@
+// Copyright 2015 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.
+
+
+load('../base.js');
+load('try-catch.js');
+
+var success = true;
+
+function PrintResult(name, result) {
+ print(name + '-Exceptions(Score): ' + result);
+}
+
+
+function PrintError(name, error) {
+ PrintResult(name, error);
+ success = false;
+}
+
+
+BenchmarkSuite.config.doWarmup = undefined;
+BenchmarkSuite.config.doDeterministic = undefined;
+
+BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
+ NotifyError: PrintError });
diff --git a/deps/v8/test/js-perf-test/Exceptions/try-catch.js b/deps/v8/test/js-perf-test/Exceptions/try-catch.js
new file mode 100644
index 0000000000..0a4a0c0a64
--- /dev/null
+++ b/deps/v8/test/js-perf-test/Exceptions/try-catch.js
@@ -0,0 +1,110 @@
+// Copyright 2015 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.
+
+new BenchmarkSuite('Try-Catch', [1000], [
+ new Benchmark('OnSuccess', false, false, 0,
+ OnSuccess, OnSuccessSetup,
+ OnSuccessTearDown),
+ new Benchmark('OnException', false, false, 0,
+ OnException, OnExceptionSetup,
+ OnExceptionTearDown),
+ new Benchmark('OnSuccessFinallyOnly', false, false, 0,
+ OnSuccessFinallyOnly, OnSuccessFinallyOnlySetup,
+ OnSuccessFinallyOnlyTearDown),
+ new Benchmark('WithFinallyOnException', false, false, 0,
+ WithFinallyOnException, WithFinallyOnExceptionSetup,
+ WithFinallyOnExceptionTearDown)
+]);
+
+var a;
+var b;
+var c;
+
+// ----------------------------------------------------------------------------
+
+function OnSuccessSetup() {
+ a = 4;
+ b = 6;
+ c = 0;
+}
+
+function OnSuccess() {
+ try {
+ c = a + b;
+ }
+ catch (e) {
+ c++;
+ }
+}
+
+function OnSuccessTearDown() {
+ return c === 10;
+}
+
+// ----------------------------------------------------------------------------
+
+function OnExceptionSetup() {
+ a = 4;
+ b = 6;
+ c = 0;
+}
+
+function OnException() {
+ try {
+ throw 'Test exception';
+ }
+ catch (e) {
+ c = a + b;
+ }
+}
+
+function OnExceptionTearDown() {
+ return c === 10;
+}
+
+// ----------------------------------------------------------------------------
+
+function OnSuccessFinallyOnlySetup() {
+ a = 4;
+ b = 6;
+ c = 0;
+}
+
+function OnSuccessFinallyOnly() {
+ try {
+ c = a + b;
+ }
+ finally {
+ c++;
+ }
+}
+
+function OnSuccessFinallyOnlyTearDown() {
+ return c === 11;
+}
+
+// ----------------------------------------------------------------------------
+
+function WithFinallyOnExceptionSetup() {
+ a = 4;
+ b = 6;
+ c = 0;
+}
+
+function WithFinallyOnException() {
+ try {
+ throw 'Test exception';
+ }
+ catch (e) {
+ c = a + b;
+ }
+ finally {
+ c++;
+ }
+}
+
+function WithFinallyOnExceptionTearDown() {
+ return c === 11;
+}
+// ----------------------------------------------------------------------------
diff --git a/deps/v8/test/js-perf-test/JSTests.json b/deps/v8/test/js-perf-test/JSTests.json
index ce7e5bb320..bff5b6536f 100644
--- a/deps/v8/test/js-perf-test/JSTests.json
+++ b/deps/v8/test/js-perf-test/JSTests.json
@@ -3,6 +3,7 @@
"run_count": 5,
"run_count_android_arm": 3,
"run_count_android_arm64": 3,
+ "timeout": 120,
"units": "score",
"total": true,
"resources": ["base.js"],
@@ -27,7 +28,6 @@
"path": ["Classes"],
"main": "run.js",
"resources": ["super.js", "default-constructor.js"],
- "flags": ["--harmony-classes"],
"results_regexp": "^%s\\-Classes\\(Score\\): (.+)$",
"tests": [
{"name": "Super"},
@@ -105,6 +105,26 @@
"tests": [
{"name": "Assign"}
]
+ },
+ {
+ "name": "Scope",
+ "path": ["Scope"],
+ "main": "run.js",
+ "resources": ["with.js"],
+ "results_regexp": "^%s\\-Scope\\(Score\\): (.+)$",
+ "tests": [
+ {"name": "With"}
+ ]
+ },
+ {
+ "name": "Exceptions",
+ "path": ["Exceptions"],
+ "main": "run.js",
+ "resources": ["try-catch.js"],
+ "results_regexp": "^%s\\-Exceptions\\(Score\\): (.+)$",
+ "tests": [
+ {"name": "Try-Catch"}
+ ]
}
]
}
diff --git a/deps/v8/test/js-perf-test/Scope/run.js b/deps/v8/test/js-perf-test/Scope/run.js
new file mode 100644
index 0000000000..9ce00a15a5
--- /dev/null
+++ b/deps/v8/test/js-perf-test/Scope/run.js
@@ -0,0 +1,26 @@
+// Copyright 2015 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.
+
+
+load('../base.js');
+load('with.js');
+
+var success = true;
+
+function PrintResult(name, result) {
+ print(name + '-Scope(Score): ' + result);
+}
+
+
+function PrintError(name, error) {
+ PrintResult(name, error);
+ success = false;
+}
+
+
+BenchmarkSuite.config.doWarmup = undefined;
+BenchmarkSuite.config.doDeterministic = undefined;
+
+BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
+ NotifyError: PrintError });
diff --git a/deps/v8/test/js-perf-test/Scope/with.js b/deps/v8/test/js-perf-test/Scope/with.js
new file mode 100644
index 0000000000..8ec2d30cf0
--- /dev/null
+++ b/deps/v8/test/js-perf-test/Scope/with.js
@@ -0,0 +1,90 @@
+// Copyright 2015 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.
+
+new BenchmarkSuite( 'With', [1000], [
+ new Benchmark('AccessOnSameLevel', false, false, 0,
+ AccessOnSameLevel, AccessOnSameLevelSetup,
+ AccessOnSameLevelTearDown),
+ new Benchmark('SetOnSameLevel', false, false, 0,
+ SetOnSameLevel, SetOnSameLevelSetup,
+ SetOnSameLevelTearDown),
+ new Benchmark('AccessOverPrototypeChain', false, false, 0,
+ AccessOverPrototypeChainSetup, AccessOverPrototypeChainSetup,
+ AccessOverPrototypeChainTearDown),
+ new Benchmark('CompetingScope', false, false, 0,
+ CompetingScope, CompetingScopeSetup, CompetingScopeTearDown)
+]);
+
+var objectUnderTest;
+var objectUnderTestExtended;
+var resultStore;
+var VALUE_OF_PROPERTY = 'Simply a string';
+var SOME_OTHER_VALUE = 'Another value';
+
+// ----------------------------------------------------------------------------
+
+function AccessOnSameLevelSetup() {
+ objectUnderTest = {first: VALUE_OF_PROPERTY};
+}
+
+function AccessOnSameLevel() {
+ with (objectUnderTest) {
+ resultStore = first;
+ }
+}
+
+function AccessOnSameLevelTearDown() {
+ return objectUnderTest.first === resultStore;
+}
+
+// ----------------------------------------------------------------------------
+
+function AccessOverPrototypeChainSetup() {
+ objectUnderTest = {first: VALUE_OF_PROPERTY};
+ objectUnderTestExtended = Object.create(objectUnderTest);
+ objectUnderTestExtended.second = 'Another string';
+}
+
+function AccessOverPrototypeChain() {
+ with (objectUnderTestExtended) {
+ resultStore = first;
+ }
+}
+
+function AccessOverPrototypeChainTearDown() {
+ return objectUnderTest.first === resultStore;
+}
+
+// ----------------------------------------------------------------------------
+
+function CompetingScopeSetup() {
+ objectUnderTest = {first: VALUE_OF_PROPERTY};
+}
+
+function CompetingScope() {
+ var first = 'Not correct';
+ with (objectUnderTest) {
+ resultStore = first;
+ }
+}
+
+function CompetingScopeTearDown() {
+ return objectUnderTest.first === resultStore;
+}
+
+// ----------------------------------------------------------------------------
+
+function SetOnSameLevelSetup() {
+ objectUnderTest = {first: VALUE_OF_PROPERTY};
+}
+
+function SetOnSameLevel() {
+ with (objectUnderTest) {
+ first = SOME_OTHER_VALUE;
+ }
+}
+
+function SetOnSameLevelTearDown() {
+ return objectUnderTest.first === SOME_OTHER_VALUE;
+}
diff --git a/deps/v8/test/js-perf-test/base.js b/deps/v8/test/js-perf-test/base.js
index b0ce40b888..cef2867f2b 100644
--- a/deps/v8/test/js-perf-test/base.js
+++ b/deps/v8/test/js-perf-test/base.js
@@ -281,28 +281,28 @@ BenchmarkSuite.prototype.RunSingleBenchmark = function(benchmark, data) {
// by minIterations, depending on the config flag doDeterministic.
for (var i = 0; (doDeterministic ?
i<benchmark.deterministicIterations : elapsed < 1000); i++) {
- benchmark.run();
+ for (var j = 0; j < 100; j++) benchmark.run();
elapsed = new Date() - start;
}
if (data != null) {
- data.runs += i;
+ data.hectoruns += i;
data.elapsed += elapsed;
}
}
// Sets up data in order to skip or not the warmup phase.
if (!doWarmup && data == null) {
- data = { runs: 0, elapsed: 0 };
+ data = { hectoruns: 0, elapsed: 0 };
}
if (data == null) {
Measure(null);
- return { runs: 0, elapsed: 0 };
+ return { hectoruns: 0, elapsed: 0 };
} else {
Measure(data);
// If we've run too few iterations, we continue for another second.
- if (data.runs < benchmark.minIterations) return data;
- var usec = (data.elapsed * 1000) / data.runs;
+ if (data.hectoruns * 100 < benchmark.minIterations) return data;
+ var usec = (data.elapsed * 10) / data.hectoruns;
var rms = (benchmark.rmsResult != null) ? benchmark.rmsResult() : 0;
this.NotifyStep(new BenchmarkResult(benchmark, usec, rms));
return null;
diff --git a/deps/v8/test/message/arrow-bare-rest-param.js b/deps/v8/test/message/arrow-bare-rest-param.js
new file mode 100644
index 0000000000..9b3916d959
--- /dev/null
+++ b/deps/v8/test/message/arrow-bare-rest-param.js
@@ -0,0 +1,7 @@
+// Copyright 2015 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-rest-parameters --harmony-arrow-functions
+
+...x => 10
diff --git a/deps/v8/test/message/arrow-bare-rest-param.out b/deps/v8/test/message/arrow-bare-rest-param.out
new file mode 100644
index 0000000000..76a25a455d
--- /dev/null
+++ b/deps/v8/test/message/arrow-bare-rest-param.out
@@ -0,0 +1,4 @@
+*%(basename)s:7: SyntaxError: Unexpected token ...
+...x => 10
+^^^
+SyntaxError: Unexpected token ...
diff --git a/deps/v8/test/message/arrow-missing.js b/deps/v8/test/message/arrow-missing.js
new file mode 100644
index 0000000000..566345a460
--- /dev/null
+++ b/deps/v8/test/message/arrow-missing.js
@@ -0,0 +1,7 @@
+// Copyright 2015 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-rest-parameters --harmony-arrow-functions
+
+function foo() { return(); }
diff --git a/deps/v8/test/message/arrow-missing.out b/deps/v8/test/message/arrow-missing.out
new file mode 100644
index 0000000000..f042a20fad
--- /dev/null
+++ b/deps/v8/test/message/arrow-missing.out
@@ -0,0 +1,4 @@
+*%(basename)s:7: SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'
+function foo() { return(); }
+ ^
+SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'
diff --git a/deps/v8/test/message/arrow-param-after-rest-2.js b/deps/v8/test/message/arrow-param-after-rest-2.js
new file mode 100644
index 0000000000..3b42f19247
--- /dev/null
+++ b/deps/v8/test/message/arrow-param-after-rest-2.js
@@ -0,0 +1,7 @@
+// Copyright 2015 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-rest-parameters --harmony-arrow-functions
+
+(w, ...x, y) => 10
diff --git a/deps/v8/test/message/arrow-param-after-rest-2.out b/deps/v8/test/message/arrow-param-after-rest-2.out
new file mode 100644
index 0000000000..27785cfb02
--- /dev/null
+++ b/deps/v8/test/message/arrow-param-after-rest-2.out
@@ -0,0 +1,4 @@
+*%(basename)s:7: SyntaxError: Rest parameter must be last formal parameter
+(w, ...x, y) => 10
+ ^
+SyntaxError: Rest parameter must be last formal parameter
diff --git a/deps/v8/test/message/arrow-param-after-rest.js b/deps/v8/test/message/arrow-param-after-rest.js
new file mode 100644
index 0000000000..0fade6c31d
--- /dev/null
+++ b/deps/v8/test/message/arrow-param-after-rest.js
@@ -0,0 +1,7 @@
+// Copyright 2015 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-rest-parameters --harmony-arrow-functions
+
+(...x, y) => 10
diff --git a/deps/v8/test/message/arrow-param-after-rest.out b/deps/v8/test/message/arrow-param-after-rest.out
new file mode 100644
index 0000000000..5b36e43584
--- /dev/null
+++ b/deps/v8/test/message/arrow-param-after-rest.out
@@ -0,0 +1,4 @@
+*%(basename)s:7: SyntaxError: Rest parameter must be last formal parameter
+(...x, y) => 10
+ ^
+SyntaxError: Rest parameter must be last formal parameter
diff --git a/deps/v8/test/message/arrow-strict-eval-bare-parameter.js b/deps/v8/test/message/arrow-strict-eval-bare-parameter.js
new file mode 100644
index 0000000000..d5692517dd
--- /dev/null
+++ b/deps/v8/test/message/arrow-strict-eval-bare-parameter.js
@@ -0,0 +1,8 @@
+// Copyright 2015 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
+
+"use strict";
+eval => 42
diff --git a/deps/v8/test/message/arrow-strict-eval-bare-parameter.out b/deps/v8/test/message/arrow-strict-eval-bare-parameter.out
new file mode 100644
index 0000000000..0eb8f8841f
--- /dev/null
+++ b/deps/v8/test/message/arrow-strict-eval-bare-parameter.out
@@ -0,0 +1,4 @@
+*%(basename)s:8: SyntaxError: Unexpected eval or arguments in strict mode
+eval => 42
+^^^^
+SyntaxError: Unexpected eval or arguments in strict mode
diff --git a/deps/v8/test/message/arrow-two-rest-params.js b/deps/v8/test/message/arrow-two-rest-params.js
new file mode 100644
index 0000000000..345545ccdf
--- /dev/null
+++ b/deps/v8/test/message/arrow-two-rest-params.js
@@ -0,0 +1,7 @@
+// Copyright 2015 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-rest-parameters --harmony-arrow-functions
+
+(w, ...x, ...y) => 10
diff --git a/deps/v8/test/message/arrow-two-rest-params.out b/deps/v8/test/message/arrow-two-rest-params.out
new file mode 100644
index 0000000000..7147ebcf11
--- /dev/null
+++ b/deps/v8/test/message/arrow-two-rest-params.out
@@ -0,0 +1,4 @@
+*%(basename)s:7: SyntaxError: Rest parameter must be last formal parameter
+(w, ...x, ...y) => 10
+ ^
+SyntaxError: Rest parameter must be last formal parameter
diff --git a/deps/v8/test/message/class-constructor-accessor.js b/deps/v8/test/message/class-constructor-accessor.js
index edc3c13169..fcc9868b14 100644
--- a/deps/v8/test/message/class-constructor-accessor.js
+++ b/deps/v8/test/message/class-constructor-accessor.js
@@ -1,8 +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: --harmony-classes
+
+
'use strict';
class C {
diff --git a/deps/v8/test/message/class-constructor-generator.js b/deps/v8/test/message/class-constructor-generator.js
index 5d370f865e..a9a0ef862d 100644
--- a/deps/v8/test/message/class-constructor-generator.js
+++ b/deps/v8/test/message/class-constructor-generator.js
@@ -1,8 +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: --harmony-classes
+
+
'use strict';
class C {
diff --git a/deps/v8/test/message/destructuring-modify-const.js b/deps/v8/test/message/destructuring-modify-const.js
new file mode 100644
index 0000000000..cabd924b37
--- /dev/null
+++ b/deps/v8/test/message/destructuring-modify-const.js
@@ -0,0 +1,9 @@
+// Copyright 2015 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-destructuring
+'use strict';
+
+const { x : x, y : y } = { x : 1, y : 2 };
+x++;
diff --git a/deps/v8/test/message/destructuring-modify-const.out b/deps/v8/test/message/destructuring-modify-const.out
new file mode 100644
index 0000000000..19bffa6d3d
--- /dev/null
+++ b/deps/v8/test/message/destructuring-modify-const.out
@@ -0,0 +1,5 @@
+*%(basename)s:9: TypeError: Assignment to constant variable.
+x++;
+ ^
+TypeError: Assignment to constant variable.
+ at *%(basename)s:9:2
diff --git a/deps/v8/test/message/invalid-spread-2.js b/deps/v8/test/message/invalid-spread-2.js
new file mode 100644
index 0000000000..67e0f7d7c0
--- /dev/null
+++ b/deps/v8/test/message/invalid-spread-2.js
@@ -0,0 +1,7 @@
+// Copyright 2015 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-rest-parameters --harmony-arrow-functions
+
+(x, ...y, z)
diff --git a/deps/v8/test/message/invalid-spread-2.out b/deps/v8/test/message/invalid-spread-2.out
new file mode 100644
index 0000000000..287390a74a
--- /dev/null
+++ b/deps/v8/test/message/invalid-spread-2.out
@@ -0,0 +1,4 @@
+*%(basename)s:7: SyntaxError: Unexpected token ...
+(x, ...y, z)
+ ^^^
+SyntaxError: Unexpected token ...
diff --git a/deps/v8/test/message/invalid-spread.js b/deps/v8/test/message/invalid-spread.js
new file mode 100644
index 0000000000..e58334e993
--- /dev/null
+++ b/deps/v8/test/message/invalid-spread.js
@@ -0,0 +1,7 @@
+// Copyright 2015 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-rest-parameters --harmony-arrow-functions
+
+(x, ...y)
diff --git a/deps/v8/test/message/invalid-spread.out b/deps/v8/test/message/invalid-spread.out
new file mode 100644
index 0000000000..5694ad6e88
--- /dev/null
+++ b/deps/v8/test/message/invalid-spread.out
@@ -0,0 +1,4 @@
+*%(basename)s:7: SyntaxError: Unexpected token ...
+(x, ...y)
+ ^^^
+SyntaxError: Unexpected token ...
diff --git a/deps/v8/test/message/message.status b/deps/v8/test/message/message.status
index f28aa2a8d3..234bf0f35c 100644
--- a/deps/v8/test/message/message.status
+++ b/deps/v8/test/message/message.status
@@ -30,11 +30,4 @@
# All tests in the bug directory are expected to fail.
'bugs/*': [FAIL],
}], # ALWAYS
-
-##############################################################################
-['arch == x87', {
-
- # Crankshaft compiler did not generate required source position for it:
- 'overwritten-builtins': [SKIP],
-}], # 'arch == x87'
]
diff --git a/deps/v8/test/message/no-legacy-const-2.js b/deps/v8/test/message/no-legacy-const-2.js
new file mode 100644
index 0000000000..29aeba5e1f
--- /dev/null
+++ b/deps/v8/test/message/no-legacy-const-2.js
@@ -0,0 +1,7 @@
+// Copyright 2015 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: --no-legacy-const
+
+const = 42;
diff --git a/deps/v8/test/message/no-legacy-const-2.out b/deps/v8/test/message/no-legacy-const-2.out
new file mode 100644
index 0000000000..55c855ee4f
--- /dev/null
+++ b/deps/v8/test/message/no-legacy-const-2.out
@@ -0,0 +1,5 @@
+*%(basename)s:7: SyntaxError: Unexpected token const
+const = 42;
+^^^^^
+
+SyntaxError: Unexpected token const
diff --git a/deps/v8/test/message/no-legacy-const-3.js b/deps/v8/test/message/no-legacy-const-3.js
new file mode 100644
index 0000000000..6981571e62
--- /dev/null
+++ b/deps/v8/test/message/no-legacy-const-3.js
@@ -0,0 +1,7 @@
+// Copyright 2015 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: --no-legacy-const
+
+const
diff --git a/deps/v8/test/message/no-legacy-const-3.out b/deps/v8/test/message/no-legacy-const-3.out
new file mode 100644
index 0000000000..046e9f7023
--- /dev/null
+++ b/deps/v8/test/message/no-legacy-const-3.out
@@ -0,0 +1,5 @@
+*%(basename)s:7: SyntaxError: Unexpected token const
+const
+^^^^^
+
+SyntaxError: Unexpected token const
diff --git a/deps/v8/test/message/no-legacy-const.js b/deps/v8/test/message/no-legacy-const.js
new file mode 100644
index 0000000000..ecad2181b8
--- /dev/null
+++ b/deps/v8/test/message/no-legacy-const.js
@@ -0,0 +1,7 @@
+// Copyright 2015 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: --no-legacy-const
+
+const x = 42;
diff --git a/deps/v8/test/message/no-legacy-const.out b/deps/v8/test/message/no-legacy-const.out
new file mode 100644
index 0000000000..b28dd10b77
--- /dev/null
+++ b/deps/v8/test/message/no-legacy-const.out
@@ -0,0 +1,5 @@
+*%(basename)s:7: SyntaxError: Unexpected token const
+const x = 42;
+^^^^^
+
+SyntaxError: Unexpected token const
diff --git a/deps/v8/test/message/rest-param-class-setter-strict.js b/deps/v8/test/message/rest-param-class-setter-strict.js
new file mode 100644
index 0000000000..2d478a6644
--- /dev/null
+++ b/deps/v8/test/message/rest-param-class-setter-strict.js
@@ -0,0 +1,12 @@
+// Copyright 2015 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-rest-parameters
+'use strict';
+
+var _bad = "setting this should fail!";
+class C {
+ get bad() { return _bad; }
+ set bad(...args) { _bad = args[0]; }
+}
diff --git a/deps/v8/test/message/rest-param-class-setter-strict.out b/deps/v8/test/message/rest-param-class-setter-strict.out
new file mode 100644
index 0000000000..3296a0f2c8
--- /dev/null
+++ b/deps/v8/test/message/rest-param-class-setter-strict.out
@@ -0,0 +1,4 @@
+*%(basename)s:11: SyntaxError: Setter function argument must not be a rest parameter
+ set bad(...args) { _bad = args[0]; }
+ ^^^^^^^^^
+SyntaxError: Setter function argument must not be a rest parameter
diff --git a/deps/v8/test/message/rest-param-object-setter-sloppy.js b/deps/v8/test/message/rest-param-object-setter-sloppy.js
new file mode 100644
index 0000000000..08c03298dc
--- /dev/null
+++ b/deps/v8/test/message/rest-param-object-setter-sloppy.js
@@ -0,0 +1,11 @@
+// Copyright 2015 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-rest-parameters
+
+var _bad = "this should fail!";
+({
+ get bad() { return _bad; },
+ set bad(...args) { _bad = args[0]; }
+});
diff --git a/deps/v8/test/message/rest-param-object-setter-sloppy.out b/deps/v8/test/message/rest-param-object-setter-sloppy.out
new file mode 100644
index 0000000000..9400a2a9ce
--- /dev/null
+++ b/deps/v8/test/message/rest-param-object-setter-sloppy.out
@@ -0,0 +1,4 @@
+*%(basename)s:10: SyntaxError: Setter function argument must not be a rest parameter
+ set bad(...args) { _bad = args[0]; }
+ ^^^^^^^^^
+SyntaxError: Setter function argument must not be a rest parameter
diff --git a/deps/v8/test/message/rest-param-object-setter-strict.js b/deps/v8/test/message/rest-param-object-setter-strict.js
new file mode 100644
index 0000000000..e3a8f604e6
--- /dev/null
+++ b/deps/v8/test/message/rest-param-object-setter-strict.js
@@ -0,0 +1,12 @@
+// Copyright 2015 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-rest-parameters
+'use strict';
+
+var _bad = "this should fail!";
+({
+ get bad() { return _bad; },
+ set bad(...args) { _bad = args[0]; }
+});
diff --git a/deps/v8/test/message/rest-param-object-setter-strict.out b/deps/v8/test/message/rest-param-object-setter-strict.out
new file mode 100644
index 0000000000..3296a0f2c8
--- /dev/null
+++ b/deps/v8/test/message/rest-param-object-setter-strict.out
@@ -0,0 +1,4 @@
+*%(basename)s:11: SyntaxError: Setter function argument must not be a rest parameter
+ set bad(...args) { _bad = args[0]; }
+ ^^^^^^^^^
+SyntaxError: Setter function argument must not be a rest parameter
diff --git a/deps/v8/test/message/strong-object-freeze-prop.js b/deps/v8/test/message/strong-object-freeze-prop.js
new file mode 100644
index 0000000000..17250158d5
--- /dev/null
+++ b/deps/v8/test/message/strong-object-freeze-prop.js
@@ -0,0 +1,11 @@
+// Copyright 2015 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: --strong-mode
+
+"use strong";
+
+let o = {};
+Object.defineProperty(o, "foo", { writable: true });
+Object.defineProperty(o, "foo", { writable: false });
diff --git a/deps/v8/test/message/strong-object-freeze-prop.out b/deps/v8/test/message/strong-object-freeze-prop.out
new file mode 100644
index 0000000000..0c611c5928
--- /dev/null
+++ b/deps/v8/test/message/strong-object-freeze-prop.out
@@ -0,0 +1,9 @@
+# Copyright 2015 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.
+*%(basename)s:11: TypeError: On strong object #<Object>, redefining writable, non-configurable property 'foo' to be non-writable is deprecated
+Object.defineProperty(o, "foo", { writable: false });
+ ^
+TypeError: On strong object #<Object>, redefining writable, non-configurable property 'foo' to be non-writable is deprecated
+ at Function.defineProperty (native)
+ at *%(basename)s:11:8
diff --git a/deps/v8/test/message/strong-object-set-proto.js b/deps/v8/test/message/strong-object-set-proto.js
new file mode 100644
index 0000000000..890dd84d72
--- /dev/null
+++ b/deps/v8/test/message/strong-object-set-proto.js
@@ -0,0 +1,9 @@
+// Copyright 2015 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: --strong-mode
+
+"use strong";
+
+({}).__proto__ = {};
diff --git a/deps/v8/test/message/strong-object-set-proto.out b/deps/v8/test/message/strong-object-set-proto.out
new file mode 100644
index 0000000000..bf2c9334f7
--- /dev/null
+++ b/deps/v8/test/message/strong-object-set-proto.out
@@ -0,0 +1,9 @@
+# Copyright 2015 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.
+*%(basename)s:9: TypeError: On strong object #<Object>, redefining the internal prototype is deprecated
+({}).__proto__ = {};
+ ^
+TypeError: On strong object #<Object>, redefining the internal prototype is deprecated
+ at Object.set __proto__ (native)
+ at *%(basename)s:9:16
diff --git a/deps/v8/test/message/super-constructor-extra-statement.js b/deps/v8/test/message/super-constructor-extra-statement.js
index e8ffe2dbfa..541bddbde1 100644
--- a/deps/v8/test/message/super-constructor-extra-statement.js
+++ b/deps/v8/test/message/super-constructor-extra-statement.js
@@ -1,8 +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: --harmony-classes
+
+
'use strict';
class C {
diff --git a/deps/v8/test/message/super-constructor.js b/deps/v8/test/message/super-constructor.js
index 430dc58ce7..93ca61844a 100644
--- a/deps/v8/test/message/super-constructor.js
+++ b/deps/v8/test/message/super-constructor.js
@@ -1,8 +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: --harmony-classes
+
+
'use strict';
class C {
diff --git a/deps/v8/test/message/super-in-function.js b/deps/v8/test/message/super-in-function.js
index edaa0e4ead..f2e2342c31 100644
--- a/deps/v8/test/message/super-in-function.js
+++ b/deps/v8/test/message/super-in-function.js
@@ -1,8 +1,8 @@
// Copyright 2015 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-classes
+
+
'use strict';
function f() {
diff --git a/deps/v8/test/mjsunit/arguments.js b/deps/v8/test/mjsunit/arguments.js
index 56c1d7224d..26eb38912a 100644
--- a/deps/v8/test/mjsunit/arguments.js
+++ b/deps/v8/test/mjsunit/arguments.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 argc0() {
return arguments.length;
}
@@ -188,3 +190,17 @@ function arg_set(x) { return (arguments[x] = 117); }
assertEquals(undefined, arg_get(0xFFFFFFFF));
assertEquals(true, arg_del(0xFFFFFFFF));
assertEquals(117, arg_set(0xFFFFFFFF));
+
+(function() {
+ function f(a) { return arguments; }
+ var a = f(1,2,3);
+ // Turn arguments into slow.
+ assertTrue(%HasSloppyArgumentsElements(a));
+ a[10000] = 1;
+ assertTrue(%HasSloppyArgumentsElements(a));
+ // Make it fast again by adding values.
+ for (var i = 0; i < 1000; i++) {
+ a[i] = 1.5;
+ }
+ assertTrue(%HasSloppyArgumentsElements(a));
+})();
diff --git a/deps/v8/test/mjsunit/array-length.js b/deps/v8/test/mjsunit/array-length.js
index 16867db733..c2b325061b 100644
--- a/deps/v8/test/mjsunit/array-length.js
+++ b/deps/v8/test/mjsunit/array-length.js
@@ -105,6 +105,13 @@ var a = new Array();
assertEquals(Object(12), a.length = new Number(12));
assertEquals(12, a.length);
+Number.prototype.valueOf = function() { return 10; }
+var n = new Number(100);
+assertEquals(n, a.length = n);
+assertEquals(10, a.length);
+n.valueOf = function() { return 20; }
+assertEquals(n, a.length = n);
+assertEquals(20, a.length);
var o = { length: -23 };
Array.prototype.pop.apply(o);
@@ -119,3 +126,9 @@ for (var i = 0; i < 7; i++) {
t = a.length = 7;
assertEquals(7, t);
}
+
+(function () {
+ "use strict";
+ var frozen_object = Object.freeze({__proto__:[]});
+ assertThrows(function () { frozen_object.length = 10 });
+})();
diff --git a/deps/v8/test/mjsunit/array-sort.js b/deps/v8/test/mjsunit/array-sort.js
index 62755426ad..36608f5e14 100644
--- a/deps/v8/test/mjsunit/array-sort.js
+++ b/deps/v8/test/mjsunit/array-sort.js
@@ -445,6 +445,22 @@ function TestSortDoesNotDependOnArrayPrototypeSort() {
fail('Should not call sort');
};
sortfn.call(arr);
+ // Restore for the next test
+ Array.prototype.sort = sortfn;
}
TestSortDoesNotDependOnArrayPrototypeSort();
+
+function TestSortToObject() {
+ Number.prototype[0] = 5;
+ Number.prototype[1] = 4;
+ Number.prototype.length = 2;
+ x = new Number(0);
+ assertEquals(0, Number(Array.prototype.sort.call(x)));
+ assertEquals(4, x[0]);
+ assertEquals(5, x[1]);
+ assertArrayEquals(["0", "1"], Object.getOwnPropertyNames(x));
+ // The following would throw if ToObject weren't called.
+ assertEquals(0, Number(Array.prototype.sort.call(0)));
+}
+TestSortToObject();
diff --git a/deps/v8/test/mjsunit/asm/atomics-add.js b/deps/v8/test/mjsunit/asm/atomics-add.js
new file mode 100644
index 0000000000..69400c8059
--- /dev/null
+++ b/deps/v8/test/mjsunit/asm/atomics-add.js
@@ -0,0 +1,93 @@
+// Copyright 2015 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-atomics --harmony-sharedarraybuffer
+
+function Module(stdlib, foreign, heap) {
+ "use asm";
+ var MEM8 = new stdlib.Int8Array(heap);
+ var MEM16 = new stdlib.Int16Array(heap);
+ var MEM32 = new stdlib.Int32Array(heap);
+ var MEMU8 = new stdlib.Uint8Array(heap);
+ var MEMU16 = new stdlib.Uint16Array(heap);
+ var MEMU32 = new stdlib.Uint32Array(heap);
+ var add = stdlib.Atomics.add;
+ var fround = stdlib.Math.fround;
+
+ function addi8(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return add(MEM8, i, x)|0;
+ }
+
+ function addi16(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return add(MEM16, i, x)|0;
+ }
+
+ function addi32(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return add(MEM32, i, x)|0;
+ }
+
+ function addu8(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return add(MEMU8, i, x)>>>0;
+ }
+
+ function addu16(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return add(MEMU16, i, x)>>>0;
+ }
+
+ function addu32(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return add(MEMU32, i, x)>>>0;
+ }
+
+ return {
+ addi8: addi8,
+ addi16: addi16,
+ addi32: addi32,
+ addu8: addu8,
+ addu16: addu16,
+ addu32: addu32,
+ };
+}
+
+var sab = new SharedArrayBuffer(16);
+var m = Module(this, {}, sab);
+
+function clearArray() {
+ var ui8 = new Uint8Array(sab);
+ for (var i = 0; i < sab.byteLength; ++i) {
+ ui8[i] = 0;
+ }
+}
+
+function testElementType(taConstr, f) {
+ clearArray();
+
+ var ta = new taConstr(sab);
+ var name = Object.prototype.toString.call(ta);
+ assertEquals(0, f(0, 10), name);
+ assertEquals(10, ta[0]);
+ assertEquals(10, f(0, 10), name);
+ assertEquals(20, ta[0]);
+ // out of bounds
+ assertEquals(0, f(-1, 0), name);
+ assertEquals(0, f(ta.length, 0), name);
+}
+
+testElementType(Int8Array, m.addi8);
+testElementType(Int16Array, m.addi16);
+testElementType(Int32Array, m.addi32);
+testElementType(Uint8Array, m.addu8);
+testElementType(Uint16Array, m.addu16);
+testElementType(Uint32Array, m.addu32);
diff --git a/deps/v8/test/mjsunit/asm/atomics-and.js b/deps/v8/test/mjsunit/asm/atomics-and.js
new file mode 100644
index 0000000000..e60f1f6a13
--- /dev/null
+++ b/deps/v8/test/mjsunit/asm/atomics-and.js
@@ -0,0 +1,94 @@
+// Copyright 2015 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-atomics --harmony-sharedarraybuffer
+
+function Module(stdlib, foreign, heap) {
+ "use asm";
+ var MEM8 = new stdlib.Int8Array(heap);
+ var MEM16 = new stdlib.Int16Array(heap);
+ var MEM32 = new stdlib.Int32Array(heap);
+ var MEMU8 = new stdlib.Uint8Array(heap);
+ var MEMU16 = new stdlib.Uint16Array(heap);
+ var MEMU32 = new stdlib.Uint32Array(heap);
+ var and = stdlib.Atomics.and;
+ var fround = stdlib.Math.fround;
+
+ function andi8(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return and(MEM8, i, x)|0;
+ }
+
+ function andi16(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return and(MEM16, i, x)|0;
+ }
+
+ function andi32(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return and(MEM32, i, x)|0;
+ }
+
+ function andu8(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return and(MEMU8, i, x)>>>0;
+ }
+
+ function andu16(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return and(MEMU16, i, x)>>>0;
+ }
+
+ function andu32(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return and(MEMU32, i, x)>>>0;
+ }
+
+ return {
+ andi8: andi8,
+ andi16: andi16,
+ andi32: andi32,
+ andu8: andu8,
+ andu16: andu16,
+ andu32: andu32,
+ };
+}
+
+var sab = new SharedArrayBuffer(16);
+var m = Module(this, {}, sab);
+
+function clearArray() {
+ var ui8 = new Uint8Array(sab);
+ for (var i = 0; i < sab.byteLength; ++i) {
+ ui8[i] = 0;
+ }
+}
+
+function testElementType(taConstr, f) {
+ clearArray();
+
+ var ta = new taConstr(sab);
+ var name = Object.prototype.toString.call(ta);
+ ta[0] = 0x7f;
+ assertEquals(0x7f, f(0, 0xf), name);
+ assertEquals(0xf, ta[0]);
+ assertEquals(0xf, f(0, 0x19), name);
+ assertEquals(0x9, ta[0]);
+ // out of bounds
+ assertEquals(0, f(-1, 0), name);
+ assertEquals(0, f(ta.length, 0), name);
+}
+
+testElementType(Int8Array, m.andi8);
+testElementType(Int16Array, m.andi16);
+testElementType(Int32Array, m.andi32);
+testElementType(Uint8Array, m.andu8);
+testElementType(Uint16Array, m.andu16);
+testElementType(Uint32Array, m.andu32);
diff --git a/deps/v8/test/mjsunit/asm/atomics-compareexchange.js b/deps/v8/test/mjsunit/asm/atomics-compareexchange.js
new file mode 100644
index 0000000000..208a06043c
--- /dev/null
+++ b/deps/v8/test/mjsunit/asm/atomics-compareexchange.js
@@ -0,0 +1,121 @@
+// Copyright 2015 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-atomics --harmony-sharedarraybuffer
+
+function Module(stdlib, foreign, heap) {
+ "use asm";
+ var MEM8 = new stdlib.Int8Array(heap);
+ var MEM16 = new stdlib.Int16Array(heap);
+ var MEM32 = new stdlib.Int32Array(heap);
+ var MEMU8 = new stdlib.Uint8Array(heap);
+ var MEMU16 = new stdlib.Uint16Array(heap);
+ var MEMU32 = new stdlib.Uint32Array(heap);
+ var MEMF32 = new stdlib.Float32Array(heap);
+ var MEMF64 = new stdlib.Float64Array(heap);
+ var compareExchange = stdlib.Atomics.compareExchange;
+ var fround = stdlib.Math.fround;
+
+ function compareExchangei8(i, o, n) {
+ i = i | 0;
+ o = o | 0;
+ n = n | 0;
+ return compareExchange(MEM8, i, o, n)|0;
+ }
+
+ function compareExchangei16(i, o, n) {
+ i = i | 0;
+ o = o | 0;
+ n = n | 0;
+ return compareExchange(MEM16, i, o, n)|0;
+ }
+
+ function compareExchangei32(i, o, n) {
+ i = i | 0;
+ o = o | 0;
+ n = n | 0;
+ return compareExchange(MEM32, i, o, n)|0;
+ }
+
+ function compareExchangeu8(i, o, n) {
+ i = i | 0;
+ o = o >>> 0;
+ n = n >>> 0;
+ return compareExchange(MEMU8, i, o, n)>>>0;
+ }
+
+ function compareExchangeu16(i, o, n) {
+ i = i | 0;
+ o = o >>> 0;
+ n = n >>> 0;
+ return compareExchange(MEMU16, i, o, n)>>>0;
+ }
+
+ function compareExchangeu32(i, o, n) {
+ i = i | 0;
+ o = o >>> 0;
+ n = n >>> 0;
+ return compareExchange(MEMU32, i, o, n)>>>0;
+ }
+
+ function compareExchangef32(i, o, n) {
+ i = i | 0;
+ o = fround(o);
+ n = fround(n);
+ return fround(compareExchange(MEMF32, i, o, n));
+ }
+
+ function compareExchangef64(i, o, n) {
+ i = i | 0;
+ o = +o;
+ n = +n;
+ return +compareExchange(MEMF64, i, o, n);
+ }
+
+ return {
+ compareExchangei8: compareExchangei8,
+ compareExchangei16: compareExchangei16,
+ compareExchangei32: compareExchangei32,
+ compareExchangeu8: compareExchangeu8,
+ compareExchangeu16: compareExchangeu16,
+ compareExchangeu32: compareExchangeu32,
+ compareExchangef32: compareExchangef32,
+ compareExchangef64: compareExchangef64
+ };
+}
+
+var sab = new SharedArrayBuffer(16);
+var m = Module(this, {}, sab);
+
+function clearArray() {
+ var ui8 = new Uint8Array(sab);
+ for (var i = 0; i < sab.byteLength; ++i) {
+ ui8[i] = 0;
+ }
+}
+
+function testElementType(taConstr, f, oobValue) {
+ clearArray();
+
+ var ta = new taConstr(sab);
+ var name = Object.prototype.toString.call(ta);
+ assertEquals(0, ta[0]);
+ assertEquals(0, f(0, 0, 50), name);
+ assertEquals(50, ta[0]);
+ // Value is not equal to 0, so compareExchange won't store 100
+ assertEquals(50, f(0, 0, 100), name);
+ assertEquals(50, ta[0]);
+ // out of bounds
+ assertEquals(oobValue, f(-1, 0, 0), name);
+ assertEquals(oobValue, f(ta.length, 0, 0), name);
+}
+
+testElementType(Int8Array, m.compareExchangei8, 0);
+testElementType(Int16Array, m.compareExchangei16, 0);
+testElementType(Int32Array, m.compareExchangei32, 0);
+testElementType(Uint8Array, m.compareExchangeu8, 0);
+testElementType(Uint16Array, m.compareExchangeu16, 0);
+testElementType(Uint32Array, m.compareExchangeu32, 0);
+testElementType(Float32Array, m.compareExchangef32, NaN);
+testElementType(Float64Array, m.compareExchangef64, NaN);
diff --git a/deps/v8/test/mjsunit/asm/atomics-exchange.js b/deps/v8/test/mjsunit/asm/atomics-exchange.js
new file mode 100644
index 0000000000..bb70322c7e
--- /dev/null
+++ b/deps/v8/test/mjsunit/asm/atomics-exchange.js
@@ -0,0 +1,92 @@
+// Copyright 2015 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-atomics --harmony-sharedarraybuffer
+
+function Module(stdlib, foreign, heap) {
+ "use asm";
+ var MEM8 = new stdlib.Int8Array(heap);
+ var MEM16 = new stdlib.Int16Array(heap);
+ var MEM32 = new stdlib.Int32Array(heap);
+ var MEMU8 = new stdlib.Uint8Array(heap);
+ var MEMU16 = new stdlib.Uint16Array(heap);
+ var MEMU32 = new stdlib.Uint32Array(heap);
+ var exchange = stdlib.Atomics.exchange;
+ var fround = stdlib.Math.fround;
+
+ function exchangei8(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return exchange(MEM8, i, x)|0;
+ }
+
+ function exchangei16(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return exchange(MEM16, i, x)|0;
+ }
+
+ function exchangei32(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return exchange(MEM32, i, x)|0;
+ }
+
+ function exchangeu8(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return exchange(MEMU8, i, x)>>>0;
+ }
+
+ function exchangeu16(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return exchange(MEMU16, i, x)>>>0;
+ }
+
+ function exchangeu32(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return exchange(MEMU32, i, x)>>>0;
+ }
+
+ return {
+ exchangei8: exchangei8,
+ exchangei16: exchangei16,
+ exchangei32: exchangei32,
+ exchangeu8: exchangeu8,
+ exchangeu16: exchangeu16,
+ exchangeu32: exchangeu32,
+ };
+}
+
+var sab = new SharedArrayBuffer(16);
+var m = Module(this, {}, sab);
+
+function clearArray() {
+ var ui8 = new Uint8Array(sab);
+ for (var i = 0; i < sab.byteLength; ++i) {
+ ui8[i] = 0;
+ }
+}
+
+function testElementType(taConstr, f) {
+ clearArray();
+
+ var ta = new taConstr(sab);
+ var name = Object.prototype.toString.call(ta);
+ ta[0] = 0x7f;
+ assertEquals(0x7f, f(0, 0xf), name);
+ assertEquals(0xf, ta[0]);
+ // out of bounds
+ assertEquals(0, f(-1, 0), name);
+ assertEquals(0, f(ta.length, 0), name);
+}
+
+testElementType(Int8Array, m.exchangei8);
+testElementType(Int16Array, m.exchangei16);
+testElementType(Int32Array, m.exchangei32);
+testElementType(Uint8Array, m.exchangeu8);
+testElementType(Uint16Array, m.exchangeu16);
+testElementType(Uint32Array, m.exchangeu32);
diff --git a/deps/v8/test/mjsunit/asm/atomics-load.js b/deps/v8/test/mjsunit/asm/atomics-load.js
new file mode 100644
index 0000000000..769fb40e2c
--- /dev/null
+++ b/deps/v8/test/mjsunit/asm/atomics-load.js
@@ -0,0 +1,102 @@
+// Copyright 2015 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-atomics --harmony-sharedarraybuffer
+
+function Module(stdlib, foreign, heap) {
+ "use asm";
+ var MEM8 = new stdlib.Int8Array(heap);
+ var MEM16 = new stdlib.Int16Array(heap);
+ var MEM32 = new stdlib.Int32Array(heap);
+ var MEMU8 = new stdlib.Uint8Array(heap);
+ var MEMU16 = new stdlib.Uint16Array(heap);
+ var MEMU32 = new stdlib.Uint32Array(heap);
+ var MEMF32 = new stdlib.Float32Array(heap);
+ var MEMF64 = new stdlib.Float64Array(heap);
+ var load = stdlib.Atomics.load;
+ var fround = stdlib.Math.fround;
+
+ function loadi8(i) {
+ i = i | 0;
+ return load(MEM8, i)|0;
+ }
+
+ function loadi16(i) {
+ i = i | 0;
+ return load(MEM16, i)|0;
+ }
+
+ function loadi32(i) {
+ i = i | 0;
+ return load(MEM32, i)|0;
+ }
+
+ function loadu8(i) {
+ i = i | 0;
+ return load(MEMU8, i)>>>0;
+ }
+
+ function loadu16(i) {
+ i = i | 0;
+ return load(MEMU16, i)>>>0;
+ }
+
+ function loadu32(i) {
+ i = i | 0;
+ return load(MEMU32, i)>>>0;
+ }
+
+ function loadf32(i) {
+ i = i | 0;
+ return fround(load(MEMF32, i));
+ }
+
+ function loadf64(i) {
+ i = i | 0;
+ return +load(MEMF64, i);
+ }
+
+ return {
+ loadi8: loadi8,
+ loadi16: loadi16,
+ loadi32: loadi32,
+ loadu8: loadu8,
+ loadu16: loadu16,
+ loadu32: loadu32,
+ loadf32: loadf32,
+ loadf64: loadf64
+ };
+}
+
+var sab = new SharedArrayBuffer(16);
+var m = Module(this, {}, sab);
+
+function clearArray() {
+ var ui8 = new Uint8Array(sab);
+ for (var i = 0; i < sab.byteLength; ++i) {
+ ui8[i] = 0;
+ }
+}
+
+function testElementType(taConstr, f, oobValue) {
+ clearArray();
+
+ var ta = new taConstr(sab);
+ var name = Object.prototype.toString.call(ta);
+ ta[0] = 10;
+ assertEquals(10, f(0), name);
+ assertEquals(0, f(1), name);
+ // out of bounds
+ assertEquals(oobValue, f(-1), name);
+ assertEquals(oobValue, f(ta.length), name);
+}
+
+testElementType(Int8Array, m.loadi8, 0);
+testElementType(Int16Array, m.loadi16, 0);
+testElementType(Int32Array, m.loadi32, 0);
+testElementType(Uint8Array, m.loadu8, 0);
+testElementType(Uint16Array, m.loadu16, 0);
+testElementType(Uint32Array, m.loadu32, 0);
+testElementType(Float32Array, m.loadf32, NaN);
+testElementType(Float64Array, m.loadf64, NaN);
diff --git a/deps/v8/test/mjsunit/asm/atomics-or.js b/deps/v8/test/mjsunit/asm/atomics-or.js
new file mode 100644
index 0000000000..df87d24d74
--- /dev/null
+++ b/deps/v8/test/mjsunit/asm/atomics-or.js
@@ -0,0 +1,93 @@
+// Copyright 2015 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-atomics --harmony-sharedarraybuffer
+
+function Module(stdlib, foreign, heap) {
+ "use asm";
+ var MEM8 = new stdlib.Int8Array(heap);
+ var MEM16 = new stdlib.Int16Array(heap);
+ var MEM32 = new stdlib.Int32Array(heap);
+ var MEMU8 = new stdlib.Uint8Array(heap);
+ var MEMU16 = new stdlib.Uint16Array(heap);
+ var MEMU32 = new stdlib.Uint32Array(heap);
+ var or = stdlib.Atomics.or;
+ var fround = stdlib.Math.fround;
+
+ function ori8(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return or(MEM8, i, x)|0;
+ }
+
+ function ori16(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return or(MEM16, i, x)|0;
+ }
+
+ function ori32(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return or(MEM32, i, x)|0;
+ }
+
+ function oru8(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return or(MEMU8, i, x)>>>0;
+ }
+
+ function oru16(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return or(MEMU16, i, x)>>>0;
+ }
+
+ function oru32(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return or(MEMU32, i, x)>>>0;
+ }
+
+ return {
+ ori8: ori8,
+ ori16: ori16,
+ ori32: ori32,
+ oru8: oru8,
+ oru16: oru16,
+ oru32: oru32,
+ };
+}
+
+var sab = new SharedArrayBuffer(16);
+var m = Module(this, {}, sab);
+
+function clearArray() {
+ var ui8 = new Uint8Array(sab);
+ for (var i = 0; i < sab.byteLength; ++i) {
+ ui8[i] = 0;
+ }
+}
+
+function testElementType(taConstr, f) {
+ clearArray();
+
+ var ta = new taConstr(sab);
+ var name = Object.prototype.toString.call(ta);
+ assertEquals(0, f(0, 0xf), name);
+ assertEquals(0xf, ta[0]);
+ assertEquals(0xf, f(0, 0x11), name);
+ assertEquals(0x1f, ta[0]);
+ // out of bounds
+ assertEquals(0, f(-1, 0), name);
+ assertEquals(0, f(ta.length, 0), name);
+}
+
+testElementType(Int8Array, m.ori8);
+testElementType(Int16Array, m.ori16);
+testElementType(Int32Array, m.ori32);
+testElementType(Uint8Array, m.oru8);
+testElementType(Uint16Array, m.oru16);
+testElementType(Uint32Array, m.oru32);
diff --git a/deps/v8/test/mjsunit/asm/atomics-store.js b/deps/v8/test/mjsunit/asm/atomics-store.js
new file mode 100644
index 0000000000..1f7a5f91c7
--- /dev/null
+++ b/deps/v8/test/mjsunit/asm/atomics-store.js
@@ -0,0 +1,109 @@
+// Copyright 2015 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-atomics --harmony-sharedarraybuffer
+
+function Module(stdlib, foreign, heap) {
+ "use asm";
+ var MEM8 = new stdlib.Int8Array(heap);
+ var MEM16 = new stdlib.Int16Array(heap);
+ var MEM32 = new stdlib.Int32Array(heap);
+ var MEMU8 = new stdlib.Uint8Array(heap);
+ var MEMU16 = new stdlib.Uint16Array(heap);
+ var MEMU32 = new stdlib.Uint32Array(heap);
+ var MEMF32 = new stdlib.Float32Array(heap);
+ var MEMF64 = new stdlib.Float64Array(heap);
+ var store = stdlib.Atomics.store;
+ var fround = stdlib.Math.fround;
+
+ function storei8(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return store(MEM8, i, x)|0;
+ }
+
+ function storei16(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return store(MEM16, i, x)|0;
+ }
+
+ function storei32(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return store(MEM32, i, x)|0;
+ }
+
+ function storeu8(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return store(MEMU8, i, x)>>>0;
+ }
+
+ function storeu16(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return store(MEMU16, i, x)>>>0;
+ }
+
+ function storeu32(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return store(MEMU32, i, x)>>>0;
+ }
+
+ function storef32(i, x) {
+ i = i | 0;
+ x = fround(x);
+ return fround(store(MEMF32, i, x));
+ }
+
+ function storef64(i, x) {
+ i = i | 0;
+ x = +x;
+ return +store(MEMF64, i, x);
+ }
+
+ return {
+ storei8: storei8,
+ storei16: storei16,
+ storei32: storei32,
+ storeu8: storeu8,
+ storeu16: storeu16,
+ storeu32: storeu32,
+ storef32: storef32,
+ storef64: storef64
+ };
+}
+
+var sab = new SharedArrayBuffer(16);
+var m = Module(this, {}, sab);
+
+function clearArray() {
+ var ui8 = new Uint8Array(sab);
+ for (var i = 0; i < sab.byteLength; ++i) {
+ ui8[i] = 0;
+ }
+}
+
+function testElementType(taConstr, f, oobValue) {
+ clearArray();
+
+ var ta = new taConstr(sab);
+ var name = Object.prototype.toString.call(ta);
+ assertEquals(10, f(0, 10), name);
+ assertEquals(10, ta[0]);
+ // out of bounds
+ assertEquals(oobValue, f(-1, 0), name);
+ assertEquals(oobValue, f(ta.length, 0), name);
+}
+
+testElementType(Int8Array, m.storei8, 0);
+testElementType(Int16Array, m.storei16, 0);
+testElementType(Int32Array, m.storei32, 0);
+testElementType(Uint8Array, m.storeu8, 0);
+testElementType(Uint16Array, m.storeu16, 0);
+testElementType(Uint32Array, m.storeu32, 0);
+testElementType(Float32Array, m.storef32, NaN);
+testElementType(Float64Array, m.storef64, NaN);
diff --git a/deps/v8/test/mjsunit/asm/atomics-sub.js b/deps/v8/test/mjsunit/asm/atomics-sub.js
new file mode 100644
index 0000000000..f9e56ffa4b
--- /dev/null
+++ b/deps/v8/test/mjsunit/asm/atomics-sub.js
@@ -0,0 +1,94 @@
+// Copyright 2015 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-atomics --harmony-sharedarraybuffer
+
+function Module(stdlib, foreign, heap) {
+ "use asm";
+ var MEM8 = new stdlib.Int8Array(heap);
+ var MEM16 = new stdlib.Int16Array(heap);
+ var MEM32 = new stdlib.Int32Array(heap);
+ var MEMU8 = new stdlib.Uint8Array(heap);
+ var MEMU16 = new stdlib.Uint16Array(heap);
+ var MEMU32 = new stdlib.Uint32Array(heap);
+ var sub = stdlib.Atomics.sub;
+ var fround = stdlib.Math.fround;
+
+ function subi8(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return sub(MEM8, i, x)|0;
+ }
+
+ function subi16(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return sub(MEM16, i, x)|0;
+ }
+
+ function subi32(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return sub(MEM32, i, x)|0;
+ }
+
+ function subu8(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return sub(MEMU8, i, x)>>>0;
+ }
+
+ function subu16(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return sub(MEMU16, i, x)>>>0;
+ }
+
+ function subu32(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return sub(MEMU32, i, x)>>>0;
+ }
+
+ return {
+ subi8: subi8,
+ subi16: subi16,
+ subi32: subi32,
+ subu8: subu8,
+ subu16: subu16,
+ subu32: subu32,
+ };
+}
+
+var sab = new SharedArrayBuffer(16);
+var m = Module(this, {}, sab);
+
+function clearArray() {
+ var ui8 = new Uint8Array(sab);
+ for (var i = 0; i < sab.byteLength; ++i) {
+ ui8[i] = 0;
+ }
+}
+
+function testElementType(taConstr, f) {
+ clearArray();
+
+ var ta = new taConstr(sab);
+ var name = Object.prototype.toString.call(ta);
+ ta[0] = 30;
+ assertEquals(30, f(0, 10), name);
+ assertEquals(20, ta[0]);
+ assertEquals(20, f(0, 10), name);
+ assertEquals(10, ta[0]);
+ // out of bounds
+ assertEquals(0, f(-1, 0), name);
+ assertEquals(0, f(ta.length, 0), name);
+}
+
+testElementType(Int8Array, m.subi8);
+testElementType(Int16Array, m.subi16);
+testElementType(Int32Array, m.subi32);
+testElementType(Uint8Array, m.subu8);
+testElementType(Uint16Array, m.subu16);
+testElementType(Uint32Array, m.subu32);
diff --git a/deps/v8/test/mjsunit/asm/atomics-xor.js b/deps/v8/test/mjsunit/asm/atomics-xor.js
new file mode 100644
index 0000000000..893ea013fd
--- /dev/null
+++ b/deps/v8/test/mjsunit/asm/atomics-xor.js
@@ -0,0 +1,93 @@
+// Copyright 2015 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-atomics --harmony-sharedarraybuffer
+
+function Module(stdlib, foreign, heap) {
+ "use asm";
+ var MEM8 = new stdlib.Int8Array(heap);
+ var MEM16 = new stdlib.Int16Array(heap);
+ var MEM32 = new stdlib.Int32Array(heap);
+ var MEMU8 = new stdlib.Uint8Array(heap);
+ var MEMU16 = new stdlib.Uint16Array(heap);
+ var MEMU32 = new stdlib.Uint32Array(heap);
+ var xor = stdlib.Atomics.xor;
+ var fround = stdlib.Math.fround;
+
+ function xori8(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return xor(MEM8, i, x)|0;
+ }
+
+ function xori16(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return xor(MEM16, i, x)|0;
+ }
+
+ function xori32(i, x) {
+ i = i | 0;
+ x = x | 0;
+ return xor(MEM32, i, x)|0;
+ }
+
+ function xoru8(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return xor(MEMU8, i, x)>>>0;
+ }
+
+ function xoru16(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return xor(MEMU16, i, x)>>>0;
+ }
+
+ function xoru32(i, x) {
+ i = i | 0;
+ x = x >>> 0;
+ return xor(MEMU32, i, x)>>>0;
+ }
+
+ return {
+ xori8: xori8,
+ xori16: xori16,
+ xori32: xori32,
+ xoru8: xoru8,
+ xoru16: xoru16,
+ xoru32: xoru32,
+ };
+}
+
+var sab = new SharedArrayBuffer(16);
+var m = Module(this, {}, sab);
+
+function clearArray() {
+ var ui8 = new Uint8Array(sab);
+ for (var i = 0; i < sab.byteLength; ++i) {
+ ui8[i] = 0;
+ }
+}
+
+function testElementType(taConstr, f) {
+ clearArray();
+
+ var ta = new taConstr(sab);
+ var name = Object.prototype.toString.call(ta);
+ assertEquals(0, f(0, 0xf), name);
+ assertEquals(0xf, ta[0]);
+ assertEquals(0xf, f(0, 0x11), name);
+ assertEquals(0x1e, ta[0]);
+ // out of bounds
+ assertEquals(0, f(-1, 0), name);
+ assertEquals(0, f(ta.length, 0), name);
+}
+
+testElementType(Int8Array, m.xori8);
+testElementType(Int16Array, m.xori16);
+testElementType(Int32Array, m.xori32);
+testElementType(Uint8Array, m.xoru8);
+testElementType(Uint16Array, m.xoru16);
+testElementType(Uint32Array, m.xoru32);
diff --git a/deps/v8/test/mjsunit/big-array-literal.js b/deps/v8/test/mjsunit/big-array-literal.js
index 7e19c0a2dc..19d1ff406d 100644
--- a/deps/v8/test/mjsunit/big-array-literal.js
+++ b/deps/v8/test/mjsunit/big-array-literal.js
@@ -27,8 +27,7 @@
// On MacOS X 10.7.5, this test needs a stack size of at least 788 kBytes.
// On PPC64, this test needs a stack size of at least 698 kBytes.
-// Flags: --stack-size=800
-// Flags: --turbo-deoptimization
+// Flags: --stack-size=1000
// Test that we can make large object literals that work.
// Also test that we can attempt to make even larger object literals without
diff --git a/deps/v8/test/mjsunit/call-counts.js b/deps/v8/test/mjsunit/call-counts.js
new file mode 100644
index 0000000000..d1488245f1
--- /dev/null
+++ b/deps/v8/test/mjsunit/call-counts.js
@@ -0,0 +1,43 @@
+// Copyright 2015 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 --noalways-opt
+
+// Locations in the type feedback vector where call counts are maintained for
+// the two calls made from bar();
+
+(function() {
+ const kFooCallExtraIndex = 5;
+ const kArrayCallExtraIndex = 7;
+
+ function GetCallCount(func, slot) {
+ var vector = %GetTypeFeedbackVector(func);
+ // Call counts are recorded doubled.
+ var value = %FixedArrayGet(vector, slot);
+ return Math.floor(value / 2);
+ }
+
+ function foo(a) { return a[3] * 16; }
+
+ function bar(a) {
+ var result = 0;
+ for (var i = 0; i < 10; i++) {
+ result = foo(a);
+ if (i % 2 === 0) {
+ var r = Array();
+ r[0] = 1;
+ result += r[0];
+ }
+ }
+ return result;
+ }
+
+ var a = [1, 2, 3];
+ bar(a);
+ assertEquals(10, GetCallCount(bar, kFooCallExtraIndex));
+ assertEquals(5, GetCallCount(bar, kArrayCallExtraIndex));
+
+ %OptimizeFunctionOnNextCall(bar);
+ bar(a);
+})();
diff --git a/deps/v8/test/mjsunit/call-runtime-tail.js b/deps/v8/test/mjsunit/call-runtime-tail.js
new file mode 100644
index 0000000000..6ad107dcb2
--- /dev/null
+++ b/deps/v8/test/mjsunit/call-runtime-tail.js
@@ -0,0 +1,81 @@
+// Copyright 2015 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 --turbo
+
+var p0 = new Object();
+var p1 = new Object();
+var p2 = new Object();
+
+// Ensure 1 parameter passed straight-through is handled correctly
+var count1 = 100000;
+tailee1 = function() {
+ "use strict";
+ if (count1-- == 0) {
+ return this;
+ }
+ return %_CallFunction(this, tailee1);
+};
+
+%OptimizeFunctionOnNextCall(tailee1);
+assertEquals(p0, tailee1.call(p0));
+
+// Ensure 2 parameters passed straight-through trigger a tail call are handled
+// correctly and don't cause a stack overflow.
+var count2 = 100000;
+tailee2 = function(px) {
+ "use strict";
+ assertEquals(p2, px);
+ assertEquals(p1, this);
+ count2 = ((count2 | 0) - 1) | 0;
+ if ((count2 | 0) === 0) {
+ return this;
+ }
+ return %_CallFunction(this, px, tailee2);
+};
+
+%OptimizeFunctionOnNextCall(tailee2);
+assertEquals(p1, tailee2.call(p1, p2));
+
+// Ensure swapped 2 parameters don't trigger a tail call (parameter swizzling
+// for the tail call isn't supported yet).
+var count3 = 100000;
+tailee3 = function(px) {
+ "use strict";
+ if (count3-- == 0) {
+ return this;
+ }
+ return %_CallFunction(px, this, tailee3);
+};
+
+%OptimizeFunctionOnNextCall(tailee3);
+assertThrows(function() { tailee3.call(p1, p2); });
+
+// Ensure too many parameters defeats the tail call optimization (currently
+// unsupported).
+var count4 = 1000000;
+tailee4 = function(px) {
+ "use strict";
+ if (count4-- == 0) {
+ return this;
+ }
+ return %_CallFunction(this, px, undefined, tailee4);
+};
+
+%OptimizeFunctionOnNextCall(tailee4);
+assertThrows(function() { tailee4.call(p1, p2); });
+
+// Ensure too few parameters defeats the tail call optimization (currently
+// unsupported).
+var count5 = 1000000;
+tailee5 = function(px) {
+ "use strict";
+ if (count5-- == 0) {
+ return this;
+ }
+ return %_CallFunction(this, tailee5);
+};
+
+%OptimizeFunctionOnNextCall(tailee5);
+assertThrows(function() { tailee5.call(p1, p2); });
diff --git a/deps/v8/test/mjsunit/compiler/deopt-tonumber-compare.js b/deps/v8/test/mjsunit/compiler/deopt-tonumber-compare.js
new file mode 100644
index 0000000000..9a7e992ada
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/deopt-tonumber-compare.js
@@ -0,0 +1,44 @@
+// Copyright 2015 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 m = (function() {
+ "use asm";
+ function f(x) {
+ return x < 0;
+ }
+ function g(x) {
+ return 0 < x;
+ }
+ return { f: f, g: g };
+})();
+var f = m.f;
+var g = m.g;
+
+var counter = 0;
+
+function deopt(f) {
+ return {
+ toString : function() {
+ %DeoptimizeFunction(f);
+ counter++;
+ return "2";
+ }
+ };
+}
+
+assertEquals(false, f(deopt(f)));
+assertEquals(1, counter);
+
+assertEquals(true, g(deopt(g)));
+assertEquals(2, counter);
+
+%OptimizeFunctionOnNextCall(f);
+assertEquals(false, f(deopt(f)));
+assertEquals(3, counter);
+
+%OptimizeFunctionOnNextCall(g);
+assertEquals(true, g(deopt(g)));
+assertEquals(4, counter);
diff --git a/deps/v8/test/mjsunit/compiler/deopt-tonumber-shift.js b/deps/v8/test/mjsunit/compiler/deopt-tonumber-shift.js
new file mode 100644
index 0000000000..bb4d1d5c1c
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/deopt-tonumber-shift.js
@@ -0,0 +1,40 @@
+// Copyright 2015 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 f = (function() {
+ "use asm";
+ function f(x, y) {
+ return x << y;
+ }
+ return f;
+})();
+
+var counter = 0;
+
+var deopt = { toString : function() {
+ %DeoptimizeFunction(f);
+ counter++;
+ return "2";
+} };
+
+var o = { toString : function() {
+ counter++;
+ return "1";
+} };
+
+counter = 0;
+assertEquals(4, f(deopt, o));
+assertEquals(2, counter);
+
+%OptimizeFunctionOnNextCall(f);
+counter = 0;
+assertEquals(4, f(o, deopt));
+assertEquals(2, counter);
+
+%OptimizeFunctionOnNextCall(f);
+counter = 0;
+assertEquals(8, f(deopt, deopt));
+assertEquals(2, counter);
diff --git a/deps/v8/test/mjsunit/compiler/jsnatives.js b/deps/v8/test/mjsunit/compiler/jsnatives.js
index ea2ecd2d30..ab70abc1bb 100644
--- a/deps/v8/test/mjsunit/compiler/jsnatives.js
+++ b/deps/v8/test/mjsunit/compiler/jsnatives.js
@@ -29,5 +29,5 @@
// Test call of JS runtime functions.
-var a = %$isNaN(0/0);
-assertEquals(true, a);
+var a = %MakeError(0, "error");
+assertInstanceof(a, Error);
diff --git a/deps/v8/test/mjsunit/compiler/optimize_max.js b/deps/v8/test/mjsunit/compiler/optimize_max.js
new file mode 100644
index 0000000000..6baefe48ba
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/optimize_max.js
@@ -0,0 +1,69 @@
+// Copyright 2015 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 DOUBLE_ZERO = %AllocateHeapNumber();
+var SMI_ZERO = 0;
+var MINUS_ZERO = -0.0;
+
+function max1(a, b) {
+ a = +a;
+ b = +b;
+ return +(a < b ? b : a);
+}
+
+function max2(a, b) {
+ a = +a;
+ b = +b;
+ return a < b ? b : a;
+}
+
+for (f of [max1, max2]) {
+ for (var i = 0; i < 5; i++) {
+ assertEquals(4, f(3, 4));
+ assertEquals(4, f(4, 3));
+ assertEquals(4.3, f(3.3, 4.3));
+ assertEquals(4.4, f(4.4, 3.4));
+
+ assertEquals(Infinity, 1 / f(SMI_ZERO, MINUS_ZERO));
+ assertEquals(Infinity, 1 / f(DOUBLE_ZERO, MINUS_ZERO));
+ assertEquals(-Infinity, 1 / f(MINUS_ZERO, SMI_ZERO));
+ assertEquals(-Infinity, 1 / f(MINUS_ZERO, DOUBLE_ZERO));
+
+ assertEquals(NaN, f(NaN, NaN));
+ assertEquals(3, f(3, NaN));
+ assertEquals(NaN, f(NaN, 3));
+ }
+}
+
+function max3(a, b) {
+ a = +a;
+ b = +b;
+ return +(a > b ? a : b);
+}
+
+function max4(a, b) {
+ a = +a;
+ b = +b;
+ return a > b ? a : b;
+}
+
+for (f of [max3, max4]) {
+ for (var i = 0; i < 5; i++) {
+ assertEquals(4, f(3, 4));
+ assertEquals(4, f(4, 3));
+ assertEquals(4.3, f(3.3, 4.3));
+ assertEquals(4.4, f(4.4, 3.4));
+
+ assertEquals(-Infinity, 1 / f(SMI_ZERO, MINUS_ZERO));
+ assertEquals(-Infinity, 1 / f(DOUBLE_ZERO, MINUS_ZERO));
+ assertEquals(Infinity, 1 / f(MINUS_ZERO, SMI_ZERO));
+ assertEquals(Infinity, 1 / f(MINUS_ZERO, DOUBLE_ZERO));
+
+ assertEquals(NaN, f(NaN, NaN));
+ assertEquals(NaN, f(3, NaN));
+ assertEquals(3, f(NaN, 3));
+ }
+}
diff --git a/deps/v8/test/mjsunit/compiler/optimize_min.js b/deps/v8/test/mjsunit/compiler/optimize_min.js
new file mode 100644
index 0000000000..906b999584
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/optimize_min.js
@@ -0,0 +1,69 @@
+// Copyright 2015 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 DOUBLE_ZERO = %AllocateHeapNumber();
+var SMI_ZERO = 0;
+var MINUS_ZERO = -0.0;
+
+function min1(a, b) {
+ a = +a;
+ b = +b;
+ return +(a < b ? a : b);
+}
+
+function min2(a, b) {
+ a = +a;
+ b = +b;
+ return a < b ? a : b;
+}
+
+for (f of [min1, min2]) {
+ for (var i = 0; i < 5; i++) {
+ assertEquals(3, f(3, 4));
+ assertEquals(3, f(4, 3));
+ assertEquals(3.3, f(3.3, 4));
+ assertEquals(3.4, f(4, 3.4));
+
+ assertEquals(-Infinity, 1 / f(SMI_ZERO, MINUS_ZERO));
+ assertEquals(-Infinity, 1 / f(DOUBLE_ZERO, MINUS_ZERO));
+ assertEquals(Infinity, 1 / f(MINUS_ZERO, SMI_ZERO));
+ assertEquals(Infinity, 1 / f(MINUS_ZERO, DOUBLE_ZERO));
+
+ assertEquals(NaN, f(NaN, NaN));
+ assertEquals(NaN, f(3, NaN));
+ assertEquals(3, f(NaN, 3));
+ }
+}
+
+function min3(a, b) {
+ a = +a;
+ b = +b;
+ return +(a > b ? b : a);
+}
+
+function min4(a, b) {
+ a = +a;
+ b = +b;
+ return a > b ? b : a;
+}
+
+for (f of [min3, min4]) {
+ for (var i = 0; i < 5; i++) {
+ assertEquals(3, f(3, 4));
+ assertEquals(3, f(4, 3));
+ assertEquals(3.3, f(3.3, 4));
+ assertEquals(3.4, f(4, 3.4));
+
+ assertEquals(Infinity, 1 / f(SMI_ZERO, MINUS_ZERO));
+ assertEquals(Infinity, 1 / f(DOUBLE_ZERO, MINUS_ZERO));
+ assertEquals(-Infinity, 1 / f(MINUS_ZERO, SMI_ZERO));
+ assertEquals(-Infinity, 1 / f(MINUS_ZERO, DOUBLE_ZERO));
+
+ assertEquals(NaN, f(NaN, NaN));
+ assertEquals(3, f(3, NaN));
+ assertEquals(NaN, f(NaN, 3));
+ }
+}
diff --git a/deps/v8/test/mjsunit/compiler/osr-array-len.js b/deps/v8/test/mjsunit/compiler/osr-array-len.js
new file mode 100644
index 0000000000..aaee860d61
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/osr-array-len.js
@@ -0,0 +1,22 @@
+// Copyright 2015 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 fastaRandom(n, table) {
+ var line = new Array(5);
+ while (n > 0) {
+ if (n < line.length) line = new Array(n);
+ %OptimizeOsr();
+ line[0] = n;
+ n--;
+ }
+}
+
+print("---BEGIN 1");
+assertEquals(undefined, fastaRandom(6, null));
+print("---BEGIN 2");
+assertEquals(undefined, fastaRandom(6, null));
+print("---END");
diff --git a/deps/v8/test/mjsunit/compiler/osr-maze1.js b/deps/v8/test/mjsunit/compiler/osr-maze1.js
index 6e192c17b7..da17282742 100644
--- a/deps/v8/test/mjsunit/compiler/osr-maze1.js
+++ b/deps/v8/test/mjsunit/compiler/osr-maze1.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: --allow-natives-syntax --use-osr --turbo-deoptimization
+// Flags: --allow-natives-syntax --use-osr
function bar(goal) {
var count = 0;
diff --git a/deps/v8/test/mjsunit/compiler/osr-maze2.js b/deps/v8/test/mjsunit/compiler/osr-maze2.js
index 96838a4c34..1fc1cd2db1 100644
--- a/deps/v8/test/mjsunit/compiler/osr-maze2.js
+++ b/deps/v8/test/mjsunit/compiler/osr-maze2.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: --allow-natives-syntax --use-osr --turbo-deoptimization
+// Flags: --allow-natives-syntax --use-osr
function bar() {
var sum = 11;
diff --git a/deps/v8/test/mjsunit/compiler/regress-4206.js b/deps/v8/test/mjsunit/compiler/regress-4206.js
new file mode 100644
index 0000000000..742ed5dfe5
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-4206.js
@@ -0,0 +1,28 @@
+// Copyright 2015 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 Module(stdlib) {
+ "use asm";
+ function TernaryMin(a, b) {
+ a=+(a);
+ b=+(b);
+ return (+((a < b) ? a : b));
+ }
+ function TernaryMax(a, b) {
+ a=+(a);
+ b=+(b);
+ return (+((b < a) ? a : b));
+ }
+ return { TernaryMin: TernaryMin,
+ TernaryMax: TernaryMax };
+}
+var min = Module(this).TernaryMin;
+var max = Module(this).TernaryMax;
+
+assertEquals(0.0, min(-0.0, 0.0));
+assertEquals(0.0, min(NaN, 0.0));
+assertEquals(-0.0, min(NaN, -0.0));
+assertEquals(-0.0, max(0.0, -0.0));
+assertEquals(0.0, max(NaN, 0.0));
+assertEquals(-0.0, max(NaN, -0.0));
diff --git a/deps/v8/test/mjsunit/compiler/regress-4207.js b/deps/v8/test/mjsunit/compiler/regress-4207.js
new file mode 100644
index 0000000000..c4ab5a7837
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-4207.js
@@ -0,0 +1,15 @@
+// Copyright 2015 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 bar() { return 0/0 && 1; }
+assertEquals(NaN, bar());
+%OptimizeFunctionOnNextCall(bar);
+assertEquals(NaN, bar());
+
+function foo() { return 0/0 || 1; }
+assertEquals(1, foo());
+%OptimizeFunctionOnNextCall(foo);
+assertEquals(1, foo());
diff --git a/deps/v8/test/mjsunit/compiler/regress-445907.js b/deps/v8/test/mjsunit/compiler/regress-445907.js
index c820753eec..8cde94457e 100644
--- a/deps/v8/test/mjsunit/compiler/regress-445907.js
+++ b/deps/v8/test/mjsunit/compiler/regress-445907.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: --turbo-deoptimization
-
v = [];
v.length = (1 << 30);
diff --git a/deps/v8/test/mjsunit/compiler/regress-446647.js b/deps/v8/test/mjsunit/compiler/regress-446647.js
index 77757abd66..6387aaa697 100644
--- a/deps/v8/test/mjsunit/compiler/regress-446647.js
+++ b/deps/v8/test/mjsunit/compiler/regress-446647.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: --always-opt --turbo-filter=* --turbo-deoptimization --allow-natives-syntax
+// Flags: --always-opt --turbo-filter=* --allow-natives-syntax
function f(a,b) {
a%b
diff --git a/deps/v8/test/mjsunit/compiler/regress-447567.js b/deps/v8/test/mjsunit/compiler/regress-447567.js
index b6dc653709..c348debee2 100644
--- a/deps/v8/test/mjsunit/compiler/regress-447567.js
+++ b/deps/v8/test/mjsunit/compiler/regress-447567.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: --turbo-deoptimization
-
assertThrows(function() {
[0].every(function(){ Object.seal((new Int8Array())); });
})
diff --git a/deps/v8/test/mjsunit/compiler/regress-491578.js b/deps/v8/test/mjsunit/compiler/regress-491578.js
new file mode 100644
index 0000000000..c27570456c
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-491578.js
@@ -0,0 +1,15 @@
+// Copyright 2015 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(x) {
+ if (x === undefined) return;
+ while (true) {
+ while (1 || 2) { }
+ f();
+ }
+}
+%OptimizeFunctionOnNextCall(foo);
+foo();
diff --git a/deps/v8/test/mjsunit/compiler/regress-shift-left.js b/deps/v8/test/mjsunit/compiler/regress-shift-left.js
new file mode 100644
index 0000000000..110e899729
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-shift-left.js
@@ -0,0 +1,41 @@
+// Copyright 2015 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 ShiftLeftWithDeoptUsage() {
+ function g() {}
+
+ function f() {
+ var tmp = 1264475713;
+ var tmp1 = tmp - (-913041544);
+ g();
+ return 1 << tmp1;
+ }
+
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(512, f());
+})();
+
+
+(function ShiftLeftWithCallUsage() {
+ var f = (function() {
+ "use asm"
+ // This is not a valid asm.js, we use the "use asm" here to
+ // trigger Turbofan without deoptimization support.
+
+ function g(x) { return x; }
+
+ function f() {
+ var tmp = 1264475713;
+ var tmp1 = tmp - (-913041544);
+ return g(1 << tmp1, tmp1);
+ }
+
+ return f;
+ })();
+
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(512, f());
+})();
diff --git a/deps/v8/test/mjsunit/compiler/regress-shift-right-logical.js b/deps/v8/test/mjsunit/compiler/regress-shift-right-logical.js
new file mode 100644
index 0000000000..f2be2ad52f
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-shift-right-logical.js
@@ -0,0 +1,41 @@
+// Copyright 2015 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 ShiftRightLogicalWithDeoptUsage() {
+ function g() {}
+
+ function f() {
+ var tmp = 1264475713;
+ var tmp1 = tmp - (-913041544);
+ g();
+ return 1 >>> tmp1;
+ }
+
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(0, f());
+})();
+
+
+(function ShiftRightLogicalWithCallUsage() {
+ var f = (function() {
+ "use asm"
+ // This is not a valid asm.js, we use the "use asm" here to
+ // trigger Turbofan without deoptimization support.
+
+ function g(x) { return x; }
+
+ function f() {
+ var tmp = 1264475713;
+ var tmp1 = tmp - (-913041544);
+ return g(1 >>> tmp1, tmp1);
+ }
+
+ return f;
+ })();
+
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(0, f());
+})();
diff --git a/deps/v8/test/mjsunit/compiler/regress-shift-right.js b/deps/v8/test/mjsunit/compiler/regress-shift-right.js
new file mode 100644
index 0000000000..71bcb21f0e
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-shift-right.js
@@ -0,0 +1,41 @@
+// Copyright 2015 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 ShiftRightWithDeoptUsage() {
+ function g() {}
+
+ function f() {
+ var tmp = 1264475713;
+ var tmp1 = tmp - (-913041544);
+ g();
+ return 1 >> tmp1;
+ }
+
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(0, f());
+})();
+
+
+(function ShiftRightWithCallUsage() {
+ var f = (function() {
+ "use asm"
+ // This is not a valid asm.js, we use the "use asm" here to
+ // trigger Turbofan without deoptimization support.
+
+ function g(x) { return x; }
+
+ function f() {
+ var tmp = 1264475713;
+ var tmp1 = tmp - (-913041544);
+ return g(1 >> tmp1, tmp1);
+ }
+
+ return f;
+ })();
+
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(0, f());
+})();
diff --git a/deps/v8/test/mjsunit/compiler/regress-uint8-deopt.js b/deps/v8/test/mjsunit/compiler/regress-uint8-deopt.js
index ba2823fa35..5be2d0ce6b 100644
--- a/deps/v8/test/mjsunit/compiler/regress-uint8-deopt.js
+++ b/deps/v8/test/mjsunit/compiler/regress-uint8-deopt.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: --turbo-asm --turbo-deoptimization --allow-natives-syntax
+// Flags: --turbo-asm --turbo-asm-deoptimization --allow-natives-syntax
function Module(heap) {
"use asm";
diff --git a/deps/v8/test/mjsunit/compiler/regress-variable-liveness.js b/deps/v8/test/mjsunit/compiler/regress-variable-liveness.js
new file mode 100644
index 0000000000..e18741d96e
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-variable-liveness.js
@@ -0,0 +1,22 @@
+// Copyright 2015 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(x) {
+ %DeoptimizeFunction(run);
+ return x;
+}
+
+function run() {
+ var line = new Array(2);
+ for (var n = 3; n > 0; n = n - 1) {
+ if (n < foo(line.length)) line = new Array(n);
+ line[0] = n;
+ }
+}
+
+assertEquals(void 0, run());
+%OptimizeFunctionOnNextCall(run);
+assertEquals(void 0, run());
diff --git a/deps/v8/test/mjsunit/compiler/stubs/floor-stub.js b/deps/v8/test/mjsunit/compiler/stubs/floor-stub.js
new file mode 100644
index 0000000000..e3fc9b6003
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/stubs/floor-stub.js
@@ -0,0 +1,54 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 --expose-natives-as=builtins --noalways-opt
+
+const kExtraTypeFeedbackMinusZeroSentinel = 1;
+const kFirstSlotExtraTypeFeedbackIndex = 5;
+
+(function(){
+ var floorFunc = function() {
+ Math.floor(NaN);
+ }
+ // Execute the function once to make sure it has a type feedback vector.
+ floorFunc(5);
+ var stub = builtins.MathFloorStub("MathFloorStub", 0);
+ assertTrue(kExtraTypeFeedbackMinusZeroSentinel !==
+ %FixedArrayGet(%GetTypeFeedbackVector(floorFunc),
+ kFirstSlotExtraTypeFeedbackIndex));
+ assertEquals(5.0, stub(floorFunc, 4, 5.5));
+ assertTrue(kExtraTypeFeedbackMinusZeroSentinel !==
+ %FixedArrayGet(%GetTypeFeedbackVector(floorFunc),
+ kFirstSlotExtraTypeFeedbackIndex));
+ // Executing floor such that it returns -0 should set the proper sentinel in
+ // the feedback vector.
+ assertEquals(-Infinity, 1/stub(floorFunc, 4, -0));
+ assertEquals(kExtraTypeFeedbackMinusZeroSentinel,
+ %FixedArrayGet(%GetTypeFeedbackVector(floorFunc),
+ kFirstSlotExtraTypeFeedbackIndex));
+ %ClearFunctionTypeFeedback(floorFunc);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/try-binop.js b/deps/v8/test/mjsunit/compiler/try-binop.js
new file mode 100644
index 0000000000..2132ad2c00
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/try-binop.js
@@ -0,0 +1,45 @@
+// Copyright 2015 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 boom = { valueOf: function() { throw "boom" } };
+
+function mult_left_plain(x) {
+ try {
+ return 2 * x;
+ } catch (e) {
+ return e;
+ }
+}
+
+%OptimizeFunctionOnNextCall(mult_left_plain);
+assertEquals("boom", mult_left_plain(boom));
+assertEquals(46, mult_left_plain(23));
+
+function mult_right_plain(x) {
+ try {
+ return x * 3;
+ } catch (e) {
+ return e;
+ }
+}
+
+%OptimizeFunctionOnNextCall(mult_right_plain);
+assertEquals("boom", mult_right_plain(boom));
+assertEquals(69, mult_right_plain(23));
+
+function mult_none_plain(x,y) {
+ try {
+ return x * y;
+ } catch (e) {
+ return e;
+ }
+}
+
+%OptimizeFunctionOnNextCall(mult_none_plain);
+assertEquals("boom", mult_none_plain(boom, boom));
+assertEquals("boom", mult_none_plain(boom, 2));
+assertEquals("boom", mult_none_plain(2, boom));
+assertEquals(966, mult_none_plain(23, 42));
diff --git a/deps/v8/test/mjsunit/compiler/try-deopt.js b/deps/v8/test/mjsunit/compiler/try-deopt.js
index dc44e7326f..a4a6eb0304 100644
--- a/deps/v8/test/mjsunit/compiler/try-deopt.js
+++ b/deps/v8/test/mjsunit/compiler/try-deopt.js
@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// TODO(mstarzinger): Add FLAG_turbo_exceptions once we want ClusterFuzz.
-// Flags: --allow-natives-syntax --turbo-deoptimization
+// Flags: --allow-natives-syntax
function DeoptFromTry(x) {
try {
diff --git a/deps/v8/test/mjsunit/compiler/try-osr.js b/deps/v8/test/mjsunit/compiler/try-osr.js
new file mode 100644
index 0000000000..e4eb8dd9fa
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/try-osr.js
@@ -0,0 +1,51 @@
+// Copyright 2015 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 --turbo-osr
+
+function OSRInsideTry(x) {
+ try {
+ for (var i = 0; i < 10; i++) { if (i == 5) %OptimizeOsr(); }
+ throw x;
+ } catch (e) {
+ return e + 1;
+ }
+ return x + 2;
+}
+assertEquals(24, OSRInsideTry(23));
+
+
+function OSRInsideCatch(x) {
+ try {
+ throw x;
+ } catch (e) {
+ for (var i = 0; i < 10; i++) { if (i == 5) %OptimizeOsr(); }
+ return e + 1;
+ }
+ return x + 2;
+}
+assertEquals(24, OSRInsideCatch(23));
+
+
+function OSRInsideFinally_Return(x) {
+ try {
+ throw x;
+ } finally {
+ for (var i = 0; i < 10; i++) { if (i == 5) %OptimizeOsr(); }
+ return x + 1;
+ }
+ return x + 2;
+}
+assertEquals(24, OSRInsideFinally_Return(23));
+
+
+function OSRInsideFinally_ReThrow(x) {
+ try {
+ throw x;
+ } finally {
+ for (var i = 0; i < 10; i++) { if (i == 5) %OptimizeOsr(); }
+ }
+ return x + 2;
+}
+assertThrows("OSRInsideFinally_ReThrow(new Error)", Error);
diff --git a/deps/v8/test/mjsunit/regress/regress-1878.js b/deps/v8/test/mjsunit/d8-worker-sharedarraybuffer.js
index fbc47bdd14..791529fc89 100644
--- a/deps/v8/test/mjsunit/regress/regress-1878.js
+++ b/deps/v8/test/mjsunit/d8-worker-sharedarraybuffer.js
@@ -1,4 +1,4 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
+// Copyright 2015 the V8 project authors. 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,44 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// See: http://code.google.com/p/v8/issues/detail?id=1878
+// Flags: --harmony-sharedarraybuffer --harmony-atomics
-// Flags: --allow-natives-syntax --expose_natives_as=natives
+var workerScript =
+ `onmessage = function(m) {
+ var sab = m;
+ var ta = new Uint32Array(sab);
+ if (sab.byteLength !== 16) {
+ throw new Error('SharedArrayBuffer transfer byteLength');
+ }
+ for (var i = 0; i < 4; ++i) {
+ if (ta[i] !== i) {
+ throw new Error('SharedArrayBuffer transfer value ' + i);
+ }
+ }
+ // Atomically update ta[0]
+ Atomics.store(ta, 0, 100);
+ };`;
-var a = Array();
+if (this.Worker) {
+ var w = new Worker(workerScript);
-for (var i = 0; i < 1000; i++) {
- var ai = natives.InternalArray(10000);
- assertFalse(%HaveSameMap(ai, a));
- assertTrue(%HasFastObjectElements(ai));
-}
+ var sab = new SharedArrayBuffer(16);
+ var ta = new Uint32Array(sab);
+ for (var i = 0; i < 4; ++i) {
+ ta[i] = i;
+ }
+
+ // Transfer SharedArrayBuffer
+ w.postMessage(sab, [sab]);
+ assertEquals(16, sab.byteLength); // ArrayBuffer should not be neutered.
+
+ // Spinwait for the worker to update ta[0]
+ var ta0;
+ while ((ta0 = Atomics.load(ta, 0)) == 0) {}
+
+ assertEquals(100, ta0);
+
+ w.terminate();
-for (var i = 0; i < 1000; i++) {
- var ai = new natives.InternalArray(10000);
- assertFalse(%HaveSameMap(ai, a));
- assertTrue(%HasFastObjectElements(ai));
+ assertEquals(16, sab.byteLength); // Still not neutered.
}
diff --git a/deps/v8/test/mjsunit/regress/regress-parse-object-literal.js b/deps/v8/test/mjsunit/d8-worker-spawn-worker.js
index 93725ebadb..a114d8587e 100644
--- a/deps/v8/test/mjsunit/regress/regress-parse-object-literal.js
+++ b/deps/v8/test/mjsunit/d8-worker-spawn-worker.js
@@ -1,4 +1,4 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright 2015 the V8 project authors. 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,8 +24,17 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (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: --noharmony-classes --noharmony-object-literals
-// Should throw, not crash.
-assertThrows("var o = { get /*space*/ () {} }");
+if (this.Worker) {
+ var workerScript =
+ `var w = new Worker('postMessage(42)');
+ onmessage = function(parentMsg) {
+ w.postMessage(parentMsg);
+ var childMsg = w.getMessage();
+ postMessage(childMsg);
+ };`;
+
+ var w = new Worker(workerScript);
+ w.postMessage(9);
+ assertEquals(42, w.getMessage());
+}
diff --git a/deps/v8/test/mjsunit/d8-worker.js b/deps/v8/test/mjsunit/d8-worker.js
new file mode 100644
index 0000000000..f172fb1603
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8-worker.js
@@ -0,0 +1,137 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test the Worker API of d8. This test only makes sense with d8. A Worker
+// spawns a new OS thread and isolate, and runs it concurrently with the
+// current running thread.
+
+var workerScript =
+ `postMessage('Starting worker');
+// Set a global variable; should not be visible outside of the worker's
+// context.
+ foo = 100;
+ var c = 0;
+ onmessage = function(m) {
+ switch (c++) {
+ case 0:
+ if (m !== undefined) throw new Error('undefined');
+ break;
+ case 1:
+ if (m !== null) throw new Error('null');
+ break;
+ case 2:
+ if (m !== true) throw new Error('true');
+ break;
+ case 3:
+ if (m !== false) throw new Error('false');
+ break;
+ case 4:
+ if (m !== 100) throw new Error('Number');
+ break;
+ case 5:
+ if (m !== 'hi') throw new Error('String');
+ break;
+ case 6:
+ if (JSON.stringify(m) !== '[4,true,\"bye\"]') {
+ throw new Error('Array');
+ }
+ break;
+ case 7:
+ if (JSON.stringify(m) !== \"{'a':1,'b':2.5,'c':'three'}\")
+ throw new Error('Object');
+ break;
+ case 8:
+ var ab = m;
+ var t = new Uint32Array(ab);
+ if (ab.byteLength !== 16)
+ throw new Error('ArrayBuffer clone byteLength');
+ for (var i = 0; i < 4; ++i)
+ if (t[i] !== i)
+ throw new Error('ArrayBuffer clone value ' + i);
+ break;
+ case 9:
+ var ab = m;
+ var t = new Uint32Array(ab);
+ if (ab.byteLength !== 32)
+ throw new Error('ArrayBuffer transfer byteLength');
+ for (var i = 0; i < 8; ++i)
+ if (t[i] !== i)
+ throw new Error('ArrayBuffer transfer value ' + i);
+ break;
+ }
+ if (c == 10) {
+ postMessage('DONE');
+ }
+ };`;
+
+
+if (this.Worker) {
+ function createArrayBuffer(byteLength) {
+ var ab = new ArrayBuffer(byteLength);
+ var t = new Uint32Array(ab);
+ for (var i = 0; i < byteLength / 4; ++i)
+ t[i] = i;
+ return ab;
+ }
+
+ var w = new Worker(workerScript);
+
+ assertEquals("Starting worker", w.getMessage());
+
+ w.postMessage(undefined);
+ w.postMessage(null);
+ w.postMessage(true);
+ w.postMessage(false);
+ w.postMessage(100);
+ w.postMessage("hi");
+ w.postMessage([4, true, "bye"]);
+ w.postMessage({a: 1, b: 2.5, c: "three"});
+
+ // Clone ArrayBuffer
+ var ab1 = createArrayBuffer(16);
+ w.postMessage(ab1);
+ assertEquals(16, ab1.byteLength); // ArrayBuffer should not be neutered.
+
+ // Transfer ArrayBuffer
+ var ab2 = createArrayBuffer(32);
+ w.postMessage(ab2, [ab2]);
+ assertEquals(0, ab2.byteLength); // ArrayBuffer should be neutered.
+
+ assertEquals("undefined", typeof foo);
+
+ // Read a message from the worker.
+ assertEquals("DONE", w.getMessage());
+
+ w.terminate();
+
+
+ // Make sure that the main thread doesn't block forever in getMessage() if
+ // the worker dies without posting a message.
+ var w2 = new Worker('');
+ var msg = w2.getMessage();
+ assertEquals(undefined, msg);
+}
diff --git a/deps/v8/test/mjsunit/date.js b/deps/v8/test/mjsunit/date.js
index 3d72032ab8..0fa23f8de1 100644
--- a/deps/v8/test/mjsunit/date.js
+++ b/deps/v8/test/mjsunit/date.js
@@ -340,3 +340,17 @@ date.getYear();
%OptimizeFunctionOnNextCall(Date.prototype.getYear);
assertThrows(function() { Date.prototype.getYear.call(""); }, TypeError);
assertUnoptimized(Date.prototype.getYear);
+
+delete Date.prototype.getUTCFullYear;
+delete Date.prototype.getUTCMonth;
+delete Date.prototype.getUTCDate;
+delete Date.prototype.getUTCHours;
+delete Date.prototype.getUTCMinutes;
+delete Date.prototype.getUTCSeconds;
+delete Date.prototype.getUTCMilliseconds;
+date.toISOString();
+
+(function TestDeleteToString() {
+ assertTrue(delete Date.prototype.toString);
+ assertTrue('[object Date]' !== Date());
+})();
diff --git a/deps/v8/test/mjsunit/debug-backtrace-text.js b/deps/v8/test/mjsunit/debug-backtrace-text.js
index 3bfaeb0dad..61648fa4e2 100644
--- a/deps/v8/test/mjsunit/debug-backtrace-text.js
+++ b/deps/v8/test/mjsunit/debug-backtrace-text.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-debug-as debug --turbo-deoptimization
+// Flags: --expose-debug-as debug
// The functions used for testing backtraces.
function Point(x, y) {
diff --git a/deps/v8/test/mjsunit/debug-backtrace.js b/deps/v8/test/mjsunit/debug-backtrace.js
index b4fb2c8535..01775f560e 100644
--- a/deps/v8/test/mjsunit/debug-backtrace.js
+++ b/deps/v8/test/mjsunit/debug-backtrace.js
@@ -165,7 +165,7 @@ function listener(event, exec_state, event_data, data) {
assertEquals("f", response.lookup(frame.func.ref).name);
assertTrue(frame.constructCall);
assertEquals(31, frame.line);
- assertEquals(3, frame.column);
+ assertEquals(2, frame.column);
assertEquals(2, frame.arguments.length);
assertEquals('x', frame.arguments[0].name);
assertEquals('number', response.lookup(frame.arguments[0].value.ref).type);
@@ -179,7 +179,7 @@ function listener(event, exec_state, event_data, data) {
assertEquals(0, frame.index);
assertEquals("f", response.lookup(frame.func.ref).name);
assertEquals(31, frame.line);
- assertEquals(3, frame.column);
+ assertEquals(2, frame.column);
assertEquals(2, frame.arguments.length);
assertEquals('x', frame.arguments[0].name);
assertEquals('number', response.lookup(frame.arguments[0].value.ref).type);
diff --git a/deps/v8/test/mjsunit/debug-break-inline.js b/deps/v8/test/mjsunit/debug-break-inline.js
index 3ef4d4eafe..4418fa8d1b 100644
--- a/deps/v8/test/mjsunit/debug-break-inline.js
+++ b/deps/v8/test/mjsunit/debug-break-inline.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-debug-as debug --allow-natives-syntax --turbo-deoptimization
+// Flags: --expose-debug-as debug --allow-natives-syntax
// This test tests that deoptimization due to debug breaks works for
// inlined functions where the full-code is generated before the
diff --git a/deps/v8/test/mjsunit/debug-breakpoints.js b/deps/v8/test/mjsunit/debug-breakpoints.js
index 22c7ab51b2..c293eb313a 100644
--- a/deps/v8/test/mjsunit/debug-breakpoints.js
+++ b/deps/v8/test/mjsunit/debug-breakpoints.js
@@ -211,7 +211,6 @@ assertTrue(Debug.showBreakPoints(g).indexOf("[B0]") < 0);
// (This may be sensitive to compiler break position map generation).
function h() {a=f(f2(1,2),f3())+f3();b=f3();}
var scenario = [
- [5, "{a[B0]=f"],
[6, "{a=[B0]f("],
[7, "{a=f([B0]f2("],
[16, "f2(1,2),[B0]f3()"],
diff --git a/deps/v8/test/mjsunit/debug-clearbreakpointgroup.js b/deps/v8/test/mjsunit/debug-clearbreakpointgroup.js
index 3c03bdaa39..b0ff38371f 100644
--- a/deps/v8/test/mjsunit/debug-clearbreakpointgroup.js
+++ b/deps/v8/test/mjsunit/debug-clearbreakpointgroup.js
@@ -26,7 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
-// Flags: --turbo-deoptimization
// Get the Debug object exposed from the debug context global object.
var Debug = debug.Debug
diff --git a/deps/v8/test/mjsunit/debug-evaluate-arguments.js b/deps/v8/test/mjsunit/debug-evaluate-arguments.js
index 9765f19370..92b745f1da 100644
--- a/deps/v8/test/mjsunit/debug-evaluate-arguments.js
+++ b/deps/v8/test/mjsunit/debug-evaluate-arguments.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-debug-as debug --turbo-deoptimization
+// Flags: --expose-debug-as debug
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
diff --git a/deps/v8/test/mjsunit/debug-evaluate-closure.js b/deps/v8/test/mjsunit/debug-evaluate-closure.js
index cf507b57d2..778defd0ab 100644
--- a/deps/v8/test/mjsunit/debug-evaluate-closure.js
+++ b/deps/v8/test/mjsunit/debug-evaluate-closure.js
@@ -26,7 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug --allow-natives-syntax
-// Flags: --turbo-deoptimization
Debug = debug.Debug;
var listened = false;
diff --git a/deps/v8/test/mjsunit/debug-evaluate-with.js b/deps/v8/test/mjsunit/debug-evaluate-with.js
index 3f3310f9f5..4e02d9e188 100644
--- a/deps/v8/test/mjsunit/debug-evaluate-with.js
+++ b/deps/v8/test/mjsunit/debug-evaluate-with.js
@@ -26,7 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
-// Flags: --turbo-deoptimization
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
diff --git a/deps/v8/test/mjsunit/debug-liveedit-breakpoints.js b/deps/v8/test/mjsunit/debug-liveedit-breakpoints.js
index 1d28ab9ff6..bbcb4cda94 100644
--- a/deps/v8/test/mjsunit/debug-liveedit-breakpoints.js
+++ b/deps/v8/test/mjsunit/debug-liveedit-breakpoints.js
@@ -29,6 +29,7 @@
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
+Debug.setListener(function(){});
var function_z_text =
" function Z() {\n"
@@ -111,3 +112,4 @@ for (var i = 0; i < breaks_ids.length; i++) {
}
assertEquals(0, Debug.scriptBreakPoints().length);
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/debug-liveedit-patch-positions.js b/deps/v8/test/mjsunit/debug-liveedit-patch-positions.js
index b0d3c20d9a..c669b5e862 100644
--- a/deps/v8/test/mjsunit/debug-liveedit-patch-positions.js
+++ b/deps/v8/test/mjsunit/debug-liveedit-patch-positions.js
@@ -33,6 +33,7 @@
// corresponding byte-code PCs should coincide before change and after it.
Debug = debug.Debug
+Debug.setListener(function() {});
eval(
"function F1() { return 5; }\n" +
@@ -124,3 +125,5 @@ print(pcArray2);
if (pcArray1 && pcArray2) {
assertArrayEquals(pcArray1, pcArray2);
}
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/debug-liveedit-stack-padding.js b/deps/v8/test/mjsunit/debug-liveedit-stack-padding.js
index 36de356973..b219e568a7 100644
--- a/deps/v8/test/mjsunit/debug-liveedit-stack-padding.js
+++ b/deps/v8/test/mjsunit/debug-liveedit-stack-padding.js
@@ -29,6 +29,7 @@
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug;
+Debug.setListener(listener);
SlimFunction = eval(
"(function() {\n " +
@@ -76,7 +77,6 @@ function listener(event, exec_state, event_data, data) {
}
}
-Debug.setListener(listener);
var animal = SlimFunction();
@@ -86,3 +86,5 @@ if (saved_exception) {
}
assertEquals("Capybara", animal);
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/debug-receiver.js b/deps/v8/test/mjsunit/debug-receiver.js
index 2d5d2e08de..21cdde84a2 100644
--- a/deps/v8/test/mjsunit/debug-receiver.js
+++ b/deps/v8/test/mjsunit/debug-receiver.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-debug-as debug --turbo-deoptimization
+// Flags: --expose-debug-as debug
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug;
diff --git a/deps/v8/test/mjsunit/debug-references.js b/deps/v8/test/mjsunit/debug-references.js
index cb9f3701e2..f1a0508de6 100644
--- a/deps/v8/test/mjsunit/debug-references.js
+++ b/deps/v8/test/mjsunit/debug-references.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: --expose-debug-as debug --turbo-deoptimization
-// Flags: --stack-trace-on-illegal
+// Flags: --expose-debug-as debug --stack-trace-on-illegal
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
diff --git a/deps/v8/test/mjsunit/debug-scopes.js b/deps/v8/test/mjsunit/debug-scopes.js
index ad137de205..c388a67196 100644
--- a/deps/v8/test/mjsunit/debug-scopes.js
+++ b/deps/v8/test/mjsunit/debug-scopes.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-debug-as debug --allow-natives-syntax --turbo-deoptimization
+// Flags: --expose-debug-as debug --allow-natives-syntax
// The functions used for testing backtraces. They are at the top to make the
// testing of source line/column easier.
@@ -167,6 +167,10 @@ function CheckScopeContent(content, number, exec_state) {
if (!scope.scopeObject().property('arguments').isUndefined()) {
scope_size--;
}
+ // Ditto for 'this'.
+ if (!scope.scopeObject().property('this').isUndefined()) {
+ scope_size--;
+ }
// Skip property with empty name.
if (!scope.scopeObject().property('').isUndefined()) {
scope_size--;
diff --git a/deps/v8/test/mjsunit/debug-script-breakpoints.js b/deps/v8/test/mjsunit/debug-script-breakpoints.js
index ec9656c28c..d4ce6dc98b 100644
--- a/deps/v8/test/mjsunit/debug-script-breakpoints.js
+++ b/deps/v8/test/mjsunit/debug-script-breakpoints.js
@@ -28,6 +28,7 @@
// Flags: --expose-debug-as debug
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
+Debug.setListener(function(){});
// Set and remove a script break point for a named script.
var sbp = Debug.setScriptBreakPointByName("1", 2, 3);
@@ -110,3 +111,5 @@ Debug.clearBreakPoint(sbp3);
assertEquals(1, Debug.scriptBreakPoints().length);
Debug.clearBreakPoint(sbp2);
assertEquals(0, Debug.scriptBreakPoints().length);
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/debug-script.js b/deps/v8/test/mjsunit/debug-script.js
index af1eb454d6..32415c2428 100644
--- a/deps/v8/test/mjsunit/debug-script.js
+++ b/deps/v8/test/mjsunit/debug-script.js
@@ -26,7 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug --expose-gc --send-idle-notification
-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --expose-natives-as natives
// Flags: --noharmony-shipping
// Note: this test checks that that the number of scripts reported as native
// by Debug.scripts() is the same as a number of core native scripts.
@@ -36,6 +36,7 @@
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug;
+Debug.setListener(function(){});
Date();
RegExp();
@@ -103,3 +104,5 @@ assertEquals(Debug.ScriptType.Normal, debug_script.type);
// Check a nonexistent script.
var dummy_script = Debug.findScript('dummy.js');
assertTrue(typeof dummy_script == 'undefined');
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/debug-step-2.js b/deps/v8/test/mjsunit/debug-step-2.js
index 5fe7466cb7..502b426ee2 100644
--- a/deps/v8/test/mjsunit/debug-step-2.js
+++ b/deps/v8/test/mjsunit/debug-step-2.js
@@ -26,7 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
-// Flags: --turbo-deoptimization
// This test tests that full code compiled without debug break slots
// is recompiled with debug break slots when debugging is started.
diff --git a/deps/v8/test/mjsunit/debug-stepframe.js b/deps/v8/test/mjsunit/debug-stepframe.js
index 8f4ee4ca11..f7983c010e 100644
--- a/deps/v8/test/mjsunit/debug-stepframe.js
+++ b/deps/v8/test/mjsunit/debug-stepframe.js
@@ -11,7 +11,7 @@ function f0() {
try {
throw 1;
} catch (e) {
- try{
+ try {
f1();
} catch (e) {
var v02 = 2; // Break 13
@@ -19,6 +19,8 @@ function f0() {
}
var v03 = 3;
var v04 = 4;
+ eval('var v05 = 5; // Break 14');
+ var v06 = 6; // Break 15
}
function f1() {
@@ -104,7 +106,7 @@ for (step_size = 1; step_size < 6; step_size++) {
Debug.setListener(listener);
debugger; // Break 0
f0();
- Debug.setListener(null); // Break 14
+ Debug.setListener(null); // Break 16
assertTrue(break_count > 14);
}
diff --git a/deps/v8/test/mjsunit/debug-stepin-accessor-ic.js b/deps/v8/test/mjsunit/debug-stepin-accessor-ic.js
new file mode 100644
index 0000000000..5f40dcb250
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-stepin-accessor-ic.js
@@ -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.
+
+// Flags: --expose-debug-as debug
+
+function get() {
+ return 3; // Break
+} // Break
+
+function set(x) {
+ this.x = x; // Break
+} // Break
+
+var o = {};
+Object.defineProperty(o, "get", { get : get });
+Object.defineProperty(o, "set", { set : set });
+
+function f() {
+ for (var i = 0; i < 10; i++) { // Break
+ o.get; // Break
+ o.set = 1; // Break
+ }
+} // Break
+
+var break_count = 0;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ var source_line = exec_state.frame(0).sourceLineText();
+ assertTrue(source_line.indexOf("// Break") > 0);
+ exec_state.prepareStep(Debug.StepAction.StepIn, 1);
+ break_count++;
+ } catch (e) {
+ exception = e;
+ }
+}
+
+var Debug = debug.Debug;
+Debug.setListener(listener);
+
+debugger; // Break
+f(); // Break
+
+Debug.setListener(null); // Break
+assertEquals(86, break_count);
+assertNull(exception);
diff --git a/deps/v8/test/mjsunit/debug-stepin-positions.js b/deps/v8/test/mjsunit/debug-stepin-positions.js
index ff532e3dd7..ac010aac42 100644
--- a/deps/v8/test/mjsunit/debug-stepin-positions.js
+++ b/deps/v8/test/mjsunit/debug-stepin-positions.js
@@ -33,7 +33,7 @@ function DebuggerStatement() {
debugger; /*pause*/
}
-function TestCase(fun, frame_number) {
+function TestCase(fun, frame_number, line_number) {
var exception = false;
var codeSnippet = undefined;
var resultPositions = undefined;
@@ -64,8 +64,13 @@ function TestCase(fun, frame_number) {
Debug.setListener(listener);
+ var breakpointId;
+ if (line_number) breakpointId = Debug.setBreakPoint(fun, line_number);
+
fun();
+ if (line_number) Debug.clearBreakPoint(breakpointId);
+
Debug.setListener(null);
assertTrue(!exception, exception);
@@ -116,9 +121,7 @@ function TestCaseWithDebugger(fun) {
}
function TestCaseWithBreakpoint(fun, line_number, frame_number) {
- var breakpointId = Debug.setBreakPoint(fun, line_number);
- TestCase(fun, frame_number);
- Debug.clearBreakPoint(breakpointId);
+ TestCase(fun, frame_number, line_number);
}
function TestCaseWithException(fun, frame_number) {
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part1.js b/deps/v8/test/mjsunit/debug-stepout-scope-part1.js
index f49b1a07eb..cce88b73dc 100644
--- a/deps/v8/test/mjsunit/debug-stepout-scope-part1.js
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-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: --expose-debug-as debug --expose-natives-as=builtins
+// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part2.js b/deps/v8/test/mjsunit/debug-stepout-scope-part2.js
index 69cee994aa..ba05317979 100644
--- a/deps/v8/test/mjsunit/debug-stepout-scope-part2.js
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-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: --expose-debug-as debug --expose-natives-as=builtins
+// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part3.js b/deps/v8/test/mjsunit/debug-stepout-scope-part3.js
index 319f87991f..c120640605 100644
--- a/deps/v8/test/mjsunit/debug-stepout-scope-part3.js
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-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: --expose-debug-as debug --expose-natives-as=builtins
+// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part4.js b/deps/v8/test/mjsunit/debug-stepout-scope-part4.js
index eb9c82f8c7..a5743fe566 100644
--- a/deps/v8/test/mjsunit/debug-stepout-scope-part4.js
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-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: --expose-debug-as debug --expose-natives-as=builtins
+// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part5.js b/deps/v8/test/mjsunit/debug-stepout-scope-part5.js
index 250bee4d81..cabacbaa8e 100644
--- a/deps/v8/test/mjsunit/debug-stepout-scope-part5.js
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-part5.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-debug-as debug --expose-natives-as=builtins
+// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part6.js b/deps/v8/test/mjsunit/debug-stepout-scope-part6.js
index 2d8357fea4..f222fbd4fb 100644
--- a/deps/v8/test/mjsunit/debug-stepout-scope-part6.js
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-part6.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-debug-as debug --expose-natives-as=builtins
+// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part7.js b/deps/v8/test/mjsunit/debug-stepout-scope-part7.js
index 4f0c066843..eba115d26f 100644
--- a/deps/v8/test/mjsunit/debug-stepout-scope-part7.js
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-part7.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-debug-as debug --expose-natives-as=builtins
+// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part8.js b/deps/v8/test/mjsunit/debug-stepout-scope-part8.js
index f91fab5e4d..c0a8a0034a 100644
--- a/deps/v8/test/mjsunit/debug-stepout-scope-part8.js
+++ b/deps/v8/test/mjsunit/debug-stepout-scope-part8.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-debug-as debug --expose-natives-as=builtins
+// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
diff --git a/deps/v8/test/mjsunit/declare-locally.js b/deps/v8/test/mjsunit/declare-locally.js
index 20bfe6da1f..dca357b060 100644
--- a/deps/v8/test/mjsunit/declare-locally.js
+++ b/deps/v8/test/mjsunit/declare-locally.js
@@ -33,7 +33,7 @@
// This exercises the code in runtime.cc in
// DeclareGlobal...Locally().
-// Flags: --es52_globals
+// Flags: --es52-globals
this.__proto__.foo = 42;
this.__proto__.bar = 87;
diff --git a/deps/v8/test/mjsunit/deserialize-script-id.js b/deps/v8/test/mjsunit/deserialize-script-id.js
index ba54b4698e..5dca9f353a 100644
--- a/deps/v8/test/mjsunit/deserialize-script-id.js
+++ b/deps/v8/test/mjsunit/deserialize-script-id.js
@@ -5,13 +5,13 @@
// Flags: --allow-natives-syntax --cache=code
// Test that script ids are unique and we found the correct ones.
+var Debug = %GetDebugContext().Debug;
+Debug.setListener(function(){});
+
var scripts = %DebugGetLoadedScripts();
scripts.sort(function(a, b) { return a.id - b.id; });
-var user_script_count = 0;
scripts.reduce(function(prev, cur) {
assertTrue(prev === undefined || prev.id != cur.id);
- if (cur.type == 2) user_script_count++;
});
-// Found mjsunit.js and this script.
-assertEquals(2, user_script_count);
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/elements-kind.js b/deps/v8/test/mjsunit/elements-kind.js
index 64b4a094ff..cb2d178a7e 100644
--- a/deps/v8/test/mjsunit/elements-kind.js
+++ b/deps/v8/test/mjsunit/elements-kind.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 --expose-gc --nostress-opt --typed-array-max_size_in-heap=2048
+// 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',
diff --git a/deps/v8/test/mjsunit/enumeration-order.js b/deps/v8/test/mjsunit/enumeration-order.js
index 70942ee13c..d2ac90485e 100644
--- a/deps/v8/test/mjsunit/enumeration-order.js
+++ b/deps/v8/test/mjsunit/enumeration-order.js
@@ -71,9 +71,9 @@ proto2.a = 0;
proto2[2] = 0;
proto2[3] = 0; // also on the 'proto1' object
proto2.b = 0;
-proto2[4294967295] = 0;
+proto2[4294967294] = 0;
proto2.c = 0;
-proto2[4294967296] = 0;
+proto2[4294967295] = 0;
var proto1 = {};
proto1[5] = 0;
@@ -98,8 +98,8 @@ var expected = ['23', '42', // indexed from 'o'
'-23', '300000000000', 'f', 'g', '-4', // named from 'o'
'3', '5', // indexed from 'proto1'
'd', 'e', // named from 'proto1'
- '2', '140000', '4294967295', // indexed from 'proto2'
- 'a', 'b', 'c', '4294967296']; // named from 'proto2'
+ '2', '140000', '4294967294', // indexed from 'proto2'
+ 'a', 'b', 'c', '4294967295']; // named from 'proto2'
var actual = [];
for (var p in o) actual.push(p);
assertArrayEquals(expected, actual);
diff --git a/deps/v8/test/mjsunit/es6/arguments-iterator.js b/deps/v8/test/mjsunit/es6/arguments-iterator.js
index 32d4b11ee1..cf1e1f97ca 100644
--- a/deps/v8/test/mjsunit/es6/arguments-iterator.js
+++ b/deps/v8/test/mjsunit/es6/arguments-iterator.js
@@ -219,10 +219,7 @@ function TestArgumentsAsProto() {
assertSame([][Symbol.iterator], o[Symbol.iterator]);
assertFalse(o.hasOwnProperty(Symbol.iterator));
assertSame([][Symbol.iterator], o[Symbol.iterator]);
- // This should throw, but currently it doesn't, because
- // ExecutableAccessorInfo callbacks don't see the current strict mode.
- // See note in accessors.cc:SetPropertyOnInstanceIfInherited.
- o[Symbol.iterator] = 10;
+ assertThrows(function () { o[Symbol.iterator] = 10 });
assertFalse(o.hasOwnProperty(Symbol.iterator));
assertEquals([][Symbol.iterator], o[Symbol.iterator]);
assertSame([][Symbol.iterator], arguments[Symbol.iterator]);
diff --git a/deps/v8/test/mjsunit/es6/block-for.js b/deps/v8/test/mjsunit/es6/block-for.js
index b91af0116c..420c41e610 100644
--- a/deps/v8/test/mjsunit/es6/block-for.js
+++ b/deps/v8/test/mjsunit/es6/block-for.js
@@ -158,7 +158,7 @@ closure_in_for_next();
// In a for-in statement the iteration variable is fresh
-// for earch iteration.
+// for each iteration.
function closures3(x) {
let a = [];
for (let p in x) {
@@ -171,3 +171,28 @@ function closures3(x) {
}
}
closures3({a : [0], b : 1, c : {v : 1}, get d() {}, set e(x) {}});
+
+// Check normal for statement completion values.
+assertEquals(1, eval("for (let i = 0; i < 10; i++) { 1; }"));
+assertEquals(9, eval("for (let i = 0; i < 10; i++) { i; }"));
+assertEquals(undefined, eval("for (let i = 0; false;) { }"));
+assertEquals(undefined, eval("for (const i = 0; false;) { }"));
+assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { }"));
+assertEquals(undefined, eval("for (let i = 0; false;) { i; }"));
+assertEquals(undefined, eval("for (const i = 0; false;) { i; }"));
+assertEquals(undefined, eval("for (let i = 0; true;) { break; }"));
+assertEquals(undefined, eval("for (const i = 0; true;) { break; }"));
+assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { continue; }"));
+assertEquals(undefined, eval("for (let i = 0; true;) { break; i; }"));
+assertEquals(undefined, eval("for (const i = 0; true;) { break; i; }"));
+assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { continue; i; }"));
+assertEquals(0, eval("for (let i = 0; true;) { i; break; }"));
+assertEquals(0, eval("for (const i = 0; true;) { i; break; }"));
+assertEquals(9, eval("for (let i = 0; i < 10; i++) { i; continue; }"));
+assertEquals(3, eval("for (let i = 0; true; i++) { i; if (i >= 3) break; }"));
+assertEquals(2, eval("for (let i = 0; true; i++) { if (i >= 3) break; i; }"));
+assertEquals(
+ 2, eval("for (let i = 0; i < 10; i++) { if (i >= 3) continue; i; }"));
+assertEquals(undefined, eval("foo: for (let i = 0; true;) { break foo; }"));
+assertEquals(undefined, eval("foo: for (const i = 0; true;) { break foo; }"));
+assertEquals(3, eval("foo: for (let i = 3; true;) { i; break foo; }"));
diff --git a/deps/v8/test/mjsunit/es6/block-non-strict-errors.js b/deps/v8/test/mjsunit/es6/block-non-strict-errors.js
index 48cac21141..50d5f22cf1 100644
--- a/deps/v8/test/mjsunit/es6/block-non-strict-errors.js
+++ b/deps/v8/test/mjsunit/es6/block-non-strict-errors.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-classes
-
function CheckError(source) {
var exception = null;
try {
diff --git a/deps/v8/test/mjsunit/harmony/class-property-name-eval-arguments.js b/deps/v8/test/mjsunit/es6/class-property-name-eval-arguments.js
index cc53030920..72ff60fd3e 100644
--- a/deps/v8/test/mjsunit/harmony/class-property-name-eval-arguments.js
+++ b/deps/v8/test/mjsunit/es6/class-property-name-eval-arguments.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-classes --harmony-sloppy
+// Flags: --harmony-sloppy
(function Method() {
diff --git a/deps/v8/test/mjsunit/harmony/classes-experimental.js b/deps/v8/test/mjsunit/es6/classes-experimental.js
index e7ebbda735..4607a25957 100644
--- a/deps/v8/test/mjsunit/harmony/classes-experimental.js
+++ b/deps/v8/test/mjsunit/es6/classes-experimental.js
@@ -1,8 +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.
-//
-// Flags: --harmony-classes
'use strict';
(function TestArgumentsAccess() {
diff --git a/deps/v8/test/mjsunit/harmony/classes-lazy-parsing.js b/deps/v8/test/mjsunit/es6/classes-lazy-parsing.js
index 2c0301957a..c1bf31da2d 100644
--- a/deps/v8/test/mjsunit/harmony/classes-lazy-parsing.js
+++ b/deps/v8/test/mjsunit/es6/classes-lazy-parsing.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-classes --min-preparse-length=0
+// Flags: --min-preparse-length=0
'use strict';
@@ -16,6 +16,19 @@ class Derived extends Base {
m() {
return super.m();
}
+ evalM() {
+ return eval('super.m()');
+ }
}
assertEquals(42, new Derived().m());
+assertEquals(42, new Derived().evalM());
+
+
+class LazyDerived extends Base {
+ constructor() {
+ eval('super()');
+ }
+}
+assertInstanceof(new LazyDerived(), LazyDerived);
+assertInstanceof(new LazyDerived(), Base);
diff --git a/deps/v8/test/mjsunit/harmony/classes-maps.js b/deps/v8/test/mjsunit/es6/classes-maps.js
index c82fc52d8d..e519676aa6 100644
--- a/deps/v8/test/mjsunit/harmony/classes-maps.js
+++ b/deps/v8/test/mjsunit/es6/classes-maps.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-classes --allow-natives-syntax
+// Flags: --allow-natives-syntax
'use strict';
(function TestMaps() {
diff --git a/deps/v8/test/mjsunit/harmony/classes-subclass-arrays.js b/deps/v8/test/mjsunit/es6/classes-subclass-arrays.js
index e0363c715b..74feb6aeb4 100644
--- a/deps/v8/test/mjsunit/harmony/classes-subclass-arrays.js
+++ b/deps/v8/test/mjsunit/es6/classes-subclass-arrays.js
@@ -1,8 +1,7 @@
// Copyright 2015 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-classes
+
'use strict';
(function TestDefaultConstructor() {
diff --git a/deps/v8/test/mjsunit/harmony/classes.js b/deps/v8/test/mjsunit/es6/classes.js
index 9c09041345..a1420be1c2 100644
--- a/deps/v8/test/mjsunit/harmony/classes.js
+++ b/deps/v8/test/mjsunit/es6/classes.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-classes --harmony-sloppy
+// Flags: --harmony-sloppy
(function TestBasics() {
var C = class C {}
diff --git a/deps/v8/test/mjsunit/es6/debug-blockscopes.js b/deps/v8/test/mjsunit/es6/debug-blockscopes.js
index 39849da95f..31208d41f4 100644
--- a/deps/v8/test/mjsunit/es6/debug-blockscopes.js
+++ b/deps/v8/test/mjsunit/es6/debug-blockscopes.js
@@ -372,13 +372,16 @@ function for_loop_1() {
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Block,
+ debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x:'y'}, 0, exec_state);
// The function scope contains a temporary iteration variable, but it is
// hidden to the debugger.
- CheckScopeContent({}, 1, exec_state);
+ // TODO(adamk): This variable is only used to provide a TDZ for the enumerable
+ // expression and should not be visible to the debugger.
+ CheckScopeContent({x:undefined}, 1, exec_state);
};
for_loop_1();
EndTest();
@@ -398,6 +401,7 @@ function for_loop_2() {
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Block,
debug.ScopeType.Block,
+ debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
@@ -405,7 +409,9 @@ listener_delegate = function(exec_state) {
CheckScopeContent({x:'y'}, 1, exec_state);
// The function scope contains a temporary iteration variable, hidden to the
// debugger.
- CheckScopeContent({}, 2, exec_state);
+ // TODO(adamk): This variable is only used to provide a TDZ for the enumerable
+ // expression and should not be visible to the debugger.
+ CheckScopeContent({x:undefined}, 2, exec_state);
};
for_loop_2();
EndTest();
diff --git a/deps/v8/test/mjsunit/es6/debug-evaluate-blockscopes.js b/deps/v8/test/mjsunit/es6/debug-evaluate-blockscopes.js
index e24ca78315..efc334e35f 100644
--- a/deps/v8/test/mjsunit/es6/debug-evaluate-blockscopes.js
+++ b/deps/v8/test/mjsunit/es6/debug-evaluate-blockscopes.js
@@ -48,8 +48,6 @@ function f() {
// Get the Debug object exposed from the debug context global object.
var Debug = debug.Debug
-// Set breakpoint on line 6.
-var bp = Debug.setBreakPoint(f, 6);
function listener(event, exec_state, event_data, data) {
if (event == Debug.DebugEvent.Break) {
@@ -59,6 +57,10 @@ function listener(event, exec_state, event_data, data) {
// Add the debug event listener.
Debug.setListener(listener);
+
+//Set breakpoint on line 6.
+var bp = Debug.setBreakPoint(f, 6);
+
result = -1;
f();
assertEquals(1, result);
@@ -107,3 +109,5 @@ assertEquals(null, exception, exception);
exception = null;
f2();
assertEquals(null, exception, exception);
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/harmony/debug-step-into-class-extends.js b/deps/v8/test/mjsunit/es6/debug-step-into-class-extends.js
index ffc6fda63f..c368414ffc 100644
--- a/deps/v8/test/mjsunit/harmony/debug-step-into-class-extends.js
+++ b/deps/v8/test/mjsunit/es6/debug-step-into-class-extends.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-classes
+// Flags: --expose-debug-as debug
'use strict';
diff --git a/deps/v8/test/mjsunit/harmony/debug-step-into-constructor.js b/deps/v8/test/mjsunit/es6/debug-step-into-constructor.js
index dbef60f846..66fc0b99d0 100644
--- a/deps/v8/test/mjsunit/harmony/debug-step-into-constructor.js
+++ b/deps/v8/test/mjsunit/es6/debug-step-into-constructor.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-classes
+// Flags: --expose-debug-as debug
'use strict';
@@ -14,6 +14,7 @@ function listener(event, execState, eventData, data) {
if (!done) {
execState.prepareStep(Debug.StepAction.StepInto);
var s = execState.frame().sourceLineText();
+ print(s);
assertTrue(s.indexOf('// ' + stepCount + '.') !== -1);
stepCount++;
}
@@ -24,10 +25,10 @@ Debug.setListener(listener);
class Base {
- constructor() {
- var x = 1; // 1.
- var y = 2; // 2.
- done = true; // 3.
+ constructor() { // 1.
+ var x = 1; // 2.
+ var y = 2; // 3.
+ done = true; // 4.
}
}
@@ -40,7 +41,7 @@ class Derived extends Base {}
var bp = Debug.setBreakPoint(Base, 0);
new Base();
- assertEquals(4, stepCount);
+ assertEquals(5, stepCount);
Debug.clearBreakPoint(bp);
})();
@@ -52,7 +53,7 @@ class Derived extends Base {}
var bp = Debug.setBreakPoint(Base, 0);
new Derived();
- assertEquals(4, stepCount);
+ assertEquals(5, stepCount);
Debug.clearBreakPoint(bp);
})();
@@ -68,7 +69,7 @@ class Derived extends Base {}
var bp = Debug.setBreakPoint(f, 0);
f();
- assertEquals(4, stepCount);
+ assertEquals(5, stepCount);
Debug.clearBreakPoint(bp);
})();
@@ -86,7 +87,7 @@ class Derived extends Base {}
var bp = Debug.setBreakPoint(f, 0);
f();
- assertEquals(4, stepCount);
+ assertEquals(5, stepCount);
Debug.clearBreakPoint(bp);
})();
@@ -104,7 +105,7 @@ class Derived extends Base {}
var bp = Debug.setBreakPoint(f, 0);
f();
- assertEquals(4, stepCount);
+ assertEquals(5, stepCount);
Debug.clearBreakPoint(bp);
})();
diff --git a/deps/v8/test/mjsunit/es6/debug-stepnext-for.js b/deps/v8/test/mjsunit/es6/debug-stepnext-for.js
index 98af911ae3..fe50fa76b9 100644
--- a/deps/v8/test/mjsunit/es6/debug-stepnext-for.js
+++ b/deps/v8/test/mjsunit/es6/debug-stepnext-for.js
@@ -58,7 +58,9 @@ function f() {
s += a[j]; // Break L
}
- // TODO(yangguo): add test case for for-let.
+ for (let i = 0; i < 3; i++) { // Break m
+ s += a[i]; // Break M
+ }
} // Break y
function listener(event, exec_state, event_data, data) {
@@ -81,36 +83,39 @@ Debug.setListener(listener);
f();
Debug.setListener(null); // Break z
-print(JSON.stringify(log));
+print("log:\n"+ JSON.stringify(log));
// The let declaration differs from var in that the loop variable
// is declared in every iteration.
var expected = [
// Entry
"a2","b2",
- // Empty for-in-var: var decl, get enumerable
- "c7","c16",
+ // Empty for-in-var: get enumerable
+ "c16",
// Empty for-in: get enumerable
"d12",
- // For-in-var: var decl, get enumerable, assign, body, assign, body, ...
- "e7","e16","e11","E4","e11","E4","e11","E4","e11",
+ // For-in-var: get enumerable, assign, body, assign, body, ...
+ "e16","e11","E4","e11","E4","e11","E4","e11",
// For-in: get enumerable, assign, body, assign, body, ...
"f12","f7","F4","f7","F4","f7","F4","f7",
- // For-in-let: get enumerable, next, new let, body, next, new let, ...
- "g16","g11","g7","G4","g11","g7","G4","g11","g7","G4","g11",
- // For-of-var: var decl, next(), body, next(), body, ...
- "h7","h16","H4","h16","H4","h16","H4","h16",
+ // For-in-let: get enumerable, next, body, next, ...
+ "g16","g11","G4","g11","G4","g11","G4","g11",
+ // For-of-var: next(), body, next(), body, ...
+ "h16","H4","h16","H4","h16","H4","h16",
// For-of: next(), body, next(), body, ...
"i12","I4","i12","I4","i12","I4","i12",
- // For-of-let: next(), new let, body, next(), new let, ...
- "j16","j7","J4","j16","j7","J4","j16","j7","J4","j16",
+ // For-of-let: next(), body, next(), ...
+ "j16","J4","j16","J4","j16","J4","j16",
// For-var: var decl, condition, body, next, condition, body, ...
"k7","k20","K4","k23","k20","K4","k23","k20","K4","k23","k20",
// For: init, condition, body, next, condition, body, ...
- "l11","l16","L4","l19","l16","L4","l19","l16","L4","l19","l16",
+ "l7","l16","L4","l19","l16","L4","l19","l16","L4","l19","l16",
+ // For-let: init, condition, body, next, condition, body, ...
+ "m7","m20","M4","m23","m20","M4","m23","m20","M4","m23","m20",
// Exit.
"y0","z0",
]
+print("expected:\n"+ JSON.stringify(expected));
assertArrayEquals(expected, log);
-assertEquals(48, s);
+assertEquals(54, s);
assertNull(exception);
diff --git a/deps/v8/test/mjsunit/es6/generators-relocation.js b/deps/v8/test/mjsunit/es6/generators-relocation.js
index 6babb148be..2636f52d7b 100644
--- a/deps/v8/test/mjsunit/es6/generators-relocation.js
+++ b/deps/v8/test/mjsunit/es6/generators-relocation.js
@@ -25,13 +25,13 @@ function RunTest(formals_and_body, args, value1, value2) {
// Advance to the first yield.
assertIteratorResult(value1, false, obj.next());
- // Add a breakpoint on line 3 (the second yield).
- var bp = Debug.setBreakPoint(gen, 3);
-
// Enable the debugger, which should force recompilation of the generator
// function and relocation of the suspended generator activation.
Debug.setListener(listener);
+ // Add a breakpoint on line 3 (the second yield).
+ var bp = Debug.setBreakPoint(gen, 3);
+
// Check that the generator resumes and suspends properly.
assertIteratorResult(value2, false, obj.next());
diff --git a/deps/v8/test/mjsunit/es6/generators-runtime.js b/deps/v8/test/mjsunit/es6/generators-runtime.js
index 115c7a4149..98015b7f7c 100644
--- a/deps/v8/test/mjsunit/es6/generators-runtime.js
+++ b/deps/v8/test/mjsunit/es6/generators-runtime.js
@@ -35,6 +35,7 @@ function* g() { yield 1; }
var GeneratorFunctionPrototype = Object.getPrototypeOf(g);
var GeneratorFunction = GeneratorFunctionPrototype.constructor;
var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype;
+var IteratorPrototype = Object.getPrototypeOf(GeneratorObjectPrototype);
// A generator function should have the same set of properties as any
// other function.
@@ -51,16 +52,9 @@ function TestGeneratorFunctionInstance() {
var prop = f_own_property_names[i];
var f_desc = Object.getOwnPropertyDescriptor(f, prop);
var g_desc = Object.getOwnPropertyDescriptor(g, prop);
- if (prop === "prototype") {
- // ES6 draft 03-17-2015 section 25.2.2.2
- assertFalse(g_desc.writable, prop);
- assertFalse(g_desc.enumerable, prop);
- assertFalse(g_desc.configurable, prop);
- } else {
- assertEquals(f_desc.configurable, g_desc.configurable, prop);
- assertEquals(f_desc.writable, g_desc.writable, prop);
- assertEquals(f_desc.enumerable, g_desc.enumerable, prop);
- }
+ assertEquals(f_desc.configurable, g_desc.configurable, prop);
+ assertEquals(f_desc.writable, g_desc.writable, prop);
+ assertEquals(f_desc.enumerable, g_desc.enumerable, prop);
}
}
TestGeneratorFunctionInstance();
@@ -100,7 +94,7 @@ TestGeneratorFunctionPrototype();
// Functions that we associate with generator objects are actually defined by
// a common prototype.
function TestGeneratorObjectPrototype() {
- assertSame(Object.prototype,
+ assertSame(IteratorPrototype,
Object.getPrototypeOf(GeneratorObjectPrototype));
assertSame(GeneratorObjectPrototype,
Object.getPrototypeOf((function*(){yield 1}).prototype));
@@ -134,16 +128,6 @@ function TestGeneratorObjectPrototype() {
assertTrue(throw_desc.writable);
assertFalse(throw_desc.enumerable);
assertTrue(throw_desc.configurable);
-
- var 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();
@@ -165,6 +149,13 @@ function TestGeneratorFunction() {
assertTrue((new GeneratorFunction()) instanceof GeneratorFunction);
assertTrue(GeneratorFunction() instanceof GeneratorFunction);
+
+ // ES6 draft 04-14-15, section 25.2.2.2
+ var prototype_desc = Object.getOwnPropertyDescriptor(GeneratorFunction,
+ "prototype");
+ assertFalse(prototype_desc.writable);
+ assertFalse(prototype_desc.enumerable);
+ assertFalse(prototype_desc.configurable);
}
TestGeneratorFunction();
diff --git a/deps/v8/test/mjsunit/es6/indexed-integer-exotics.js b/deps/v8/test/mjsunit/es6/indexed-integer-exotics.js
index 7aefd78c4f..85ae3692d8 100644
--- a/deps/v8/test/mjsunit/es6/indexed-integer-exotics.js
+++ b/deps/v8/test/mjsunit/es6/indexed-integer-exotics.js
@@ -8,7 +8,7 @@ Object.prototype["10"] = "unreachable";
Object.prototype["7"] = "unreachable";
Object.prototype["-1"] = "unreachable";
Object.prototype["-0"] = "unreachable";
-Object.prototype["4294967296"] = "unreachable";
+Object.prototype["4294967295"] = "unreachable";
var array = new Int32Array(10);
@@ -17,12 +17,12 @@ function check() {
assertEquals(undefined, array["-1"]);
assertEquals(undefined, array["-0"]);
assertEquals(undefined, array["10"]);
- assertEquals(undefined, array["4294967296"]);
+ assertEquals(undefined, array["4294967295"]);
}
assertEquals("unreachable", array.__proto__["-1"]);
assertEquals("unreachable", array.__proto__["-0"]);
assertEquals("unreachable", array.__proto__["10"]);
- assertEquals("unreachable", array.__proto__["4294967296"]);
+ assertEquals("unreachable", array.__proto__["4294967295"]);
}
check();
@@ -30,19 +30,19 @@ check();
array["-1"] = "unreachable";
array["-0"] = "unreachable";
array["10"] = "unreachable";
-array["4294967296"] = "unreachable";
+array["4294967295"] = "unreachable";
check();
delete array["-0"];
delete array["-1"];
delete array["10"];
-delete array["4294967296"];
+delete array["4294967295"];
assertEquals(undefined, Object.getOwnPropertyDescriptor(array, "-1"));
assertEquals(undefined, Object.getOwnPropertyDescriptor(array, "-0"));
assertEquals(undefined, Object.getOwnPropertyDescriptor(array, "10"));
-assertEquals(undefined, Object.getOwnPropertyDescriptor(array, "4294967296"));
+assertEquals(undefined, Object.getOwnPropertyDescriptor(array, "4294967295"));
assertEquals(10, Object.keys(array).length);
check();
@@ -55,9 +55,10 @@ for (var i = 0; i < 3; i++) {
%OptimizeFunctionOnNextCall(f);
assertEquals(undefined, f());
-Object.defineProperty(new Int32Array(), "-1", {'value': 1});
-Object.defineProperty(new Int32Array(), "-0", {'value': 1});
-Object.defineProperty(new Int32Array(), "-10", {'value': 1});
-Object.defineProperty(new Int32Array(), "4294967296", {'value': 1});
+assertThrows('Object.defineProperty(new Int32Array(100), -1, {value: 1})');
+// -0 gets converted to the string "0", so use "-0" instead.
+assertThrows('Object.defineProperty(new Int32Array(100), "-0", {value: 1})');
+assertThrows('Object.defineProperty(new Int32Array(100), -10, {value: 1})');
+assertThrows('Object.defineProperty(new Int32Array(), 4294967295, {value: 1})');
check();
diff --git a/deps/v8/test/mjsunit/es6/iterator-prototype.js b/deps/v8/test/mjsunit/es6/iterator-prototype.js
new file mode 100644
index 0000000000..0b266e9897
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/iterator-prototype.js
@@ -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.
+
+var arrayIteratorPrototype = [].entries().__proto__;
+var iteratorPrototype = arrayIteratorPrototype.__proto__;
+
+assertSame(Object.prototype, Object.getPrototypeOf(iteratorPrototype));
+assertTrue(Object.isExtensible(iteratorPrototype));
+assertSame(0, Object.getOwnPropertyNames(iteratorPrototype).length);
+assertSame(1, Object.getOwnPropertySymbols(iteratorPrototype).length);
+assertSame(Symbol.iterator,
+ Object.getOwnPropertySymbols(iteratorPrototype)[0]);
+
+var descr = Object.getOwnPropertyDescriptor(iteratorPrototype, Symbol.iterator);
+assertTrue(descr.configurable);
+assertFalse(descr.enumerable);
+assertTrue(descr.writable);
+
+var iteratorFunction = descr.value;
+assertSame('function', typeof iteratorFunction);
+assertSame(0, iteratorFunction.length);
+assertSame('[Symbol.iterator]', iteratorFunction.name);
+
+var obj = {};
+assertSame(obj, iteratorFunction.call(obj));
+assertSame(iteratorPrototype, iteratorPrototype[Symbol.iterator]());
+
+var mapIteratorPrototype = new Map().entries().__proto__;
+var setIteratorPrototype = new Set().values().__proto__;
+var stringIteratorPrototype = 'abc'[Symbol.iterator]().__proto__;
+assertSame(iteratorPrototype, mapIteratorPrototype.__proto__);
+assertSame(iteratorPrototype, setIteratorPrototype.__proto__);
+assertSame(iteratorPrototype, stringIteratorPrototype.__proto__);
+
+var typedArrays = [
+ Float32Array,
+ Float64Array,
+ Int16Array,
+ Int32Array,
+ Int8Array,
+ Uint16Array,
+ Uint32Array,
+ Uint8Array,
+ Uint8ClampedArray,
+];
+
+for (var constructor of typedArrays) {
+ var array = new constructor();
+ var iterator = array[Symbol.iterator]();
+ assertSame(iteratorPrototype, iterator.__proto__.__proto__);
+}
+
+function* gen() {}
+assertSame(iteratorPrototype, gen.prototype.__proto__.__proto__);
+var g = gen();
+assertSame(gen.prototype, g.__proto__);
+assertSame(iteratorPrototype, g.__proto__.__proto__.__proto__);
diff --git a/deps/v8/test/mjsunit/harmony/method-name-eval-arguments.js b/deps/v8/test/mjsunit/es6/method-name-eval-arguments.js
index 360aadbca9..8792177e25 100644
--- a/deps/v8/test/mjsunit/harmony/method-name-eval-arguments.js
+++ b/deps/v8/test/mjsunit/es6/method-name-eval-arguments.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-object-literals
-
(function TestSloppyMode() {
var o = {
eval() {
diff --git a/deps/v8/test/mjsunit/harmony/object-literals-method.js b/deps/v8/test/mjsunit/es6/object-literals-method.js
index 535231ea62..e4527cb776 100644
--- a/deps/v8/test/mjsunit/harmony/object-literals-method.js
+++ b/deps/v8/test/mjsunit/es6/object-literals-method.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-object-literals --allow-natives-syntax
+// Flags: --allow-natives-syntax
(function TestBasics() {
@@ -156,6 +156,7 @@
var GeneratorFunction = function*() {}.__proto__.constructor;
+var GeneratorPrototype = Object.getPrototypeOf(function*() {}).prototype;
function assertIteratorResult(value, done, result) {
@@ -215,6 +216,19 @@ function assertIteratorResult(value, done, result) {
})();
+(function TestGeneratorPrototypeDescriptor() {
+ var object = {
+ *method() {}
+ };
+
+ var desc = Object.getOwnPropertyDescriptor(object.method, 'prototype');
+ assertFalse(desc.enumerable);
+ assertFalse(desc.configurable);
+ assertTrue(desc.writable);
+ assertEquals(GeneratorPrototype, Object.getPrototypeOf(desc.value));
+})();
+
+
(function TestGeneratorProto() {
var object = {
*method() {}
diff --git a/deps/v8/test/mjsunit/harmony/object-literals-property-shorthand.js b/deps/v8/test/mjsunit/es6/object-literals-property-shorthand.js
index 9756da46c1..29ce66d270 100644
--- a/deps/v8/test/mjsunit/harmony/object-literals-property-shorthand.js
+++ b/deps/v8/test/mjsunit/es6/object-literals-property-shorthand.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-object-literals
-
(function TestBasics() {
var x = 1;
diff --git a/deps/v8/test/mjsunit/es6/promise-internal-setter.js b/deps/v8/test/mjsunit/es6/promise-internal-setter.js
new file mode 100644
index 0000000000..83e4738316
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/promise-internal-setter.js
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+'use strict';
+
+Object.defineProperties(Object.prototype, {
+ promise: {set: assertUnreachable},
+ reject: {set: assertUnreachable},
+ resolve: {set: assertUnreachable},
+});
+
+class P extends Promise {}
+
+P.all([Promise.resolve('ok')]);
+P.race([Promise.resolve('ok')]);
+P.defer();
diff --git a/deps/v8/test/mjsunit/es6/regress/regress-2506.js b/deps/v8/test/mjsunit/es6/regress/regress-2506.js
index b5cc91dbd7..5f88fcd1d4 100644
--- a/deps/v8/test/mjsunit/es6/regress/regress-2506.js
+++ b/deps/v8/test/mjsunit/es6/regress/regress-2506.js
@@ -18,15 +18,15 @@ assertEquals(3, f[2]());
let x = 1;
s = 0;
-for (const x of [x, x+1, x+2]) {
- s += x;
+for (const z of [x, x+1, x+2]) {
+ s += z;
}
assertEquals(6, s);
s = 0;
var q = 1;
-for (const q of [q, q+1, q+2]) {
- s += q;
+for (const x of [q, q+1, q+2]) {
+ s += x;
}
assertEquals(6, s);
@@ -56,15 +56,15 @@ assertThrows("'use strict'; for (const x in [1,2,3]) { x++ }", TypeError);
let x = 1;
s = 0;
- for (const x of [x, x+1, x+2]) {
- s += x;
+ for (const q of [x, x+1, x+2]) {
+ s += q;
}
assertEquals(6, s);
s = 0;
var q = 1;
- for (const q of [q, q+1, q+2]) {
- s += q;
+ for (const x of [q, q+1, q+2]) {
+ s += x;
}
assertEquals(6, s);
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-3750.js b/deps/v8/test/mjsunit/es6/regress/regress-3750.js
index d1f21f9bd3..a425def2b7 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-3750.js
+++ b/deps/v8/test/mjsunit/es6/regress/regress-3750.js
@@ -1,8 +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-classes
+
'use strict';
class Example { }
Object.observe(Example.prototype, function(){});
diff --git a/deps/v8/test/mjsunit/es6/regress/regress-4097.js b/deps/v8/test/mjsunit/es6/regress/regress-4097.js
new file mode 100644
index 0000000000..52f2e9f20d
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/regress/regress-4097.js
@@ -0,0 +1,37 @@
+// Copyright 2015 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 StoreToSuper () {
+ "use strict";
+ class A {
+ s() {
+ super.bla = 10;
+ }
+ };
+
+ let a = new A();
+ (new A).s.call(a);
+ assertEquals(10, a.bla);
+ assertThrows(function() { (new A).s.call(undefined); }, TypeError);
+ assertThrows(function() { (new A).s.call(42); }, TypeError);
+ assertThrows(function() { (new A).s.call(null); }, TypeError);
+ assertThrows(function() { (new A).s.call("abc"); }, TypeError);
+})();
+
+
+(function LoadFromSuper () {
+ "use strict";
+ class A {
+ s() {
+ return super.bla;
+ }
+ };
+
+ let a = new A();
+ assertSame(undefined, (new A).s.call(a));
+ assertSame(undefined, (new A).s.call(undefined));
+ assertSame(undefined, (new A).s.call(42));
+ assertSame(undefined, (new A).s.call(null));
+ assertSame(undefined, (new A).s.call("abc"));
+})();
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-455141.js b/deps/v8/test/mjsunit/es6/regress/regress-455141.js
index cf2141f903..676adebe72 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-455141.js
+++ b/deps/v8/test/mjsunit/es6/regress/regress-455141.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-classes --no-lazy
+// Flags: --no-lazy
"use strict";
class Base {
}
diff --git a/deps/v8/test/mjsunit/es6/string-html.js b/deps/v8/test/mjsunit/es6/string-html.js
index 4f3feb56dd..690830ba84 100644
--- a/deps/v8/test/mjsunit/es6/string-html.js
+++ b/deps/v8/test/mjsunit/es6/string-html.js
@@ -157,3 +157,45 @@ assertThrows(function() {
String.prototype.sup.call(null);
}, TypeError);
assertEquals(String.prototype.sup.length, 0);
+
+
+(function TestToString() {
+ var calls = 0;
+ var obj = {
+ toString() {
+ calls++;
+ return 'abc';
+ },
+ valueOf() {
+ assertUnreachable();
+ }
+ };
+
+ var methodNames = [
+ 'anchor',
+ 'big',
+ 'blink',
+ 'bold',
+ 'fixed',
+ 'fontcolor',
+ 'fontsize',
+ 'italics',
+ 'link',
+ 'small',
+ 'strike',
+ 'sub',
+ 'sup',
+ ];
+ for (var name of methodNames) {
+ calls = 0;
+ String.prototype[name].call(obj);
+ assertEquals(1, calls);
+ }
+})();
+
+
+(function TestDeleteStringRelace() {
+ assertEquals('<a name="n">s</a>', 's'.anchor('n'));
+ assertTrue(delete String.prototype.replace);
+ assertEquals('<a name="n">s</a>', 's'.anchor('n'));
+})();
diff --git a/deps/v8/test/mjsunit/es6/templates.js b/deps/v8/test/mjsunit/es6/templates.js
index 0734f0e5d0..feb7364613 100644
--- a/deps/v8/test/mjsunit/es6/templates.js
+++ b/deps/v8/test/mjsunit/es6/templates.js
@@ -588,6 +588,26 @@ var global = this;
})();
+(function testReturnValueAsTagFn() {
+ "use strict";
+ var i = 0;
+ function makeTag() {
+ return function tag(cs) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ var rcs = [];
+ rcs.raw = cs.map(function(s) {
+ return '!' + s + '!';
+ });
+ args.unshift(rcs);
+ return String.raw.apply(null, args);
+ }
+ }
+ assertEquals('!hi!', makeTag()`hi`);
+ assertEquals('!test!0!test!', makeTag()`test${0}test`);
+ assertEquals('!!', makeTag()``);
+});
+
+
(function testToStringSubstitutions() {
var a = {
toString: function() { return "a"; },
diff --git a/deps/v8/test/mjsunit/harmony/toMethod.js b/deps/v8/test/mjsunit/es6/toMethod.js
index 81db5830c2..c18251b2dc 100644
--- a/deps/v8/test/mjsunit/harmony/toMethod.js
+++ b/deps/v8/test/mjsunit/es6/toMethod.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-classes --allow-natives-syntax
+// Flags: --allow-natives-syntax
(function TestSingleClass() {
diff --git a/deps/v8/test/mjsunit/es6/typedarray-copywithin.js b/deps/v8/test/mjsunit/es6/typedarray-copywithin.js
new file mode 100644
index 0000000000..ad5a0df563
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/typedarray-copywithin.js
@@ -0,0 +1,173 @@
+// Copyright 2015 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 typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array];
+
+function CheckEachTypedArray(fn) {
+ typedArrayConstructors.forEach(fn);
+}
+
+CheckEachTypedArray(function copyWithinArity(constructor) {
+ assertEquals(new constructor([]).copyWithin.length, 2);
+});
+
+
+CheckEachTypedArray(function copyWithinTargetAndStart(constructor) {
+ // works with two arguments
+ assertArrayEquals([4, 5, 3, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(0, 3));
+ assertArrayEquals([1, 4, 5, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(1, 3));
+ assertArrayEquals([1, 3, 4, 5, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(1, 2));
+ assertArrayEquals([1, 2, 3, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(2, 2));
+});
+
+
+CheckEachTypedArray(function copyWithinTargetStartAndEnd(constructor) {
+ // works with three arguments
+ assertArrayEquals(new constructor([1, 2, 3, 4, 5]).copyWithin(0, 3, 4),
+ [4, 2, 3, 4, 5]);
+ assertArrayEquals(new constructor([1, 2, 3, 4, 5]).copyWithin(1, 3, 4),
+ [1, 4, 3, 4, 5]);
+ assertArrayEquals(new constructor([1, 2, 3, 4, 5]).copyWithin(1, 2, 4),
+ [1, 3, 4, 4, 5]);
+});
+
+
+CheckEachTypedArray(function copyWithinNegativeRelativeOffsets(constructor) {
+ // works with negative arguments
+ assertArrayEquals([4, 5, 3, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(0, -2));
+ assertArrayEquals([4, 2, 3, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(0, -2, -1));
+ assertArrayEquals([1, 3, 3, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(-4, -3, -2));
+ assertArrayEquals([1, 3, 4, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(-4, -3, -1));
+ assertArrayEquals([1, 3, 4, 5, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(-4, -3));
+ // test with arguments equal to -this.length
+ assertArrayEquals([1, 2, 3, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(-5, 0));
+});
+
+
+CheckEachTypedArray(function mustBeTypedArray(constructor) {
+ // throws on non-TypedArray values
+ assertThrows(function() {
+ return constructor.prototype.copyWithin.call(null, 0, 3);
+ }, TypeError);
+ assertThrows(function() {
+ return constructor.prototype.copyWithin.call(undefined, 0, 3);
+ }, TypeError);
+ assertThrows(function() {
+ return constructor.prototype.copyWithin.call(34, 0, 3);
+ }, TypeError);
+ assertThrows(function() {
+ return constructor.prototype.copyWithin.call([1, 2, 3, 4, 5], 0, 3);
+ }, TypeError);
+});
+
+
+CheckEachTypedArray(function copyWithinStartLessThanTarget(constructor) {
+ // test with target > start on 2 arguments
+ assertArrayEquals([1, 2, 3, 1, 2],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(3, 0));
+
+ // test with target > start on 3 arguments
+ assertArrayEquals([1, 2, 3, 1, 2],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(3, 0, 4));
+});
+
+CheckEachTypedArray(function copyWithinNonIntegerRelativeOffsets(constructor) {
+ // test on fractional arguments
+ assertArrayEquals([4, 5, 3, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(0.2, 3.9));
+});
+
+
+CheckEachTypedArray(function copyWithinNegativeZeroTarget(constructor) {
+ // test with -0
+ assertArrayEquals([4, 5, 3, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(-0, 3));
+});
+
+
+CheckEachTypedArray(function copyWithinTargetOutsideStart(constructor) {
+ // test with arguments more than this.length
+ assertArrayEquals([1, 2, 3, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(0, 7));
+
+ // test with arguments less than -this.length
+ assertArrayEquals([1, 2, 3, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(-7, 0));
+});
+
+
+CheckEachTypedArray(function copyWithinEmptyArray(constructor) {
+ // test on empty array
+ assertArrayEquals([], new constructor([]).copyWithin(0, 3));
+});
+
+
+CheckEachTypedArray(function copyWithinTargetCutOff(constructor) {
+ // test with target range being shorter than end - start
+ assertArrayEquals([1, 2, 2, 3, 4], [1, 2, 3, 4, 5].copyWithin(2, 1, 4));
+});
+
+
+CheckEachTypedArray(function copyWithinOverlappingRanges(constructor) {
+ // test overlapping ranges
+ var arr = [1, 2, 3, 4, 5];
+ arr.copyWithin(2, 1, 4);
+ assertArrayEquals([1, 2, 2, 2, 3], arr.copyWithin(2, 1, 4));
+});
+
+
+CheckEachTypedArray(function copyWithinDefaultEnd(constructor) {
+ // undefined as third argument
+ assertArrayEquals([4, 5, 3, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(0, 3, undefined));
+});
+
+
+CheckEachTypedArray(function copyWithinLargeArray(constructor) {
+ var large = 10000;
+
+ // test on a large array
+ var arr = new constructor(large);
+ assertArrayEquals(arr, arr.copyWithin(45, 9000));
+
+ var expected = new Array(large);
+ // test on numbers
+ for (var i = 0; i < large; i++) {
+ arr[i] = Math.random() * 100; // May be cast to an int
+ expected[i] = arr[i];
+ if (i >= 9000) {
+ expected[(i - 9000) + 45] = arr[i];
+ }
+ }
+ assertArrayEquals(expected, arr.copyWithin(45, 9000));
+
+ // test array length remains same
+ assertEquals(large, arr.length);
+});
+
+
+CheckEachTypedArray(function copyWithinNullEnd(constructor) {
+ // test null on third argument is converted to +0
+ assertArrayEquals([1, 2, 3, 4, 5],
+ new constructor([1, 2, 3, 4, 5]).copyWithin(0, 3, null));
+});
diff --git a/deps/v8/test/mjsunit/harmony/typedarrays-every.js b/deps/v8/test/mjsunit/es6/typedarray-every.js
index 3f95ba9d4c..22132f32b1 100644
--- a/deps/v8/test/mjsunit/harmony/typedarrays-every.js
+++ b/deps/v8/test/mjsunit/es6/typedarray-every.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-arrays --allow-natives-syntax
+// Flags: --allow-natives-syntax
var typedArrayConstructors = [
Uint8Array,
@@ -85,8 +85,9 @@ function TestTypedArrayForEach(constructor) {
// still make .forEach() finish, and the array should keep being
// empty after neutering it.
count = 0;
- a = new constructor(2);
+ a = new constructor(3);
result = a.every(function (n, index, array) {
+ assertFalse(array[index] === undefined); // don't get here if neutered
if (count > 0) %ArrayBufferNeuter(array.buffer);
array[index] = n + 1;
count++;
@@ -134,6 +135,16 @@ function TestTypedArrayForEach(constructor) {
constructor.prototype.every.call(a, function (x) { count++; return true; });
assertEquals(a.length, count);
}
+
+ // Shadowing length doesn't affect every, unlike Array.prototype.every
+ a = new constructor([1, 2]);
+ Object.defineProperty(a, 'length', {value: 1});
+ var x = 0;
+ assertEquals(a.every(function(elt) { x += elt; return true; }), true);
+ assertEquals(x, 3);
+ assertEquals(Array.prototype.every.call(a,
+ function(elt) { x += elt; return true; }), true);
+ assertEquals(x, 4);
}
for (i = 0; i < typedArrayConstructors.length; i++) {
diff --git a/deps/v8/test/mjsunit/es6/typedarray-fill.js b/deps/v8/test/mjsunit/es6/typedarray-fill.js
new file mode 100644
index 0000000000..2c612016f6
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/typedarray-fill.js
@@ -0,0 +1,45 @@
+// Copyright 2015 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 typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array];
+
+for (var constructor of typedArrayConstructors) {
+ assertEquals(1, constructor.prototype.fill.length);
+
+ assertArrayEquals(new constructor([]).fill(8), []);
+ assertArrayEquals(new constructor([0, 0, 0, 0, 0]).fill(8), [8, 8, 8, 8, 8]);
+ assertArrayEquals(new constructor([0, 0, 0, 0, 0]).fill(8, 1), [0, 8, 8, 8, 8]);
+ assertArrayEquals(new constructor([0, 0, 0, 0, 0]).fill(8, 10), [0, 0, 0, 0, 0]);
+ assertArrayEquals(new constructor([0, 0, 0, 0, 0]).fill(8, -5), [8, 8, 8, 8, 8]);
+ assertArrayEquals(new constructor([0, 0, 0, 0, 0]).fill(8, 1, 4), [0, 8, 8, 8, 0]);
+ assertArrayEquals(new constructor([0, 0, 0, 0, 0]).fill(8, 1, -1), [0, 8, 8, 8, 0]);
+ assertArrayEquals(new constructor([0, 0, 0, 0, 0]).fill(8, 1, 42), [0, 8, 8, 8, 8]);
+ assertArrayEquals(new constructor([0, 0, 0, 0, 0]).fill(8, -3, 42), [0, 0, 8, 8, 8]);
+ assertArrayEquals(new constructor([0, 0, 0, 0, 0]).fill(8, -3, 4), [0, 0, 8, 8, 0]);
+ assertArrayEquals(new constructor([0, 0, 0, 0, 0]).fill(8, -2, -1), [0, 0, 0, 8, 0]);
+ assertArrayEquals(new constructor([0, 0, 0, 0, 0]).fill(8, -1, -3), [0, 0, 0, 0, 0]);
+ assertArrayEquals(new constructor([0, 0, 0, 0, 0]).fill(8, 0, 4), [8, 8, 8, 8, 0]);
+
+ // Test exceptions
+ assertThrows('constructor.prototype.fill.call(null)', TypeError);
+ assertThrows('constructor.prototype.fill.call(undefined)', TypeError);
+ assertThrows('constructor.prototype.fill.call([])', TypeError);
+
+ // Shadowing length doesn't affect fill, unlike Array.prototype.fill
+ var a = new constructor([2, 2]);
+ Object.defineProperty(a, 'length', {value: 1});
+ a.fill(3);
+ assertArrayEquals([a[0], a[1]], [3, 3]);
+ Array.prototype.fill.call(a, 4);
+ assertArrayEquals([a[0], a[1]], [4, 3]);
+}
diff --git a/deps/v8/test/mjsunit/es6/typedarray-find.js b/deps/v8/test/mjsunit/es6/typedarray-find.js
new file mode 100644
index 0000000000..69ceedc8b5
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/typedarray-find.js
@@ -0,0 +1,187 @@
+// Copyright 2015 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 typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array];
+
+for (var constructor of typedArrayConstructors) {
+
+assertEquals(1, constructor.prototype.find.length);
+
+var a = new constructor([21, 22, 23, 24]);
+assertEquals(undefined, a.find(function() { return false; }));
+assertEquals(21, a.find(function() { return true; }));
+assertEquals(undefined, a.find(function(val) { return 121 === val; }));
+assertEquals(24, a.find(function(val) { return 24 === val; }));
+assertEquals(23, a.find(function(val) { return 23 === val; }), null);
+assertEquals(22, a.find(function(val) { return 22 === val; }), undefined);
+
+
+//
+// Test predicate is not called when array is empty
+//
+(function() {
+ var a = new constructor([]);
+ var l = -1;
+ var o = -1;
+ var v = -1;
+ var k = -1;
+
+ a.find(function(val, key, obj) {
+ o = obj;
+ l = obj.length;
+ v = val;
+ k = key;
+
+ return false;
+ });
+
+ assertEquals(-1, l);
+ assertEquals(-1, o);
+ assertEquals(-1, v);
+ assertEquals(-1, k);
+})();
+
+
+//
+// Test predicate is called with correct arguments
+//
+(function() {
+ var a = new constructor([5]);
+ var l = -1;
+ var o = -1;
+ var v = -1;
+ var k = -1;
+
+ var found = a.find(function(val, key, obj) {
+ o = obj;
+ l = obj.length;
+ v = val;
+ k = key;
+
+ return false;
+ });
+
+ assertArrayEquals(a, o);
+ assertEquals(a.length, l);
+ assertEquals(5, v);
+ assertEquals(0, k);
+ assertEquals(undefined, found);
+})();
+
+
+//
+// Test predicate is called array.length times
+//
+(function() {
+ var a = new constructor([1, 2, 3, 4, 5]);
+ var l = 0;
+ var found = a.find(function() {
+ l++;
+ return false;
+ });
+
+ assertEquals(a.length, l);
+ assertEquals(undefined, found);
+})();
+
+
+//
+// Test array modifications
+//
+(function() {
+ a = new constructor([1, 2, 3]);
+ found = a.find(function(val, key) { a[key] = ++val; return false; });
+ assertArrayEquals([2, 3, 4], a);
+ assertEquals(3, a.length);
+ assertEquals(undefined, found);
+})();
+
+//
+// Test thisArg
+//
+(function() {
+ // Test String as a thisArg
+ var found = new constructor([1, 2, 3]).find(function(val, key) {
+ return this.charAt(Number(key)) === String(val);
+ }, "321");
+ assertEquals(2, found);
+
+ // Test object as a thisArg
+ var thisArg = {
+ elementAt: function(key) {
+ return this[key];
+ }
+ };
+ Array.prototype.push.apply(thisArg, [3, 2, 1]);
+
+ found = new constructor([1, 2, 3]).find(function(val, key) {
+ return this.elementAt(key) === val;
+ }, thisArg);
+ assertEquals(2, found);
+
+ // Create a new object in each function call when receiver is a
+ // primitive value. See ECMA-262, Annex C.
+ a = [];
+ new constructor([1, 2]).find(function() { a.push(this) }, "");
+ assertTrue(a[0] !== a[1]);
+
+ // Do not create a new object otherwise.
+ a = [];
+ new constructor([1, 2]).find(function() { a.push(this) }, {});
+ assertEquals(a[0], a[1]);
+
+ // In strict mode primitive values should not be coerced to an object.
+ a = [];
+ new constructor([1, 2]).find(function() { 'use strict'; a.push(this); }, "");
+ assertEquals("", a[0]);
+ assertEquals(a[0], a[1]);
+
+})();
+
+// Test exceptions
+assertThrows('constructor.prototype.find.call(null, function() { })',
+ TypeError);
+assertThrows('constructor.prototype.find.call(undefined, function() { })',
+ TypeError);
+assertThrows('constructor.prototype.find.apply(null, function() { }, [])',
+ TypeError);
+assertThrows('constructor.prototype.find.apply(undefined, function() { }, [])',
+ TypeError);
+assertThrows('constructor.prototype.find.apply([], function() { }, [])',
+ TypeError);
+assertThrows('constructor.prototype.find.apply({}, function() { }, [])',
+ TypeError);
+assertThrows('constructor.prototype.find.apply("", function() { }, [])',
+ TypeError);
+
+assertThrows('new constructor([]).find(null)', TypeError);
+assertThrows('new constructor([]).find(undefined)', TypeError);
+assertThrows('new constructor([]).find(0)', TypeError);
+assertThrows('new constructor([]).find(true)', TypeError);
+assertThrows('new constructor([]).find(false)', TypeError);
+assertThrows('new constructor([]).find("")', TypeError);
+assertThrows('new constructor([]).find({})', TypeError);
+assertThrows('new constructor([]).find([])', TypeError);
+assertThrows('new constructor([]).find(/\d+/)', TypeError);
+
+// Shadowing length doesn't affect find, unlike Array.prototype.find
+a = new constructor([1, 2]);
+Object.defineProperty(a, 'length', {value: 1});
+var x = 0;
+assertEquals(a.find(function(elt) { x += elt; return false; }), undefined);
+assertEquals(x, 3);
+assertEquals(Array.prototype.find.call(a,
+ function(elt) { x += elt; return false; }), undefined);
+assertEquals(x, 4);
+
+}
diff --git a/deps/v8/test/mjsunit/es6/typedarray-findindex.js b/deps/v8/test/mjsunit/es6/typedarray-findindex.js
new file mode 100644
index 0000000000..51c439203d
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/typedarray-findindex.js
@@ -0,0 +1,187 @@
+// 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 typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array];
+
+for (var constructor of typedArrayConstructors) {
+
+assertEquals(1, constructor.prototype.findIndex.length);
+
+var a = new constructor([21, 22, 23, 24]);
+assertEquals(-1, a.findIndex(function() { return false; }));
+assertEquals(-1, a.findIndex(function(val) { return 121 === val; }));
+assertEquals(0, a.findIndex(function() { return true; }));
+assertEquals(1, a.findIndex(function(val) { return 22 === val; }), undefined);
+assertEquals(2, a.findIndex(function(val) { return 23 === val; }), null);
+assertEquals(3, a.findIndex(function(val) { return 24 === val; }));
+
+
+//
+// Test predicate is not called when array is empty
+//
+(function() {
+ var a = new constructor([]);
+ var l = -1;
+ var o = -1;
+ var v = -1;
+ var k = -1;
+
+ a.findIndex(function(val, key, obj) {
+ o = obj;
+ l = obj.length;
+ v = val;
+ k = key;
+
+ return false;
+ });
+
+ assertEquals(-1, l);
+ assertEquals(-1, o);
+ assertEquals(-1, v);
+ assertEquals(-1, k);
+})();
+
+
+//
+// Test predicate is called with correct argumetns
+//
+(function() {
+ var a = new constructor([5]);
+ var l = -1;
+ var o = -1;
+ var v = -1;
+ var k = -1;
+
+ var index = a.findIndex(function(val, key, obj) {
+ o = obj;
+ l = obj.length;
+ v = val;
+ k = key;
+
+ return false;
+ });
+
+ assertArrayEquals(a, o);
+ assertEquals(a.length, l);
+ assertEquals(5, v);
+ assertEquals(0, k);
+ assertEquals(-1, index);
+})();
+
+
+//
+// Test predicate is called array.length times
+//
+(function() {
+ var a = new constructor([1, 2, 3, 4, 5]);
+ var l = 0;
+
+ a.findIndex(function() {
+ l++;
+ return false;
+ });
+
+ assertEquals(a.length, l);
+})();
+
+
+//
+// Test array modifications
+//
+(function() {
+ a = new constructor([1, 2, 3]);
+ a.findIndex(function(val, key) { a[key] = ++val; return false; });
+ assertArrayEquals([2, 3, 4], a);
+ assertEquals(3, a.length);
+})();
+
+
+//
+// Test thisArg
+//
+(function() {
+ // Test String as a thisArg
+ var index = new constructor([1, 2, 3]).findIndex(function(val, key) {
+ return this.charAt(Number(key)) === String(val);
+ }, "321");
+ assertEquals(1, index);
+
+ // Test object as a thisArg
+ var thisArg = {
+ elementAt: function(key) {
+ return this[key];
+ }
+ };
+ Array.prototype.push.apply(thisArg, [3, 2, 1]);
+
+ index = new constructor([1, 2, 3]).findIndex(function(val, key) {
+ return this.elementAt(key) === val;
+ }, thisArg);
+ assertEquals(1, index);
+
+ // Create a new object in each function call when receiver is a
+ // primitive value. See ECMA-262, Annex C.
+ a = [];
+ new constructor([1, 2]).findIndex(function() { a.push(this) }, "");
+ assertTrue(a[0] !== a[1]);
+
+ // Do not create a new object otherwise.
+ a = [];
+ new constructor([1, 2]).findIndex(function() { a.push(this) }, {});
+ assertEquals(a[0], a[1]);
+
+ // In strict mode primitive values should not be coerced to an object.
+ a = [];
+ new constructor([1, 2]).findIndex(function() { 'use strict'; a.push(this); }, "");
+ assertEquals("", a[0]);
+ assertEquals(a[0], a[1]);
+
+})();
+
+// Test exceptions
+assertThrows('constructor.prototype.findIndex.call(null, function() { })',
+ TypeError);
+assertThrows('constructor.prototype.findIndex.call(undefined, function() { })',
+ TypeError);
+assertThrows('constructor.prototype.findIndex.apply(null, function() { }, [])',
+ TypeError);
+assertThrows('constructor.prototype.findIndex.apply(undefined, function() { }, [])',
+ TypeError);
+assertThrows('constructor.prototype.findIndex.apply([], function() { }, [])',
+ TypeError);
+assertThrows('constructor.prototype.findIndex.apply({}, function() { }, [])',
+ TypeError);
+assertThrows('constructor.prototype.findIndex.apply("", function() { }, [])',
+ TypeError);
+
+assertThrows('new constructor([]).findIndex(null)', TypeError);
+assertThrows('new constructor([]).findIndex(undefined)', TypeError);
+assertThrows('new constructor([]).findIndex(0)', TypeError);
+assertThrows('new constructor([]).findIndex(true)', TypeError);
+assertThrows('new constructor([]).findIndex(false)', TypeError);
+assertThrows('new constructor([]).findIndex("")', TypeError);
+assertThrows('new constructor([]).findIndex({})', TypeError);
+assertThrows('new constructor([]).findIndex([])', TypeError);
+assertThrows('new constructor([]).findIndex(/\d+/)', TypeError);
+
+// Shadowing length doesn't affect findIndex, unlike Array.prototype.findIndex
+a = new constructor([1, 2]);
+Object.defineProperty(a, 'length', {value: 1});
+var x = 0;
+assertEquals(a.findIndex(function(elt) { x += elt; return false; }), -1);
+assertEquals(x, 3);
+assertEquals(Array.prototype.findIndex.call(a,
+ function(elt) { x += elt; return false; }), -1);
+assertEquals(x, 4);
+
+}
diff --git a/deps/v8/test/mjsunit/harmony/typedarrays-foreach.js b/deps/v8/test/mjsunit/es6/typedarray-foreach.js
index 4bfa655449..b9789805f6 100644
--- a/deps/v8/test/mjsunit/harmony/typedarrays-foreach.js
+++ b/deps/v8/test/mjsunit/es6/typedarray-foreach.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-arrays --allow-natives-syntax
+// Flags: --allow-natives-syntax
var typedArrayConstructors = [
Uint8Array,
@@ -85,8 +85,13 @@ function TestTypedArrayForEach(constructor) {
assertEquals(42, a[1]);
// Neutering the buffer backing the typed array mid-way should
- // still make .forEach() finish, and the array should keep being
- // empty after neutering it.
+ // still make .forEach() finish, but exiting early due to the missing
+ // elements, and the array should keep being empty after detaching it.
+ // TODO(dehrenberg): According to the ES6 spec, accessing or testing
+ // for members on a detached TypedArray should throw, so really this
+ // should throw in the third iteration. However, this behavior matches
+ // the Khronos spec.
+ a = new constructor(3);
count = 0;
a.forEach(function (n, index, array) {
if (count > 0) %ArrayBufferNeuter(array.buffer);
@@ -133,6 +138,16 @@ function TestTypedArrayForEach(constructor) {
constructor.prototype.forEach.call(a, function (x) { count++ });
assertEquals(a.length, count);
}
+
+ // Shadowing length doesn't affect forEach, unlike Array.prototype.forEach
+ a = new constructor([1, 2]);
+ Object.defineProperty(a, 'length', {value: 1});
+ var x = 0;
+ assertEquals(a.forEach(function(elt) { x += elt; }), undefined);
+ assertEquals(x, 3);
+ assertEquals(Array.prototype.forEach.call(a,
+ function(elt) { x += elt; }), undefined);
+ assertEquals(x, 4);
}
for (i = 0; i < typedArrayConstructors.length; i++) {
diff --git a/deps/v8/test/mjsunit/es6/typedarray-from.js b/deps/v8/test/mjsunit/es6/typedarray-from.js
new file mode 100644
index 0000000000..709c453379
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/typedarray-from.js
@@ -0,0 +1,121 @@
+// Copyright 2015 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 typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array
+];
+
+for (var constructor of typedArrayConstructors) {
+ assertEquals(1, constructor.from.length);
+
+ // TypedArray.from only callable on this subclassing %TypedArray%
+ assertThrows(function () {constructor.from.call(Array, [])}, TypeError);
+
+ function assertArrayLikeEquals(value, expected, type) {
+ assertEquals(value.__proto__, type.prototype);
+ assertEquals(expected.length, value.length);
+ for (var i = 0; i < value.length; ++i) {
+ assertEquals(expected[i], value[i]);
+ }
+ }
+
+ // Assert that calling mapfn with / without thisArg in sloppy and strict modes
+ // works as expected.
+ var global = this;
+ function non_strict() { assertEquals(global, this); }
+ function strict() { 'use strict'; assertEquals(undefined, this); }
+ function strict_null() { 'use strict'; assertEquals(null, this); }
+ constructor.from([1], non_strict);
+ constructor.from([1], non_strict, void 0);
+ constructor.from([1], non_strict, null);
+ constructor.from([1], strict);
+ constructor.from([1], strict, void 0);
+ constructor.from([1], strict_null, null);
+
+ // TypedArray.from can only be called on TypedArray constructors
+ assertThrows(function() {constructor.from.call({}, [])}, TypeError);
+ assertThrows(function() {constructor.from.call([], [])}, TypeError);
+ assertThrows(function() {constructor.from.call(1, [])}, TypeError);
+ assertThrows(function() {constructor.from.call(undefined, [])}, TypeError);
+
+ // Converting from various other types, demonstrating that it can
+ // operate on array-like objects as well as iterables.
+ // TODO(littledan): constructors should have similar flexibility.
+ assertArrayLikeEquals(constructor.from(
+ { length: 1, 0: 5 }), [5], constructor);
+
+ assertArrayLikeEquals(constructor.from(
+ { length: -1, 0: 5 }), [], constructor);
+
+ assertArrayLikeEquals(constructor.from(
+ [1, 2, 3]), [1, 2, 3], constructor);
+
+ var set = new Set([1, 2, 3]);
+ assertArrayLikeEquals(constructor.from(set), [1, 2, 3],
+ constructor);
+
+ function* generator() {
+ yield 4;
+ yield 5;
+ yield 6;
+ }
+
+ assertArrayLikeEquals(constructor.from(generator()),
+ [4, 5, 6], constructor);
+
+ assertThrows(function() { constructor.from(null); }, TypeError);
+ assertThrows(function() { constructor.from(undefined); }, TypeError);
+ assertThrows(function() { constructor.from([], null); }, TypeError);
+ assertThrows(function() { constructor.from([], 'noncallable'); },
+ TypeError);
+
+ var nullIterator = {};
+ nullIterator[Symbol.iterator] = null;
+ assertArrayLikeEquals(constructor.from(nullIterator), [],
+ constructor);
+
+ var nonObjIterator = {};
+ nonObjIterator[Symbol.iterator] = function() { return 'nonObject'; };
+ assertThrows(function() { constructor.from(nonObjIterator); },
+ TypeError);
+
+ assertThrows(function() { constructor.from([], null); }, TypeError);
+
+ // Ensure iterator is only accessed once, and only invoked once
+ var called = 0;
+ var arr = [1, 2, 3];
+ var obj = {};
+ var counter = 0;
+
+ // Test order --- only get iterator method once
+ function testIterator() {
+ called++;
+ assertEquals(obj, this);
+ return arr[Symbol.iterator]();
+ }
+ var getCalled = 0;
+ Object.defineProperty(obj, Symbol.iterator, {
+ get: function() {
+ getCalled++;
+ return testIterator;
+ },
+ set: function() {
+ assertUnreachable('@@iterator should not be set');
+ }
+ });
+ assertArrayLikeEquals(constructor.from(obj), [1, 2, 3], constructor);
+ assertEquals(getCalled, 1);
+ assertEquals(called, 1);
+
+ assertEquals(constructor, Uint8Array.from.call(constructor, [1]).constructor);
+ assertEquals(Uint8Array, constructor.from.call(Uint8Array, [1]).constructor);
+}
diff --git a/deps/v8/test/mjsunit/es6/typedarray-indexing.js b/deps/v8/test/mjsunit/es6/typedarray-indexing.js
new file mode 100644
index 0000000000..44472e3eb3
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/typedarray-indexing.js
@@ -0,0 +1,71 @@
+// Copyright 2015 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 typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array
+];
+
+for (var constructor of typedArrayConstructors) {
+ var array = new constructor([1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]);
+
+ // ----------------------------------------------------------------------
+ // %TypedArray%.prototype.indexOf.
+ // ----------------------------------------------------------------------
+
+ // Negative cases.
+ assertEquals(-1, new constructor([]).indexOf(1));
+ assertEquals(-1, array.indexOf(4));
+ assertEquals(-1, array.indexOf(3, array.length));
+
+ assertEquals(2, array.indexOf(3));
+ // Negative index out of range.
+ assertEquals(0, array.indexOf(1, -17));
+ // Negative index in rage.
+ assertEquals(3, array.indexOf(1, -11));
+ // Index in range.
+ assertEquals(3, array.indexOf(1, 1));
+ assertEquals(3, array.indexOf(1, 3));
+ assertEquals(6, array.indexOf(1, 4));
+
+ // Basic TypedArray function properties
+ assertEquals(1, array.indexOf.length);
+ assertThrows(function(){ array.indexOf.call([1], 1); }, TypeError);
+ Object.defineProperty(array, 'length', {value: 1});
+ assertEquals(array.indexOf(2), 1);
+
+
+ // ----------------------------------------------------------------------
+ // %TypedArray%.prototype.lastIndexOf.
+ // ----------------------------------------------------------------------
+ array = new constructor([1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]);
+
+ // Negative cases.
+ assertEquals(-1, new constructor([]).lastIndexOf(1));
+ assertEquals(-1, array.lastIndexOf(1, -17));
+
+ assertEquals(9, array.lastIndexOf(1));
+ // Index out of range.
+ assertEquals(9, array.lastIndexOf(1, array.length));
+ // Index in range.
+ assertEquals(0, array.lastIndexOf(1, 2));
+ assertEquals(3, array.lastIndexOf(1, 4));
+ assertEquals(3, array.lastIndexOf(1, 3));
+ // Negative index in range.
+ assertEquals(0, array.lastIndexOf(1, -11));
+
+ // Basic TypedArray function properties
+ assertEquals(1, array.lastIndexOf.length);
+ assertThrows(function(){ array.lastIndexOf.call([1], 1); }, TypeError);
+ Object.defineProperty(array, 'length', {value: 1});
+ assertEquals(array.lastIndexOf(2), 10);
+ delete array.length;
+}
diff --git a/deps/v8/test/mjsunit/es6/typedarray-iteration.js b/deps/v8/test/mjsunit/es6/typedarray-iteration.js
new file mode 100644
index 0000000000..9560cbc5df
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/typedarray-iteration.js
@@ -0,0 +1,194 @@
+// Copyright 2015 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 for standard TypedArray array iteration functions.
+
+var typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array
+];
+
+function assertArrayLikeEquals(expected, value, type) {
+ assertEquals(value.__proto__, type.prototype);
+ assertEquals(expected.length, value.length);
+ for (var i = 0; i < value.length; ++i) {
+ assertEquals(expected[i], value[i]);
+ }
+}
+
+for (var constructor of typedArrayConstructors) {
+ (function TypedArrayFilterTest() {
+ // Simple use.
+ var a = new constructor([0, 1]);
+ assertArrayLikeEquals([0], a.filter(function(n) { return n == 0; }),
+ constructor);
+ assertArrayLikeEquals([0, 1], a, constructor);
+
+ // Use specified object as this object when calling the function.
+ var o = { value: 42 }
+ a = new constructor([1, 42, 3, 42, 4]);
+ assertArrayLikeEquals([42, 42], a.filter(function(n) {
+ return this.value == n
+ }, o), constructor);
+
+ // Modify original array.
+ a = new constructor([1, 42, 3, 42, 4]);
+ assertArrayLikeEquals([42, 42], a.filter(function(n, index, array) {
+ array[index] = 43; return 42 == n;
+ }), constructor);
+ assertArrayLikeEquals([43, 43, 43, 43, 43], a, constructor);
+
+ // Create a new object in each function call when receiver is a
+ // primitive value. See ECMA-262, Annex C.
+ a = [];
+ new constructor([1, 2]).filter(function() { a.push(this) }, '');
+ assertTrue(a[0] !== a[1]);
+
+ // Do not create a new object otherwise.
+ a = [];
+ new constructor([1, 2]).filter(function() { a.push(this) }, {});
+ assertEquals(a[0], a[1]);
+
+ // In strict mode primitive values should not be coerced to an object.
+ a = [];
+ new constructor([1, 2]).filter(function() {
+ 'use strict';
+ a.push(this);
+ }, '');
+ assertEquals('', a[0]);
+ assertEquals(a[0], a[1]);
+
+ // Calling this method on other types is a TypeError
+ assertThrows(function() {
+ constructor.prototype.filter.call([], function() {});
+ }, TypeError);
+
+ // Shadowing the length property doesn't change anything
+ a = new constructor([1, 2]);
+ Object.defineProperty(a, 'length', { value: 1 });
+ assertArrayLikeEquals([2], a.filter(function(elt) {
+ return elt == 2;
+ }), constructor);
+ })();
+
+ (function TypedArrayMapTest() {
+ var a = new constructor([0, 1, 2, 3, 4]);
+
+ // Simple use.
+ var result = [1, 2, 3, 4, 5];
+ assertArrayLikeEquals(result, a.map(function(n) { return n + 1; }),
+ constructor);
+ assertEquals(a, a);
+
+ // Use specified object as this object when calling the function.
+ var o = { delta: 42 }
+ result = [42, 43, 44, 45, 46];
+ assertArrayLikeEquals(result, a.map(function(n) {
+ return this.delta + n;
+ }, o), constructor);
+
+ // Modify original array.
+ a = new constructor([0, 1, 2, 3, 4]);
+ result = [1, 2, 3, 4, 5];
+ assertArrayLikeEquals(result, a.map(function(n, index, array) {
+ array[index] = n + 1;
+ return n + 1;
+ }), constructor);
+ assertArrayLikeEquals(result, a, constructor);
+
+ // Create a new object in each function call when receiver is a
+ // primitive value. See ECMA-262, Annex C.
+ a = [];
+ new constructor([1, 2]).map(function() { a.push(this) }, '');
+ assertTrue(a[0] !== a[1]);
+
+ // Do not create a new object otherwise.
+ a = [];
+ new constructor([1, 2]).map(function() { a.push(this) }, {});
+ assertEquals(a[0], a[1]);
+
+ // In strict mode primitive values should not be coerced to an object.
+ a = [];
+ new constructor([1, 2]).map(function() { 'use strict'; a.push(this); }, '');
+ assertEquals('', a[0]);
+ assertEquals(a[0], a[1]);
+
+ // Test that the result is converted to the right type
+ assertArrayLikeEquals([3, 3], new constructor([1, 2]).map(function() {
+ return "3";
+ }), constructor);
+ if (constructor !== Float32Array && constructor !== Float64Array) {
+ assertArrayLikeEquals([0, 0], new constructor([1, 2]).map(function() {
+ return NaN;
+ }), constructor);
+ }
+ })();
+
+ //
+ // %TypedArray%.prototype.some
+ //
+ (function TypedArraySomeTest() {
+ var a = new constructor([0, 1, 2, 3, 4]);
+
+ // Simple use.
+ assertTrue(a.some(function(n) { return n == 3}));
+ assertFalse(a.some(function(n) { return n == 5}));
+
+ // Use specified object as this object when calling the function.
+ var o = { element: 42 };
+ a = new constructor([1, 42, 3]);
+ assertTrue(a.some(function(n) { return this.element == n; }, o));
+ a = new constructor([1]);
+ assertFalse(a.some(function(n) { return this.element == n; }, o));
+
+ // Modify original array.
+ a = new constructor([0, 1, 2, 3]);
+ assertTrue(a.some(function(n, index, array) {
+ array[index] = n + 1;
+ return n == 2;
+ }));
+ assertArrayLikeEquals([1, 2, 3, 3], a, constructor);
+
+ // Create a new object in each function call when receiver is a
+ // primitive value. See ECMA-262, Annex C.
+ a = [];
+ new constructor([1, 2]).some(function() { a.push(this) }, '');
+ assertTrue(a[0] !== a[1]);
+
+ // Do not create a new object otherwise.
+ a = [];
+ new constructor([1, 2]).some(function() { a.push(this) }, {});
+ assertEquals(a[0], a[1]);
+
+ // In strict mode primitive values should not be coerced to an object.
+ a = [];
+ new constructor([1, 2]).some(function() {
+ 'use strict';
+ a.push(this);
+ }, '');
+ assertEquals('', a[0]);
+ assertEquals(a[0], a[1]);
+
+ // Calling this method on other types is a TypeError
+ assertThrows(function() {
+ constructor.prototype.some.call([], function() {});
+ }, TypeError);
+
+ // Shadowing the length property doesn't change anything
+ a = new constructor([1, 2]);
+ Object.defineProperty(a, 'length', { value: 1 });
+ assertEquals(true, a.some(function(elt) { return elt == 2; }));
+ assertEquals(false, Array.prototype.some.call(a, function(elt) {
+ return elt == 2;
+ }));
+ })();
+
+}
diff --git a/deps/v8/test/mjsunit/harmony/typedarrays-of.js b/deps/v8/test/mjsunit/es6/typedarray-of.js
index 9df1d30c8e..cf57615d12 100644
--- a/deps/v8/test/mjsunit/harmony/typedarrays-of.js
+++ b/deps/v8/test/mjsunit/es6/typedarray-of.js
@@ -4,8 +4,6 @@
// Based on Mozilla Array.of() tests at http://dxr.mozilla.org/mozilla-central/source/js/src/jit-test/tests/collections
-// Flags: --harmony-arrays
-
var typedArrayConstructors = [
Uint8Array,
Int8Array,
diff --git a/deps/v8/test/mjsunit/harmony/typedarray-proto.js b/deps/v8/test/mjsunit/es6/typedarray-proto.js
index c164a317e5..558cb0ad7a 100644
--- a/deps/v8/test/mjsunit/harmony/typedarray-proto.js
+++ b/deps/v8/test/mjsunit/es6/typedarray-proto.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-arrays
-
// Test that the methods for different TypedArray types have the same
// identity.
// TODO(dehrenberg): Test that the TypedArray proto hierarchy is set
diff --git a/deps/v8/test/mjsunit/es6/typedarray-reduce.js b/deps/v8/test/mjsunit/es6/typedarray-reduce.js
new file mode 100644
index 0000000000..1fddeca0bc
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/typedarray-reduce.js
@@ -0,0 +1,250 @@
+// Copyright 2015 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 typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array
+];
+
+function clone(v) {
+ // Shallow-copies arrays, returns everything else verbatim.
+ if (v instanceof Array) {
+ // Shallow-copy an array.
+ var newArray = new Array(v.length);
+ for (var i in v) {
+ newArray[i] = v[i];
+ }
+ return newArray;
+ }
+ return v;
+}
+
+
+// Creates a callback function for reduce/reduceRight that tests the number
+// of arguments and otherwise behaves as "func", but which also
+// records all calls in an array on the function (as arrays of arguments
+// followed by result).
+function makeRecorder(func, testName) {
+ var record = [];
+ var f = function recorder(a, b, i, s) {
+ assertEquals(4, arguments.length,
+ testName + "(number of arguments: " + arguments.length + ")");
+ assertEquals("number", typeof(i), testName + "(index must be number)");
+ assertEquals(s[i], b, testName + "(current argument is at index)");
+ if (record.length > 0) {
+ var prevRecord = record[record.length - 1];
+ var prevResult = prevRecord[prevRecord.length - 1];
+ assertEquals(prevResult, a,
+ testName + "(prev result -> current input)");
+ }
+ var args = [clone(a), clone(b), i, clone(s)];
+ var result = func.apply(this, arguments);
+ args.push(clone(result));
+ record.push(args);
+ return result;
+ };
+ f.record = record;
+ return f;
+}
+
+
+function testReduce(type,
+ testName,
+ expectedResult,
+ expectedCalls,
+ array,
+ combine,
+ init) {
+ var rec = makeRecorder(combine);
+ var result;
+ var performsCall;
+ if (arguments.length > 6) {
+ result = array[type](rec, init);
+ } else {
+ result = array[type](rec);
+ }
+ var calls = rec.record;
+ assertEquals(expectedCalls.length, calls.length,
+ testName + " (number of calls)");
+ for (var i = 0; i < expectedCalls.length; i++) {
+ assertEquals(expectedCalls[i], calls[i],
+ testName + " (call " + (i + 1) + ")");
+ }
+ assertEquals(expectedResult, result, testName + " (result)");
+}
+
+
+function sum(a, b) { return a + b; }
+function prod(a, b) { return a * b; }
+function dec(a, b, i, arr) { return a + b * Math.pow(10, arr.length - i - 1); }
+function accumulate(acc, elem, i) { acc[i] = elem; return acc; }
+
+for (var constructor of typedArrayConstructors) {
+ // ---- Test Reduce[Left]
+
+ var simpleArray = new constructor([2,4,6])
+
+ testReduce("reduce", "SimpleReduceSum", 12,
+ [[0, 2, 0, simpleArray, 2],
+ [2, 4, 1, simpleArray, 6],
+ [6, 6, 2, simpleArray, 12]],
+ simpleArray, sum, 0);
+
+ testReduce("reduce", "SimpleReduceProd", 48,
+ [[1, 2, 0, simpleArray, 2],
+ [2, 4, 1, simpleArray, 8],
+ [8, 6, 2, simpleArray, 48]],
+ simpleArray, prod, 1);
+
+ testReduce("reduce", "SimpleReduceDec", 246,
+ [[0, 2, 0, simpleArray, 200],
+ [200, 4, 1, simpleArray, 240],
+ [240, 6, 2, simpleArray, 246]],
+ simpleArray, dec, 0);
+
+ testReduce("reduce", "SimpleReduceAccumulate", [2, 4, 6],
+ [[[], 2, 0, simpleArray, [2]],
+ [[2], 4, 1, simpleArray, [2, 4]],
+ [[2,4], 6, 2, simpleArray, [2, 4, 6]]],
+ simpleArray, accumulate, []);
+
+
+ testReduce("reduce", "EmptyReduceSum", 0, [], new constructor([]), sum, 0);
+ testReduce("reduce", "EmptyReduceProd", 1, [], new constructor([]), prod, 1);
+ testReduce("reduce", "EmptyReduceDec", 0, [], new constructor([]), dec, 0);
+ testReduce("reduce", "EmptyReduceAccumulate", [], [], new constructor([]), accumulate, []);
+
+ testReduce("reduce", "EmptyReduceSumNoInit", 0, [], new constructor([0]), sum);
+ testReduce("reduce", "EmptyReduceProdNoInit", 1, [], new constructor([1]), prod);
+ testReduce("reduce", "EmptyReduceDecNoInit", 0, [], new constructor([0]), dec);
+
+ // ---- Test ReduceRight
+
+ testReduce("reduceRight", "SimpleReduceRightSum", 12,
+ [[0, 6, 2, simpleArray, 6],
+ [6, 4, 1, simpleArray, 10],
+ [10, 2, 0, simpleArray, 12]],
+ simpleArray, sum, 0);
+
+ testReduce("reduceRight", "SimpleReduceRightProd", 48,
+ [[1, 6, 2, simpleArray, 6],
+ [6, 4, 1, simpleArray, 24],
+ [24, 2, 0, simpleArray, 48]],
+ simpleArray, prod, 1);
+
+ testReduce("reduceRight", "SimpleReduceRightDec", 246,
+ [[0, 6, 2, simpleArray, 6],
+ [6, 4, 1, simpleArray, 46],
+ [46, 2, 0, simpleArray, 246]],
+ simpleArray, dec, 0);
+
+
+ testReduce("reduceRight", "EmptyReduceRightSum", 0, [], new constructor([]), sum, 0);
+ testReduce("reduceRight", "EmptyReduceRightProd", 1, [], new constructor([]), prod, 1);
+ testReduce("reduceRight", "EmptyReduceRightDec", 0, [], new constructor([]), dec, 0);
+ testReduce("reduceRight", "EmptyReduceRightAccumulate", [],
+ [], new constructor([]), accumulate, []);
+
+ testReduce("reduceRight", "EmptyReduceRightSumNoInit", 0, [], new constructor([0]), sum);
+ testReduce("reduceRight", "EmptyReduceRightProdNoInit", 1, [], new constructor([1]), prod);
+ testReduce("reduceRight", "EmptyReduceRightDecNoInit", 0, [], new constructor([0]), dec);
+
+ // Ignore non-array properties:
+
+ var arrayPlus = new constructor([1,2,3]);
+ arrayPlus[-1] = NaN;
+ arrayPlus["00"] = NaN;
+ arrayPlus["02"] = NaN;
+ arrayPlus["-0"] = NaN;
+ arrayPlus.x = NaN;
+
+ testReduce("reduce", "ArrayWithNonElementPropertiesReduce", 6,
+ [[0, 1, 0, arrayPlus, 1],
+ [1, 2, 1, arrayPlus, 3],
+ [3, 3, 2, arrayPlus, 6],
+ ], arrayPlus, sum, 0);
+
+ testReduce("reduceRight", "ArrayWithNonElementPropertiesReduceRight", 6,
+ [[0, 3, 2, arrayPlus, 3],
+ [3, 2, 1, arrayPlus, 5],
+ [5, 1, 0, arrayPlus, 6],
+ ], arrayPlus, sum, 0);
+
+
+ // Test error conditions:
+
+ var exception = false;
+ try {
+ new constructor([1]).reduce("not a function");
+ } catch (e) {
+ exception = true;
+ assertTrue(e instanceof TypeError,
+ "reduce callback not a function not throwing TypeError");
+ assertTrue(e.message.indexOf(" is not a function") >= 0,
+ "reduce non function TypeError type");
+ }
+ assertTrue(exception);
+
+ exception = false;
+ try {
+ new constructor([1]).reduceRight("not a function");
+ } catch (e) {
+ exception = true;
+ assertTrue(e instanceof TypeError,
+ "reduceRight callback not a function not throwing TypeError");
+ assertTrue(e.message.indexOf(" is not a function") >= 0,
+ "reduceRight non function TypeError type");
+ }
+ assertTrue(exception);
+
+ exception = false;
+ try {
+ new constructor([]).reduce(sum);
+ } catch (e) {
+ exception = true;
+ assertTrue(e instanceof TypeError,
+ "reduce no initial value not throwing TypeError");
+ assertEquals("Reduce of empty array with no initial value", e.message,
+ "reduce no initial TypeError type");
+ }
+ assertTrue(exception);
+
+ exception = false;
+ try {
+ new constructor([]).reduceRight(sum);
+ } catch (e) {
+ exception = true;
+ assertTrue(e instanceof TypeError,
+ "reduceRight no initial value not throwing TypeError");
+ assertEquals("Reduce of empty array with no initial value", e.message,
+ "reduceRight no initial TypeError type");
+ }
+ assertTrue(exception);
+
+ // Reduce fails when called on non-TypedArrays
+ assertThrows(function() {
+ constructor.prototype.reduce.call([], function() {}, null);
+ }, TypeError);
+ assertThrows(function() {
+ constructor.prototype.reduceRight.call([], function() {}, null);
+ }, TypeError);
+
+ // Shadowing length doesn't affect every, unlike Array.prototype.every
+ var a = new constructor([1, 2]);
+ Object.defineProperty(a, 'length', {value: 1});
+ assertEquals(a.reduce(sum, 0), 3);
+ assertEquals(Array.prototype.reduce.call(a, sum, 0), 1);
+ assertEquals(a.reduceRight(sum, 0), 3);
+ assertEquals(Array.prototype.reduceRight.call(a, sum, 0), 1);
+
+ assertEquals(1, constructor.prototype.reduce.length);
+ assertEquals(1, constructor.prototype.reduceRight.length);
+}
diff --git a/deps/v8/test/mjsunit/es6/typedarray-reverse.js b/deps/v8/test/mjsunit/es6/typedarray-reverse.js
new file mode 100644
index 0000000000..f32813e155
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/typedarray-reverse.js
@@ -0,0 +1,54 @@
+// Copyright 2015 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 ArrayMaker(x) {
+ return x;
+}
+ArrayMaker.prototype = Array.prototype;
+
+var arrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array,
+ ArrayMaker // Also test arrays
+];
+
+function assertArrayLikeEquals(value, expected, type) {
+ assertEquals(value.__proto__, type.prototype);
+ assertEquals(expected.length, value.length);
+ for (var i = 0; i < value.length; ++i) {
+ assertEquals(expected[i], value[i]);
+ }
+}
+
+for (var constructor of arrayConstructors) {
+ // Test reversing both even and odd length arrays
+ var a = new constructor([1, 2, 3]);
+ assertArrayLikeEquals(a.reverse(), [3, 2, 1], constructor);
+ assertArrayLikeEquals(a, [3, 2, 1], constructor);
+
+ a = new constructor([1, 2, 3, 4]);
+ assertArrayLikeEquals(a.reverse(), [4, 3, 2, 1], constructor);
+ assertArrayLikeEquals(a, [4, 3, 2, 1], constructor);
+
+ if (constructor != ArrayMaker) {
+ // Cannot be called on objects which are not TypedArrays
+ assertThrows(function () { a.reverse.call({ length: 0 }); }, TypeError);
+ } else {
+ // Array.reverse works on array-like objects
+ var x = { length: 2, 1: 5 };
+ a.reverse.call(x);
+ assertEquals(2, x.length);
+ assertFalse(Object.hasOwnProperty(x, '1'));
+ assertEquals(5, x[0]);
+ }
+
+ assertEquals(0, a.reverse.length);
+}
diff --git a/deps/v8/test/mjsunit/es6/typedarray-slice.js b/deps/v8/test/mjsunit/es6/typedarray-slice.js
new file mode 100644
index 0000000000..ddd021a8fa
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/typedarray-slice.js
@@ -0,0 +1,71 @@
+// Copyright 2015 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 typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array
+];
+
+for (var constructor of typedArrayConstructors) {
+ // Check various variants of empty array's slicing.
+ var array = new constructor(0);
+ for (var i = 0; i < 7; i++) {
+ assertEquals(0, array.slice(0, 0).length);
+ assertEquals(0, array.slice(1, 0).length);
+ assertEquals(0, array.slice(0, 1).length);
+ assertEquals(0, array.slice(-1, 0).length);
+ }
+
+
+ // Check various forms of arguments omission.
+ array = new constructor(7);
+
+ for (var i = 0; i < 7; i++) {
+ assertEquals(array, array.slice());
+ assertEquals(array, array.slice(0));
+ assertEquals(array, array.slice(undefined));
+ assertEquals(array, array.slice("foobar"));
+ assertEquals(array, array.slice(undefined, undefined));
+ }
+
+
+ // Check variants of negatives and positive indices.
+ array = new constructor(7);
+
+ assertEquals(7, array.slice(-100).length);
+ assertEquals(3, array.slice(-3).length);
+ assertEquals(3, array.slice(4).length);
+ assertEquals(1, array.slice(6).length);
+ assertEquals(0, array.slice(7).length);
+ assertEquals(0, array.slice(8).length);
+ assertEquals(0, array.slice(100).length);
+
+ assertEquals(0, array.slice(0, -100).length);
+ assertEquals(4, array.slice(0, -3).length);
+ assertEquals(4, array.slice(0, 4).length);
+ assertEquals(6, array.slice(0, 6).length);
+ assertEquals(7, array.slice(0, 7).length);
+ assertEquals(7, array.slice(0, 8).length);
+ assertEquals(7, array.slice(0, 100).length);
+
+ // Does not permit being called on other types
+ assertThrows(function () {
+ constructor.prototype.slice.call([], 0, 0);
+ }, TypeError);
+
+ // Check that elements are copied properly in slice
+ array = new constructor([1, 2, 3, 4]);
+ var slice = array.slice(1, 3);
+ assertEquals(2, slice.length);
+ assertEquals(2, slice[0]);
+ assertEquals(3, slice[1]);
+ assertTrue(slice instanceof constructor);
+}
diff --git a/deps/v8/test/mjsunit/es6/typedarray-sort.js b/deps/v8/test/mjsunit/es6/typedarray-sort.js
new file mode 100644
index 0000000000..4fb8469075
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/typedarray-sort.js
@@ -0,0 +1,55 @@
+// Copyright 2015 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 typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array
+];
+
+function assertArrayLikeEquals(value, expected, type) {
+ assertEquals(value.__proto__, type.prototype);
+ // Don't test value.length because we mess with that;
+ // instead in certain callsites we check that length
+ // is set appropriately.
+ for (var i = 0; i < expected.length; ++i) {
+ // Use Object.is to differentiate between +-0
+ assertSame(expected[i], value[i]);
+ }
+}
+
+for (var constructor of typedArrayConstructors) {
+ // Test default numerical sorting order
+ var a = new constructor([100, 7, 45])
+ assertEquals(a.sort(), a);
+ assertArrayLikeEquals(a, [7, 45, 100], constructor);
+ assertEquals(a.length, 3);
+
+ // For arrays of floats, certain handling of +-0/NaN
+ if (constructor === Float32Array || constructor === Float64Array) {
+ var b = new constructor([+0, -0, NaN, -0, NaN, +0])
+ b.sort();
+ assertArrayLikeEquals(b, [-0, -0, +0, +0, NaN, NaN], constructor);
+ assertEquals(b.length, 6);
+ }
+
+ // Custom sort--backwards
+ a.sort(function(x, y) { return y - x; });
+ assertArrayLikeEquals(a, [100, 45, 7], constructor);
+
+ // Basic TypedArray method properties:
+ // Length field is ignored
+ Object.defineProperty(a, 'length', {value: 1});
+ assertEquals(a.sort(), a);
+ assertArrayLikeEquals(a, [7, 45, 100], constructor);
+ assertEquals(a.length, 1);
+ // Method doesn't work on other objects
+ assertThrows(function() { a.sort.call([]); }, TypeError);
+}
diff --git a/deps/v8/test/mjsunit/es6/typedarray-tostring.js b/deps/v8/test/mjsunit/es6/typedarray-tostring.js
new file mode 100644
index 0000000000..e6adda0405
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/typedarray-tostring.js
@@ -0,0 +1,86 @@
+// Copyright 2015 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.
+
+// Array's toString should call the object's own join method, if one exists and
+// is callable. Otherwise, just use the original Object.toString function.
+
+var typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array
+];
+
+for (var constructor of typedArrayConstructors) {
+ var success = "[test success]";
+ var expectedThis;
+ function testJoin() {
+ assertEquals(0, arguments.length);
+ assertSame(expectedThis, this);
+ return success;
+ }
+
+
+ // On an Array object.
+
+ // Default case.
+ var a1 = new constructor([1, 2, 3]);
+ assertEquals("1,2,3", a1.toString());
+ assertEquals("1,2,3", a1.join());
+ assertEquals("1,2,3", a1.toLocaleString());
+
+ // Non-standard "join" function is called correctly.
+ var a2 = new constructor([1, 2, 3]);
+ a2.join = testJoin;
+ expectedThis = a2;
+ assertEquals(success, a2.toString());
+ assertEquals(success, a2.join());
+ assertEquals("1,2,3", a2.toLocaleString());
+
+ // Non-callable join function is ignored and Object.prototype.toString is
+ // used instead.
+ var a3 = new constructor([1, 2, 3]);
+ a3.join = "not callable";
+ assertEquals(0, a3.toString().search(/\[object .+Array\]/));
+
+ // Non-existing join function is treated same as non-callable.
+ var a4 = new constructor([1, 2, 3]);
+ a4.__proto__ = { toString: constructor.prototype.toString };
+ // No join on Array.
+ assertEquals(0, a3.toString().search(/\[object .+Array\]/));
+
+
+ // On a non-Array object, throws.
+ var o1 = {length: 3, 0: 1, 1: 2, 2: 3,
+ toString: constructor.prototype.toString,
+ join: constructor.prototype.join,
+ toLocaleString: constructor.prototype.toLocaleString};
+ assertThrows(function() { o1.join() }, TypeError);
+ assertThrows(function() { o1.toString() }, TypeError);
+ assertThrows(function() { o1.toLocaleString() }, TypeError);
+ // toString is OK if join not from here:
+ o1.join = Array.prototype.join;
+ assertEquals("1,2,3", o1.join());
+ assertEquals("1,2,3", o1.toString());
+ assertThrows(function() { o1.toLocaleString() }, TypeError);
+ // TODO(littledan): Use the same function for TypedArray as for
+ // Array, as the spec says (but Firefox doesn't do either).
+ // Currently, using the same method leads to a bootstrap failure.
+ // assertEquals(o1.toString, Array.prototype.toString);
+
+ // Redefining length does not change result
+ var a5 = new constructor([1, 2, 3])
+ Object.defineProperty(a5, 'length', { value: 2 });
+ assertEquals("1,2,3", a5.join());
+ assertEquals("1,2,3", a5.toString());
+ assertEquals("1,2,3", a5.toLocaleString());
+ assertEquals("1,2", Array.prototype.join.call(a5));
+ assertEquals("1,2,3", Array.prototype.toString.call(a5));
+ assertEquals("1,2", Array.prototype.toLocaleString.call(a5));
+}
diff --git a/deps/v8/test/mjsunit/harmony/typedarrays.js b/deps/v8/test/mjsunit/es6/typedarray.js
index 70bd17e338..ef7955ce92 100644
--- a/deps/v8/test/mjsunit/harmony/typedarrays.js
+++ b/deps/v8/test/mjsunit/es6/typedarray.js
@@ -276,6 +276,43 @@ function TestTypedArray(constr, elementSize, typicalElement) {
assertFalse(!!desc.writable);
assertFalse(!!desc.set);
assertEquals("function", typeof desc.get);
+
+ // Test that the constructor can be called with an iterable
+ function* gen() { for (var i = 0; i < 10; i++) yield i; }
+ var genArr = new constr(gen());
+ assertEquals(10, genArr.length);
+ assertEquals(0, genArr[0]);
+ assertEquals(9, genArr[9]);
+ // Arrays can be converted to TypedArrays
+ genArr = new constr([1, 2, 3]);
+ assertEquals(3, genArr.length);
+ assertEquals(1, genArr[0]);
+ assertEquals(3, genArr[2]);
+ // Redefining Array.prototype[Symbol.iterator] still works
+ var arrayIterator = Array.prototype[Symbol.iterator];
+ Array.prototype[Symbol.iterator] = gen;
+ genArr = new constr([1, 2, 3]);
+ assertEquals(10, genArr.length);
+ assertEquals(0, genArr[0]);
+ assertEquals(9, genArr[9]);
+ Array.prototype[Symbol.iterator] = arrayIterator;
+ // Other array-like things can be made into a TypedArray
+ var myObject = { 0: 5, 1: 6, length: 2 };
+ genArr = new constr(myObject);
+ assertEquals(2, genArr.length);
+ assertEquals(5, genArr[0]);
+ assertEquals(6, genArr[1]);
+ // Iterator takes precedence over array-like, and the property
+ // is read only once.
+ var iteratorReadCount = 0;
+ Object.defineProperty(myObject, Symbol.iterator, {
+ get: function() { iteratorReadCount++; return gen; }
+ });
+ genArr = new constr(myObject);
+ assertEquals(10, genArr.length);
+ assertEquals(0, genArr[0]);
+ assertEquals(9, genArr[9]);
+ assertEquals(1, iteratorReadCount);
}
TestTypedArray(Uint8Array, 1, 0xFF);
diff --git a/deps/v8/test/mjsunit/external-array-no-sse2.js b/deps/v8/test/mjsunit/external-array-no-sse2.js
deleted file mode 100644
index 575a8b53cf..0000000000
--- a/deps/v8/test/mjsunit/external-array-no-sse2.js
+++ /dev/null
@@ -1,715 +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: --allow-natives-syntax --noenable-sse2
-
-// Helper
-function assertInstance(o, f) {
- assertSame(o.constructor, f);
- assertInstanceof(o, f);
-}
-
-// This is a regression test for overlapping key and value registers.
-function f(a) {
- a[0] = 0;
- a[1] = 0;
-}
-
-var a = new Int32Array(2);
-for (var i = 0; i < 5; i++) {
- f(a);
-}
-%OptimizeFunctionOnNextCall(f);
-f(a);
-
-assertEquals(0, a[0]);
-assertEquals(0, a[1]);
-
-// Test derivation from an ArrayBuffer
-var ab = new ArrayBuffer(12);
-assertInstance(ab, ArrayBuffer);
-var derived_uint8 = new Uint8Array(ab);
-assertInstance(derived_uint8, Uint8Array);
-assertSame(ab, derived_uint8.buffer);
-assertEquals(12, derived_uint8.length);
-assertEquals(12, derived_uint8.byteLength);
-assertEquals(0, derived_uint8.byteOffset);
-assertEquals(1, derived_uint8.BYTES_PER_ELEMENT);
-var derived_uint8_2 = new Uint8Array(ab,7);
-assertInstance(derived_uint8_2, Uint8Array);
-assertSame(ab, derived_uint8_2.buffer);
-assertEquals(5, derived_uint8_2.length);
-assertEquals(5, derived_uint8_2.byteLength);
-assertEquals(7, derived_uint8_2.byteOffset);
-assertEquals(1, derived_uint8_2.BYTES_PER_ELEMENT);
-var derived_int16 = new Int16Array(ab);
-assertInstance(derived_int16, Int16Array);
-assertSame(ab, derived_int16.buffer);
-assertEquals(6, derived_int16.length);
-assertEquals(12, derived_int16.byteLength);
-assertEquals(0, derived_int16.byteOffset);
-assertEquals(2, derived_int16.BYTES_PER_ELEMENT);
-var derived_int16_2 = new Int16Array(ab,6);
-assertInstance(derived_int16_2, Int16Array);
-assertSame(ab, derived_int16_2.buffer);
-assertEquals(3, derived_int16_2.length);
-assertEquals(6, derived_int16_2.byteLength);
-assertEquals(6, derived_int16_2.byteOffset);
-assertEquals(2, derived_int16_2.BYTES_PER_ELEMENT);
-var derived_uint32 = new Uint32Array(ab);
-assertInstance(derived_uint32, Uint32Array);
-assertSame(ab, derived_uint32.buffer);
-assertEquals(3, derived_uint32.length);
-assertEquals(12, derived_uint32.byteLength);
-assertEquals(0, derived_uint32.byteOffset);
-assertEquals(4, derived_uint32.BYTES_PER_ELEMENT);
-var derived_uint32_2 = new Uint32Array(ab,4);
-assertInstance(derived_uint32_2, Uint32Array);
-assertSame(ab, derived_uint32_2.buffer);
-assertEquals(2, derived_uint32_2.length);
-assertEquals(8, derived_uint32_2.byteLength);
-assertEquals(4, derived_uint32_2.byteOffset);
-assertEquals(4, derived_uint32_2.BYTES_PER_ELEMENT);
-var derived_uint32_3 = new Uint32Array(ab,4,1);
-assertInstance(derived_uint32_3, Uint32Array);
-assertSame(ab, derived_uint32_3.buffer);
-assertEquals(1, derived_uint32_3.length);
-assertEquals(4, derived_uint32_3.byteLength);
-assertEquals(4, derived_uint32_3.byteOffset);
-assertEquals(4, derived_uint32_3.BYTES_PER_ELEMENT);
-var derived_float64 = new Float64Array(ab,0,1);
-assertInstance(derived_float64, Float64Array);
-assertSame(ab, derived_float64.buffer);
-assertEquals(1, derived_float64.length);
-assertEquals(8, derived_float64.byteLength);
-assertEquals(0, derived_float64.byteOffset);
-assertEquals(8, derived_float64.BYTES_PER_ELEMENT);
-
-// If a given byteOffset and length references an area beyond the end of the
-// ArrayBuffer an exception is raised.
-function abfunc3() {
- new Uint32Array(ab,4,3);
-}
-assertThrows(abfunc3);
-function abfunc4() {
- new Uint32Array(ab,16);
-}
-assertThrows(abfunc4);
-
-// The given byteOffset must be a multiple of the element size of the specific
-// type, otherwise an exception is raised.
-function abfunc5() {
- new Uint32Array(ab,5);
-}
-assertThrows(abfunc5);
-
-// If length is not explicitly specified, the length of the ArrayBuffer minus
-// the byteOffset must be a multiple of the element size of the specific type,
-// or an exception is raised.
-var ab2 = new ArrayBuffer(13);
-function abfunc6() {
- new Uint32Array(ab2,4);
-}
-assertThrows(abfunc6);
-
-// Test that an array constructed without an array buffer creates one properly.
-a = new Uint8Array(31);
-assertEquals(a.byteLength, a.buffer.byteLength);
-assertEquals(a.length, a.buffer.byteLength);
-assertEquals(a.length * a.BYTES_PER_ELEMENT, a.buffer.byteLength);
-a = new Int16Array(5);
-assertEquals(a.byteLength, a.buffer.byteLength);
-assertEquals(a.length * a.BYTES_PER_ELEMENT, a.buffer.byteLength);
-a = new Float64Array(7);
-assertEquals(a.byteLength, a.buffer.byteLength);
-assertEquals(a.length * a.BYTES_PER_ELEMENT, a.buffer.byteLength);
-
-// Test that an implicitly created buffer is a valid buffer.
-a = new Float64Array(7);
-assertSame(a.buffer, (new Uint16Array(a.buffer)).buffer);
-assertSame(a.buffer, (new Float32Array(a.buffer,4)).buffer);
-assertSame(a.buffer, (new Int8Array(a.buffer,3,51)).buffer);
-assertInstance(a.buffer, ArrayBuffer);
-
-// Test the correct behavior of the |BYTES_PER_ELEMENT| property.
-a = new Int32Array(2);
-assertEquals(4, a.BYTES_PER_ELEMENT);
-a.BYTES_PER_ELEMENT = 42;
-a = new Uint8Array(2);
-assertEquals(1, a.BYTES_PER_ELEMENT);
-a = new Int16Array(2);
-assertEquals(2, a.BYTES_PER_ELEMENT);
-
-// Test Float64Arrays.
-function get(a, index) {
- return a[index];
-}
-function set(a, index, value) {
- a[index] = value;
-}
-function temp() {
-var array = new Float64Array(2);
-for (var i = 0; i < 5; i++) {
- set(array, 0, 2.5);
- assertEquals(2.5, array[0]);
-}
-%OptimizeFunctionOnNextCall(set);
-set(array, 0, 2.5);
-assertEquals(2.5, array[0]);
-set(array, 1, 3.5);
-assertEquals(3.5, array[1]);
-for (var i = 0; i < 5; i++) {
- assertEquals(2.5, get(array, 0));
- assertEquals(3.5, array[1]);
-}
-%OptimizeFunctionOnNextCall(get);
-assertEquals(2.5, get(array, 0));
-assertEquals(3.5, get(array, 1));
-}
-
-// Test non-number parameters.
-var array_with_length_from_non_number = new Int32Array("2");
-assertEquals(2, array_with_length_from_non_number.length);
-
-// Test loads and stores.
-types = [Array, Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array,
- Uint32Array, Uint8ClampedArray, Float32Array, Float64Array];
-
-test_result_nan = [NaN, 0, 0, 0, 0, 0, 0, 0, NaN, NaN];
-test_result_low_int = [-1, -1, 255, -1, 65535, -1, 0xFFFFFFFF, 0, -1, -1];
-test_result_low_double = [-1.25, -1, 255, -1, 65535, -1, 0xFFFFFFFF, 0, -1.25, -1.25];
-test_result_middle = [253.75, -3, 253, 253, 253, 253, 253, 254, 253.75, 253.75];
-test_result_high_int = [256, 0, 0, 256, 256, 256, 256, 255, 256, 256];
-test_result_high_double = [256.25, 0, 0, 256, 256, 256, 256, 255, 256.25, 256.25];
-
-const kElementCount = 40;
-
-function test_load(array, sum) {
- for (var i = 0; i < kElementCount; i++) {
- sum += array[i];
- }
- return sum;
-}
-
-function test_load_const_key(array, sum) {
- sum += array[0];
- sum += array[1];
- sum += array[2];
- return sum;
-}
-
-function test_store(array, sum) {
- for (var i = 0; i < kElementCount; i++) {
- sum += array[i] = i+1;
- }
- return sum;
-}
-
-function test_store_const_key(array, sum) {
- sum += array[0] = 1;
- sum += array[1] = 2;
- sum += array[2] = 3;
- return sum;
-}
-
-function zero() {
- return 0.0;
-}
-
-function test_store_middle_tagged(array, sum) {
- array[0] = 253.75;
- return array[0];
-}
-
-function test_store_high_tagged(array, sum) {
- array[0] = 256.25;
- return array[0];
-}
-
-function test_store_middle_double(array, sum) {
- array[0] = 253.75 + zero(); // + forces double type feedback
- return array[0];
-}
-
-function test_store_high_double(array, sum) {
- array[0] = 256.25 + zero(); // + forces double type feedback
- return array[0];
-}
-
-function test_store_high_double(array, sum) {
- array[0] = 256.25;
- return array[0];
-}
-
-function test_store_low_int(array, sum) {
- array[0] = -1;
- return array[0];
-}
-
-function test_store_low_tagged(array, sum) {
- array[0] = -1.25;
- return array[0];
-}
-
-function test_store_low_double(array, sum) {
- array[0] = -1.25 + zero(); // + forces double type feedback
- return array[0];
-}
-
-function test_store_high_int(array, sum) {
- array[0] = 256;
- return array[0];
-}
-
-function test_store_nan(array, sum) {
- array[0] = NaN;
- return array[0];
-}
-
-const kRuns = 10;
-
-function run_test(test_func, array, expected_result) {
- for (var i = 0; i < 5; i++) test_func(array, 0);
- %OptimizeFunctionOnNextCall(test_func);
- var sum = 0;
- for (var i = 0; i < kRuns; i++) {
- sum = test_func(array, sum);
- }
- assertEquals(expected_result, sum);
- %DeoptimizeFunction(test_func);
- %ClearFunctionTypeFeedback(test_func);
-}
-
-function run_bounds_test(test_func, array, expected_result) {
- assertEquals(undefined, a[kElementCount]);
- a[kElementCount] = 456;
- assertEquals(undefined, a[kElementCount]);
- assertEquals(undefined, a[kElementCount+1]);
- a[kElementCount+1] = 456;
- assertEquals(undefined, a[kElementCount+1]);
-}
-
-for (var t = 0; t < types.length; t++) {
- var type = types[t];
- var a = new type(kElementCount);
-
- for (var i = 0; i < kElementCount; i++) {
- a[i] = i;
- }
-
- // Run test functions defined above.
- run_test(test_load, a, 780 * kRuns);
- run_test(test_load_const_key, a, 3 * kRuns);
- run_test(test_store, a, 820 * kRuns);
- run_test(test_store_const_key, a, 6 * kRuns);
- run_test(test_store_low_int, a, test_result_low_int[t]);
- run_test(test_store_low_double, a, test_result_low_double[t]);
- run_test(test_store_low_tagged, a, test_result_low_double[t]);
- run_test(test_store_high_int, a, test_result_high_int[t]);
- run_test(test_store_nan, a, test_result_nan[t]);
- run_test(test_store_middle_double, a, test_result_middle[t]);
- run_test(test_store_middle_tagged, a, test_result_middle[t]);
- run_test(test_store_high_double, a, test_result_high_double[t]);
- run_test(test_store_high_tagged, a, test_result_high_double[t]);
-
- // Test the correct behavior of the |length| property (which is read-only).
- if (t != 0) {
- assertEquals(kElementCount, a.length);
- a.length = 2;
- assertEquals(kElementCount, a.length);
- assertTrue(delete a.length);
-
- // Make sure bounds checks are handled correctly for external arrays.
- run_bounds_test(a);
- run_bounds_test(a);
- run_bounds_test(a);
- %OptimizeFunctionOnNextCall(run_bounds_test);
- run_bounds_test(a);
- %DeoptimizeFunction(run_bounds_test);
- %ClearFunctionTypeFeedback(run_bounds_test);
- }
-
- function array_load_set_smi_check(a) {
- return a[0] = a[0] = 1;
- }
-
- array_load_set_smi_check(a);
- array_load_set_smi_check(0);
-
- function array_load_set_smi_check2(a) {
- return a[0] = a[0] = 1;
- }
-
- array_load_set_smi_check2(a);
- %OptimizeFunctionOnNextCall(array_load_set_smi_check2);
- array_load_set_smi_check2(a);
- array_load_set_smi_check2(0);
- %DeoptimizeFunction(array_load_set_smi_check2);
- %ClearFunctionTypeFeedback(array_load_set_smi_check2);
-}
-
-// Check handling of undefined in 32- and 64-bit external float arrays.
-
-function store_float32_undefined(ext_array) {
- ext_array[0] = undefined;
-}
-
-var float32_array = new Float32Array(1);
-// Make sure runtime does it right
-store_float32_undefined(float32_array);
-assertTrue(isNaN(float32_array[0]));
-// Make sure the ICs do it right
-store_float32_undefined(float32_array);
-assertTrue(isNaN(float32_array[0]));
-// Make sure that Cranskshft does it right.
-%OptimizeFunctionOnNextCall(store_float32_undefined);
-store_float32_undefined(float32_array);
-assertTrue(isNaN(float32_array[0]));
-
-function store_float64_undefined(ext_array) {
- ext_array[0] = undefined;
-}
-
-var float64_array = new Float64Array(1);
-// Make sure runtime does it right
-store_float64_undefined(float64_array);
-assertTrue(isNaN(float64_array[0]));
-// Make sure the ICs do it right
-store_float64_undefined(float64_array);
-assertTrue(isNaN(float64_array[0]));
-// Make sure that Cranskshft does it right.
-%OptimizeFunctionOnNextCall(store_float64_undefined);
-store_float64_undefined(float64_array);
-assertTrue(isNaN(float64_array[0]));
-
-
-// Check handling of 0-sized buffers and arrays.
-ab = new ArrayBuffer(0);
-assertInstance(ab, ArrayBuffer);
-assertEquals(0, ab.byteLength);
-a = new Int8Array(ab);
-assertInstance(a, Int8Array);
-assertEquals(0, a.byteLength);
-assertEquals(0, a.length);
-a[0] = 1;
-assertEquals(undefined, a[0]);
-ab = new ArrayBuffer(16);
-assertInstance(ab, ArrayBuffer);
-a = new Float32Array(ab,4,0);
-assertInstance(a, Float32Array);
-assertEquals(0, a.byteLength);
-assertEquals(0, a.length);
-a[0] = 1;
-assertEquals(undefined, a[0]);
-a = new Uint16Array(0);
-assertInstance(a, Uint16Array);
-assertEquals(0, a.byteLength);
-assertEquals(0, a.length);
-a[0] = 1;
-assertEquals(undefined, a[0]);
-
-
-// Check construction from arrays.
-a = new Uint32Array([]);
-assertInstance(a, Uint32Array);
-assertEquals(0, a.length);
-assertEquals(0, a.byteLength);
-assertEquals(0, a.buffer.byteLength);
-assertEquals(4, a.BYTES_PER_ELEMENT);
-assertInstance(a.buffer, ArrayBuffer);
-a = new Uint16Array([1,2,3]);
-assertInstance(a, Uint16Array);
-assertEquals(3, a.length);
-assertEquals(6, a.byteLength);
-assertEquals(6, a.buffer.byteLength);
-assertEquals(2, a.BYTES_PER_ELEMENT);
-assertEquals(1, a[0]);
-assertEquals(3, a[2]);
-assertInstance(a.buffer, ArrayBuffer);
-a = new Uint32Array(a);
-assertInstance(a, Uint32Array);
-assertEquals(3, a.length);
-assertEquals(12, a.byteLength);
-assertEquals(12, a.buffer.byteLength);
-assertEquals(4, a.BYTES_PER_ELEMENT);
-assertEquals(1, a[0]);
-assertEquals(3, a[2]);
-assertInstance(a.buffer, ArrayBuffer);
-
-// Check subarrays.
-a = new Uint16Array([1,2,3,4,5,6]);
-aa = a.subarray(3);
-assertInstance(aa, Uint16Array);
-assertEquals(3, aa.length);
-assertEquals(6, aa.byteLength);
-assertEquals(2, aa.BYTES_PER_ELEMENT);
-assertSame(a.buffer, aa.buffer);
-aa = a.subarray(3,5);
-assertInstance(aa, Uint16Array);
-assertEquals(2, aa.length);
-assertEquals(4, aa.byteLength);
-assertEquals(2, aa.BYTES_PER_ELEMENT);
-assertSame(a.buffer, aa.buffer);
-aa = a.subarray(4,8);
-assertInstance(aa, Uint16Array);
-assertEquals(2, aa.length);
-assertEquals(4, aa.byteLength);
-assertEquals(2, aa.BYTES_PER_ELEMENT);
-assertSame(a.buffer, aa.buffer);
-aa = a.subarray(9);
-assertInstance(aa, Uint16Array);
-assertEquals(0, aa.length);
-assertEquals(0, aa.byteLength);
-assertEquals(2, aa.BYTES_PER_ELEMENT);
-assertSame(a.buffer, aa.buffer);
-aa = a.subarray(-4);
-assertInstance(aa, Uint16Array);
-assertEquals(4, aa.length);
-assertEquals(8, aa.byteLength);
-assertEquals(2, aa.BYTES_PER_ELEMENT);
-assertSame(a.buffer, aa.buffer);
-aa = a.subarray(-3,-1);
-assertInstance(aa, Uint16Array);
-assertEquals(2, aa.length);
-assertEquals(4, aa.byteLength);
-assertEquals(2, aa.BYTES_PER_ELEMENT);
-assertSame(a.buffer, aa.buffer);
-aa = a.subarray(3,2);
-assertInstance(aa, Uint16Array);
-assertEquals(0, aa.length);
-assertEquals(0, aa.byteLength);
-assertEquals(2, aa.BYTES_PER_ELEMENT);
-assertSame(a.buffer, aa.buffer);
-aa = a.subarray(-3,-4);
-assertInstance(aa, Uint16Array);
-assertEquals(0, aa.length);
-assertEquals(0, aa.byteLength);
-assertEquals(2, aa.BYTES_PER_ELEMENT);
-assertSame(a.buffer, aa.buffer);
-aa = a.subarray(0,-8);
-assertInstance(aa, Uint16Array);
-assertEquals(0, aa.length);
-assertEquals(0, aa.byteLength);
-assertEquals(2, aa.BYTES_PER_ELEMENT);
-assertSame(a.buffer, aa.buffer);
-
-assertThrows(function(){ a.subarray.call({}, 0) });
-assertThrows(function(){ a.subarray.call([], 0) });
-
-// Try to call constructors directly as functions, and through .call
-// and .apply. Should fail.
-
-assertThrows(function() { ArrayBuffer(100); }, TypeError);
-assertThrows(function() { Int8Array(b, 5, 77); }, TypeError);
-assertThrows(function() { ArrayBuffer.call(null, 10); }, TypeError);
-assertThrows(function() { Uint16Array.call(null, b, 2, 4); }, TypeError);
-assertThrows(function() { ArrayBuffer.apply(null, [1000]); }, TypeError);
-assertThrows(function() { Float32Array.apply(null, [b, 128, 1]); }, TypeError);
-
-// Test array.set in different combinations.
-
-function assertArrayPrefix(expected, array) {
- for (var i = 0; i < expected.length; ++i) {
- assertEquals(expected[i], array[i]);
- }
-}
-
-var a11 = new Int16Array([1, 2, 3, 4, 0, -1])
-var a12 = new Uint16Array(15)
-a12.set(a11, 3)
-assertArrayPrefix([0, 0, 0, 1, 2, 3, 4, 0, 0xffff, 0, 0], a12)
-assertThrows(function(){ a11.set(a12) })
-
-var a21 = [1, undefined, 10, NaN, 0, -1, {valueOf: function() {return 3}}]
-var a22 = new Int32Array(12)
-a22.set(a21, 2)
-assertArrayPrefix([0, 0, 1, 0, 10, 0, 0, -1, 3, 0], a22)
-
-var a31 = new Float32Array([2, 4, 6, 8, 11, NaN, 1/0, -3])
-var a32 = a31.subarray(2, 6)
-a31.set(a32, 4)
-assertArrayPrefix([2, 4, 6, 8, 6, 8, 11, NaN], a31)
-assertArrayPrefix([6, 8, 6, 8], a32)
-
-var a4 = new Uint8ClampedArray([3,2,5,6])
-a4.set(a4)
-assertArrayPrefix([3, 2, 5, 6], a4)
-
-// Cases with overlapping backing store but different element sizes.
-var b = new ArrayBuffer(4)
-var a5 = new Int16Array(b)
-var a50 = new Int8Array(b)
-var a51 = new Int8Array(b, 0, 2)
-var a52 = new Int8Array(b, 1, 2)
-var a53 = new Int8Array(b, 2, 2)
-
-a5.set([0x5050, 0x0a0a])
-assertArrayPrefix([0x50, 0x50, 0x0a, 0x0a], a50)
-assertArrayPrefix([0x50, 0x50], a51)
-assertArrayPrefix([0x50, 0x0a], a52)
-assertArrayPrefix([0x0a, 0x0a], a53)
-
-a50.set([0x50, 0x50, 0x0a, 0x0a])
-a51.set(a5)
-assertArrayPrefix([0x50, 0x0a, 0x0a, 0x0a], a50)
-
-a50.set([0x50, 0x50, 0x0a, 0x0a])
-a52.set(a5)
-assertArrayPrefix([0x50, 0x50, 0x0a, 0x0a], a50)
-
-a50.set([0x50, 0x50, 0x0a, 0x0a])
-a53.set(a5)
-assertArrayPrefix([0x50, 0x50, 0x50, 0x0a], a50)
-
-a50.set([0x50, 0x51, 0x0a, 0x0b])
-a5.set(a51)
-assertArrayPrefix([0x0050, 0x0051], a5)
-
-a50.set([0x50, 0x51, 0x0a, 0x0b])
-a5.set(a52)
-assertArrayPrefix([0x0051, 0x000a], a5)
-
-a50.set([0x50, 0x51, 0x0a, 0x0b])
-a5.set(a53)
-assertArrayPrefix([0x000a, 0x000b], a5)
-
-// Mixed types of same size.
-var a61 = new Float32Array([1.2, 12.3])
-var a62 = new Int32Array(2)
-a62.set(a61)
-assertArrayPrefix([1, 12], a62)
-a61.set(a62)
-assertArrayPrefix([1, 12], a61)
-
-// Invalid source
-assertThrows(function() { a.set(0); }, TypeError);
-assertArrayPrefix([1,2,3,4,5,6], a);
-a.set({}); // does not throw
-assertArrayPrefix([1,2,3,4,5,6], a);
-
-
-// Test arraybuffer.slice
-
-var a0 = new Int8Array([1, 2, 3, 4, 5, 6])
-var b0 = a0.buffer
-
-var b1 = b0.slice(0)
-assertEquals(b0.byteLength, b1.byteLength)
-assertArrayPrefix([1, 2, 3, 4, 5, 6], new Int8Array(b1))
-
-var b2 = b0.slice(3)
-assertEquals(b0.byteLength - 3, b2.byteLength)
-assertArrayPrefix([4, 5, 6], new Int8Array(b2))
-
-var b3 = b0.slice(2, 4)
-assertEquals(2, b3.byteLength)
-assertArrayPrefix([3, 4], new Int8Array(b3))
-
-function goo(a, i) {
- return a[i];
-}
-
-function boo(a, i, v) {
- return a[i] = v;
-}
-
-function do_tagged_index_external_array_test(constructor) {
- var t_array = new constructor([1, 2, 3, 4, 5, 6]);
- assertEquals(1, goo(t_array, 0));
- assertEquals(1, goo(t_array, 0));
- boo(t_array, 0, 13);
- assertEquals(13, goo(t_array, 0));
- %OptimizeFunctionOnNextCall(goo);
- %OptimizeFunctionOnNextCall(boo);
- boo(t_array, 0, 15);
- assertEquals(15, goo(t_array, 0));
- %ClearFunctionTypeFeedback(goo);
- %ClearFunctionTypeFeedback(boo);
-}
-
-do_tagged_index_external_array_test(Int8Array);
-do_tagged_index_external_array_test(Uint8Array);
-do_tagged_index_external_array_test(Int16Array);
-do_tagged_index_external_array_test(Uint16Array);
-do_tagged_index_external_array_test(Int32Array);
-do_tagged_index_external_array_test(Uint32Array);
-do_tagged_index_external_array_test(Float32Array);
-do_tagged_index_external_array_test(Float64Array);
-
-var built_in_array = new Array(1, 2, 3, 4, 5, 6);
-assertEquals(1, goo(built_in_array, 0));
-assertEquals(1, goo(built_in_array, 0));
-%OptimizeFunctionOnNextCall(goo);
-%OptimizeFunctionOnNextCall(boo);
-boo(built_in_array, 0, 11);
-assertEquals(11, goo(built_in_array, 0));
-%ClearFunctionTypeFeedback(goo);
-%ClearFunctionTypeFeedback(boo);
-
-built_in_array = new Array(1.5, 2, 3, 4, 5, 6);
-assertEquals(1.5, goo(built_in_array, 0));
-assertEquals(1.5, goo(built_in_array, 0));
-%OptimizeFunctionOnNextCall(goo);
-%OptimizeFunctionOnNextCall(boo);
-boo(built_in_array, 0, 2.5);
-assertEquals(2.5, goo(built_in_array, 0));
-%ClearFunctionTypeFeedback(goo);
-%ClearFunctionTypeFeedback(boo);
-
-// Check all int range edge cases
-function checkRange() {
- var e32 = Math.pow(2,32); var e31 = Math.pow(2,31);
- var e16 = Math.pow(2,16); var e15 = Math.pow(2,15);
- var e8 = Math.pow(2,8); var e7 = Math.pow(2,7);
- var a7 = new Uint32Array(2); var a71 = new Int32Array(2);
- var a72 = new Uint16Array(2); var a73 = new Int16Array(2);
- var a74 = new Uint8Array(2); var a75 = new Int8Array(2);
- for (i = 1; i <= Math.pow(2,33); i *= 2) {
- var j = i-1;
- a7[0] = i; a71[0] = i; a72[0] = i; a73[0] = i; a74[0] = i; a75[0] = i;
- a7[1] = j; a71[1] = j; a72[1] = j; a73[1] = j; a74[1] = j; a75[1] = j;
-
- if (i < e32) { assertEquals(a7[0], i); } else { assertEquals(a7[0], 0); }
- if (j < e32) { assertEquals(a7[1], j); } else { assertEquals(a7[1],e32-1); }
- if (i < e31) { assertEquals(a71[0], i); } else {
- assertEquals(a71[0], (i < e32) ? -e31 : 0 ); }
- if (j < e31) { assertEquals(a71[1], j); } else { assertEquals(a71[1], -1); }
-
- if (i < e16) { assertEquals(a72[0], i); } else { assertEquals(a72[0], 0); }
- if (j < e16) { assertEquals(a72[1], j); } else { assertEquals(a72[1], e16-1); }
- if (i < e15) { assertEquals(a73[0], i); } else {
- assertEquals(a73[0], (i < e16) ? -e15 : 0 ); }
- if (j < e15) { assertEquals(a73[1], j); } else { assertEquals(a73[1], -1); }
-
- if (i < e8) { assertEquals(a74[0], i); } else { assertEquals(a74[0], 0); }
- if (j < e8) { assertEquals(a74[1], j); } else { assertEquals(a74[1], e8-1); }
- if (i < e7) { assertEquals(a75[0], i); } else {
- assertEquals(a75[0], (i < e8) ? -e7 : 0); }
- if (j < e7) { assertEquals(a75[1], j); } else { assertEquals(a75[1], -1); }
- }
-}
-checkRange();
diff --git a/deps/v8/test/mjsunit/for-in.js b/deps/v8/test/mjsunit/for-in.js
index ab35e95ee3..644c27a632 100644
--- a/deps/v8/test/mjsunit/for-in.js
+++ b/deps/v8/test/mjsunit/for-in.js
@@ -119,3 +119,15 @@ for (i=0 ; i < 3; ++i) {
assertEquals("undefined", typeof y[2], "y[2]");
assertEquals("undefined", typeof y[0], "y[0]");
}
+
+(function() {
+ var large_key = 2147483650;
+ var o = {__proto__: {}};
+ o[large_key] = 1;
+ o.__proto__[large_key] = 1;
+ var keys = [];
+ for (var k in o) {
+ keys.push(k);
+ }
+ assertEquals(["2147483650"], keys);
+})();
diff --git a/deps/v8/test/mjsunit/function-bind-name.js b/deps/v8/test/mjsunit/function-bind-name.js
new file mode 100644
index 0000000000..3bebf3e72d
--- /dev/null
+++ b/deps/v8/test/mjsunit/function-bind-name.js
@@ -0,0 +1,13 @@
+// Copyright 2015 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() {}
+var fb = f.bind({});
+assertEquals('bound f', fb.name);
+assertEquals('function bound f() { [native code] }', fb.toString());
+
+Object.defineProperty(f, 'name', {value: 42});
+var fb2 = f.bind({});
+assertEquals('bound ', fb2.name);
+assertEquals('function bound () { [native code] }', fb2.toString());
diff --git a/deps/v8/test/mjsunit/get-caller-js-function-throws.js b/deps/v8/test/mjsunit/get-caller-js-function-throws.js
new file mode 100644
index 0000000000..42b098aee9
--- /dev/null
+++ b/deps/v8/test/mjsunit/get-caller-js-function-throws.js
@@ -0,0 +1,14 @@
+// Copyright 2015 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 --noalways-opt --nostress-opt
+
+// Ensure that "real" js functions that call GetCallerJSFunction get an
+// exception, since they are not stubs.
+(function() {
+ var a = function() {
+ return %_GetCallerJSFunction();
+ }
+ assertThrows(a);
+}());
diff --git a/deps/v8/test/mjsunit/get-caller-js-function.js b/deps/v8/test/mjsunit/get-caller-js-function.js
new file mode 100644
index 0000000000..5c7af64814
--- /dev/null
+++ b/deps/v8/test/mjsunit/get-caller-js-function.js
@@ -0,0 +1,21 @@
+// Copyright 2015 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 --turbo-filter=* --nostress-opt
+
+// Test that for fully optimized but non inlined code, GetCallerJSFunction walks
+// up a single stack frame to get the calling function. Full optimization elides
+// the check in the runtime version of the intrinsic that would throw since the
+// caller isn't a stub. It's a bit of a hack, but allows minimal testing of the
+// intrinsic without writing a full-blown cctest.
+(function() {
+ var a = function() {
+ return %_GetCallerJSFunction();
+ };
+ var b = function() {
+ return a();
+ };
+ %OptimizeFunctionOnNextCall(a);
+ assertEquals(b, b());
+}());
diff --git a/deps/v8/test/mjsunit/global-deleted-property-keyed.js b/deps/v8/test/mjsunit/global-deleted-property-keyed.js
index dba3a4d405..a0e48ffdeb 100644
--- a/deps/v8/test/mjsunit/global-deleted-property-keyed.js
+++ b/deps/v8/test/mjsunit/global-deleted-property-keyed.js
@@ -26,9 +26,9 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --expose-natives_as natives
-// Test keyed access to deleted property in a global object without access checks.
-// Regression test that exposed the_hole value from Runtime_KeyedGetPoperty.
+// Flags: --expose-natives-as natives
+// Test keyed access to deleted property in a global object w/o access checks.
+// Regression test that exposed the_hole value from Runtime_KeyedGetProperty.
var name = "fisk";
natives[name] = name;
diff --git a/deps/v8/test/mjsunit/global-hash.js b/deps/v8/test/mjsunit/global-hash.js
new file mode 100644
index 0000000000..54dfc4c779
--- /dev/null
+++ b/deps/v8/test/mjsunit/global-hash.js
@@ -0,0 +1,19 @@
+// Copyright 2015 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 global = this;
+
+assertEquals("object", typeof global); // Global object.
+
+var s = new Set();
+s.add(global); // Puts a hash code on the global object.
+assertTrue(s.has(global));
+for (var i = 0; i < 100; i++) {
+ // Force rehash. Global object is placed according to the hash code that it
+ // gets in the C++ runtime.
+ s.add(i);
+}
+
+// Hopefully still findable using the JS hash code.
+assertTrue(s.has(global));
diff --git a/deps/v8/test/mjsunit/handle-count-ast.js b/deps/v8/test/mjsunit/handle-count-ast.js
new file mode 100644
index 0000000000..8d095598e7
--- /dev/null
+++ b/deps/v8/test/mjsunit/handle-count-ast.js
@@ -0,0 +1,12 @@
+// Copyright 2015 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: --check-handle-count
+
+var ones = eval("[" + Array(12 * 1024).join("1,") + 1 + "]")
+
+var sum = 0;
+for (var i = 0; i < ones.length; i++) {
+ sum += ones[i];
+}
diff --git a/deps/v8/test/mjsunit/handle-count-runtime-literals.js b/deps/v8/test/mjsunit/handle-count-runtime-literals.js
new file mode 100644
index 0000000000..91774d2b6f
--- /dev/null
+++ b/deps/v8/test/mjsunit/handle-count-runtime-literals.js
@@ -0,0 +1,1230 @@
+// Copyright 2015 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: --check-handle-count
+
+(function (s) {
+ s.frob = function () {
+ var j;
+ var p0 = /^[\],:{}\s]*$/;
+ var p1 = /"[^"\\\n\r]*"|a|b|c|_*-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g;
+ var p2 = /(?:^|:|,)(?:\s*\[)+/g;
+ if (p0.test(this.replace(/\\./g, '@').replace(p1, ']').replace(p2, ''))) {
+ var tmp = eval('(' + this + ')');
+ return 0;
+ }
+ return -1;
+ };
+})(String.prototype);
+
+var kvJSON = '[\
+ {\n \"key\": "ionion",\n \"value\": 779249\n },\
+ {\n \"key\": "essess",\n \"value\": 775215\n },\
+ {\n \"key\": "lerler",\n \"value\": 773163\n },\
+ {\n \"key\": "essess",\n \"value\": 778638\n },\
+ {\n \"key\": "suosuo",\n \"value\": 778428\n },\
+ {\n \"key\": "astast",\n \"value\": 779719\n },\
+ {\n \"key\": "oidoid",\n \"value\": 776316\n },\
+ {\n \"key\": "onyony",\n \"value\": 777017\n },\
+ {\n \"key\": "oryory",\n \"value\": 775785\n },\
+ {\n \"key\": "ardard",\n \"value\": 776276\n },\
+ {\n \"key\": "nicnic",\n \"value\": 773163\n },\
+ {\n \"key\": "udyudy",\n \"value\": 775255\n },\
+ {\n \"key\": "blybly",\n \"value\": 776546\n },\
+ {\n \"key\": "ormorm",\n \"value\": 770040\n },\
+ {\n \"key\": "izeize",\n \"value\": 774534\n },\
+ {\n \"key\": "lialia",\n \"value\": 775135\n },\
+ {\n \"key\": "thythy",\n \"value\": 773823\n },\
+ {\n \"key\": "hiphip",\n \"value\": 776526\n },\
+ {\n \"key\": "iseise",\n \"value\": 772322\n },\
+ {\n \"key\": "salsal",\n \"value\": 772122\n },\
+ {\n \"key\": "essess",\n \"value\": 775915\n },\
+ {\n \"key\": "etaeta",\n \"value\": 779719\n },\
+ {\n \"key\": "kcakca",\n \"value\": 776616\n },\
+ {\n \"key\": "tiktik",\n \"value\": 773513\n },\
+ {\n \"key\": "rerrer",\n \"value\": 773413\n },\
+ {\n \"key\": "teatea",\n \"value\": 773313\n },\
+ {\n \"key\": "izeize",\n \"value\": 774214\n },\
+ {\n \"key\": "reyrey",\n \"value\": 777117\n },\
+ {\n \"key\": "oteote",\n \"value\": 770110\n },\
+ {\n \"key\": "essess",\n \"value\": 773013\n },\
+ {\n \"key\": "essess",\n \"value\": 778798\n },\
+ {\n \"key\": "tchtch",\n \"value\": 774294\n },\
+ {\n \"key\": "taltal",\n \"value\": 775785\n },\
+ {\n \"key\": "risris",\n \"value\": 770380\n },\
+ {\n \"key\": "ateate",\n \"value\": 779879\n },\
+ {\n \"key\": "ousous",\n \"value\": 770570\n },\
+ {\n \"key\": "essess",\n \"value\": 775175\n },\
+ {\n \"key\": "lesles",\n \"value\": 772862\n },\
+ {\n \"key\": "iveive",\n \"value\": 771561\n },\
+ {\n \"key\": "diadia",\n \"value\": 772262\n },\
+ {\n \"key\": "ekieki",\n \"value\": 776956\n },\
+ {\n \"key\": "omaoma",\n \"value\": 771751\n },\
+ {\n \"key\": "nalnal",\n \"value\": 777457\n },\
+ {\n \"key\": "essess",\n \"value\": 776256\n },\
+ {\n \"key\": "ilyily",\n \"value\": 775055\n },\
+ {\n \"key\": "emuemu",\n \"value\": 776846\n },\
+ {\n \"key\": "eeteet",\n \"value\": 778648\n },\
+ {\n \"key\": "rerrer",\n \"value\": 770540\n },\
+ {\n \"key\": "eaeeae",\n \"value\": 774344\n },\
+ {\n \"key\": "lumlum",\n \"value\": 779149\n },\
+ {\n \"key\": "essess",\n \"value\": 774044\n },\
+ {\n \"key\": "antant",\n \"value\": 771931\n },\
+ {\n \"key\": "lahlah",\n \"value\": 778738\n },\
+ {\n \"key\": "tnatna",\n \"value\": 775635\n },\
+ {\n \"key\": "oseose",\n \"value\": 774534\n },\
+ {\n \"key\": "ataata",\n \"value\": 773433\n },\
+ {\n \"key\": "inging",\n \"value\": 772332\n },\
+ {\n \"key\": "ypeype",\n \"value\": 772232\n },\
+ {\n \"key\": "tictic",\n \"value\": 772132\n },\
+ {\n \"key\": "hiphip",\n \"value\": 773033\n },\
+ {\n \"key\": "taltal",\n \"value\": 774924\n },\
+ {\n \"key\": "istist",\n \"value\": 776826\n },\
+ {\n \"key\": "ralral",\n \"value\": 778728\n },\
+ {\n \"key\": "tortor",\n \"value\": 770720\n },\
+ {\n \"key\": "rnsrns",\n \"value\": 773623\n },\
+ {\n \"key\": "siasia",\n \"value\": 776526\n },\
+ {\n \"key\": "yabyab",\n \"value\": 779429\n },\
+ {\n \"key\": "noinoi",\n \"value\": 773423\n },\
+ {\n \"key\": "ardard",\n \"value\": 777327\n },\
+ {\n \"key\": "derder",\n \"value\": 771321\n },\
+ {\n \"key\": "iveive",\n \"value\": 775225\n },\
+ {\n \"key\": "ateate",\n \"value\": 779129\n },\
+ {\n \"key\": "imoimo",\n \"value\": 774124\n },\
+ {\n \"key\": "adeade",\n \"value\": 779029\n },\
+ {\n \"key\": "ugeuge",\n \"value\": 774024\n },\
+ {\n \"key\": "iveive",\n \"value\": 779919\n },\
+ {\n \"key\": "belbel",\n \"value\": 775915\n },\
+ {\n \"key\": "inging",\n \"value\": 770910\n },\
+ {\n \"key\": "barbar",\n \"value\": 776816\n },\
+ {\n \"key\": "ionion",\n \"value\": 772812\n },\
+ {\n \"key\": "ineine",\n \"value\": 778718\n },\
+ {\n \"key\": "ityity",\n \"value\": 774714\n },\
+ {\n \"key\": "ytiyti",\n \"value\": 770710\n },\
+ {\n \"key\": "ismism",\n \"value\": 777617\n },\
+ {\n \"key\": "iumium",\n \"value\": 773613\n },\
+ {\n \"key\": "hichic",\n \"value\": 770610\n },\
+ {\n \"key\": "ideide",\n \"value\": 777517\n },\
+ {\n \"key\": "denden",\n \"value\": 774514\n },\
+ {\n \"key\": "redred",\n \"value\": 770510\n },\
+ {\n \"key\": "perper",\n \"value\": 778418\n },\
+ {\n \"key\": "rusrus",\n \"value\": 775415\n },\
+ {\n \"key\": "herher",\n \"value\": 772412\n },\
+ {\n \"key\": "sidsid",\n \"value\": 779319\n },\
+ {\n \"key\": "ianian",\n \"value\": 777317\n },\
+ {\n \"key\": "ricric",\n \"value\": 774314\n },\
+ {\n \"key\": "odyody",\n \"value\": 772312\n },\
+ {\n \"key\": "ferfer",\n \"value\": 779219\n },\
+ {\n \"key\": "ogyogy",\n \"value\": 777217\n },\
+ {\n \"key\": "micmic",\n \"value\": 775215\n },\
+ {\n \"key\": "ateate",\n \"value\": 772212\n },\
+ {\n \"key\": "tantan",\n \"value\": 770210\n },\
+ {\n \"key\": "getget",\n \"value\": 778118\n },\
+ {\n \"key\": "ulaula",\n \"value\": 776116\n },\
+ {\n \"key\": "calcal",\n \"value\": 774114\n },\
+ {\n \"key\": "izeize",\n \"value\": 772112\n },\
+ {\n \"key\": "manman",\n \"value\": 770110\n },\
+ {\n \"key\": "terter",\n \"value\": 778018\n },\
+ {\n \"key\": "hedhed",\n \"value\": 777017\n },\
+ {\n \"key\": "berber",\n \"value\": 775015\n },\
+ {\n \"key\": "olfolf",\n \"value\": 773013\n },\
+ {\n \"key\": "opeope",\n \"value\": 772012\n },\
+ {\n \"key\": "hiphip",\n \"value\": 770010\n },\
+ {\n \"key\": "tedted",\n \"value\": 779899\n },\
+ {\n \"key\": "ismism",\n \"value\": 773793\n },\
+ {\n \"key\": "terter",\n \"value\": 778598\n },\
+ {\n \"key\": "ismism",\n \"value\": 774494\n },\
+ {\n \"key\": "ikeike",\n \"value\": 779299\n },\
+ {\n \"key\": "sdrsdr",\n \"value\": 776196\n },\
+ {\n \"key\": "calcal",\n \"value\": 772092\n },\
+ {\n \"key\": "ledled",\n \"value\": 779889\n },\
+ {\n \"key\": "coicoi",\n \"value\": 776786\n },\
+ {\n \"key\": "ialial",\n \"value\": 773683\n },\
+ {\n \"key\": "izeize",\n \"value\": 771581\n },\
+ {\n \"key\": "ogyogy",\n \"value\": 778388\n },\
+ {\n \"key\": "ismism",\n \"value\": 777287\n },\
+ {\n \"key\": "Huk",\n \"value\": 775185\n },\
+ {\n \"key\": "nonnon",\n \"value\": 774084\n },\
+ {\n \"key\": "ledled",\n \"value\": 773973\n },\
+ {\n \"key\": "llylly",\n \"value\": 772872\n },\
+ {\n \"key\": "ishish",\n \"value\": 771771\n },\
+ {\n \"key\": "terter",\n \"value\": 771671\n },\
+ {\n \"key\": "iorior",\n \"value\": 771571\n },\
+ {\n \"key\": "ionion",\n \"value\": 771471\n },\
+ {\n \"key\": "luslus",\n \"value\": 771371\n },\
+ {\n \"key\": "detdet",\n \"value\": 771271\n },\
+ {\n \"key\": "ionion",\n \"value\": 772172\n },\
+ {\n \"key\": "ezoezo",\n \"value\": 773073\n },\
+ {\n \"key\": "iceice",\n \"value\": 774964\n },\
+ {\n \"key\": "piapia",\n \"value\": 775865\n },\
+ {\n \"key\": "nedned",\n \"value\": 776766\n },\
+ {\n \"key\": "ffaffa",\n \"value\": 778668\n },\
+ {\n \"key\": "oidoid",\n \"value\": 779569\n },\
+ {\n \"key\": "ureure",\n \"value\": 771561\n },\
+ {\n \"key\": "akaaka",\n \"value\": 773463\n },\
+ {\n \"key\": "jimjim",\n \"value\": 775365\n },\
+ {\n \"key\": "calcal",\n \"value\": 778268\n },\
+ {\n \"key\": "istist",\n \"value\": 770260\n },\
+ {\n \"key\": "ickick",\n \"value\": 773163\n },\
+ {\n \"key\": "ncence",\n \"value\": 775065\n },\
+ {\n \"key\": "ikeike",\n \"value\": 778958\n },\
+ {\n \"key\": "omeome",\n \"value\": 771951\n },\
+ {\n \"key\": "ismism",\n \"value\": 774854\n },\
+ {\n \"key\": "eeleel",\n \"value\": 778758\n },\
+ {\n \"key\": "ialial",\n \"value\": 771751\n },\
+ {\n \"key\": "deadea",\n \"value\": 774654\n },\
+ {\n \"key\": "fulful",\n \"value\": 778558\n },\
+ {\n \"key\": "bleble",\n \"value\": 772552\n },\
+ {\n \"key\": "tahtah",\n \"value\": 776456\n },\
+ {\n \"key\": "astast",\n \"value\": 770450\n },\
+ {\n \"key\": "ylsyls",\n \"value\": 774354\n },\
+ {\n \"key\": "ziazia",\n \"value\": 778258\n },\
+ {\n \"key\": "ssesse",\n \"value\": 772252\n },\
+ {\n \"key\": "essess",\n \"value\": 776156\n },\
+ {\n \"key\": "lewlew",\n \"value\": 771151\n },\
+ {\n \"key\": "ionion",\n \"value\": 775055\n },\
+ {\n \"key\": "ackack",\n \"value\": 770050\n },\
+ {\n \"key\": "wedwed",\n \"value\": 775945\n },\
+ {\n \"key\": "gnigni",\n \"value\": 779849\n },\
+ {\n \"key\": "areare",\n \"value\": 774844\n },\
+ {\n \"key\": "oleole",\n \"value\": 779749\n },\
+ {\n \"key\": "ateate",\n \"value\": 774744\n },\
+ {\n \"key\": "ousous",\n \"value\": 779649\n },\
+ {\n \"key\": "niania",\n \"value\": 775645\n },\
+ {\n \"key\": "tletle",\n \"value\": 770640\n },\
+ {\n \"key\": "cimcim",\n \"value\": 775545\n },\
+ {\n \"key\": "eedeed",\n \"value\": 771541\n },\
+ {\n \"key\": "bleble",\n \"value\": 776446\n },\
+ {\n \"key\": "tcatca",\n \"value\": 772442\n },\
+ {\n \"key\": "oneone",\n \"value\": 777347\n },\
+ {\n \"key\": "nidnid",\n \"value\": 773343\n },\
+ {\n \"key\": "hnahna",\n \"value\": 779249\n },\
+ {\n \"key\": "olfolf",\n \"value\": 775245\n },\
+ {\n \"key\": "ousous",\n \"value\": 770240\n },\
+ {\n \"key\": "verver",\n \"value\": 776146\n },\
+ {\n \"key\": "oseose",\n \"value\": 772142\n },\
+ {\n \"key\": "tictic",\n \"value\": 779049\n },\
+ {\n \"key\": "essess",\n \"value\": 775045\n },\
+ {\n \"key\": "ionion",\n \"value\": 771041\n },\
+ {\n \"key\": "iedied",\n \"value\": 777937\n },\
+ {\n \"key\": "diadia",\n \"value\": 773933\n },\
+ {\n \"key\": "ityity",\n \"value\": 770930\n },\
+ {\n \"key\": "fulful",\n \"value\": 776836\n },\
+ {\n \"key\": "ukeuke",\n \"value\": 773833\n },\
+ {\n \"key\": "intint",\n \"value\": 779739\n },\
+ {\n \"key\": "hoqhoq",\n \"value\": 776736\n },\
+ {\n \"key\": "yoxyox",\n \"value\": 772732\n },\
+ {\n \"key\": "taltal",\n \"value\": 779639\n },\
+ {\n \"key\": "paipai",\n \"value\": 776636\n },\
+ {\n \"key\": "eanean",\n \"value\": 772632\n },\
+ {\n \"key\": "ineine",\n \"value\": 779539\n },\
+ {\n \"key\": "uthuth",\n \"value\": 776536\n },\
+ {\n \"key\": "izeize",\n \"value\": 773533\n },\
+ {\n \"key\": "rubrub",\n \"value\": 770530\n },\
+ {\n \"key\": "ilyily",\n \"value\": 777437\n },\
+ {\n \"key\": "ylbylb",\n \"value\": 774434\n },\
+ {\n \"key\": "liclic",\n \"value\": 771431\n },\
+ {\n \"key\": "bleble",\n \"value\": 778338\n },\
+ {\n \"key\": "elyely",\n \"value\": 775335\n },\
+ {\n \"key\": "nelnel",\n \"value\": 772332\n },\
+ {\n \"key\": "siasia",\n \"value\": 779239\n },\
+ {\n \"key\": "monmon",\n \"value\": 777237\n },\
+ {\n \"key\": "rinrin",\n \"value\": 774234\n },\
+ {\n \"key\": "nalnal",\n \"value\": 771231\n },\
+ {\n \"key\": "etyety",\n \"value\": 779139\n },\
+ {\n \"key\": "tictic",\n \"value\": 776136\n },\
+ {\n \"key\": "hsuhsu",\n \"value\": 773133\n },\
+ {\n \"key\": "testes",\n \"value\": 771131\n },\
+ {\n \"key\": "ritrit",\n \"value\": 778038\n },\
+ {\n \"key\": "gabgab",\n \"value\": 776036\n },\
+ {\n \"key\": "naenae",\n \"value\": 773033\n },\
+ {\n \"key\": "noinoi",\n \"value\": 771031\n },\
+ {\n \"key\": "ondond",\n \"value\": 778928\n },\
+ {\n \"key\": "nisnis",\n \"value\": 776926\n },\
+ {\n \"key\": "ianian",\n \"value\": 774924\n },\
+ {\n \"key\": "cincin",\n \"value\": 771921\n },\
+ {\n \"key\": "luslus",\n \"value\": 779829\n },\
+ {\n \"key\": "llylly",\n \"value\": 777827\n },\
+ {\n \"key\": "ltylty",\n \"value\": 775825\n },\
+ {\n \"key\": "nienie",\n \"value\": 772822\n },\
+ {\n \"key\": "ookook",\n \"value\": 770820\n },\
+ {\n \"key\": "oinoin",\n \"value\": 778728\n },\
+ {\n \"key\": "dmidmi",\n \"value\": 776726\n },\
+ {\n \"key\": "macmac",\n \"value\": 774724\n },\
+ {\n \"key\": "bleble",\n \"value\": 772722\n },\
+ {\n \"key\": "ionion",\n \"value\": 770720\n },\
+ {\n \"key\": "manman",\n \"value\": 778628\n },\
+ {\n \"key\": "cipcip",\n \"value\": 776626\n },\
+ {\n \"key\": "barbar",\n \"value\": 774624\n },\
+ {\n \"key\": "llylly",\n \"value\": 772622\n },\
+ {\n \"key\": "hothot",\n \"value\": 770620\n },\
+ {\n \"key\": "oodood",\n \"value\": 778528\n },\
+ {\n \"key\": "cumcum",\n \"value\": 776526\n },\
+ {\n \"key\": "rkarka",\n \"value\": 774524\n },\
+ {\n \"key\": "iveive",\n \"value\": 772522\n },\
+ {\n \"key\": "ranran",\n \"value\": 771521\n },\
+ {\n \"key\": "lesles",\n \"value\": 779429\n },\
+ {\n \"key\": "fulful",\n \"value\": 777427\n },\
+ {\n \"key\": "nalnal",\n \"value\": 775425\n },\
+ {\n \"key\": "ousous",\n \"value\": 773423\n },\
+ {\n \"key\": "inging",\n \"value\": 772422\n },\
+ {\n \"key\": "ionion",\n \"value\": 770420\n },\
+ {\n \"key\": "ousous",\n \"value\": 778328\n },\
+ {\n \"key\": "pitpit",\n \"value\": 777327\n },\
+ {\n \"key\": "oicoic",\n \"value\": 775325\n },\
+ {\n \"key\": "vetvet",\n \"value\": 773323\n },\
+ {\n \"key\": "erkerk",\n \"value\": 772322\n },\
+ {\n \"key\": "ncyncy",\n \"value\": 770320\n },\
+ {\n \"key\": "ionion",\n \"value\": 779229\n },\
+ {\n \"key\": "inging",\n \"value\": 777227\n },\
+ {\n \"key\": "tictic",\n \"value\": 775225\n },\
+ {\n \"key\": "sissis",\n \"value\": 774224\n },\
+ {\n \"key\": "rgyrgy",\n \"value\": 772222\n },\
+ {\n \"key\": "tictic",\n \"value\": 771221\n },\
+ {\n \"key\": "oedoed",\n \"value\": 779129\n },\
+ {\n \"key\": "omaoma",\n \"value\": 778128\n },\
+ {\n \"key\": "hiphip",\n \"value\": 777127\n },\
+ {\n \"key\": "ncence",\n \"value\": 775125\n },\
+ {\n \"key\": "ousous",\n \"value\": 774124\n },\
+ {\n \"key\": "rghrgh",\n \"value\": 772122\n },\
+ {\n \"key\": "ebtebt",\n \"value\": 771121\n },\
+ {\n \"key\": "msimsi",\n \"value\": 779029\n },\
+ {\n \"key\": "inging",\n \"value\": 778028\n },\
+ {\n \"key\": "aukauk",\n \"value\": 777027\n },\
+ {\n \"key\": "getget",\n \"value\": 775025\n },\
+ {\n \"key\": "otaota",\n \"value\": 774024\n },\
+ {\n \"key\": "oseose",\n \"value\": 773023\n },\
+ {\n \"key\": "sapsap",\n \"value\": 771021\n },\
+ {\n \"key\": "micmic",\n \"value\": 770020\n },\
+ {\n \"key\": "calcal",\n \"value\": 779919\n },\
+ {\n \"key\": "ismism",\n \"value\": 778918\n },\
+ {\n \"key\": "dlydly",\n \"value\": 776916\n },\
+ {\n \"key\": "ionion",\n \"value\": 775915\n },\
+ {\n \"key\": "stysty",\n \"value\": 774914\n },\
+ {\n \"key\": "kgokgo",\n \"value\": 773913\n },\
+ {\n \"key\": "entent",\n \"value\": 772912\n },\
+ {\n \"key\": "entent",\n \"value\": 770910\n },\
+ {\n \"key\": "manman",\n \"value\": 779819\n },\
+ {\n \"key\": "minmin",\n \"value\": 778818\n },\
+ {\n \"key\": "gotgot",\n \"value\": 777817\n },\
+ {\n \"key\": "unkunk",\n \"value\": 776816\n },\
+ {\n \"key\": "ionion",\n \"value\": 775815\n },\
+ {\n \"key\": "kerker",\n \"value\": 773813\n },\
+ {\n \"key\": "eltelt",\n \"value\": 772812\n },\
+ {\n \"key\": "manman",\n \"value\": 771811\n },\
+ {\n \"key\": "ncence",\n \"value\": 770810\n },\
+ {\n \"key\": "ernern",\n \"value\": 779719\n },\
+ {\n \"key\": "eegeeg",\n \"value\": 778718\n },\
+ {\n \"key\": "athath",\n \"value\": 777717\n },\
+ {\n \"key\": "daedae",\n \"value\": 776716\n },\
+ {\n \"key\": "ionion",\n \"value\": 775715\n },\
+ {\n \"key\": "kerker",\n \"value\": 774714\n },\
+ {\n \"key\": "terter",\n \"value\": 773713\n },\
+ {\n \"key\": "essess",\n \"value\": 772712\n },\
+ {\n \"key\": "aneane",\n \"value\": 771711\n },\
+ {\n \"key\": "lahlah",\n \"value\": 770710\n },\
+ {\n \"key\": "inging",\n \"value\": 779619\n },\
+ {\n \"key\": "pilpil",\n \"value\": 778618\n },\
+ {\n \"key\": "iseise",\n \"value\": 777617\n },\
+ {\n \"key\": "sonson",\n \"value\": 776616\n },\
+ {\n \"key\": "ityity",\n \"value\": 775615\n },\
+ {\n \"key\": "esaesa",\n \"value\": 774614\n },\
+ {\n \"key\": "araara",\n \"value\": 773613\n },\
+ {\n \"key\": "perper",\n \"value\": 772612\n },\
+ {\n \"key\": "siasia",\n \"value\": 771611\n },\
+ {\n \"key\": "bleble",\n \"value\": 770610\n },\
+ {\n \"key\": "rumrum",\n \"value\": 779519\n },\
+ {\n \"key\": "toltol",\n \"value\": 779519\n },\
+ {\n \"key\": "ousous",\n \"value\": 778518\n },\
+ {\n \"key\": "ateate",\n \"value\": 777517\n },\
+ {\n \"key\": "verver",\n \"value\": 776516\n },\
+ {\n \"key\": "psepse",\n \"value\": 775515\n },\
+ {\n \"key\": "rkyrky",\n \"value\": 774514\n },\
+ {\n \"key\": "uleule",\n \"value\": 773513\n },\
+ {\n \"key\": "adaada",\n \"value\": 772512\n },\
+ {\n \"key\": "minmin",\n \"value\": 772512\n },\
+ {\n \"key\": "amiami",\n \"value\": 771511\n },\
+ {\n \"key\": "ulfulf",\n \"value\": 770510\n },\
+ {\n \"key\": "rtzrtz",\n \"value\": 779419\n },\
+ {\n \"key\": "ockock",\n \"value\": 778418\n },\
+ {\n \"key\": "izeize",\n \"value\": 778418\n },\
+ {\n \"key\": "oidoid",\n \"value\": 777417\n },\
+ {\n \"key\": "bisbis",\n \"value\": 776416\n },\
+ {\n \"key\": "nedned",\n \"value\": 775415\n },\
+ {\n \"key\": "ralral",\n \"value\": 774414\n },\
+ {\n \"key\": "aryary",\n \"value\": 774414\n },\
+ {\n \"key\": "ikeike",\n \"value\": 773413\n },\
+ {\n \"key\": "terter",\n \"value\": 772412\n },\
+ {\n \"key\": "oveove",\n \"value\": 771411\n },\
+ {\n \"key\": "ineine",\n \"value\": 771411\n },\
+ {\n \"key\": "ebiebi",\n \"value\": 770410\n },\
+ {\n \"key\": "iumium",\n \"value\": 779319\n },\
+ {\n \"key\": "dgedge",\n \"value\": 779319\n },\
+ {\n \"key\": "riaria",\n \"value\": 778318\n },\
+ {\n \"key\": "upaupa",\n \"value\": 777317\n },\
+ {\n \"key\": "entent",\n \"value\": 776316\n },\
+ {\n \"key\": "eneene",\n \"value\": 776316\n },\
+ {\n \"key\": "ridrid",\n \"value\": 775315\n },\
+ {\n \"key\": "llelle",\n \"value\": 774314\n },\
+ {\n \"key\": "dlydly",\n \"value\": 774314\n },\
+ {\n \"key\": "angang",\n \"value\": 773313\n },\
+ {\n \"key\": "tictic",\n \"value\": 772312\n },\
+ {\n \"key\": "ontont",\n \"value\": 772312\n },\
+ {\n \"key\": "astast",\n \"value\": 771311\n },\
+ {\n \"key\": "suosuo",\n \"value\": 770310\n },\
+ {\n \"key\": "essess",\n \"value\": 770310\n },\
+ {\n \"key\": "essess",\n \"value\": 779219\n },\
+ {\n \"key\": "istist",\n \"value\": 778218\n },\
+ {\n \"key\": "inaina",\n \"value\": 778218\n },\
+ {\n \"key\": "ewdewd",\n \"value\": 777217\n },\
+ {\n \"key\": "verver",\n \"value\": 776216\n },\
+ {\n \"key\": "ionion",\n \"value\": 776216\n },\
+ {\n \"key\": "ardard",\n \"value\": 775215\n },\
+ {\n \"key\": "pidpid",\n \"value\": 775215\n },\
+ {\n \"key\": "eltelt",\n \"value\": 774214\n },\
+ {\n \"key\": "letlet",\n \"value\": 773213\n },\
+ {\n \"key\": "iesies",\n \"value\": 773213\n },\
+ {\n \"key\": "ityity",\n \"value\": 772212\n },\
+ {\n \"key\": "chacha",\n \"value\": 772212\n },\
+ {\n \"key\": "ngenge",\n \"value\": 771211\n },\
+ {\n \"key\": "terter",\n \"value\": 770210\n },\
+ {\n \"key\": "eanean",\n \"value\": 770210\n },\
+ {\n \"key\": "bleble",\n \"value\": 779119\n },\
+ {\n \"key\": "llylly",\n \"value\": 779119\n },\
+ {\n \"key\": "hiphip",\n \"value\": 778118\n },\
+ {\n \"key\": "omaoma",\n \"value\": 778118\n },\
+ {\n \"key\": "agoago",\n \"value\": 777117\n },\
+ {\n \"key\": "oidoid",\n \"value\": 776116\n },\
+ {\n \"key\": "manman",\n \"value\": 776116\n },\
+ {\n \"key\": "ismism",\n \"value\": 775115\n },\
+ {\n \"key\": "audaud",\n \"value\": 775115\n },\
+ {\n \"key\": "ismism",\n \"value\": 774114\n },\
+ {\n \"key\": "ionion",\n \"value\": 774114\n },\
+ {\n \"key\": "thgthg",\n \"value\": 773113\n },\
+ {\n \"key\": "endend",\n \"value\": 773113\n },\
+ {\n \"key\": "udeude",\n \"value\": 772112\n },\
+ {\n \"key\": "ashash",\n \"value\": 772112\n },\
+ {\n \"key\": "ankank",\n \"value\": 771111\n },\
+ {\n \"key\": "calcal",\n \"value\": 771111\n },\
+ {\n \"key\": "pleple",\n \"value\": 770110\n },\
+ {\n \"key\": "hedhed",\n \"value\": 770110\n },\
+ {\n \"key\": "bleble",\n \"value\": 779019\n },\
+ {\n \"key\": "tictic",\n \"value\": 779019\n },\
+ {\n \"key\": "yteyte",\n \"value\": 778018\n },\
+ {\n \"key\": "oldold",\n \"value\": 778018\n },\
+ {\n \"key\": "steste",\n \"value\": 777017\n },\
+ {\n \"key\": "ishish",\n \"value\": 777017\n },\
+ {\n \"key\": "ineine",\n \"value\": 776016\n },\
+ {\n \"key\": "manman",\n \"value\": 776016\n },\
+ {\n \"key\": "miamia",\n \"value\": 775015\n },\
+ {\n \"key\": "ifeife",\n \"value\": 775015\n },\
+ {\n \"key\": "ssassa",\n \"value\": 774014\n },\
+ {\n \"key\": "apeape",\n \"value\": 774014\n },\
+ {\n \"key\": "essess",\n \"value\": 773013\n },\
+ {\n \"key\": "fowfow",\n \"value\": 773013\n },\
+ {\n \"key\": "siasia",\n \"value\": 773013\n },\
+ {\n \"key\": "bleble",\n \"value\": 772012\n },\
+ {\n \"key\": "eaeeae",\n \"value\": 772012\n },\
+ {\n \"key\": "larlar",\n \"value\": 771011\n },\
+ {\n \"key\": "tedted",\n \"value\": 771011\n },\
+ {\n \"key\": "ralral",\n \"value\": 770010\n },\
+ {\n \"key\": "ousous",\n \"value\": 770010\n },\
+ {\n \"key\": "hpahpa",\n \"value\": 779999\n },\
+ {\n \"key\": "iumium",\n \"value\": 775995\n },\
+ {\n \"key\": "reeree",\n \"value\": 770990\n },\
+ {\n \"key\": "hinhin",\n \"value\": 776896\n },\
+ {\n \"key\": "malmal",\n \"value\": 772892\n },\
+ {\n \"key\": "hathat",\n \"value\": 778798\n },\
+ {\n \"key\": "dondon",\n \"value\": 774794\n },\
+ {\n \"key\": "tictic",\n \"value\": 770790\n },\
+ {\n \"key\": "ataata",\n \"value\": 776696\n },\
+ {\n \"key\": "ilyily",\n \"value\": 771691\n },\
+ {\n \"key\": "assass",\n \"value\": 777597\n },\
+ {\n \"key\": "trytry",\n \"value\": 773593\n },\
+ {\n \"key\": "essess",\n \"value\": 779499\n },\
+ {\n \"key\": "ssesse",\n \"value\": 775495\n },\
+ {\n \"key\": "horhor",\n \"value\": 772492\n },\
+ {\n \"key\": "ionion",\n \"value\": 778398\n },\
+ {\n \"key\": "glygly",\n \"value\": 774394\n },\
+ {\n \"key\": "izeize",\n \"value\": 770390\n },\
+ {\n \"key\": "essess",\n \"value\": 776296\n },\
+ {\n \"key\": "dledle",\n \"value\": 772292\n },\
+ {\n \"key\": "calcal",\n \"value\": 778198\n },\
+ {\n \"key\": "denden",\n \"value\": 775195\n },\
+ {\n \"key\": "ateate",\n \"value\": 771191\n },\
+ {\n \"key\": "ylsyls",\n \"value\": 777097\n },\
+ {\n \"key\": "oidoid",\n \"value\": 774094\n },\
+ {\n \"key\": "llalla",\n \"value\": 770090\n },\
+ {\n \"key\": "inging",\n \"value\": 776986\n },\
+ {\n \"key\": "omeome",\n \"value\": 773983\n },\
+ {\n \"key\": "ttette",\n \"value\": 779889\n },\
+ {\n \"key\": "uliuli",\n \"value\": 776886\n },\
+ {\n \"key\": "istist",\n \"value\": 772882\n },\
+ {\n \"key\": "dlydly",\n \"value\": 778788\n },\
+ {\n \"key\": "riaria",\n \"value\": 775785\n },\
+ {\n \"key\": "ianian",\n \"value\": 771781\n },\
+ {\n \"key\": "deldel",\n \"value\": 778688\n },\
+ {\n \"key\": "eaeeae",\n \"value\": 775685\n },\
+ {\n \"key\": "gungun",\n \"value\": 771681\n },\
+ {\n \"key\": "inging",\n \"value\": 778588\n },\
+ {\n \"key\": "noinoi",\n \"value\": 774584\n },\
+ {\n \"key\": "serser",\n \"value\": 771581\n },\
+ {\n \"key\": "ikeike",\n \"value\": 778488\n },\
+ {\n \"key\": "rkyrky",\n \"value\": 774484\n },\
+ {\n \"key\": "fulful",\n \"value\": 771481\n },\
+ {\n \"key\": "acyacy",\n \"value\": 778388\n },\
+ {\n \"key\": "nedned",\n \"value\": 775385\n },\
+ {\n \"key\": "icaica",\n \"value\": 771381\n },\
+ {\n \"key\": "ousous",\n \"value\": 778288\n },\
+ {\n \"key\": "gyegye",\n \"value\": 775285\n },\
+ {\n \"key\": "iumium",\n \"value\": 772282\n },\
+ {\n \"key\": "ockock",\n \"value\": 779189\n },\
+ {\n \"key\": "ushush",\n \"value\": 775185\n },\
+ {\n \"key\": "noinoi",\n \"value\": 772182\n },\
+ {\n \"key\": "ootoot",\n \"value\": 779089\n },\
+ {\n \"key\": "entent",\n \"value\": 776086\n },\
+ {\n \"key\": "llylly",\n \"value\": 773083\n },\
+ {\n \"key\": "ilyily",\n \"value\": 770080\n },\
+ {\n \"key\": "sdrsdr",\n \"value\": 777977\n },\
+ {\n \"key\": "ionion",\n \"value\": 774974\n },\
+ {\n \"key\": "hlyhly",\n \"value\": 771971\n },\
+ {\n \"key\": "adoado",\n \"value\": 778878\n },\
+ {\n \"key\": "inkink",\n \"value\": 775875\n },\
+ {\n \"key\": "ineine",\n \"value\": 772872\n },\
+ {\n \"key\": "ousous",\n \"value\": 779779\n },\
+ {\n \"key\": "opeope",\n \"value\": 776776\n },\
+ {\n \"key\": "cilcil",\n \"value\": 773773\n },\
+ {\n \"key\": "ncyncy",\n \"value\": 771771\n },\
+ {\n \"key\": "opyopy",\n \"value\": 778678\n },\
+ {\n \"key\": "essess",\n \"value\": 775675\n },\
+ {\n \"key\": "ygoygo",\n \"value\": 772672\n },\
+ {\n \"key\": "ricric",\n \"value\": 779579\n },\
+ {\n \"key\": "inging",\n \"value\": 776576\n },\
+ {\n \"key\": "einein",\n \"value\": 774574\n },\
+ {\n \"key\": "onaona",\n \"value\": 771571\n },\
+ {\n \"key\": "elyely",\n \"value\": 778478\n },\
+ {\n \"key\": "auraur",\n \"value\": 775475\n },\
+ {\n \"key\": "tortor",\n \"value\": 773473\n },\
+ {\n \"key\": "iveive",\n \"value\": 770470\n },\
+ {\n \"key\": "taltal",\n \"value\": 777377\n },\
+ {\n \"key\": "daedae",\n \"value\": 775375\n },\
+ {\n \"key\": "rkarka",\n \"value\": 772372\n },\
+ {\n \"key\": "wayway",\n \"value\": 779279\n },\
+ {\n \"key\": "ousous",\n \"value\": 777277\n },\
+ {\n \"key\": "iveive",\n \"value\": 774274\n },\
+ {\n \"key\": "woewoe",\n \"value\": 772272\n },\
+ {\n \"key\": "rphrph",\n \"value\": 779179\n },\
+ {\n \"key\": "eeteet",\n \"value\": 776176\n },\
+ {\n \"key\": "gnigni",\n \"value\": 774174\n },\
+ {\n \"key\": "inkink",\n \"value\": 771171\n },\
+ {\n \"key\": "terter",\n \"value\": 779079\n },\
+ {\n \"key\": "ronron",\n \"value\": 776076\n },\
+ {\n \"key\": "ageage",\n \"value\": 774074\n },\
+ {\n \"key\": "oeaoea",\n \"value\": 771071\n },\
+ {\n \"key\": "geygey",\n \"value\": 779969\n },\
+ {\n \"key\": "oryory",\n \"value\": 776966\n },\
+ {\n \"key\": "gilgil",\n \"value\": 774964\n },\
+ {\n \"key\": "oraora",\n \"value\": 772962\n },\
+ {\n \"key\": "tsrtsr",\n \"value\": 779869\n },\
+ {\n \"key\": "iteite",\n \"value\": 777867\n },\
+ {\n \"key\": "essess",\n \"value\": 774864\n },\
+ {\n \"key\": "ashash",\n \"value\": 772862\n },\
+ {\n \"key\": "redred",\n \"value\": 770860\n },\
+ {\n \"key\": "dnedne",\n \"value\": 777767\n },\
+ {\n \"key\": "inging",\n \"value\": 775765\n },\
+ {\n \"key\": "eryery",\n \"value\": 773763\n },\
+ {\n \"key\": "istist",\n \"value\": 770760\n },\
+ {\n \"key\": "essess",\n \"value\": 778668\n },\
+ {\n \"key\": "gesges",\n \"value\": 776666\n },\
+ {\n \"key\": "odeode",\n \"value\": 773663\n },\
+ {\n \"key\": "essess",\n \"value\": 771661\n },\
+ {\n \"key\": "detdet",\n \"value\": 779569\n },\
+ {\n \"key\": "uleule",\n \"value\": 777567\n },\
+ {\n \"key\": "ousous",\n \"value\": 774564\n },\
+ {\n \"key\": "hsihsi",\n \"value\": 772562\n },\
+ {\n \"key\": "ishish",\n \"value\": 770560\n },\
+ {\n \"key\": "esoeso",\n \"value\": 778468\n },\
+ {\n \"key\": "eloelo",\n \"value\": 776466\n },\
+ {\n \"key\": "outout",\n \"value\": 774464\n },\
+ {\n \"key\": "ideide",\n \"value\": 771461\n },\
+ {\n \"key\": "eedeed",\n \"value\": 779369\n },\
+ {\n \"key\": "oidoid",\n \"value\": 777367\n },\
+ {\n \"key\": "oaloal",\n \"value\": 775365\n },\
+ {\n \"key\": "namnam",\n \"value\": 773363\n },\
+ {\n \"key\": "inging",\n \"value\": 771361\n },\
+ {\n \"key\": "inging",\n \"value\": 779269\n },\
+ {\n \"key\": "upiupi",\n \"value\": 777267\n },\
+ {\n \"key\": "ankank",\n \"value\": 775265\n },\
+ {\n \"key\": "kedked",\n \"value\": 772262\n },\
+ {\n \"key\": "iseise",\n \"value\": 770260\n },\
+ {\n \"key\": "dradra",\n \"value\": 778168\n },\
+ {\n \"key\": "ityity",\n \"value\": 776166\n },\
+ {\n \"key\": "diadia",\n \"value\": 774164\n },\
+ {\n \"key\": "essess",\n \"value\": 772162\n },\
+ {\n \"key\": "areare",\n \"value\": 770160\n },\
+ {\n \"key\": "ontont",\n \"value\": 778068\n },\
+ {\n \"key\": "werwer",\n \"value\": 776066\n },\
+ {\n \"key\": "ousous",\n \"value\": 774064\n },\
+ {\n \"key\": "manman",\n \"value\": 772062\n },\
+ {\n \"key\": "nutnut",\n \"value\": 771061\n },\
+ {\n \"key\": "oidoid",\n \"value\": 779959\n },\
+ {\n \"key\": "lahlah",\n \"value\": 777957\n },\
+ {\n \"key\": "ricric",\n \"value\": 775955\n },\
+ {\n \"key\": "ueruer",\n \"value\": 773953\n },\
+ {\n \"key\": "naenae",\n \"value\": 771951\n },\
+ {\n \"key\": "iteite",\n \"value\": 779859\n },\
+ {\n \"key\": "bleble",\n \"value\": 777857\n },\
+ {\n \"key\": "terter",\n \"value\": 775855\n },\
+ {\n \"key\": "nicnic",\n \"value\": 773853\n },\
+ {\n \"key\": "aidaid",\n \"value\": 772852\n },\
+ {\n \"key\": "fulful",\n \"value\": 770850\n },\
+ {\n \"key\": "essess",\n \"value\": 778758\n },\
+ {\n \"key\": "iteite",\n \"value\": 776756\n },\
+ {\n \"key\": "glygly",\n \"value\": 774754\n },\
+ {\n \"key\": "iseise",\n \"value\": 772752\n },\
+ {\n \"key\": "ityity",\n \"value\": 771751\n },\
+ {\n \"key\": "essess",\n \"value\": 779659\n },\
+ {\n \"key\": "ealeal",\n \"value\": 777657\n },\
+ {\n \"key\": "aryary",\n \"value\": 775655\n },\
+ {\n \"key\": "ronron",\n \"value\": 774654\n },\
+ {\n \"key\": "etaeta",\n \"value\": 772652\n },\
+ {\n \"key\": "aveave",\n \"value\": 770650\n },\
+ {\n \"key\": "llylly",\n \"value\": 778558\n },\
+ {\n \"key\": "iteite",\n \"value\": 777557\n },\
+ {\n \"key\": "ianian",\n \"value\": 775555\n },\
+ {\n \"key\": "oleole",\n \"value\": 773553\n },\
+ {\n \"key\": "ithith",\n \"value\": 771551\n },\
+ {\n \"key\": "aryary",\n \"value\": 770550\n },\
+ {\n \"key\": "ondond",\n \"value\": 778458\n },\
+ {\n \"key\": "oosoos",\n \"value\": 776456\n },\
+ {\n \"key\": "hlyhly",\n \"value\": 775455\n },\
+ {\n \"key\": "ncence",\n \"value\": 773453\n },\
+ {\n \"key\": "eleele",\n \"value\": 771451\n },\
+ {\n \"key\": "iotiot",\n \"value\": 770450\n },\
+ {\n \"key\": "istist",\n \"value\": 778358\n },\
+ {\n \"key\": "nesnes",\n \"value\": 777357\n },\
+ {\n \"key\": "izeize",\n \"value\": 775355\n },\
+ {\n \"key\": "gusgus",\n \"value\": 773353\n },\
+ {\n \"key\": "laylay",\n \"value\": 772352\n },\
+ {\n \"key\": "eneene",\n \"value\": 770350\n },\
+ {\n \"key\": "eteete",\n \"value\": 779259\n },\
+ {\n \"key\": "tictic",\n \"value\": 777257\n },\
+ {\n \"key\": "fulful",\n \"value\": 775255\n },\
+ {\n \"key\": "toltol",\n \"value\": 774254\n },\
+ {\n \"key\": "tictic",\n \"value\": 772252\n },\
+ {\n \"key\": "iveive",\n \"value\": 771251\n },\
+ {\n \"key\": "manman",\n \"value\": 779159\n },\
+ {\n \"key\": "bleble",\n \"value\": 778158\n },\
+ {\n \"key\": "oidoid",\n \"value\": 776156\n },\
+ {\n \"key\": "salsal",\n \"value\": 775155\n },\
+ {\n \"key\": "kalkal",\n \"value\": 773153\n },\
+ {\n \"key\": "essess",\n \"value\": 771151\n },\
+ {\n \"key\": "omyomy",\n \"value\": 770150\n },\
+ {\n \"key\": "oreore",\n \"value\": 778058\n },\
+ {\n \"key\": "ionion",\n \"value\": 777057\n },\
+ {\n \"key\": "eanean",\n \"value\": 775055\n },\
+ {\n \"key\": "ellell",\n \"value\": 774054\n },\
+ {\n \"key\": "daldal",\n \"value\": 773053\n },\
+ {\n \"key\": "ateate",\n \"value\": 771051\n },\
+ {\n \"key\": "ssesse",\n \"value\": 770050\n },\
+ {\n \"key\": "deidei",\n \"value\": 778948\n },\
+ {\n \"key\": "ousous",\n \"value\": 777947\n },\
+ {\n \"key\": "glygly",\n \"value\": 775945\n },\
+ {\n \"key\": "sitsit",\n \"value\": 774944\n },\
+ {\n \"key\": "sissis",\n \"value\": 772942\n },\
+ {\n \"key\": "larlar",\n \"value\": 771941\n },\
+ {\n \"key\": "salsal",\n \"value\": 770940\n },\
+ {\n \"key\": "herher",\n \"value\": 778848\n },\
+ {\n \"key\": "tictic",\n \"value\": 777847\n },\
+ {\n \"key\": "lamlam",\n \"value\": 775845\n },\
+ {\n \"key\": "ionion",\n \"value\": 774844\n },\
+ {\n \"key\": "lumlum",\n \"value\": 773843\n },\
+ {\n \"key\": "oleole",\n \"value\": 771841\n },\
+ {\n \"key\": "chmchm",\n \"value\": 770840\n },\
+ {\n \"key\": "omeome",\n \"value\": 779749\n },\
+ {\n \"key\": "eaeeae",\n \"value\": 777747\n },\
+ {\n \"key\": "adeade",\n \"value\": 776746\n },\
+ {\n \"key\": "hiohio",\n \"value\": 774744\n },\
+ {\n \"key\": "lumlum",\n \"value\": 773743\n },\
+ {\n \"key\": "hpahpa",\n \"value\": 772742\n },\
+ {\n \"key\": "entent",\n \"value\": 770740\n },\
+ {\n \"key\": "gusgus",\n \"value\": 779649\n },\
+ {\n \"key\": "essess",\n \"value\": 778648\n },\
+ {\n \"key\": "ityity",\n \"value\": 777647\n },\
+ {\n \"key\": "ousous",\n \"value\": 775645\n },\
+ {\n \"key\": "eloelo",\n \"value\": 774644\n },\
+ {\n \"key\": "orkork",\n \"value\": 773643\n },\
+ {\n \"key\": "otaota",\n \"value\": 771641\n },\
+ {\n \"key\": "omyomy",\n \"value\": 770640\n },\
+ {\n \"key\": "lislis",\n \"value\": 779549\n },\
+ {\n \"key\": "teltel",\n \"value\": 777547\n },\
+ {\n \"key\": "ytiyti",\n \"value\": 776546\n },\
+ {\n \"key\": "noinoi",\n \"value\": 775545\n },\
+ {\n \"key\": "micmic",\n \"value\": 774544\n },\
+ {\n \"key\": "rerrer",\n \"value\": 772542\n },\
+ {\n \"key\": "ionion",\n \"value\": 771541\n },\
+ {\n \"key\": "essess",\n \"value\": 770540\n },\
+ {\n \"key\": "larlar",\n \"value\": 779449\n },\
+ {\n \"key\": "ionion",\n \"value\": 778448\n },\
+ {\n \"key\": "nctnct",\n \"value\": 776446\n },\
+ {\n \"key\": "aceace",\n \"value\": 775445\n },\
+ {\n \"key\": "terter",\n \"value\": 774444\n },\
+ {\n \"key\": "taltal",\n \"value\": 773443\n },\
+ {\n \"key\": "hilhil",\n \"value\": 771441\n },\
+ {\n \"key\": "oleole",\n \"value\": 770440\n },\
+ {\n \"key\": "ileile",\n \"value\": 779349\n },\
+ {\n \"key\": "inging",\n \"value\": 778348\n },\
+ {\n \"key\": "omyomy",\n \"value\": 777347\n },\
+ {\n \"key\": "glegle",\n \"value\": 776346\n },\
+ {\n \"key\": "queque",\n \"value\": 774344\n },\
+ {\n \"key\": "nainai",\n \"value\": 773343\n },\
+ {\n \"key\": "buabua",\n \"value\": 772342\n },\
+ {\n \"key\": "bleble",\n \"value\": 771341\n },\
+ {\n \"key\": "aboabo",\n \"value\": 770340\n },\
+ {\n \"key\": "looloo",\n \"value\": 779249\n },\
+ {\n \"key\": "nlynly",\n \"value\": 777247\n },\
+ {\n \"key\": "inging",\n \"value\": 776246\n },\
+ {\n \"key\": "nahnah",\n \"value\": 775245\n },\
+ {\n \"key\": "omaoma",\n \"value\": 774244\n },\
+ {\n \"key\": "redred",\n \"value\": 773243\n },\
+ {\n \"key\": "nalnal",\n \"value\": 772242\n },\
+ {\n \"key\": "useuse",\n \"value\": 771241\n },\
+ {\n \"key\": "allall",\n \"value\": 770240\n },\
+ {\n \"key\": "laclac",\n \"value\": 778148\n },\
+ {\n \"key\": "sumsum",\n \"value\": 777147\n },\
+ {\n \"key\": "rerrer",\n \"value\": 776146\n },\
+ {\n \"key\": "xisxis",\n \"value\": 775145\n },\
+ {\n \"key\": "daedae",\n \"value\": 774144\n },\
+ {\n \"key\": "dledle",\n \"value\": 773143\n },\
+ {\n \"key\": "riaria",\n \"value\": 772142\n },\
+ {\n \"key\": "ityity",\n \"value\": 771141\n },\
+ {\n \"key\": "entent",\n \"value\": 770140\n },\
+ {\n \"key\": "obeobe",\n \"value\": 779049\n },\
+ {\n \"key\": "ierier",\n \"value\": 778048\n },\
+ {\n \"key\": "oreore",\n \"value\": 777047\n },\
+ {\n \"key\": "ateate",\n \"value\": 776046\n },\
+ {\n \"key\": "istist",\n \"value\": 774044\n },\
+ {\n \"key\": "oanoan",\n \"value\": 773043\n },\
+ {\n \"key\": "intint",\n \"value\": 772042\n },\
+ {\n \"key\": "sissis",\n \"value\": 771041\n },\
+ {\n \"key\": "inging",\n \"value\": 770040\n },\
+ {\n \"key\": "ineine",\n \"value\": 779939\n },\
+ {\n \"key\": "eryery",\n \"value\": 778938\n },\
+ {\n \"key\": "okooko",\n \"value\": 777937\n },\
+ {\n \"key\": "ifyify",\n \"value\": 776936\n },\
+ {\n \"key\": "detdet",\n \"value\": 775935\n },\
+ {\n \"key\": "augaug",\n \"value\": 774934\n },\
+ {\n \"key\": "essess",\n \"value\": 773933\n },\
+ {\n \"key\": "ailail",\n \"value\": 772932\n },\
+ {\n \"key\": "oonoon",\n \"value\": 771931\n },\
+ {\n \"key\": "sissis",\n \"value\": 770930\n },\
+ {\n \"key\": "neknek",\n \"value\": 779839\n },\
+ {\n \"key\": "doodoo",\n \"value\": 778838\n },\
+ {\n \"key\": "llylly",\n \"value\": 777837\n },\
+ {\n \"key\": "icsics",\n \"value\": 776836\n },\
+ {\n \"key\": "inging",\n \"value\": 775835\n },\
+ {\n \"key\": "ratrat",\n \"value\": 774834\n },\
+ {\n \"key\": "daldal",\n \"value\": 773833\n },\
+ {\n \"key\": "andand",\n \"value\": 772832\n },\
+ {\n \"key\": "odeode",\n \"value\": 772832\n },\
+ {\n \"key\": "ismism",\n \"value\": 771831\n },\
+ {\n \"key\": "anyany",\n \"value\": 770830\n },\
+ {\n \"key\": "ageage",\n \"value\": 779739\n },\
+ {\n \"key\": "essess",\n \"value\": 778738\n },\
+ {\n \"key\": "bleble",\n \"value\": 777737\n },\
+ {\n \"key\": "angang",\n \"value\": 776736\n },\
+ {\n \"key\": "ionion",\n \"value\": 775735\n },\
+ {\n \"key\": "tedted",\n \"value\": 774734\n },\
+ {\n \"key\": "ifyify",\n \"value\": 773733\n },\
+ {\n \"key\": "istist",\n \"value\": 772732\n },\
+ {\n \"key\": "bleble",\n \"value\": 771731\n },\
+ {\n \"key\": "ionion",\n \"value\": 770730\n },\
+ {\n \"key\": "iveive",\n \"value\": 779639\n },\
+ {\n \"key\": "noinoi",\n \"value\": 779639\n },\
+ {\n \"key\": "raerae",\n \"value\": 778638\n },\
+ {\n \"key\": "gedged",\n \"value\": 777637\n },\
+ {\n \"key\": "nalnal",\n \"value\": 776636\n },\
+ {\n \"key\": "ierier",\n \"value\": 775635\n },\
+ {\n \"key\": "hidhid",\n \"value\": 774634\n },\
+ {\n \"key\": "ionion",\n \"value\": 773633\n },\
+ {\n \"key\": "irtirt",\n \"value\": 772632\n },\
+ {\n \"key\": "glygly",\n \"value\": 771631\n },\
+ {\n \"key\": "citcit",\n \"value\": 771631\n },\
+ {\n \"key\": "ateate",\n \"value\": 770630\n },\
+ {\n \"key\": "ikeike",\n \"value\": 779539\n },\
+ {\n \"key\": "ataata",\n \"value\": 778538\n },\
+ {\n \"key\": "letlet",\n \"value\": 777537\n },\
+ {\n \"key\": "ialial",\n \"value\": 776536\n },\
+ {\n \"key\": "sissis",\n \"value\": 775535\n },\
+ {\n \"key\": "istist",\n \"value\": 774534\n },\
+ {\n \"key\": "anaana",\n \"value\": 774534\n },\
+ {\n \"key\": "oidoid",\n \"value\": 773533\n },\
+ {\n \"key\": "ormorm",\n \"value\": 772532\n },\
+ {\n \"key\": "lexlex",\n \"value\": 771531\n },\
+ {\n \"key\": "llylly",\n \"value\": 770530\n },\
+ {\n \"key\": "ifeife",\n \"value\": 779439\n },\
+ {\n \"key\": "nalnal",\n \"value\": 779439\n },\
+ {\n \"key\": "ionion",\n \"value\": 778438\n },\
+ {\n \"key\": "hichic",\n \"value\": 777437\n },\
+ {\n \"key\": "tootoo",\n \"value\": 776436\n },\
+ {\n \"key\": "oryory",\n \"value\": 775435\n },\
+ {\n \"key\": "llylly",\n \"value\": 774434\n },\
+ {\n \"key\": "naenae",\n \"value\": 774434\n },\
+ {\n \"key\": "izeize",\n \"value\": 773433\n },\
+ {\n \"key\": "werwer",\n \"value\": 772432\n },\
+ {\n \"key\": "oiloil",\n \"value\": 771431\n },\
+ {\n \"key\": "luslus",\n \"value\": 770430\n },\
+ {\n \"key\": "eneene",\n \"value\": 770430\n },\
+ {\n \"key\": "ismism",\n \"value\": 779339\n },\
+ {\n \"key\": "ricric",\n \"value\": 778338\n },\
+ {\n \"key\": "iveive",\n \"value\": 777337\n },\
+ {\n \"key\": "glygly",\n \"value\": 776336\n },\
+ {\n \"key\": "manman",\n \"value\": 776336\n },\
+ {\n \"key\": "rierie",\n \"value\": 775335\n },\
+ {\n \"key\": "llylly",\n \"value\": 774334\n },\
+ {\n \"key\": "ithith",\n \"value\": 773333\n },\
+ {\n \"key\": "laclac",\n \"value\": 773333\n },\
+ {\n \"key\": "ityity",\n \"value\": 772332\n },\
+ {\n \"key\": "rezrez",\n \"value\": 771331\n },\
+ {\n \"key\": "enyeny",\n \"value\": 770330\n },\
+ {\n \"key\": "iedied",\n \"value\": 770330\n },\
+ {\n \"key\": "rgerge",\n \"value\": 779239\n },\
+ {\n \"key\": "wedwed",\n \"value\": 778238\n },\
+ {\n \"key\": "iorior",\n \"value\": 777237\n },\
+ {\n \"key\": "ousous",\n \"value\": 777237\n },\
+ {\n \"key\": "ricric",\n \"value\": 776236\n },\
+ {\n \"key\": "iumium",\n \"value\": 775235\n },\
+ {\n \"key\": "neanea",\n \"value\": 774234\n },\
+ {\n \"key\": "ionion",\n \"value\": 774234\n },\
+ {\n \"key\": "ateate",\n \"value\": 773233\n },\
+ {\n \"key\": "ateate",\n \"value\": 772232\n },\
+ {\n \"key\": "ismism",\n \"value\": 771231\n },\
+ {\n \"key\": "karkar",\n \"value\": 771231\n },\
+ {\n \"key\": "essess",\n \"value\": 770230\n },\
+ {\n \"key\": "oseose",\n \"value\": 779139\n },\
+ {\n \"key\": "siasia",\n \"value\": 778138\n },\
+ {\n \"key\": "aryary",\n \"value\": 778138\n },\
+ {\n \"key\": "iteite",\n \"value\": 777137\n },\
+ {\n \"key\": "bleble",\n \"value\": 776136\n },\
+ {\n \"key\": "tustus",\n \"value\": 776136\n },\
+ {\n \"key\": "iteite",\n \"value\": 775135\n },\
+ {\n \"key\": "ikeike",\n \"value\": 774134\n },\
+ {\n \"key\": "berber",\n \"value\": 773133\n },\
+ {\n \"key\": "ismism",\n \"value\": 773133\n },\
+ {\n \"key\": "rigrig",\n \"value\": 772132\n },\
+ {\n \"key\": "yreyre",\n \"value\": 771131\n },\
+ {\n \"key\": "ismism",\n \"value\": 771131\n },\
+ {\n \"key\": "ismism",\n \"value\": 770130\n },\
+ {\n \"key\": "oodood",\n \"value\": 779039\n },\
+ {\n \"key\": "amaama",\n \"value\": 779039\n },\
+ {\n \"key\": "sissis",\n \"value\": 778038\n },\
+ {\n \"key\": "ftyfty",\n \"value\": 777037\n },\
+ {\n \"key\": "onyony",\n \"value\": 777037\n },\
+ {\n \"key\": "ismism",\n \"value\": 776036\n },\
+ {\n \"key\": "iumium",\n \"value\": 775035\n },\
+ {\n \"key\": "euseus",\n \"value\": 775035\n },\
+ {\n \"key\": "bleble",\n \"value\": 774034\n },\
+ {\n \"key\": "istist",\n \"value\": 773033\n },\
+ {\n \"key\": "bowbow",\n \"value\": 773033\n },\
+ {\n \"key\": "lielie",\n \"value\": 772032\n },\
+ {\n \"key\": "ursurs",\n \"value\": 771031\n },\
+ {\n \"key\": "hsuhsu",\n \"value\": 771031\n },\
+ {\n \"key\": "imiimi",\n \"value\": 770030\n },\
+ {\n \"key\": "dgedge",\n \"value\": 779929\n },\
+ {\n \"key\": "laglag",\n \"value\": 779929\n },\
+ {\n \"key\": "ionion",\n \"value\": 778928\n },\
+ {\n \"key\": "fulful",\n \"value\": 777927\n },\
+ {\n \"key\": "uedued",\n \"value\": 777927\n },\
+ {\n \"key\": "angang",\n \"value\": 776926\n },\
+ {\n \"key\": "ertert",\n \"value\": 775925\n },\
+ {\n \"key\": "bleble",\n \"value\": 775925\n },\
+ {\n \"key\": "tibtib",\n \"value\": 774924\n },\
+ {\n \"key\": "iteite",\n \"value\": 773923\n },\
+ {\n \"key\": "inging",\n \"value\": 773923\n },\
+ {\n \"key\": "ionion",\n \"value\": 772922\n },\
+ {\n \"key\": "ngsngs",\n \"value\": 772922\n },\
+ {\n \"key\": "ralral",\n \"value\": 771921\n },\
+ {\n \"key\": "dlydly",\n \"value\": 770920\n },\
+ {\n \"key\": "nerner",\n \"value\": 770920\n },\
+ {\n \"key\": "iveive",\n \"value\": 779829\n },\
+ {\n \"key\": "istist",\n \"value\": 778828\n },\
+ {\n \"key\": "piapia",\n \"value\": 778828\n },\
+ {\n \"key\": "ncyncy",\n \"value\": 777827\n },\
+ {\n \"key\": "geegee",\n \"value\": 777827\n },\
+ {\n \"key\": "tictic",\n \"value\": 776826\n },\
+ {\n \"key\": "bitbit",\n \"value\": 775825\n },\
+ {\n \"key\": "larlar",\n \"value\": 775825\n },\
+ {\n \"key\": "tedted",\n \"value\": 774824\n },\
+ {\n \"key\": "ineine",\n \"value\": 774824\n },\
+ {\n \"key\": "ateate",\n \"value\": 773823\n },\
+ {\n \"key\": "essess",\n \"value\": 772822\n },\
+ {\n \"key\": "rdsrds",\n \"value\": 772822\n },\
+ {\n \"key\": "laplap",\n \"value\": 771821\n },\
+ {\n \"key\": "essess",\n \"value\": 771821\n },\
+ {\n \"key\": "siasia",\n \"value\": 770820\n },\
+ {\n \"key\": "ousous",\n \"value\": 779729\n },\
+ {\n \"key\": "inging",\n \"value\": 779729\n },\
+ {\n \"key\": "pirpir",\n \"value\": 778728\n },\
+ {\n \"key\": "dlydly",\n \"value\": 778728\n },\
+ {\n \"key\": "liclic",\n \"value\": 777727\n },\
+ {\n \"key\": "cuscus",\n \"value\": 777727\n },\
+ {\n \"key\": "essess",\n \"value\": 776726\n },\
+ {\n \"key\": "glygly",\n \"value\": 775725\n },\
+ {\n \"key\": "ainain",\n \"value\": 775725\n },\
+ {\n \"key\": "etyety",\n \"value\": 774724\n },\
+ {\n \"key\": "yllyll",\n \"value\": 774724\n },\
+ {\n \"key\": "nusnus",\n \"value\": 773723\n },\
+ {\n \"key\": "iidiid",\n \"value\": 773723\n },\
+ {\n \"key\": "yonyon",\n \"value\": 772722\n },\
+ {\n \"key\": "miamia",\n \"value\": 771721\n },\
+ {\n \"key\": "domdom",\n \"value\": 771721\n },\
+ {\n \"key\": "ineine",\n \"value\": 770720\n },\
+ {\n \"key\": "ayoayo",\n \"value\": 770720\n },\
+ {\n \"key\": "essess",\n \"value\": 779629\n },\
+ {\n \"key\": "ionion",\n \"value\": 779629\n },\
+ {\n \"key\": "aftaft",\n \"value\": 778628\n },\
+ {\n \"key\": "tchtch",\n \"value\": 778628\n },\
+ {\n \"key\": "rowrow",\n \"value\": 777627\n },\
+ {\n \"key\": "euseus",\n \"value\": 776626\n },\
+ {\n \"key\": "bleble",\n \"value\": 776626\n },\
+ {\n \"key\": "manman",\n \"value\": 775625\n },\
+ {\n \"key\": "ianian",\n \"value\": 775625\n },\
+ {\n \"key\": "tlytly",\n \"value\": 774624\n },\
+ {\n \"key\": "opeope",\n \"value\": 774624\n },\
+ {\n \"key\": "parpar",\n \"value\": 773623\n },\
+ {\n \"key\": "rumrum",\n \"value\": 773623\n },\
+ {\n \"key\": "essess",\n \"value\": 772622\n },\
+ {\n \"key\": "hinhin",\n \"value\": 772622\n },\
+ {\n \"key\": "istist",\n \"value\": 771621\n },\
+ {\n \"key\": "denden",\n \"value\": 771621\n },\
+ {\n \"key\": "ualual",\n \"value\": 770620\n },\
+ {\n \"key\": "tiatia",\n \"value\": 779529\n },\
+ {\n \"key\": "sissis",\n \"value\": 779529\n },\
+ {\n \"key\": "slysly",\n \"value\": 778528\n },\
+ {\n \"key\": "ameame",\n \"value\": 778528\n },\
+ {\n \"key\": "ismism",\n \"value\": 777527\n },\
+ {\n \"key\": "ialial",\n \"value\": 777527\n },\
+ {\n \"key\": "nerner",\n \"value\": 776526\n },\
+ {\n \"key\": "ifyify",\n \"value\": 776526\n },\
+ {\n \"key\": "ismism",\n \"value\": 775525\n },\
+ {\n \"key\": "legleg",\n \"value\": 775525\n },\
+ {\n \"key\": "calcal",\n \"value\": 774524\n },\
+ {\n \"key\": "oadoad",\n \"value\": 774524\n },\
+ {\n \"key\": "iveive",\n \"value\": 773523\n },\
+ {\n \"key\": "micmic",\n \"value\": 773523\n },\
+ {\n \"key\": "chychy",\n \"value\": 772522\n },\
+ {\n \"key\": "daldal",\n \"value\": 772522\n },\
+ {\n \"key\": "ityity",\n \"value\": 771521\n },\
+ {\n \"key\": "iadiad",\n \"value\": 771521\n },\
+ {\n \"key\": "liclic",\n \"value\": 770520\n },\
+ {\n \"key\": "ionion",\n \"value\": 770520\n },\
+ {\n \"key\": "micmic",\n \"value\": 779429\n },\
+ {\n \"key\": "sissis",\n \"value\": 779429\n },\
+ {\n \"key\": "rserse",\n \"value\": 778428\n },\
+ {\n \"key\": "iteite",\n \"value\": 778428\n },\
+ {\n \"key\": "izeize",\n \"value\": 777427\n },\
+ {\n \"key\": "iumium",\n \"value\": 777427\n },\
+ {\n \"key\": "panpan",\n \"value\": 776426\n },\
+ {\n \"key\": "glygly",\n \"value\": 776426\n },\
+ {\n \"key\": "etaeta",\n \"value\": 775425\n },\
+ {\n \"key\": "ssesse",\n \"value\": 775425\n },\
+ {\n \"key\": "narnar",\n \"value\": 775425\n },\
+ {\n \"key\": "setset",\n \"value\": 774424\n },\
+ {\n \"key\": "tedted",\n \"value\": 774424\n },\
+ {\n \"key\": "oidoid",\n \"value\": 773423\n },\
+ {\n \"key\": "ineine",\n \"value\": 773423\n },\
+ {\n \"key\": "nedned",\n \"value\": 772422\n },\
+ {\n \"key\": "eadead",\n \"value\": 772422\n },\
+ {\n \"key\": "ousous",\n \"value\": 771421\n },\
+ {\n \"key\": "slysly",\n \"value\": 771421\n },\
+ {\n \"key\": "enieni",\n \"value\": 770420\n },\
+ {\n \"key\": "essess",\n \"value\": 770420\n },\
+ {\n \"key\": "terter",\n \"value\": 779329\n },\
+ {\n \"key\": "ntynty",\n \"value\": 779329\n },\
+ {\n \"key\": "sinsin",\n \"value\": 778328\n },\
+ {\n \"key\": "ismism",\n \"value\": 778328\n },\
+ {\n \"key\": "ousous",\n \"value\": 778328\n },\
+ {\n \"key\": "aryary",\n \"value\": 777327\n },\
+ {\n \"key\": "numnum",\n \"value\": 777327\n },\
+ {\n \"key\": "tlytly",\n \"value\": 776326\n },\
+ {\n \"key\": "calcal",\n \"value\": 776326\n },\
+ {\n \"key\": "slysly",\n \"value\": 775325\n },\
+ {\n \"key\": "trytry",\n \"value\": 775325\n },\
+ {\n \"key\": "ailail",\n \"value\": 774324\n },\
+ {\n \"key\": "nicnic",\n \"value\": 774324\n },\
+ {\n \"key\": "ionion",\n \"value\": 773323\n },\
+ {\n \"key\": "serser",\n \"value\": 773323\n },\
+ {\n \"key\": "essess",\n \"value\": 773323\n },\
+ {\n \"key\": "tistis",\n \"value\": 772322\n },\
+ {\n \"key\": "otlotl",\n \"value\": 772322\n },\
+ {\n \"key\": "ousous",\n \"value\": 771321\n },\
+ {\n \"key\": "dehdeh",\n \"value\": 771321\n },\
+ {\n \"key\": "essess",\n \"value\": 770320\n },\
+ {\n \"key\": "llylly",\n \"value\": 770320\n },\
+ {\n \"key\": "evievi",\n \"value\": 770320\n },\
+ {\n \"key\": "iteite",\n \"value\": 779229\n },\
+ {\n \"key\": "rnerne",\n \"value\": 779229\n },\
+ {\n \"key\": "oleole",\n \"value\": 778228\n },\
+ {\n \"key\": "oryory",\n \"value\": 778228\n },\
+ {\n \"key\": "ionion",\n \"value\": 777227\n },\
+ {\n \"key\": "eteete",\n \"value\": 777227\n },\
+ {\n \"key\": "ismism",\n \"value\": 777227\n },\
+ {\n \"key\": "oidoid",\n \"value\": 776226\n },\
+ {\n \"key\": "ismism",\n \"value\": 776226\n },\
+ {\n \"key\": "ahtaht",\n \"value\": 775225\n },\
+ {\n \"key\": "ousous",\n \"value\": 775225\n },\
+ {\n \"key\": "daedae",\n \"value\": 774224\n },\
+ {\n \"key\": "nrenre",\n \"value\": 774224\n },\
+ {\n \"key\": "daldal",\n \"value\": 774224\n },\
+ {\n \"key\": "ngsngs",\n \"value\": 773223\n },\
+ {\n \"key\": "zinzin",\n \"value\": 773223\n },\
+ {\n \"key\": "tistis",\n \"value\": 772222\n },\
+ {\n \"key\": "ikeike",\n \"value\": 772222\n },\
+ {\n \"key\": "ithith",\n \"value\": 772222\n },\
+ {\n \"key\": "fulful",\n \"value\": 771221\n },\
+ {\n \"key\": "evievi",\n \"value\": 771221\n },\
+ {\n \"key\": "earear",\n \"value\": 770220\n },\
+ {\n \"key\": "aftaft",\n \"value\": 770220\n },\
+ {\n \"key\": "eereer",\n \"value\": 770220\n },\
+ {\n \"key\": "ousous",\n \"value\": 779129\n },\
+ {\n \"key\": "aphaph",\n \"value\": 779129\n },\
+ {\n \"key\": "iteite",\n \"value\": 778128\n },\
+ {\n \"key\": "gerger",\n \"value\": 778128\n },\
+ {\n \"key\": "llylly",\n \"value\": 778128\n },\
+ {\n \"key\": "oodood",\n \"value\": 777127\n },\
+ {\n \"key\": "araara",\n \"value\": 777127\n },\
+ {\n \"key\": "suosuo",\n \"value\": 776126\n },\
+ {\n \"key\": "ionion",\n \"value\": 776126\n },\
+ {\n \"key\": "ishish",\n \"value\": 776126\n },\
+ {\n \"key\": "ynyyny",\n \"value\": 775125\n },\
+ {\n \"key\": "akeake",\n \"value\": 775125\n },\
+ {\n \"key\": "rawraw",\n \"value\": 774124\n },\
+ {\n \"key\": "fidfid",\n \"value\": 774124\n },\
+ {\n \"key\": "slysly",\n \"value\": 774124\n },\
+ {\n \"key\": "ngyngy",\n \"value\": 773123\n },\
+ {\n \"key\": "iteite",\n \"value\": 773123\n },\
+ {\n \"key\": "hichic",\n \"value\": 772122\n },\
+ {\n \"key\": "warwar",\n \"value\": 772122\n },\
+ {\n \"key\": "eziezi",\n \"value\": 772122\n },\
+ {\n \"key\": "sissis",\n \"value\": 771121\n },\
+ {\n \"key\": "aryary",\n \"value\": 771121\n },\
+ {\n \"key\": "trytry",\n \"value\": 771121\n },\
+ {\n \"key\": "eltelt",\n \"value\": 770120\n },\
+ {\n \"key\": "yteyte",\n \"value\": 770120\n },\
+ {\n \"key\": "tictic",\n \"value\": 779029\n },\
+ {\n \"key\": "testes",\n \"value\": 779029\n },\
+ {\n \"key\": "terter",\n \"value\": 779029\n },\
+ {\n \"key\": "antant",\n \"value\": 778028\n },\
+ {\n \"key\": "bleble",\n \"value\": 778028\n },\
+ {\n \"key\": "ikeike",\n \"value\": 778028\n },\
+ {\n \"key\": "ionion",\n \"value\": 777027\n },\
+ {\n \"key\": "ycnycn",\n \"value\": 777027\n },\
+ {\n \"key\": "ermerm",\n \"value\": 776026\n },\
+ {\n \"key\": "istist",\n \"value\": 776026\n },\
+ {\n \"key\": "rryrry",\n \"value\": 776026\n },\
+ {\n \"key\": "nicnic",\n \"value\": 775025\n },\
+ {\n \"key\": "dibdib",\n \"value\": 775025\n },\
+ {\n \"key\": "yroyro",\n \"value\": 775025\n },\
+ {\n \"key\": "kerker",\n \"value\": 774024\n },\
+ {\n \"key\": "zenzen",\n \"value\": 774024\n },\
+ {\n \"key\": "llylly",\n \"value\": 774024\n },\
+ {\n \"key\": "essess",\n \"value\": 773023\n },\
+ {\n \"key\": "iteite",\n \"value\": 773023\n },\
+ {\n \"key\": "eraera",\n \"value\": 773023\n },\
+ {\n \"key\": "oneone",\n \"value\": 772022\n },\
+ {\n \"key\": "saesae",\n \"value\": 772022\n },\
+ {\n \"key\": "tortor",\n \"value\": 771021\n },\
+ {\n \"key\": "testes",\n \"value\": 771021\n },\
+ {\n \"key\": "istist",\n \"value\": 771021\n },\
+ {\n \"key\": "tictic",\n \"value\": 770020\n },\
+ {\n \"key\": "liclic",\n \"value\": 770020\n },\
+ {\n \"key\": "trytry",\n \"value\": 770020\n },\
+ {\n \"key\": "ionion",\n \"value\": 779919\n },\
+ {\n \"key\": "aosaos",\n \"value\": 779919\n },\
+ {\n \"key\": "areare",\n \"value\": 779919\n },\
+ {\n \"key\": "ycayca",\n \"value\": 778918\n },\
+ {\n \"key\": "dahdah",\n \"value\": 778918\n },\
+ {\n \"key\": "eanean",\n \"value\": 778918\n },\
+ {\n \"key\": "uleule",\n \"value\": 777917\n },\
+ {\n \"key\": "ifyify",\n \"value\": 777917\n },\
+ {\n \"key\": "ialial",\n \"value\": 777917\n },\
+ {\n \"key\": "ionion",\n \"value\": 776916\n },\
+ {\n \"key\": "ronron",\n \"value\": 776916\n },\
+ {\n \"key\": "ormorm",\n \"value\": 776916\n },\
+ {\n \"key\": "lonlon",\n \"value\": 775915\n },\
+ {\n \"key\": "nalnal",\n \"value\": 775915\n },\
+ {\n \"key\": "doldol",\n \"value\": 775915\n },\
+ {\n \"key\": "arkark",\n \"value\": 774914\n },\
+ {\n \"key\": "nirnir",\n \"value\": 774914\n },\
+ {\n \"key\": "tumtum",\n \"value\": 774914\n },\
+ {\n \"key\": "ineine",\n \"value\": 773913\n },\
+ {\n \"key\": "loyloy",\n \"value\": 773913\n },\
+ {\n \"key\": "tnetne",\n \"value\": 773913\n },\
+ {\n \"key\": "rborbo",\n \"value\": 772912\n },\
+ {\n \"key\": "ismism",\n \"value\": 772912\n },\
+ {\n \"key\": "ineine",\n \"value\": 772912\n },\
+ {\n \"key\": "llylly",\n \"value\": 771911\n },\
+ {\n \"key\": "tidtid",\n \"value\": 771911\n },\
+ {\n \"key\": "inging",\n \"value\": 771911\n },\
+ {\n \"key\": "gnigni",\n \"value\": 770910\n },\
+ {\n \"key\": "naenae",\n \"value\": 770910\n },\
+ {\n \"key\": "ncence",\n \"value\": 770910\n },\
+ {\n \"key\": "ikeike",\n \"value\": 779819\n },\
+ {\n \"key\": "pedped",\n \"value\": 779819\n },\
+ {\n \"key\": "napnap",\n \"value\": 779819\n },\
+ {\n \"key\": "renren",\n \"value\": 778818\n },\
+ {\n \"key\": "dedded",\n \"value\": 778818\n },\
+ {\n \"key\": "redred",\n \"value\": 778818\n },\
+ {\n \"key\": "yltylt",\n \"value\": 777817\n },\
+ {\n \"key\": "ylgylg",\n \"value\": 777817\n },\
+ {\n \"key\": "oseose",\n \"value\": 777817\n },\
+ {\n \"key\": "ytiyti",\n \"value\": 777817\n },\
+ {\n \"key\": "etaeta",\n \"value\": 776816\n },\
+ {\n \"key\": "oluolu",\n \"value\": 776816\n },\
+ {\n \"key\": "ncence",\n \"value\": 776816\n },\
+ {\n \"key\": "riaria",\n \"value\": 775815\n },\
+ {\n \"key\": "uloulo",\n \"value\": 775815\n },\
+ {\n \"key\": "ionion",\n \"value\": 775815\n },\
+ {\n \"key\": "llylly",\n \"value\": 774814\n },\
+ {\n \"key\": "ninnin",\n \"value\": 774814\n },\
+ {\n \"key\": "ughugh",\n \"value\": 774814\n },\
+ {\n \"key\": "iveive",\n \"value\": 773813\n },\
+ {\n \"key\": "daedae",\n \"value\": 773813\n },\
+ {\n \"key\": "bleble",\n \"value\": 773813\n },\
+ {\n \"key\": "entent",\n \"value\": 773813\n },\
+ {\n \"key\": "budbud",\n \"value\": 772812\n },\
+ {\n \"key\": "ledled",\n \"value\": 772812\n },\
+ {\n \"key\": "rowrow",\n \"value\": 772812\n },\
+ {\n \"key\": "oofoof",\n \"value\": 771811\n },\
+ {\n \"key\": "eiteit",\n \"value\": 771811\n },\
+ {\n \"key\": "hedhed",\n \"value\": 771811\n },\
+ {\n \"key\": "eadead",\n \"value\": 770810\n },\
+ {\n \"key\": "ghtght",\n \"value\": 770810\n },\
+ {\n \"key\": "ncence",\n \"value\": 770810\n },\
+ {\n \"key\": "bleble",\n \"value\": 770810\n },\
+ {\n \"key\": "ralral",\n \"value\": 779719\n },\
+ {\n \"key\": "entent",\n \"value\": 779719\n },\
+ {\n \"key\": "ionion",\n \"value\": 779719\n },\
+ {\n \"key\": "hlyhly",\n \"value\": 778718\n },\
+ {\n \"key\": "dledle",\n \"value\": 778718\n },\
+ {\n \"key\": "oidoid",\n \"value\": 778718\n },\
+ {\n \"key\": "ousous",\n \"value\": 778718\n },\
+ {\n \"key\": "ineine",\n \"value\": 777717\n },\
+ {\n \"key\": "ianian",\n \"value\": 777717\n },\
+ {\n \"key\": "gicgic",\n \"value\": 777717\n },\
+ {\n \"key\": "mbombo",\n \"value\": 776716\n },\
+ {\n \"key\": "tictic",\n \"value\": 776716\n },\
+ {\n \"key\": "antant",\n \"value\": 776716\n },\
+ {\n \"key\": "nwonwo",\n \"value\": 775715\n },\
+ {\n \"key\": "ionion",\n \"value\": 775715\n },\
+ {\n \"key\": "inging",\n \"value\": 775715\n },\
+ {\n \"key\": "arkark",\n \"value\": 775715\n },\
+ {\n \"key\": "nicnic",\n \"value\": 774714\n },\
+ {\n \"key\": "ityity",\n \"value\": 774714\n },\
+ {\n \"key\": "iveive",\n \"value\": 774714\n },\
+ {\n \"key\": "testes",\n \"value\": 774714\n },\
+ {\n \"key\": "llylly",\n \"value\": 773713\n },\
+ {\n \"key\": "sissis",\n \"value\": 773713\n },\
+ {\n \"key\": "ateate",\n \"value\": 773713\n },\
+ {\n \"key\": "ledled",\n \"value\": 772712\n },\
+ {\n \"key\": "niuniu",\n \"value\": 772712\n },\
+ {\n \"key\": "linlin",\n \"value\": 772712\n },\
+ {\n \"key\": "omyomy",\n \"value\": 772712\n },\
+ {\n \"key\": "nannan",\n \"value\": 771711\n },\
+ {\n \"key\": "abeabe",\n \"value\": 771711\n },\
+ {\n \"key\": "ssesse",\n \"value\": 771711\n },\
+ {\n \"key\": "hlyhly",\n \"value\": 770710\n },\
+ {\n \"key\": "llalla",\n \"value\": 770710\n },\
+ {\n \"key\": "kinkin",\n \"value\": 770710\n },\
+ {\n \"key\": "essess",\n \"value\": 770710\n },\
+ {\n \"key\": "essess",\n \"value\": 779619\n },\
+ {\n \"key\": "itoito",\n \"value\": 779619\n },\
+ {\n \"key\": "entent",\n \"value\": 779619\n },\
+ {\n \"key\": "oidoid",\n \"value\": 779619\n },\
+ {\n \"key\": "gerger",\n \"value\": 778618\n },\
+ {\n \"key\": "moomoo",\n \"value\": 778618\n },\
+ {\n \"key\": "ogyogy",\n \"value\": 778618\n },\
+ {\n \"key\": "iseise",\n \"value\": 778618\n },\
+ {\n \"key\": "ichich",\n \"value\": 777617\n },\
+ {\n \"key\": "nedned",\n \"value\": 777617\n },\
+ {\n \"key\": "bleble",\n \"value\": 777617\n },\
+ {\n \"key\": "tictic",\n \"value\": 777617\n },\
+ {\n \"key\": "izeize",\n \"value\": 776616\n },\
+ {\n \"key\": "oxyoxy",\n \"value\": 776616\n },\
+ {\n \"key\": "daldal",\n \"value\": 776616\n },\
+ {\n \"key\": "carcar",\n \"value\": 775615\n },\
+ {\n \"key\": "entent",\n \"value\": 775615\n },\
+ {\n \"key\": "lezlez",\n \"value\": 775615\n },\
+ {\n \"key\": "ikeike",\n \"value\": 775615\n },\
+ {\n \"key\": "noinoi",\n \"value\": 774614\n },\
+ {\n \"key\": "oftoft",\n \"value\": 774614\n },\
+ {\n \"key\": "larlar",\n \"value\": 774614\n },\
+ {\n \"key\": "aicaic",\n \"value\": 774614\n },\
+ {\n \"key\": "nzonzo",\n \"value\": 773613\n },\
+ {\n \"key\": "ianian",\n \"value\": 773613\n },\
+ {\n \"key\": "hlyhly",\n \"value\": 773613\n },\
+ {\n \"key\": "manman",\n \"value\": 773613\n },\
+ {\n \"key\": "iteite",\n \"value\": 772612\n },\
+ {\n \"key\": "eryery",\n \"value\": 772612\n },\
+ {\n \"key\": "ttotto",\n \"value\": 772612\n },\
+ {\n \"key\": "nylnyl",\n \"value\": 772612\n },\
+ {\n \"key\": "ariari",\n \"value\": 771611\n },\
+ {\n \"key\": "ssesse",\n \"value\": 771611\n },\
+ {\n \"key\": "warwar",\n \"value\": 771611\n },\
+ {\n \"key\": "ousous",\n \"value\": 771611\n },\
+ {\n \"key\": "oreore",\n \"value\": 770610\n },\
+ {\n \"key\": "ionion",\n \"value\": 770610\n },\
+ {\n \"key\": "nornor",\n \"value\": 770610\n },\
+ {\n \"key\": "niania",\n \"value\": 770610\n },\
+ {\n \"key\": "niania",\n \"value\": 779519\n },\
+ {\n \"key\": "boxbox",\n \"value\": 779519\n },\
+ {\n \"key\": "aabaab",\n \"value\": 779519\n },\
+ {\n \"key\": "miamia",\n \"value\": 779519\n },\
+ {\n \"key\": "untunt",\n \"value\": 778518\n },\
+ {\n \"key\": "ogyogy",\n \"value\": 778518\n },\
+ {\n \"key\": "ousous",\n \"value\": 778518\n },\
+ {\n \"key\": "ialial",\n \"value\": 778518\n },\
+ {\n \"key\": "lialia",\n \"value\": 777517\n },\
+ {\n \"key\": "etyety",\n \"value\": 777517\n },\
+ {\n \"key\": "ionion",\n \"value\": 777517\n },\
+ {\n \"key\": "ionion",\n \"value\": 777517\n },\
+ {\n \"key\": "eateat",\n \"value\": 777517\n },\
+ {\n \"key\": "bitbit",\n \"value\": 776516\n },\
+ {\n \"key\": "ishish",\n \"value\": 776516\n },\
+ {\n \"key\": "calcal",\n \"value\": 776516\n },\
+ {\n \"key\": "ikeike",\n \"value\": 776516\n },\
+ {\n \"key\": "cincin",\n \"value\": 775515\n },\
+ {\n \"key\": "niknik",\n \"value\": 775515\n },\
+ {\n \"key\": "oneone",\n \"value\": 775515\n },\
+ {\n \"key\": "roiroi",\n \"value\": 775515\n },\
+ {\n \"key\": "ricric",\n \"value\": 774514\n },\
+ {\n \"key\": "ideide",\n \"value\": 774514\n },\
+ {\n \"key\": "nrynry",\n \"value\": 774514\n },\
+ {\n \"key\": "roiroi",\n \"value\": 775515\n },\
+ {\n \"key\": "ricric",\n \"value\": 774514\n },\
+ {\n \"key\": "ideide",\n \"value\": 774514\n },\
+ {\n \"key\": "nrynry",\n \"value\": 774514\n },\
+ {\n \"key\": "lialia",\n \"value\": 777517\n },\
+ {\n \"key\": "etyety",\n \"value\": 777517\n },\
+ {\n \"key\": "ionion",\n \"value\": 777517\n },\
+ {\n \"key\": "ionion",\n \"value\": 777517\n },\
+ {\n \"key\": "eateat",\n \"value\": 777517\n },\
+ {\n \"key\": "bitbit",\n \"value\": 776516\n },\
+ {\n \"key\": "ishish",\n \"value\": 776516\n },\
+ {\n \"key\": "calcal",\n \"value\": 776516\n },\
+ {\n \"key\": "ikeike",\n \"value\": 776516\n },\
+ {\n \"key\": "cincin",\n \"value\": 775515\n },\
+ {\n \"key\": "niknik",\n \"value\": 775515\n },\
+ {\n \"key\": "oneone",\n \"value\": 775515\n },\
+ {\n \"key\": "roiroi",\n \"value\": 775515\n },\
+ {\n \"key\": "ricric",\n \"value\": 774514\n },\
+ {\n \"key\": "ideide",\n \"value\": 774514\n },\
+ {\n \"key\": "nrynry",\n \"value\": 774514\n },\
+ {\n \"key\": "roiroi",\n \"value\": 775515\n },\
+ {\n \"key\": "ricric",\n \"value\": 774514\n },\
+ {\n \"key\": "ideide",\n \"value\": 774514\n },\
+ {\n \"key\": "nrynry",\n \"value\": 774514\n },\
+ {\n \"key\": "ralral",\n \"value\": 779049\n }]';
+
+kvJSON.frob();
diff --git a/deps/v8/test/mjsunit/harmony/array-concat.js b/deps/v8/test/mjsunit/harmony/array-concat.js
index c1ff92c8c3..71b6790bc7 100644
--- a/deps/v8/test/mjsunit/harmony/array-concat.js
+++ b/deps/v8/test/mjsunit/harmony/array-concat.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-arrays --harmony-classes
+// Flags: --harmony-concat-spreadable
(function testArrayConcatArity() {
"use strict";
@@ -194,6 +194,15 @@ assertThrows(function() {
(function testConcatArraySubclass() {
"use strict";
+ // If @@isConcatSpreadable is not used, the value of IsArray(O)
+ // is used to determine the spreadable property.
+ class A extends Array {}
+ var obj = [].concat(new A(1, 2, 3), new A(4, 5, 6), new A(7, 8, 9));
+ assertEquals(9, obj.length);
+ for (var i = 0; i < obj.length; ++i) {
+ assertEquals(i + 1, obj[i]);
+ }
+
// TODO(caitp): when concat is called on instances of classes which extend
// Array, they should:
//
@@ -203,6 +212,19 @@ assertThrows(function() {
})();
+(function testConcatArraySubclassOptOut() {
+ "use strict";
+ class A extends Array {
+ get [Symbol.isConcatSpreadable]() { return false; }
+ }
+ var obj = [].concat(new A(1, 2, 3), new A(4, 5, 6), new A(7, 8, 9));
+ assertEquals(3, obj.length);
+ assertEquals(3, obj[0].length);
+ assertEquals(3, obj[1].length);
+ assertEquals(3, obj[2].length);
+})();
+
+
(function testConcatNonArray() {
"use strict";
class NonArray {
diff --git a/deps/v8/test/mjsunit/harmony/array-find.js b/deps/v8/test/mjsunit/harmony/array-find.js
index eb32082277..44fc78292a 100644
--- a/deps/v8/test/mjsunit/harmony/array-find.js
+++ b/deps/v8/test/mjsunit/harmony/array-find.js
@@ -201,7 +201,7 @@ assertEquals(22, a.find(function(val) { return 22 === val; }), undefined);
//
-// Test predicate is only called for existing elements
+// Test predicate is called for holes
//
(function() {
var a = new Array(30);
@@ -211,7 +211,27 @@ assertEquals(22, a.find(function(val) { return 22 === val; }), undefined);
var count = 0;
a.find(function() { count++; return false; });
- assertEquals(3, count);
+ assertEquals(30, count);
+})();
+
+
+(function() {
+ var a = [0, 1, , 3];
+ var count = 0;
+ var found = a.find(function(val) { return val === undefined; });
+ assertEquals(undefined, found);
+})();
+
+
+(function() {
+ var a = [0, 1, , 3];
+ a.__proto__ = {
+ __proto__: Array.prototype,
+ 2: 42,
+ };
+ var count = 0;
+ var found = a.find(function(val) { return val === 42; });
+ assertEquals(42, found);
})();
diff --git a/deps/v8/test/mjsunit/harmony/array-findindex.js b/deps/v8/test/mjsunit/harmony/array-findindex.js
index a5df05a05c..7068a9cb40 100644
--- a/deps/v8/test/mjsunit/harmony/array-findindex.js
+++ b/deps/v8/test/mjsunit/harmony/array-findindex.js
@@ -201,7 +201,7 @@ assertEquals(3, a.findIndex(function(val) { return 24 === val; }));
//
-// Test predicate is only called for existing elements
+// Test predicate is called for holes
//
(function() {
var a = new Array(30);
@@ -211,7 +211,27 @@ assertEquals(3, a.findIndex(function(val) { return 24 === val; }));
var count = 0;
a.findIndex(function() { count++; return false; });
- assertEquals(3, count);
+ assertEquals(30, count);
+})();
+
+
+(function() {
+ var a = [0, 1, , 3];
+ var count = 0;
+ var index = a.findIndex(function(val) { return val === undefined; });
+ assertEquals(2, index);
+})();
+
+
+(function() {
+ var a = [0, 1, , 3];
+ a.__proto__ = {
+ __proto__: Array.prototype,
+ 2: 42,
+ };
+ var count = 0;
+ var index = a.findIndex(function(val) { return val === 42; });
+ assertEquals(2, index);
})();
diff --git a/deps/v8/test/mjsunit/harmony/array-from.js b/deps/v8/test/mjsunit/harmony/array-from.js
index c294786c46..2b7f2902f8 100644
--- a/deps/v8/test/mjsunit/harmony/array-from.js
+++ b/deps/v8/test/mjsunit/harmony/array-from.js
@@ -148,4 +148,32 @@ testArrayFrom(Math.cos, Array);
testArrayFrom(Math.cos.bind(Math), Array);
testArrayFrom(boundFn, boundFn);
+// Assert that [[DefineOwnProperty]] is used in ArrayFrom, meaning a
+// setter isn't called, and a failed [[DefineOwnProperty]] will throw.
+var setterCalled = 0;
+function exotic() {
+ Object.defineProperty(this, '0', {
+ get: function() { return 2; },
+ set: function() { setterCalled++; }
+ });
+}
+// Non-configurable properties can't be overwritten with DefineOwnProperty
+assertThrows(function () { Array.from.call(exotic, [1]); }, TypeError);
+// The setter wasn't called
+assertEquals(0, setterCalled);
+
+// Check that array properties defined are writable, enumerable, configurable
+function ordinary() { }
+var x = Array.from.call(ordinary, [2]);
+var xlength = Object.getOwnPropertyDescriptor(x, 'length');
+assertEquals(1, xlength.value);
+assertEquals(true, xlength.writable);
+assertEquals(true, xlength.enumerable);
+assertEquals(true, xlength.configurable);
+var x0 = Object.getOwnPropertyDescriptor(x, 0);
+assertEquals(2, x0.value);
+assertEquals(true, xlength.writable);
+assertEquals(true, xlength.enumerable);
+assertEquals(true, xlength.configurable);
+
})();
diff --git a/deps/v8/test/mjsunit/harmony/array-of.js b/deps/v8/test/mjsunit/harmony/array-of.js
index adf7cb547c..7fd5eeaf61 100644
--- a/deps/v8/test/mjsunit/harmony/array-of.js
+++ b/deps/v8/test/mjsunit/harmony/array-of.js
@@ -182,3 +182,33 @@ assertThrows(function() { new Array.of() }, TypeError); // not a constructor
assertEquals(instance instanceof boundFn, true);
assertEquals(Array.isArray(instance), false);
})();
+
+(function testDefinesOwnProperty() {
+ // Assert that [[DefineOwnProperty]] is used in ArrayFrom, meaning a
+ // setter isn't called, and a failed [[DefineOwnProperty]] will throw.
+ var setterCalled = 0;
+ function exotic() {
+ Object.defineProperty(this, '0', {
+ get: function() { return 2; },
+ set: function() { setterCalled++; }
+ });
+ }
+ // Non-configurable properties can't be overwritten with DefineOwnProperty
+ assertThrows(function () { Array.of.call(exotic, 1); }, TypeError);
+ // The setter wasn't called
+ assertEquals(0, setterCalled);
+
+ // Check that array properties defined are writable, enumerable, configurable
+ function ordinary() { }
+ var x = Array.of.call(ordinary, 2);
+ var xlength = Object.getOwnPropertyDescriptor(x, 'length');
+ assertEquals(1, xlength.value);
+ assertEquals(true, xlength.writable);
+ assertEquals(true, xlength.enumerable);
+ assertEquals(true, xlength.configurable);
+ var x0 = Object.getOwnPropertyDescriptor(x, 0);
+ assertEquals(2, x0.value);
+ assertEquals(true, xlength.writable);
+ assertEquals(true, xlength.enumerable);
+ assertEquals(true, xlength.configurable);
+})();
diff --git a/deps/v8/test/mjsunit/harmony/arrow-functions-lexical-arguments.js b/deps/v8/test/mjsunit/harmony/arrow-functions-lexical-arguments.js
index e8511051ae..b2498d78dc 100644
--- a/deps/v8/test/mjsunit/harmony/arrow-functions-lexical-arguments.js
+++ b/deps/v8/test/mjsunit/harmony/arrow-functions-lexical-arguments.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-arrow-functions --harmony-classes
+// Flags: --harmony-arrow-functions
(function testInFunctionDeclaration() {
diff --git a/deps/v8/test/mjsunit/harmony/arrow-functions-this.js b/deps/v8/test/mjsunit/harmony/arrow-functions-this.js
new file mode 100644
index 0000000000..2c2ad075d2
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/arrow-functions-this.js
@@ -0,0 +1,81 @@
+// Copyright 2015 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
+
+var object = {};
+var global = this;
+var call = Function.call.bind(Function.call);
+
+var globalSloppyArrow = () => this;
+var globalStrictArrow = () => { "use strict"; return this; };
+var globalSloppyArrowEval = (s) => eval(s);
+var globalStrictArrowEval = (s) => { "use strict"; return eval(s); };
+
+var sloppyFunctionArrow = function() {
+ return (() => this)();
+};
+var strictFunctionArrow = function() {
+ "use strict";
+ return (() => this)();
+};
+var sloppyFunctionEvalArrow = function() {
+ return eval("(() => this)()");
+};
+var strictFunctionEvalArrow = function() {
+ "use strict";
+ return eval("(() => this)()");
+};
+var sloppyFunctionArrowEval = function(s) {
+ return (() => eval(s))();
+};
+var strictFunctionArrowEval = function(s) {
+ "use strict";
+ return (() => eval(s))();
+};
+
+var withObject = { 'this': object }
+var arrowInsideWith, arrowInsideWithEval;
+with (withObject) {
+ arrowInsideWith = () => this;
+ arrowInsideWithEval = (s) => eval(s);
+}
+
+assertEquals(global, call(globalSloppyArrow, object));
+assertEquals(global, call(globalStrictArrow, object));
+assertEquals(global, call(globalSloppyArrowEval, object, "this"));
+assertEquals(global, call(globalStrictArrowEval, object, "this"));
+assertEquals(global, call(globalSloppyArrowEval, object, "(() => this)()"));
+assertEquals(global, call(globalStrictArrowEval, object, "(() => this)()"));
+
+assertEquals(object, call(sloppyFunctionArrow, object));
+assertEquals(global, call(sloppyFunctionArrow, undefined));
+assertEquals(object, call(strictFunctionArrow, object));
+assertEquals(undefined, call(strictFunctionArrow, undefined));
+
+assertEquals(object, call(sloppyFunctionEvalArrow, object));
+assertEquals(global, call(sloppyFunctionEvalArrow, undefined));
+assertEquals(object, call(strictFunctionEvalArrow, object));
+assertEquals(undefined, call(strictFunctionEvalArrow, undefined));
+
+assertEquals(object, call(sloppyFunctionArrowEval, object, "this"));
+assertEquals(global, call(sloppyFunctionArrowEval, undefined, "this"));
+assertEquals(object, call(strictFunctionArrowEval, object, "this"));
+assertEquals(undefined, call(strictFunctionArrowEval, undefined, "this"));
+
+assertEquals(object,
+ call(sloppyFunctionArrowEval, object, "(() => this)()"));
+assertEquals(global,
+ call(sloppyFunctionArrowEval, undefined, "(() => this)()"));
+assertEquals(object,
+ call(strictFunctionArrowEval, object, "(() => this)()"));
+assertEquals(undefined,
+ call(strictFunctionArrowEval, undefined, "(() => this)()"));
+
+assertEquals(global, call(arrowInsideWith, undefined));
+assertEquals(global, call(arrowInsideWith, object));
+assertEquals(global, call(arrowInsideWithEval, undefined, "this"));
+assertEquals(global, call(arrowInsideWithEval, object, "this"));
+assertEquals(global, call(arrowInsideWithEval, undefined, "(() => this)()"));
+assertEquals(global, call(arrowInsideWithEval, object, "(() => this)()"));
diff --git a/deps/v8/test/mjsunit/harmony/arrow-rest-params.js b/deps/v8/test/mjsunit/harmony/arrow-rest-params.js
new file mode 100644
index 0000000000..b1e8dcc1b9
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/arrow-rest-params.js
@@ -0,0 +1,142 @@
+// 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-rest-parameters --harmony-arrow-functions
+
+(function testRestIndex() {
+ assertEquals(5, ((...args) => args.length)(1,2,3,4,5));
+ assertEquals(4, ((a, ...args) => args.length)(1,2,3,4,5));
+ assertEquals(3, ((a, b, ...args) => args.length)(1,2,3,4,5));
+ assertEquals(2, ((a, b, c, ...args) => args.length)(1,2,3,4,5));
+ assertEquals(1, ((a, b, c, d, ...args) => args.length)(1,2,3,4,5));
+ assertEquals(0, ((a, b, c, d, e, ...args) => args.length)(1,2,3,4,5));
+})();
+
+// strictTest and sloppyTest should be called with descending natural
+// numbers, as in:
+//
+// strictTest(6,5,4,3,2,1)
+//
+var strictTest = (a, b, ...c) => {
+ "use strict";
+ assertEquals(Array, c.constructor);
+ assertTrue(Array.isArray(c));
+
+ var expectedLength = (a === undefined) ? 0 : a - 2;
+ assertEquals(expectedLength, c.length);
+
+ for (var i = 2; i < a; ++i) {
+ assertEquals(c[i - 2], a - i);
+ }
+}
+
+var sloppyTest = (a, b, ...c) => {
+ assertEquals(Array, c.constructor);
+ assertTrue(Array.isArray(c));
+
+ var expectedLength = (a === undefined) ? 0 : a - 2;
+ assertEquals(expectedLength, c.length);
+
+ for (var i = 2; i < a; ++i) {
+ assertEquals(c[i - 2], a - i);
+ }
+}
+
+
+var O = {
+ strict: strictTest,
+ sloppy: sloppyTest
+};
+
+(function testStrictRestParamArity() {
+ assertEquals(2, strictTest.length);
+ assertEquals(2, O.strict.length);
+})();
+
+
+(function testRestParamsStrictMode() {
+ strictTest();
+ strictTest(2, 1);
+ strictTest(6, 5, 4, 3, 2, 1);
+ strictTest(3, 2, 1);
+ O.strict();
+ O.strict(2, 1);
+ O.strict(6, 5, 4, 3, 2, 1);
+ O.strict(3, 2, 1);
+})();
+
+
+(function testRestParamsStrictModeApply() {
+ strictTest.apply(null, []);
+ strictTest.apply(null, [2, 1]);
+ strictTest.apply(null, [6, 5, 4, 3, 2, 1]);
+ strictTest.apply(null, [3, 2, 1]);
+ O.strict.apply(O, []);
+ O.strict.apply(O, [2, 1]);
+ O.strict.apply(O, [6, 5, 4, 3, 2, 1]);
+ O.strict.apply(O, [3, 2, 1]);
+})();
+
+
+(function testRestParamsStrictModeCall() {
+ strictTest.call(null);
+ strictTest.call(null, 2, 1);
+ strictTest.call(null, 6, 5, 4, 3, 2, 1);
+ strictTest.call(null, 3, 2, 1);
+ O.strict.call(O);
+ O.strict.call(O, 2, 1);
+ O.strict.call(O, 6, 5, 4, 3, 2, 1);
+ O.strict.call(O, 3, 2, 1);
+})();
+
+
+(function testsloppyRestParamArity() {
+ assertEquals(2, sloppyTest.length);
+ assertEquals(2, O.sloppy.length);
+})();
+
+
+(function testRestParamssloppyMode() {
+ sloppyTest();
+ sloppyTest(2, 1);
+ sloppyTest(6, 5, 4, 3, 2, 1);
+ sloppyTest(3, 2, 1);
+ O.sloppy();
+ O.sloppy(2, 1);
+ O.sloppy(6, 5, 4, 3, 2, 1);
+ O.sloppy(3, 2, 1);
+})();
+
+
+(function testRestParamssloppyModeApply() {
+ sloppyTest.apply(null, []);
+ sloppyTest.apply(null, [2, 1]);
+ sloppyTest.apply(null, [6, 5, 4, 3, 2, 1]);
+ sloppyTest.apply(null, [3, 2, 1]);
+ O.sloppy.apply(O, []);
+ O.sloppy.apply(O, [2, 1]);
+ O.sloppy.apply(O, [6, 5, 4, 3, 2, 1]);
+ O.sloppy.apply(O, [3, 2, 1]);
+})();
+
+
+(function testRestParamssloppyModeCall() {
+ sloppyTest.call(null);
+ sloppyTest.call(null, 2, 1);
+ sloppyTest.call(null, 6, 5, 4, 3, 2, 1);
+ sloppyTest.call(null, 3, 2, 1);
+ O.sloppy.call(O);
+ O.sloppy.call(O, 2, 1);
+ O.sloppy.call(O, 6, 5, 4, 3, 2, 1);
+ O.sloppy.call(O, 3, 2, 1);
+})();
+
+
+(function testUnmappedArguments() {
+ // Normal functions make their arguments object unmapped, but arrow
+ // functions don't have an arguments object anyway. Check that the
+ // right thing happens for arguments in arrow functions with rest
+ // parameters.
+ assertSame(arguments, ((...rest) => arguments)());
+})();
diff --git a/deps/v8/test/mjsunit/harmony/atomics.js b/deps/v8/test/mjsunit/harmony/atomics.js
new file mode 100644
index 0000000000..ff403b8bd1
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/atomics.js
@@ -0,0 +1,444 @@
+// 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-atomics --harmony-sharedarraybuffer
+//
+
+function toRangeWrapped(value) {
+ var range = this.max - this.min + 1;
+ while (value < this.min) {
+ value += range;
+ }
+ while (value > this.max) {
+ value -= range;
+ }
+ return value;
+}
+
+function toRangeClamped(value) {
+ if (value < this.min) return this.min;
+ if (value > this.max) return this.max;
+ return value;
+}
+
+function makeConstructorObject(constr, min, max, toRange) {
+ var o = {constr: constr, min: min, max: max};
+ o.toRange = toRange.bind(o);
+ return o;
+}
+
+var IntegerTypedArrayConstructors = [
+ makeConstructorObject(Int8Array, -128, 127, toRangeWrapped),
+ makeConstructorObject(Int16Array, -32768, 32767, toRangeWrapped),
+ makeConstructorObject(Int32Array, -0x80000000, 0x7fffffff, toRangeWrapped),
+ makeConstructorObject(Uint8Array, 0, 255, toRangeWrapped),
+ makeConstructorObject(Uint8ClampedArray, 0, 255, toRangeClamped),
+ makeConstructorObject(Uint16Array, 0, 65535, toRangeWrapped),
+ makeConstructorObject(Uint32Array, 0, 0xffffffff, toRangeWrapped),
+];
+
+var TypedArrayConstructors = IntegerTypedArrayConstructors.concat([
+ {constr: Float32Array},
+ {constr: Float64Array},
+]);
+
+(function TestBadArray() {
+ var ab = new ArrayBuffer(16);
+ var u32a = new Uint32Array(16);
+ var sab = new SharedArrayBuffer(128);
+ var sf32a = new Float32Array(sab);
+ var sf64a = new Float64Array(sab);
+
+ // Atomic ops required shared typed arrays
+ [undefined, 1, 'hi', 3.4, ab, u32a, sab].forEach(function(o) {
+ assertThrows(function() { Atomics.compareExchange(o, 0, 0, 0); },
+ TypeError);
+ assertThrows(function() { Atomics.load(o, 0); }, TypeError);
+ assertThrows(function() { Atomics.store(o, 0, 0); }, TypeError);
+ assertThrows(function() { Atomics.add(o, 0, 0); }, TypeError);
+ assertThrows(function() { Atomics.sub(o, 0, 0); }, TypeError);
+ assertThrows(function() { Atomics.and(o, 0, 0); }, TypeError);
+ assertThrows(function() { Atomics.or(o, 0, 0); }, TypeError);
+ assertThrows(function() { Atomics.xor(o, 0, 0); }, TypeError);
+ assertThrows(function() { Atomics.exchange(o, 0, 0); }, TypeError);
+ });
+
+ // Arithmetic atomic ops require integer shared arrays
+ [sab, sf32a, sf64a].forEach(function(o) {
+ assertThrows(function() { Atomics.add(o, 0, 0); }, TypeError);
+ assertThrows(function() { Atomics.sub(o, 0, 0); }, TypeError);
+ assertThrows(function() { Atomics.and(o, 0, 0); }, TypeError);
+ assertThrows(function() { Atomics.or(o, 0, 0); }, TypeError);
+ assertThrows(function() { Atomics.xor(o, 0, 0); }, TypeError);
+ assertThrows(function() { Atomics.exchange(o, 0, 0); }, TypeError);
+ });
+})();
+
+function testAtomicOp(op, ia, index, expectedIndex, name) {
+ for (var i = 0; i < ia.length; ++i)
+ ia[i] = 22;
+
+ ia[expectedIndex] = 0;
+ assertEquals(0, op(ia, index, 0, 0), name);
+ assertEquals(0, ia[expectedIndex], name);
+
+ for (var i = 0; i < ia.length; ++i) {
+ if (i == expectedIndex) continue;
+ assertEquals(22, ia[i], name);
+ }
+}
+
+(function TestBadIndex() {
+ var sab = new SharedArrayBuffer(8);
+ var si32a = new Int32Array(sab);
+
+ // Non-integer indexes are converted to an integer first, so they should all
+ // operate on index 0.
+ [undefined, null, false, 'hi', {}].forEach(function(i) {
+ var name = String(i);
+
+ testAtomicOp(Atomics.compareExchange, si32a, i, 0, name);
+ testAtomicOp(Atomics.load, si32a, i, 0, name);
+ testAtomicOp(Atomics.store, si32a, i, 0, name);
+ testAtomicOp(Atomics.add, si32a, i, 0, name);
+ testAtomicOp(Atomics.sub, si32a, i, 0, name);
+ testAtomicOp(Atomics.and, si32a, i, 0, name);
+ testAtomicOp(Atomics.or, si32a, i, 0, name);
+ testAtomicOp(Atomics.xor, si32a, i, 0, name);
+ testAtomicOp(Atomics.exchange, si32a, i, 0, name);
+ });
+
+ // Out-of-bounds indexes should return undefined.
+ // TODO(binji): Should these throw RangeError instead?
+ [-1, 2, 100].forEach(function(i) {
+ var name = String(i);
+ assertEquals(undefined, Atomics.compareExchange(si32a, i, 0, 0), name);
+ assertEquals(undefined, Atomics.load(si32a, i), name);
+ assertEquals(undefined, Atomics.store(si32a, i, 0), name);
+ assertEquals(undefined, Atomics.add(si32a, i, 0), name);
+ assertEquals(undefined, Atomics.sub(si32a, i, 0), name);
+ assertEquals(undefined, Atomics.and(si32a, i, 0), name);
+ assertEquals(undefined, Atomics.or(si32a, i, 0), name);
+ assertEquals(undefined, Atomics.xor(si32a, i, 0), name);
+ assertEquals(undefined, Atomics.exchange(si32a, i, 0), name);
+ });
+})();
+
+(function TestGoodIndex() {
+ var sab = new SharedArrayBuffer(64);
+ var si32a = new Int32Array(sab);
+
+ var valueOf = {valueOf: function(){ return 3;}};
+ var toString = {toString: function(){ return '3';}};
+
+ [3, 3.5, '3', '3.5', valueOf, toString].forEach(function(i) {
+ var name = String(i);
+
+ testAtomicOp(Atomics.compareExchange, si32a, i, 3, name);
+ testAtomicOp(Atomics.load, si32a, i, 3, name);
+ testAtomicOp(Atomics.store, si32a, i, 3, name);
+ testAtomicOp(Atomics.add, si32a, i, 3, name);
+ testAtomicOp(Atomics.sub, si32a, i, 3, name);
+ testAtomicOp(Atomics.and, si32a, i, 3, name);
+ testAtomicOp(Atomics.or, si32a, i, 3, name);
+ testAtomicOp(Atomics.xor, si32a, i, 3, name);
+ testAtomicOp(Atomics.exchange, si32a, i, 3, name);
+ });
+})();
+
+(function TestCompareExchange() {
+ TypedArrayConstructors.forEach(function(t) {
+ var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
+ var sta = new t.constr(sab);
+ var name = Object.prototype.toString.call(sta);
+ for (var i = 0; i < 10; ++i) {
+ // sta[i] == 0, CAS will store
+ assertEquals(0, Atomics.compareExchange(sta, i, 0, 50), name);
+ assertEquals(50, sta[i], name);
+
+ // sta[i] == 50, CAS will not store
+ assertEquals(50, Atomics.compareExchange(sta, i, 0, 100), name);
+ assertEquals(50, sta[i], name);
+ }
+ });
+
+ // * Exact float values should be OK
+ // * Infinity, -Infinity should be OK (has exact representation)
+ // * NaN is not OK, it has many representations, cannot ensure successful CAS
+ // because it does a bitwise compare
+ [1.5, 4.25, -1e8, -Infinity, Infinity].forEach(function(v) {
+ var sab = new SharedArrayBuffer(10 * Float32Array.BYTES_PER_ELEMENT);
+ var sf32a = new Float32Array(sab);
+ sf32a[0] = 0;
+ assertEquals(0, Atomics.compareExchange(sf32a, 0, 0, v));
+ assertEquals(v, sf32a[0]);
+ assertEquals(v, Atomics.compareExchange(sf32a, 0, v, 0));
+ assertEquals(0, sf32a[0]);
+
+ var sab2 = new SharedArrayBuffer(10 * Float64Array.BYTES_PER_ELEMENT);
+ var sf64a = new Float64Array(sab2);
+ sf64a[0] = 0;
+ assertEquals(0, Atomics.compareExchange(sf64a, 0, 0, v));
+ assertEquals(v, sf64a[0]);
+ assertEquals(v, Atomics.compareExchange(sf64a, 0, v, 0));
+ assertEquals(0, sf64a[0]);
+ });
+})();
+
+(function TestLoad() {
+ TypedArrayConstructors.forEach(function(t) {
+ var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
+ var sta = new t.constr(sab);
+ var name = Object.prototype.toString.call(sta);
+ for (var i = 0; i < 10; ++i) {
+ sta[i] = 0;
+ assertEquals(0, Atomics.load(sta, i), name);
+ sta[i] = 50;
+ assertEquals(50, Atomics.load(sta, i), name);
+ }
+ });
+})();
+
+(function TestStore() {
+ TypedArrayConstructors.forEach(function(t) {
+ var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
+ var sta = new t.constr(sab);
+ var name = Object.prototype.toString.call(sta);
+ for (var i = 0; i < 10; ++i) {
+ assertEquals(50, Atomics.store(sta, i, 50), name);
+ assertEquals(50, sta[i], name);
+
+ assertEquals(100, Atomics.store(sta, i, 100), name);
+ assertEquals(100, sta[i], name);
+ }
+ });
+
+ [1.5, 4.25, -1e8, -Infinity, Infinity, NaN].forEach(function(v) {
+ var sab = new SharedArrayBuffer(10 * Float32Array.BYTES_PER_ELEMENT);
+ var sf32a = new Float32Array(sab);
+ sf32a[0] = 0;
+ assertEquals(v, Atomics.store(sf32a, 0, v));
+ assertEquals(v, sf32a[0]);
+
+ var sab2 = new SharedArrayBuffer(10 * Float64Array.BYTES_PER_ELEMENT);
+ var sf64a = new Float64Array(sab2);
+ sf64a[0] = 0;
+ assertEquals(v, Atomics.store(sf64a, 0, v));
+ assertEquals(v, sf64a[0]);
+ });
+})();
+
+(function TestAdd() {
+ IntegerTypedArrayConstructors.forEach(function(t) {
+ var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
+ var sta = new t.constr(sab);
+ var name = Object.prototype.toString.call(sta);
+ for (var i = 0; i < 10; ++i) {
+ assertEquals(0, Atomics.add(sta, i, 50), name);
+ assertEquals(50, sta[i], name);
+
+ assertEquals(50, Atomics.add(sta, i, 70), name);
+ assertEquals(120, sta[i], name);
+ }
+ });
+})();
+
+(function TestSub() {
+ IntegerTypedArrayConstructors.forEach(function(t) {
+ var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
+ var sta = new t.constr(sab);
+ var name = Object.prototype.toString.call(sta);
+ for (var i = 0; i < 10; ++i) {
+ sta[i] = 120;
+ assertEquals(120, Atomics.sub(sta, i, 50), name);
+ assertEquals(70, sta[i], name);
+
+ assertEquals(70, Atomics.sub(sta, i, 70), name);
+ assertEquals(0, sta[i], name);
+ }
+ });
+})();
+
+(function TestAnd() {
+ IntegerTypedArrayConstructors.forEach(function(t) {
+ var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
+ var sta = new t.constr(sab);
+ var name = Object.prototype.toString.call(sta);
+ for (var i = 0; i < 10; ++i) {
+ sta[i] = 0x3f;
+ assertEquals(0x3f, Atomics.and(sta, i, 0x30), name);
+ assertEquals(0x30, sta[i], name);
+
+ assertEquals(0x30, Atomics.and(sta, i, 0x20), name);
+ assertEquals(0x20, sta[i], name);
+ }
+ });
+})();
+
+(function TestOr() {
+ IntegerTypedArrayConstructors.forEach(function(t) {
+ var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
+ var sta = new t.constr(sab);
+ var name = Object.prototype.toString.call(sta);
+ for (var i = 0; i < 10; ++i) {
+ sta[i] = 0x30;
+ assertEquals(0x30, Atomics.or(sta, i, 0x1c), name);
+ assertEquals(0x3c, sta[i], name);
+
+ assertEquals(0x3c, Atomics.or(sta, i, 0x09), name);
+ assertEquals(0x3d, sta[i], name);
+ }
+ });
+})();
+
+(function TestXor() {
+ IntegerTypedArrayConstructors.forEach(function(t) {
+ var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
+ var sta = new t.constr(sab);
+ var name = Object.prototype.toString.call(sta);
+ for (var i = 0; i < 10; ++i) {
+ sta[i] = 0x30;
+ assertEquals(0x30, Atomics.xor(sta, i, 0x1c), name);
+ assertEquals(0x2c, sta[i], name);
+
+ assertEquals(0x2c, Atomics.xor(sta, i, 0x09), name);
+ assertEquals(0x25, sta[i], name);
+ }
+ });
+})();
+
+(function TestExchange() {
+ IntegerTypedArrayConstructors.forEach(function(t) {
+ var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
+ var sta = new t.constr(sab);
+ var name = Object.prototype.toString.call(sta);
+ for (var i = 0; i < 10; ++i) {
+ sta[i] = 0x30;
+ assertEquals(0x30, Atomics.exchange(sta, i, 0x1c), name);
+ assertEquals(0x1c, sta[i], name);
+
+ assertEquals(0x1c, Atomics.exchange(sta, i, 0x09), name);
+ assertEquals(0x09, sta[i], name);
+ }
+ });
+})();
+
+(function TestIsLockFree() {
+ // For all platforms we support, 1, 2 and 4 bytes should be lock-free.
+ assertEquals(true, Atomics.isLockFree(1));
+ assertEquals(true, Atomics.isLockFree(2));
+ assertEquals(true, Atomics.isLockFree(4));
+
+ // Sizes that aren't equal to a typedarray BYTES_PER_ELEMENT always return
+ // false.
+ var validSizes = {};
+ TypedArrayConstructors.forEach(function(t) {
+ validSizes[t.constr.BYTES_PER_ELEMENT] = true;
+ });
+
+ for (var i = 0; i < 1000; ++i) {
+ if (!validSizes[i]) {
+ assertEquals(false, Atomics.isLockFree(i));
+ }
+ }
+})();
+
+(function TestWrapping() {
+ IntegerTypedArrayConstructors.forEach(function(t) {
+ var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
+ var sta = new t.constr(sab);
+ var name = Object.prototype.toString.call(sta);
+ var range = t.max - t.min + 1;
+ var offset;
+ var operand;
+ var val, newVal;
+ var valWrapped, newValWrapped;
+
+ for (offset = -range; offset <= range; offset += range) {
+ // CompareExchange
+ sta[0] = val = 0;
+ newVal = val + offset + 1;
+ newValWrapped = t.toRange(newVal);
+ assertEquals(val, Atomics.compareExchange(sta, 0, val, newVal), name);
+ assertEquals(newValWrapped, sta[0], name);
+
+ sta[0] = val = t.min;
+ newVal = val + offset - 1;
+ newValWrapped = t.toRange(newVal);
+ assertEquals(val, Atomics.compareExchange(sta, 0, val, newVal), name);
+ assertEquals(newValWrapped, sta[0], name);
+
+ // Store
+ sta[0] = 0;
+ val = t.max + offset + 1;
+ valWrapped = t.toRange(val);
+ assertEquals(val, Atomics.store(sta, 0, val), name);
+ assertEquals(valWrapped, sta[0], name);
+
+ sta[0] = val = t.min + offset - 1;
+ valWrapped = t.toRange(val);
+ assertEquals(val, Atomics.store(sta, 0, val), name);
+ assertEquals(valWrapped, sta[0], name);
+
+ // Add
+ sta[0] = val = t.max;
+ operand = offset + 1;
+ valWrapped = t.toRange(val + operand);
+ assertEquals(val, Atomics.add(sta, 0, operand), name);
+ assertEquals(valWrapped, sta[0], name);
+
+ sta[0] = val = t.min;
+ operand = offset - 1;
+ valWrapped = t.toRange(val + operand);
+ assertEquals(val, Atomics.add(sta, 0, operand), name);
+ assertEquals(valWrapped, sta[0], name);
+
+ // Sub
+ sta[0] = val = t.max;
+ operand = offset - 1;
+ valWrapped = t.toRange(val - operand);
+ assertEquals(val, Atomics.sub(sta, 0, operand), name);
+ assertEquals(valWrapped, sta[0], name);
+
+ sta[0] = val = t.min;
+ operand = offset + 1;
+ valWrapped = t.toRange(val - operand);
+ assertEquals(val, Atomics.sub(sta, 0, operand), name);
+ assertEquals(valWrapped, sta[0], name);
+
+ // There's no way to wrap results with logical operators, just test that
+ // using an out-of-range value is properly wrapped/clamped when written
+ // to memory.
+
+ // And
+ sta[0] = val = 0xf;
+ operand = 0x3 + offset;
+ valWrapped = t.toRange(val & operand);
+ assertEquals(val, Atomics.and(sta, 0, operand), name);
+ assertEquals(valWrapped, sta[0], name);
+
+ // Or
+ sta[0] = val = 0x12;
+ operand = 0x22 + offset;
+ valWrapped = t.toRange(val | operand);
+ assertEquals(val, Atomics.or(sta, 0, operand), name);
+ assertEquals(valWrapped, sta[0], name);
+
+ // Xor
+ sta[0] = val = 0x12;
+ operand = 0x22 + offset;
+ valWrapped = t.toRange(val ^ operand);
+ assertEquals(val, Atomics.xor(sta, 0, operand), name);
+ assertEquals(valWrapped, sta[0], name);
+
+ // Exchange
+ sta[0] = val = 0x12;
+ operand = 0x22 + offset;
+ valWrapped = t.toRange(operand);
+ assertEquals(val, Atomics.exchange(sta, 0, operand), name);
+ assertEquals(valWrapped, sta[0], name);
+ }
+
+ });
+})();
diff --git a/deps/v8/test/mjsunit/harmony/class-computed-property-names-super.js b/deps/v8/test/mjsunit/harmony/class-computed-property-names-super.js
index 5a5db67d48..a68b53c18f 100644
--- a/deps/v8/test/mjsunit/harmony/class-computed-property-names-super.js
+++ b/deps/v8/test/mjsunit/harmony/class-computed-property-names-super.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
// Flags: --harmony-computed-property-names --harmony-sloppy
-// Flags: --harmony-classes --allow-natives-syntax
+// Flags: --allow-natives-syntax
function ID(x) {
diff --git a/deps/v8/test/mjsunit/harmony/computed-property-names-classes.js b/deps/v8/test/mjsunit/harmony/computed-property-names-classes.js
index e8cae460a5..46a9e9ec2d 100644
--- a/deps/v8/test/mjsunit/harmony/computed-property-names-classes.js
+++ b/deps/v8/test/mjsunit/harmony/computed-property-names-classes.js
@@ -4,7 +4,7 @@
'use strict';
-// Flags: --harmony-computed-property-names --harmony-classes
+// Flags: --harmony-computed-property-names
function ID(x) {
diff --git a/deps/v8/test/mjsunit/harmony/computed-property-names-deopt.js b/deps/v8/test/mjsunit/harmony/computed-property-names-deopt.js
new file mode 100644
index 0000000000..1f0b0585fc
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/computed-property-names-deopt.js
@@ -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.
+
+// Flags: --harmony-computed-property-names --allow-natives-syntax
+
+
+(function TestProtoDeopt() {
+ var proto = {};
+
+ function deoptMe() {
+ %DeoptimizeFunction(f);
+ return proto;
+ }
+
+ function checkObject(name, value, o) {
+ assertSame(proto, Object.getPrototypeOf(o));
+ assertTrue(o.hasOwnProperty(name));
+ assertEquals(value, o[name]);
+ }
+
+ function f(name, value) {
+ return { [name]: value, __proto__: deoptMe() };
+ }
+
+ checkObject("a", 1, f("a", 1));
+ checkObject("b", 2, f("b", 2));
+ %OptimizeFunctionOnNextCall(f);
+ checkObject("c", 3, f("c", 3));
+})();
diff --git a/deps/v8/test/mjsunit/harmony/computed-property-names-object-literals-methods.js b/deps/v8/test/mjsunit/harmony/computed-property-names-object-literals-methods.js
index 135d09854e..7ba15aca92 100644
--- a/deps/v8/test/mjsunit/harmony/computed-property-names-object-literals-methods.js
+++ b/deps/v8/test/mjsunit/harmony/computed-property-names-object-literals-methods.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-computed-property-names --harmony-object-literals
+// Flags: --harmony-computed-property-names
function ID(x) {
diff --git a/deps/v8/test/mjsunit/harmony/computed-property-names-super.js b/deps/v8/test/mjsunit/harmony/computed-property-names-super.js
index 096e010317..bfc31c668f 100644
--- a/deps/v8/test/mjsunit/harmony/computed-property-names-super.js
+++ b/deps/v8/test/mjsunit/harmony/computed-property-names-super.js
@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-computed-property-names --harmony-object-literals
-// Flags: --harmony-classes --allow-natives-syntax
+// Flags: --harmony-computed-property-names --allow-natives-syntax
function ID(x) {
diff --git a/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount-nolazy.js b/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount-nolazy.js
new file mode 100644
index 0000000000..fdf1233f90
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount-nolazy.js
@@ -0,0 +1,41 @@
+// Copyright 2015 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-destructuring --harmony-computed-property-names
+// Flags: --harmony-arrow-functions --no-lazy --allow-natives-syntax
+
+
+var t1 = [1];
+var t2 = [2];
+var t3 = [3];
+var t4 = [4];
+var t5 = [5];
+function g({x = {a:10,b:20}},
+ {y = [1,2,3],
+ n = [],
+ p = /abc/}) {
+ assertSame(10, x.a);
+ assertSame(20, x.b);
+ assertSame(2, y[1]);
+ assertSame(0, n.length);
+ assertTrue(p.test("abc"));
+}
+g({},{});
+%OptimizeFunctionOnNextCall(g);
+g({},{});
+
+
+var h = ({x = {a:10,b:20}},
+ {y = [1,2,3],
+ n = [],
+ p = /abc/ }) => {
+ assertSame(10, x.a);
+ assertSame(20, x.b);
+ assertSame(2, y[1]);
+ assertSame(0, n.length);
+ assertTrue(p.test("abc"));
+ };
+h({},{});
+%OptimizeFunctionOnNextCall(h);
+h({},{});
diff --git a/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount.js b/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount.js
new file mode 100644
index 0000000000..85a45ea822
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount.js
@@ -0,0 +1,41 @@
+// Copyright 2015 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-destructuring --harmony-computed-property-names
+// Flags: --harmony-arrow-functions --allow-natives-syntax
+
+
+var t1 = [1];
+var t2 = [2];
+var t3 = [3];
+var t4 = [4];
+var t5 = [5];
+function g({x = {a:10,b:20}},
+ {y = [1,2,3],
+ n = [],
+ p = /abc/}) {
+ assertSame(10, x.a);
+ assertSame(20, x.b);
+ assertSame(2, y[1]);
+ assertSame(0, n.length);
+ assertTrue(p.test("abc"));
+}
+g({},{});
+%OptimizeFunctionOnNextCall(g);
+g({},{});
+
+
+var h = ({x = {a:10,b:20}},
+ {y = [1,2,3],
+ n = [],
+ p = /abc/ }) => {
+ assertSame(10, x.a);
+ assertSame(20, x.b);
+ assertSame(2, y[1]);
+ assertSame(0, n.length);
+ assertTrue(p.test("abc"));
+ };
+h({},{});
+%OptimizeFunctionOnNextCall(h);
+h({},{});
diff --git a/deps/v8/test/mjsunit/harmony/destructuring.js b/deps/v8/test/mjsunit/harmony/destructuring.js
new file mode 100644
index 0000000000..198d4c0257
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/destructuring.js
@@ -0,0 +1,738 @@
+// Copyright 2015 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-destructuring --harmony-computed-property-names
+// Flags: --harmony-arrow-functions
+
+(function TestObjectLiteralPattern() {
+ var { x : x, y : y } = { x : 1, y : 2 };
+ assertEquals(1, x);
+ assertEquals(2, y);
+
+ var {z} = { z : 3 };
+ assertEquals(3, z);
+
+
+ var sum = 0;
+ for (var {z} = { z : 3 }; z != 0; z--) {
+ sum += z;
+ }
+ assertEquals(6, sum);
+
+
+ var log = [];
+ var o = {
+ get x() {
+ log.push("x");
+ return 0;
+ },
+ get y() {
+ log.push("y");
+ return {
+ get z() { log.push("z"); return 1; }
+ }
+ }
+ };
+ var { x : x0, y : { z : z1 }, x : x1 } = o;
+ assertSame(0, x0);
+ assertSame(1, z1);
+ assertSame(0, x1);
+ assertArrayEquals(["x", "y", "z", "x"], log);
+}());
+
+
+(function TestObjectLiteralPatternInitializers() {
+ var { x : x, y : y = 2 } = { x : 1 };
+ assertEquals(1, x);
+ assertEquals(2, y);
+
+ var {z = 3} = {};
+ assertEquals(3, z);
+
+ var sum = 0;
+ for (var {z = 3} = {}; z != 0; z--) {
+ sum += z;
+ }
+ assertEquals(6, sum);
+
+ var log = [];
+ var o = {
+ get x() {
+ log.push("x");
+ return undefined;
+ },
+ get y() {
+ log.push("y");
+ return {
+ get z() { log.push("z"); return undefined; }
+ }
+ }
+ };
+ var { x : x0 = 0, y : { z : z1 = 1}, x : x1 = 0} = o;
+ assertSame(0, x0);
+ assertSame(1, z1);
+ assertSame(0, x1);
+ assertArrayEquals(["x", "y", "z", "x"], log);
+}());
+
+
+(function TestObjectLiteralPatternLexicalInitializers() {
+ 'use strict';
+ let { x : x, y : y = 2 } = { x : 1 };
+ assertEquals(1, x);
+ assertEquals(2, y);
+
+ let {z = 3} = {};
+ assertEquals(3, z);
+
+ let log = [];
+ let o = {
+ get x() {
+ log.push("x");
+ return undefined;
+ },
+ get y() {
+ log.push("y");
+ return {
+ get z() { log.push("z"); return undefined; }
+ }
+ }
+ };
+
+ let { x : x0 = 0, y : { z : z1 = 1 }, x : x1 = 5} = o;
+ assertSame(0, x0);
+ assertSame(1, z1);
+ assertSame(5, x1);
+ assertArrayEquals(["x", "y", "z", "x"], log);
+
+ let sum = 0;
+ for (let {x = 0, z = 3} = {}; z != 0; z--) {
+ assertEquals(0, x);
+ sum += z;
+ }
+ assertEquals(6, sum);
+}());
+
+
+(function TestObjectLiteralPatternLexical() {
+ 'use strict';
+ let { x : x, y : y } = { x : 1, y : 2 };
+ assertEquals(1, x);
+ assertEquals(2, y);
+
+ let {z} = { z : 3 };
+ assertEquals(3, z);
+
+ let log = [];
+ let o = {
+ get x() {
+ log.push("x");
+ return 0;
+ },
+ get y() {
+ log.push("y");
+ return {
+ get z() { log.push("z"); return 1; }
+ }
+ }
+ };
+ let { x : x0, y : { z : z1 }, x : x1 } = o;
+ assertSame(0, x0);
+ assertSame(1, z1);
+ assertSame(0, x1);
+ assertArrayEquals(["x", "y", "z", "x"], log);
+
+ let sum = 0;
+ for (let {x, z} = { x : 0, z : 3 }; z != 0; z--) {
+ assertEquals(0, x);
+ sum += z;
+ }
+ assertEquals(6, sum);
+}());
+
+
+(function TestObjectLiteralPatternLexicalConst() {
+ 'use strict';
+ const { x : x, y : y } = { x : 1, y : 2 };
+ assertEquals(1, x);
+ assertEquals(2, y);
+
+ assertThrows(function() { x++; }, TypeError);
+ assertThrows(function() { y++; }, TypeError);
+
+ const {z} = { z : 3 };
+ assertEquals(3, z);
+
+ for (const {x, z} = { x : 0, z : 3 }; z != 3 || x != 0;) {
+ assertTrue(false);
+ }
+}());
+
+
+(function TestFailingMatchesSloppy() {
+ var {x, y} = {};
+ assertSame(undefined, x);
+ assertSame(undefined, y);
+
+ var { x : { z1 }, y2} = { x : {}, y2 : 42 }
+ assertSame(undefined, z1);
+ assertSame(42, y2);
+}());
+
+
+(function TestFailingMatchesStrict() {
+ 'use strict';
+ var {x, y} = {};
+ assertSame(undefined, x);
+ assertSame(undefined, y);
+
+ var { x : { z1 }, y2} = { x : {}, y2 : 42 }
+ assertSame(undefined, z1);
+ assertSame(42, y2);
+
+ {
+ let {x1,y1} = {};
+ assertSame(undefined, x1);
+ assertSame(undefined, y1);
+
+ let { x : { z1 }, y2} = { x : {}, y2 : 42 }
+ assertSame(undefined, z1);
+ assertSame(42, y2);
+ }
+}());
+
+
+(function TestTDZInIntializers() {
+ 'use strict';
+ {
+ let {x, y = x} = {x : 42, y : 27};
+ assertSame(42, x);
+ assertSame(27, y);
+ }
+
+ {
+ let {x, y = x + 1} = { x : 42 };
+ assertSame(42, x);
+ assertSame(43, y);
+ }
+ assertThrows(function() {
+ let {x = y, y} = { y : 42 };
+ }, ReferenceError);
+
+ {
+ let {x, y = eval("x+1")} = {x:42};
+ assertEquals(42, x);
+ assertEquals(43, y);
+ }
+
+ {
+ let {x = function() {return y+1;}, y} = {y:42};
+ assertEquals(43, x());
+ assertEquals(42, y);
+ }
+ {
+ let {x = function() {return eval("y+1");}, y} = {y:42};
+ assertEquals(43, x());
+ assertEquals(42, y);
+ }
+}());
+
+
+(function TestSideEffectsInInitializers() {
+ var callCount = 0;
+ function f(v) { callCount++; return v; }
+
+ callCount = 0;
+ var { x = f(42) } = { x : 27 };
+ assertSame(27, x);
+ assertEquals(0, callCount);
+
+ callCount = 0;
+ var { x = f(42) } = {};
+ assertSame(42, x);
+ assertEquals(1, callCount);
+}());
+
+
+(function TestMultipleAccesses() {
+ assertThrows(
+ "'use strict';"+
+ "const {x,x} = {x:1};",
+ SyntaxError);
+
+ assertThrows(
+ "'use strict';"+
+ "let {x,x} = {x:1};",
+ SyntaxError);
+
+ (function() {
+ var {x,x = 2} = {x : 1};
+ assertSame(1, x);
+ }());
+
+ assertThrows(function () {
+ 'use strict';
+ let {x = (function() { x = 2; }())} = {};
+ }, ReferenceError);
+
+ (function() {
+ 'use strict';
+ let {x = (function() { x = 2; }())} = {x:1};
+ assertSame(1, x);
+ }());
+}());
+
+
+(function TestComputedNames() {
+ var x = 1;
+ var {[x]:y} = {1:2};
+ assertSame(2, y);
+
+ (function(){
+ 'use strict';
+ let {[x]:y} = {1:2};
+ assertSame(2, y);
+ }());
+
+ var callCount = 0;
+ function foo(v) { callCount++; return v; }
+
+ (function() {
+ callCount = 0;
+ var {[foo("abc")]:x} = {abc:42};
+ assertSame(42, x);
+ assertEquals(1, callCount);
+ }());
+
+ (function() {
+ 'use strict';
+ callCount = 0;
+ let {[foo("abc")]:x} = {abc:42};
+ assertSame(42, x);
+ assertEquals(1, callCount);
+ }());
+
+ (function() {
+ callCount = 0;
+ var {[foo("abc")]:x} = {};
+ assertSame(undefined, x);
+ assertEquals(1, callCount);
+ }());
+
+ (function() {
+ 'use strict';
+ callCount = 0;
+ let {[foo("abc")]:x} = {};
+ assertSame(undefined, x);
+ assertEquals(1, callCount);
+ }());
+
+ for (val of [null, undefined]) {
+ callCount = 0;
+ assertThrows(function() {
+ var {[foo()]:x} = val;
+ }, TypeError);
+ assertEquals(0, callCount);
+
+ callCount = 0;
+ assertThrows(function() {
+ 'use strict';
+ let {[foo()]:x} = val;
+ }, TypeError);
+ assertEquals(0, callCount);
+ }
+
+ var log = [];
+ var o = {
+ get x() { log.push("get x"); return 1; },
+ get y() { log.push("get y"); return 2; }
+ }
+ function f(v) { log.push("f " + v); return v; }
+
+ (function() {
+ log = [];
+ var { [f('x')]:x, [f('y')]:y } = o;
+ assertSame(1, x);
+ assertSame(2, y);
+ assertArrayEquals(["f x", "get x", "f y", "get y"], log);
+ }());
+
+ (function() {
+ 'use strict';
+ log = [];
+ let { [f('x')]:x, [f('y')]:y } = o;
+ assertSame(1, x);
+ assertSame(2, y);
+ assertArrayEquals(["f x", "get x", "f y", "get y"], log);
+ }());
+
+ (function() {
+ 'use strict';
+ log = [];
+ const { [f('x')]:x, [f('y')]:y } = o;
+ assertSame(1, x);
+ assertSame(2, y);
+ assertArrayEquals(["f x", "get x", "f y", "get y"], log);
+ }());
+}());
+
+
+(function TestExceptions() {
+ for (var val of [null, undefined]) {
+ assertThrows(function() { var {} = val; }, TypeError);
+ assertThrows(function() { var {x} = val; }, TypeError);
+ assertThrows(function() { var { x : {} } = { x : val }; }, TypeError);
+ assertThrows(function() { 'use strict'; let {} = val; }, TypeError);
+ assertThrows(function() { 'use strict'; let {x} = val; }, TypeError);
+ assertThrows(function() { 'use strict'; let { x : {} } = { x : val }; },
+ TypeError);
+ }
+}());
+
+
+(function TestArrayLiteral() {
+ var [a, b, c] = [1, 2, 3];
+ assertSame(1, a);
+ assertSame(2, b);
+ assertSame(3, c);
+}());
+
+(function TestIterators() {
+ var log = [];
+ function* f() {
+ log.push("1");
+ yield 1;
+ log.push("2");
+ yield 2;
+ log.push("3");
+ yield 3;
+ log.push("done");
+ };
+
+ (function() {
+ log = [];
+ var [a, b, c] = f();
+ assertSame(1, a);
+ assertSame(2, b);
+ assertSame(3, c);
+ assertArrayEquals(["1", "2", "3"], log);
+ }());
+
+ (function() {
+ log = [];
+ var [a, b, c, d] = f();
+ assertSame(1, a);
+ assertSame(2, b);
+ assertSame(3, c);
+ assertSame(undefined, d);
+ assertArrayEquals(["1", "2", "3", "done"], log);
+ }());
+
+ (function() {
+ log = [];
+ var [a, , c] = f();
+ assertSame(1, a);
+ assertSame(3, c);
+ assertArrayEquals(["1", "2", "3"], log);
+ }());
+
+ (function() {
+ log = [];
+ var [a, , c, d] = f();
+ assertSame(1, a);
+ assertSame(3, c);
+ assertSame(undefined, d);
+ assertArrayEquals(["1", "2", "3", "done"], log);
+ }());
+
+ (function() {
+ log = [];
+ // last comma is not an elision.
+ var [a, b,] = f();
+ assertSame(1, a);
+ assertSame(2, b);
+ assertArrayEquals(["1", "2"], log);
+ }());
+
+ (function() {
+ log = [];
+ // last comma is not an elision, but the comma before the last is.
+ var [a, b, ,] = f();
+ assertSame(1, a);
+ assertSame(2, b);
+ assertArrayEquals(["1", "2", "3"], log);
+ }());
+
+ (function() {
+ log = [];
+ var [a, ...rest] = f();
+ assertSame(1, a);
+ assertArrayEquals([2,3], rest);
+ assertArrayEquals(["1", "2", "3", "done"], log);
+ }());
+
+ (function() {
+ log = [];
+ var [a, b, c, ...rest] = f();
+ assertSame(1, a);
+ assertSame(2, b);
+ assertSame(3, c);
+ assertArrayEquals([], rest);
+ assertArrayEquals(["1", "2", "3", "done"], log);
+ }());
+
+ (function() {
+ log = [];
+ var [a, b, c, d, ...rest] = f();
+ assertSame(1, a);
+ assertSame(2, b);
+ assertSame(3, c);
+ assertSame(undefined, d);
+ assertArrayEquals([], rest);
+ assertArrayEquals(["1", "2", "3", "done"], log);
+ }());
+}());
+
+
+(function TestIteratorsLexical() {
+ 'use strict';
+ var log = [];
+ function* f() {
+ log.push("1");
+ yield 1;
+ log.push("2");
+ yield 2;
+ log.push("3");
+ yield 3;
+ log.push("done");
+ };
+
+ (function() {
+ log = [];
+ let [a, b, c] = f();
+ assertSame(1, a);
+ assertSame(2, b);
+ assertSame(3, c);
+ assertArrayEquals(["1", "2", "3"], log);
+ }());
+
+ (function() {
+ log = [];
+ let [a, b, c, d] = f();
+ assertSame(1, a);
+ assertSame(2, b);
+ assertSame(3, c);
+ assertSame(undefined, d);
+ assertArrayEquals(["1", "2", "3", "done"], log);
+ }());
+
+ (function() {
+ log = [];
+ let [a, , c] = f();
+ assertSame(1, a);
+ assertSame(3, c);
+ assertArrayEquals(["1", "2", "3"], log);
+ }());
+
+ (function() {
+ log = [];
+ let [a, , c, d] = f();
+ assertSame(1, a);
+ assertSame(3, c);
+ assertSame(undefined, d);
+ assertArrayEquals(["1", "2", "3", "done"], log);
+ }());
+
+ (function() {
+ log = [];
+ // last comma is not an elision.
+ let [a, b,] = f();
+ assertSame(1, a);
+ assertSame(2, b);
+ assertArrayEquals(["1", "2"], log);
+ }());
+
+ (function() {
+ log = [];
+ // last comma is not an elision, but the comma before the last is.
+ let [a, b, ,] = f();
+ assertSame(1, a);
+ assertSame(2, b);
+ assertArrayEquals(["1", "2", "3"], log);
+ }());
+
+ (function() {
+ log = [];
+ let [a, ...rest] = f();
+ assertSame(1, a);
+ assertArrayEquals([2,3], rest);
+ assertArrayEquals(["1", "2", "3", "done"], log);
+ }());
+
+ (function() {
+ log = [];
+ let [a, b, c, ...rest] = f();
+ assertSame(1, a);
+ assertSame(2, b);
+ assertSame(3, c);
+ assertArrayEquals([], rest);
+ assertArrayEquals(["1", "2", "3", "done"], log);
+ }());
+
+ (function() {
+ log = [];
+ let [a, b, c, d, ...rest] = f();
+ assertSame(1, a);
+ assertSame(2, b);
+ assertSame(3, c);
+ assertSame(undefined, d);
+ assertArrayEquals([], rest);
+ assertArrayEquals(["1", "2", "3", "done"], log);
+ }());
+}());
+
+(function TestIteratorsRecursive() {
+ var log = [];
+ function* f() {
+ log.push("1");
+ yield {x : 1, y : 2};
+ log.push("2");
+ yield [42, 27, 30];
+ log.push("3");
+ yield "abc";
+ log.push("done");
+ };
+
+ (function() {
+ var [{x, y}, [a, b]] = f();
+ assertSame(1, x);
+ assertSame(2, y);
+ assertSame(42, a);
+ assertSame(27, b);
+ assertArrayEquals(["1", "2"], log);
+ }());
+
+ (function() {
+ 'use strict';
+ log = [];
+ let [{x, y}, [a, b]] = f();
+ assertSame(1, x);
+ assertSame(2, y);
+ assertSame(42, a);
+ assertSame(27, b);
+ assertArrayEquals(["1", "2"], log);
+ }());
+}());
+
+
+(function TestForEachLexical() {
+ 'use strict';
+ let a = [{x:1, y:-1}, {x:2,y:-2}, {x:3,y:-3}];
+ let sumX = 0;
+ let sumY = 0;
+ let fs = [];
+ for (let {x,y} of a) {
+ sumX += x;
+ sumY += y;
+ fs.push({fx : function() { return x; }, fy : function() { return y }});
+ }
+ assertSame(6, sumX);
+ assertSame(-6, sumY);
+ assertSame(3, fs.length);
+ for (let i = 0; i < fs.length; i++) {
+ let {fx,fy} = fs[i];
+ assertSame(i+1, fx());
+ assertSame(-(i+1), fy());
+ }
+
+ var o = { __proto__:null, 'a1':1, 'b2':2 };
+ let sx = '';
+ let sy = '';
+ for (let [x,y] in o) {
+ sx += x;
+ sy += y;
+ }
+ assertEquals('ab', sx);
+ assertEquals('12', sy);
+}());
+
+
+(function TestForEachVars() {
+ var a = [{x:1, y:-1}, {x:2,y:-2}, {x:3,y:-3}];
+ var sumX = 0;
+ var sumY = 0;
+ var fs = [];
+ for (var {x,y} of a) {
+ sumX += x;
+ sumY += y;
+ fs.push({fx : function() { return x; }, fy : function() { return y }});
+ }
+ assertSame(6, sumX);
+ assertSame(-6, sumY);
+ assertSame(3, fs.length);
+ for (var i = 0; i < fs.length; i++) {
+ var {fx,fy} = fs[i];
+ assertSame(3, fx());
+ assertSame(-3, fy());
+ }
+
+ var o = { __proto__:null, 'a1':1, 'b2':2 };
+ var sx = '';
+ var sy = '';
+ for (var [x,y] in o) {
+ sx += x;
+ sy += y;
+ }
+ assertEquals('ab', sx);
+ assertEquals('12', sy);
+}());
+
+
+(function TestParameters() {
+ function f({a, b}) { return a - b; }
+ assertEquals(1, f({a : 6, b : 5}));
+
+ function f1(c, {a, b}) { return c + a - b; }
+ assertEquals(8, f1(7, {a : 6, b : 5}));
+
+ function f2({c, d}, {a, b}) { return c - d + a - b; }
+ assertEquals(7, f2({c : 7, d : 1}, {a : 6, b : 5}));
+
+ function f3([{a, b}]) { return a - b; }
+ assertEquals(1, f3([{a : 6, b : 5}]));
+
+ var g = ({a, b}) => { return a - b; };
+ assertEquals(1, g({a : 6, b : 5}));
+
+ var g1 = (c, {a, b}) => { return c + a - b; };
+ assertEquals(8, g1(7, {a : 6, b : 5}));
+
+ var g2 = ({c, d}, {a, b}) => { return c - d + a - b; };
+ assertEquals(7, g2({c : 7, d : 1}, {a : 6, b : 5}));
+
+ var g3 = ([{a, b}]) => { return a - b; };
+ assertEquals(1, g3([{a : 6, b : 5}]));
+}());
+
+
+(function TestDuplicatesInParameters() {
+ assertThrows("'use strict';function f(x,x){}", SyntaxError);
+ assertThrows("'use strict';function f({x,x}){}", SyntaxError);
+ assertThrows("'use strict';function f(x, {x}){}", SyntaxError);
+ assertThrows("'use strict';var f = (x,x) => {};", SyntaxError);
+ assertThrows("'use strict';var f = ({x,x}) => {};", SyntaxError);
+ assertThrows("'use strict';var f = (x, {x}) => {};", SyntaxError);
+
+ function ok(x) { var x; }; ok();
+ assertThrows("function f({x}) { var x; }; f({});", SyntaxError);
+ assertThrows("'use strict'; function f({x}) { let x = 0; }; f({});", SyntaxError);
+}());
+
+
+(function TestForInOfTDZ() {
+ assertThrows("'use strict'; let x = {}; for (let [x, y] of {x});", ReferenceError);
+ assertThrows("'use strict'; let x = {}; for (let [y, x] of {x});", ReferenceError);
+ assertThrows("'use strict'; let x = {}; for (let [x, y] in {x});", ReferenceError);
+ assertThrows("'use strict'; let x = {}; for (let [y, x] in {x});", ReferenceError);
+}());
diff --git a/deps/v8/test/mjsunit/harmony/new-target.js b/deps/v8/test/mjsunit/harmony/new-target.js
new file mode 100644
index 0000000000..587461a958
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/new-target.js
@@ -0,0 +1,370 @@
+// Copyright 2015 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-classes --harmony-new-target --harmony-reflect
+// Flags: --harmony-rest-parameters --harmony-arrow-functions
+
+
+(function TestClass() {
+ 'use strict';
+
+ var calls = 0;
+ class Base {
+ constructor(_) {
+ assertEquals(Base, new.target);
+ calls++;
+ }
+ }
+ assertInstanceof(new Base(1), Base);
+ assertInstanceof(new Base(1, 2), Base);
+ assertInstanceof(new Base(), Base);
+ assertEquals(3, calls);
+})();
+
+
+(function TestDerivedClass() {
+ 'use strict';
+
+ var calls = 0;
+ class Base {
+ constructor(expected) {
+ assertEquals(expected, new.target);
+ }
+ }
+ class Derived extends Base {
+ constructor(expected) {
+ super(expected);
+ assertEquals(expected, new.target);
+ calls++;
+ }
+ }
+ new Derived(Derived, 'extra');
+ new Derived(Derived);
+ assertEquals(2, calls);
+
+ class Derived2 extends Derived {}
+ calls = 0;
+ new Derived2(Derived2);
+ new Derived2(Derived2, 'extra');
+ assertEquals(2, calls);
+})();
+
+
+(function TestFunctionCall() {
+ var calls;
+ function f(expected) {
+ calls++;
+ assertEquals(expected, new.target);
+ }
+
+ calls = 0;
+ f(undefined);
+ f(undefined, 'extra');
+ f();
+ assertEquals(3, calls);
+
+ calls = 0;
+ f.call({}, undefined);
+ f.call({}, undefined, 'extra');
+ f.call({});
+ assertEquals(3, calls);
+
+ calls = 0;
+ f.apply({}, [undefined]);
+ f.apply({}, [undefined, 'extra']);
+ f.apply({}, []);
+ assertEquals(3, calls);
+})();
+
+
+(function TestFunctionConstruct() {
+ var calls;
+ function f(expected) {
+ calls++;
+ assertEquals(expected, new.target);
+ }
+
+ calls = 0;
+ new f(f);
+ new f(f, 'extra');
+ assertEquals(2, calls);
+})();
+
+
+(function TestClassExtendsFunction() {
+ 'use strict';
+
+ var calls = 0;
+ function f(expected) {
+ assertEquals(expected, new.target);
+ }
+ class Derived extends f {
+ constructor(expected) {
+ super(expected);
+ assertEquals(expected, new.target);
+ calls++;
+ }
+ }
+
+ new Derived(Derived);
+ new Derived(Derived, 'extra');
+ assertEquals(2, calls);
+})();
+
+
+(function TestFunctionReturnObject() {
+ function f(expected) {
+ assertEquals(expected, new.target);
+ return /abc/;
+ }
+
+ assertInstanceof(new f(f), RegExp);
+ assertInstanceof(new f(f, 'extra'), RegExp);
+
+ assertInstanceof(f(undefined), RegExp);
+ assertInstanceof(f(), RegExp);
+ assertInstanceof(f(undefined, 'extra'), RegExp);
+})();
+
+
+(function TestClassReturnObject() {
+ 'use strict';
+
+ class Base {
+ constructor(expected) {
+ assertEquals(expected, new.target);
+ return /abc/;
+ }
+ }
+
+ assertInstanceof(new Base(Base), RegExp);
+ assertInstanceof(new Base(Base, 'extra'), RegExp);
+
+ class Derived extends Base {}
+ assertInstanceof(new Derived(Derived), RegExp);
+ assertInstanceof(new Derived(Derived, 'extra'), RegExp);
+
+ class Derived2 extends Base {
+ constructor(expected) {
+ super(expected);
+ assertInstanceof(this, RegExp);
+ }
+ }
+ assertInstanceof(new Derived2(Derived2), RegExp);
+ assertInstanceof(new Derived2(Derived2, 'extra'), RegExp);
+})();
+
+
+(function TestReflectConstruct() {
+ var calls = 0;
+ function f(expected) {
+ calls++;
+ assertEquals(expected, new.target);
+ }
+
+ var o = Reflect.construct(f, [f]);
+ assertEquals(Object.getPrototypeOf(o), f.prototype);
+ o = Reflect.construct(f, [f, 'extra']);
+ assertEquals(Object.getPrototypeOf(o), f.prototype);
+ assertEquals(2, calls);
+
+ calls = 0;
+ o = Reflect.construct(f, [f], f);
+ assertEquals(Object.getPrototypeOf(o), f.prototype);
+ o = Reflect.construct(f, [f, 'extra'], f);
+ assertEquals(Object.getPrototypeOf(o), f.prototype);
+ assertEquals(2, calls);
+
+
+ function g() {}
+ calls = 0;
+ o = Reflect.construct(f, [g], g);
+ assertEquals(Object.getPrototypeOf(o), g.prototype);
+ o = Reflect.construct(f, [g, 'extra'], g);
+ assertEquals(Object.getPrototypeOf(o), g.prototype);
+ assertEquals(2, calls);
+})();
+
+
+(function TestRestParametersFunction() {
+ function f(...rest) {
+ assertEquals(rest[0], new.target);
+ }
+
+ assertInstanceof(new f(f), f);
+ assertInstanceof(new f(f, 'extra'), f);
+})();
+
+
+(function TestRestParametersClass() {
+ 'use strict';
+
+ class Base {
+ constructor(...rest) {
+ assertEquals(rest[0], new.target);
+ }
+ }
+
+ assertInstanceof(new Base(Base), Base);
+ assertInstanceof(new Base(Base, 'extra'), Base);
+
+ class Derived extends Base {}
+
+ assertInstanceof(new Derived(Derived), Derived);
+ assertInstanceof(new Derived(Derived, 'extra'), Derived);
+})();
+
+
+(function TestArrowFunction() {
+ function f(expected) {
+ (() => {
+ assertEquals(expected, new.target);
+ })();
+ }
+
+ assertInstanceof(new f(f), f);
+ assertInstanceof(new f(f, 'extra'), f);
+})();
+
+
+(function TestRestParametersClass() {
+ 'use strict';
+
+ class Base {
+ constructor(expected) {
+ (() => {
+ assertEquals(expected, new.target);
+ })();
+ }
+ }
+
+ assertInstanceof(new Base(Base), Base);
+ assertInstanceof(new Base(Base, 'extra'), Base);
+
+ class Derived extends Base {}
+
+ assertInstanceof(new Derived(Derived), Derived);
+ assertInstanceof(new Derived(Derived, 'extra'), Derived);
+})();
+
+
+(function TestSloppyArguments() {
+ var length, a0, a1, a2, nt;
+ function f(x) {
+ assertEquals(length, arguments.length);
+ assertEquals(a0, arguments[0]);
+ assertEquals(a1, arguments[1]);
+ assertEquals(a2, arguments[2]);
+ assertEquals(nt, new.target);
+
+ if (length > 0) {
+ x = 42;
+ assertEquals(42, x);
+ assertEquals(42, arguments[0]);
+
+ arguments[0] = 33;
+ assertEquals(33, x);
+ assertEquals(33, arguments[0]);
+ }
+ }
+
+ nt = f;
+ length = 0;
+ new f();
+
+ length = 1;
+ a0 = 1;
+ new f(1);
+
+ length = 2;
+ a0 = 1;
+ a1 = 2;
+ new f(1, 2);
+
+ length = 3;
+ a0 = 1;
+ a1 = 2;
+ a2 = 3;
+ new f(1, 2, 3);
+
+ nt = undefined;
+ a0 = a1 = a2 = undefined;
+ length = 0;
+ f();
+
+ length = 1;
+ a0 = 1;
+ f(1);
+
+ length = 2;
+ a0 = 1;
+ a1 = 2;
+ f(1, 2);
+
+ length = 3;
+ a0 = 1;
+ a1 = 2;
+ a2 = 3;
+ f(1, 2, 3);
+})();
+
+
+(function TestStrictArguments() {
+ var length, a0, a1, a2, nt;
+ function f(x) {
+ 'use strict';
+ assertEquals(length, arguments.length);
+ assertEquals(a0, arguments[0]);
+ assertEquals(a1, arguments[1]);
+ assertEquals(a2, arguments[2]);
+ assertEquals(nt, new.target);
+
+ if (length > 0) {
+ x = 42;
+ assertEquals(a0, arguments[0]);
+
+ arguments[0] = 33;
+ assertEquals(33, arguments[0]);
+ }
+ }
+
+ nt = f;
+ length = 0;
+ new f();
+
+ length = 1;
+ a0 = 1;
+ new f(1);
+
+ length = 2;
+ a0 = 1;
+ a1 = 2;
+ new f(1, 2);
+
+ length = 3;
+ a0 = 1;
+ a1 = 2;
+ a2 = 3;
+ new f(1, 2, 3);
+
+ nt = undefined;
+ a0 = a1 = a2 = undefined;
+ length = 0;
+ f();
+
+ length = 1;
+ a0 = 1;
+ f(1);
+
+ length = 2;
+ a0 = 1;
+ a1 = 2;
+ f(1, 2);
+
+ length = 3;
+ a0 = 1;
+ a1 = 2;
+ a2 = 3;
+ f(1, 2, 3);
+})();
diff --git a/deps/v8/test/mjsunit/harmony/object-literals-super.js b/deps/v8/test/mjsunit/harmony/object-literals-super.js
index c2d456c877..c6fb6334de 100644
--- a/deps/v8/test/mjsunit/harmony/object-literals-super.js
+++ b/deps/v8/test/mjsunit/harmony/object-literals-super.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-classes --allow-natives-syntax
+// Flags: --harmony-arrow-functions --allow-natives-syntax
(function TestHomeObject() {
@@ -131,3 +131,52 @@
assertEquals(42, o.g().next().value);
})();
+
+
+(function TestSuperPropertyInEval() {
+ var y = 3;
+ var p = {
+ m() { return 1; },
+ get x() { return 2; }
+ };
+ var o = {
+ __proto__: p,
+ evalM() {
+ assertEquals(1, eval('super.m()'));
+ },
+ evalX() {
+ assertEquals(2, eval('super.x'));
+ },
+ globalEval1() {
+ assertThrows('super.x', SyntaxError);
+ assertThrows('super.m()', SyntaxError);
+ },
+ globalEval2() {
+ super.x;
+ assertThrows('super.x', SyntaxError);
+ assertThrows('super.m()', SyntaxError);
+ }
+ };
+ o.evalM();
+ o.evalX();
+ o.globalEval1();
+ o.globalEval2();
+})();
+
+
+(function TestSuperPropertyInArrow() {
+ var y = 3;
+ var p = {
+ m() { return 1; },
+ get x() { return 2; }
+ };
+ var o = {
+ __proto__: p,
+ arrow() {
+ assertSame(super.x, (() => super.x)());
+ assertSame(super.m(), (() => super.m())());
+ return (() => super.m())();
+ }
+ };
+ assertSame(1, o.arrow());
+})();
diff --git a/deps/v8/test/mjsunit/harmony/private.js b/deps/v8/test/mjsunit/harmony/private.js
index c08daf1050..0adbb13b21 100644
--- a/deps/v8/test/mjsunit/harmony/private.js
+++ b/deps/v8/test/mjsunit/harmony/private.js
@@ -241,7 +241,8 @@ function TestKeyGet(obj) {
var obj2 = Object.create(obj)
for (var i in symbols) {
assertEquals(i|0, obj[symbols[i]])
- assertEquals(i|0, obj2[symbols[i]])
+ // Private symbols key own-properties.
+ assertEquals(undefined, obj2[symbols[i]])
}
}
@@ -352,3 +353,52 @@ function TestSealAndFreeze(freeze) {
TestSealAndFreeze(Object.seal)
TestSealAndFreeze(Object.freeze)
TestSealAndFreeze(Object.preventExtensions)
+
+
+var s = %CreatePrivateSymbol("s");
+var s1 = %CreatePrivateSymbol("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/harmony/proxies-for.js b/deps/v8/test/mjsunit/harmony/proxies-for.js
index d0f2a022fd..e98c34afe5 100644
--- a/deps/v8/test/mjsunit/harmony/proxies-for.js
+++ b/deps/v8/test/mjsunit/harmony/proxies-for.js
@@ -165,4 +165,19 @@ TestForInThrow(Proxy.create({
get: function(pr, pk) {
return function() { throw "myexn" }
}
-}))
+}));
+
+(function() {
+ var p = Proxy.create({enumerate:function() { return [0]; }});
+ var o = [0];
+ o.__proto__ = p;
+ var keys = [];
+ for (var k in o) { keys.push(k); };
+ assertEquals(["0"], keys);
+})();
+
+(function () {
+ var p = Proxy.create({getOwnPropertyNames:
+ function() { return [1, Symbol(), 2] }});
+ assertEquals(["1","2"], Object.getOwnPropertyNames(p));
+})();
diff --git a/deps/v8/test/mjsunit/harmony/proxies.js b/deps/v8/test/mjsunit/harmony/proxies.js
index 2500ecca85..585574eb43 100644
--- a/deps/v8/test/mjsunit/harmony/proxies.js
+++ b/deps/v8/test/mjsunit/harmony/proxies.js
@@ -29,8 +29,7 @@
// test enters an infinite recursion which goes through the runtime and we
// overflow the system stack before the simulator stack.
-// Flags: --harmony-proxies --sim-stack-size=500 --turbo-deoptimization
-// Flags: --allow-natives-syntax
+// Flags: --harmony-proxies --sim-stack-size=500 --allow-natives-syntax
// Helper.
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-4160.js b/deps/v8/test/mjsunit/harmony/regress/regress-4160.js
new file mode 100644
index 0000000000..b02daeed40
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/regress/regress-4160.js
@@ -0,0 +1,29 @@
+// Copyright 2015 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 --allow-natives-syntax
+
+(function(x) {
+ (function(x) {
+ var boom = (() => eval(x));
+ assertEquals(23, boom());
+ assertEquals(23, boom());
+ %OptimizeFunctionOnNextCall(boom);
+ assertEquals(23, boom());
+ assertEquals("23", x);
+ })("23");
+ assertEquals("42", x);
+})("42");
+
+(function(x) {
+ (function(x) {
+ var boom = (() => (eval("var x = 66"), x));
+ assertEquals(66, boom());
+ assertEquals(66, boom());
+ %OptimizeFunctionOnNextCall(boom);
+ assertEquals(66, boom());
+ assertEquals("23", x);
+ })("23");
+ assertEquals("42", x);
+})("42");
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-arrow-duplicate-params.js b/deps/v8/test/mjsunit/harmony/regress/regress-arrow-duplicate-params.js
new file mode 100644
index 0000000000..a43f022c02
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/regress/regress-arrow-duplicate-params.js
@@ -0,0 +1,7 @@
+// Copyright 2015 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
+
+assertThrows("(x, x, y) => 10;", SyntaxError);
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-crbug-451770.js b/deps/v8/test/mjsunit/harmony/regress/regress-crbug-451770.js
index 942814a316..eaf1d1961f 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-crbug-451770.js
+++ b/deps/v8/test/mjsunit/harmony/regress/regress-crbug-451770.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-computed-property-names --harmony-classes --harmony-sloppy
+// Flags: --harmony-computed-property-names --harmony-sloppy
assertThrows(function f() {
var t = { toString: function() { throw new Error(); } };
diff --git a/deps/v8/test/mjsunit/harmony/rest-params-lazy-parsing.js b/deps/v8/test/mjsunit/harmony/rest-params-lazy-parsing.js
index ba8e3008b9..b50a990f5c 100644
--- a/deps/v8/test/mjsunit/harmony/rest-params-lazy-parsing.js
+++ b/deps/v8/test/mjsunit/harmony/rest-params-lazy-parsing.js
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-rest-parameters --min-preparse-length=0
+// Flags: --harmony-rest-parameters --harmony-arrow-functions
+// Flags: --min-preparse-length=0
function variadic(co, ...values) {
var sum = 0;
@@ -12,6 +13,21 @@ function variadic(co, ...values) {
return sum;
}
+var arrowVariadic = (co, ...values) => {
+ var sum = 0;
+ while (values.length) {
+ sum += co * values.pop();
+ }
+ return sum;
+}
+
+assertEquals(1, variadic.length);
+assertEquals(1, arrowVariadic.length);
+
assertEquals(90, variadic(2, 1, 2, 3, 4, 5, 6, 7, 8, 9));
assertEquals(74, variadic(2, 1, 2, 3, 4, 5, 6, 7, 9));
assertEquals(110, variadic(2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
+
+assertEquals(90, arrowVariadic(2, 1, 2, 3, 4, 5, 6, 7, 8, 9));
+assertEquals(74, arrowVariadic(2, 1, 2, 3, 4, 5, 6, 7, 9));
+assertEquals(110, arrowVariadic(2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
diff --git a/deps/v8/test/mjsunit/harmony/rest-params.js b/deps/v8/test/mjsunit/harmony/rest-params.js
index 341cb33087..fe7ee2adb8 100644
--- a/deps/v8/test/mjsunit/harmony/rest-params.js
+++ b/deps/v8/test/mjsunit/harmony/rest-params.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-rest-parameters --harmony-classes
+// Flags: --harmony-rest-parameters
(function testRestIndex() {
assertEquals(5, (function(...args) { return args.length; })(1,2,3,4,5));
diff --git a/deps/v8/test/mjsunit/harmony/set-prototype-of.js b/deps/v8/test/mjsunit/harmony/set-prototype-of.js
index e06215a0ed..e92a0c37bc 100644
--- a/deps/v8/test/mjsunit/harmony/set-prototype-of.js
+++ b/deps/v8/test/mjsunit/harmony/set-prototype-of.js
@@ -139,6 +139,24 @@ function TestSetPrototypeOfNonExtensibleObject() {
TestSetPrototypeOfNonExtensibleObject();
+function TestSetPrototypeCyclic() {
+ var objects = [
+ Object.prototype, {},
+ Array.prototype, [],
+ Error.prototype, new TypeError,
+ // etc ...
+ ];
+ for (var i = 0; i < objects.length; i += 2) {
+ var object = objects[i];
+ var value = objects[i + 1];
+ assertThrows(function() {
+ Object.setPrototypeOf(object, value);
+ }, TypeError);
+ }
+}
+TestSetPrototypeCyclic();
+
+
function TestLookup() {
var object = {};
assertFalse('x' in object);
diff --git a/deps/v8/test/mjsunit/harmony/sharedarraybuffer.js b/deps/v8/test/mjsunit/harmony/sharedarraybuffer.js
new file mode 100644
index 0000000000..bac42681ab
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/sharedarraybuffer.js
@@ -0,0 +1,577 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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-sharedarraybuffer --harmony-tostring
+
+
+// SharedArrayBuffer
+
+function TestByteLength(param, expectedByteLength) {
+ var sab = new SharedArrayBuffer(param);
+ assertSame(expectedByteLength, sab.byteLength);
+}
+
+function TestArrayBufferCreation() {
+ TestByteLength(1, 1);
+ TestByteLength(256, 256);
+ TestByteLength(2.567, 2);
+
+ TestByteLength("abc", 0);
+
+ TestByteLength(0, 0);
+
+ assertThrows(function() { new SharedArrayBuffer(-10); }, RangeError);
+ assertThrows(function() { new SharedArrayBuffer(-2.567); }, RangeError);
+
+/* TODO[dslomov]: Reenable the test
+ assertThrows(function() {
+ var ab1 = new SharedArrayBuffer(0xFFFFFFFFFFFF)
+ }, RangeError);
+*/
+
+ var sab = new SharedArrayBuffer();
+ assertSame(0, sab.byteLength);
+ assertEquals("[object SharedArrayBuffer]",
+ Object.prototype.toString.call(sab));
+}
+
+TestArrayBufferCreation();
+
+function TestByteLengthNotWritable() {
+ var sab = new SharedArrayBuffer(1024);
+ assertSame(1024, sab.byteLength);
+
+ assertThrows(function() { "use strict"; sab.byteLength = 42; }, TypeError);
+}
+
+TestByteLengthNotWritable();
+
+function TestArrayBufferNoSlice() {
+ var sab = new SharedArrayBuffer(10);
+ assertEquals(undefined, sab.slice);
+}
+
+TestArrayBufferNoSlice();
+
+// Typed arrays using SharedArrayBuffers
+
+// TODO(binji): how many of these tests are necessary if there are no new
+// TypedArray types?
+
+function MakeSharedTypedArray(constr, numElements) {
+ var sab = new SharedArrayBuffer(constr.BYTES_PER_ELEMENT * numElements);
+ return new constr(sab);
+}
+
+function TestTypedArray(constr, elementSize, typicalElement) {
+ assertSame(elementSize, constr.BYTES_PER_ELEMENT);
+
+ var sab = new SharedArrayBuffer(256*elementSize);
+
+ var a0 = new constr(30);
+ assertEquals("[object " + constr.name + "]",
+ Object.prototype.toString.call(a0));
+
+ // TODO(binji): Should this return false here? It is a view, but it doesn't
+ // view a SharedArrayBuffer...
+ assertTrue(SharedArrayBuffer.isView(a0));
+ assertSame(elementSize, a0.BYTES_PER_ELEMENT);
+ assertSame(30, a0.length);
+ assertSame(30*elementSize, a0.byteLength);
+ assertSame(0, a0.byteOffset);
+ assertSame(30*elementSize, a0.buffer.byteLength);
+
+ var aOverBufferLen0 = new constr(sab, 128*elementSize, 0);
+ assertSame(sab, aOverBufferLen0.buffer);
+ assertSame(elementSize, aOverBufferLen0.BYTES_PER_ELEMENT);
+ assertSame(0, aOverBufferLen0.length);
+ assertSame(0, aOverBufferLen0.byteLength);
+ assertSame(128*elementSize, aOverBufferLen0.byteOffset);
+
+ var a1 = new constr(sab, 128*elementSize, 128);
+ assertSame(sab, a1.buffer);
+ assertSame(elementSize, a1.BYTES_PER_ELEMENT);
+ assertSame(128, a1.length);
+ assertSame(128*elementSize, a1.byteLength);
+ assertSame(128*elementSize, a1.byteOffset);
+
+
+ var a2 = new constr(sab, 64*elementSize, 128);
+ assertSame(sab, a2.buffer);
+ assertSame(elementSize, a2.BYTES_PER_ELEMENT);
+ assertSame(128, a2.length);
+ assertSame(128*elementSize, a2.byteLength);
+ assertSame(64*elementSize, a2.byteOffset);
+
+ var a3 = new constr(sab, 192*elementSize);
+ assertSame(sab, a3.buffer);
+ assertSame(64, a3.length);
+ assertSame(64*elementSize, a3.byteLength);
+ assertSame(192*elementSize, a3.byteOffset);
+
+ var a4 = new constr(sab);
+ assertSame(sab, a4.buffer);
+ assertSame(256, a4.length);
+ assertSame(256*elementSize, a4.byteLength);
+ assertSame(0, a4.byteOffset);
+
+
+ var i;
+ for (i = 0; i < 128; i++) {
+ a1[i] = typicalElement;
+ }
+
+ for (i = 0; i < 128; i++) {
+ assertSame(typicalElement, a1[i]);
+ }
+
+ for (i = 0; i < 64; i++) {
+ assertSame(0, a2[i]);
+ }
+
+ for (i = 64; i < 128; i++) {
+ assertSame(typicalElement, a2[i]);
+ }
+
+ for (i = 0; i < 64; i++) {
+ assertSame(typicalElement, a3[i]);
+ }
+
+ for (i = 0; i < 128; i++) {
+ assertSame(0, a4[i]);
+ }
+
+ for (i = 128; i < 256; i++) {
+ assertSame(typicalElement, a4[i]);
+ }
+
+ var aAtTheEnd = new constr(sab, 256*elementSize);
+ assertSame(elementSize, aAtTheEnd.BYTES_PER_ELEMENT);
+ assertSame(0, aAtTheEnd.length);
+ assertSame(0, aAtTheEnd.byteLength);
+ assertSame(256*elementSize, aAtTheEnd.byteOffset);
+
+ assertThrows(function () { new constr(sab, 257*elementSize); }, RangeError);
+ assertThrows(
+ function () { new constr(sab, 128*elementSize, 192); },
+ RangeError);
+
+ if (elementSize !== 1) {
+ assertThrows(function() { new constr(sab, 128*elementSize - 1, 10); },
+ RangeError);
+ var unalignedArrayBuffer = new SharedArrayBuffer(10*elementSize + 1);
+ var goodArray = new constr(unalignedArrayBuffer, 0, 10);
+ assertSame(10, goodArray.length);
+ assertSame(10*elementSize, goodArray.byteLength);
+ assertThrows(function() { new constr(unalignedArrayBuffer)}, RangeError);
+ assertThrows(function() { new constr(unalignedArrayBuffer, 5*elementSize)},
+ RangeError);
+ }
+
+ var abLen0 = new SharedArrayBuffer(0);
+ var aOverAbLen0 = new constr(abLen0);
+ assertSame(abLen0, aOverAbLen0.buffer);
+ assertSame(elementSize, aOverAbLen0.BYTES_PER_ELEMENT);
+ assertSame(0, aOverAbLen0.length);
+ assertSame(0, aOverAbLen0.byteLength);
+ assertSame(0, aOverAbLen0.byteOffset);
+
+ var a = new constr(sab, 64*elementSize, 128);
+ assertEquals("[object " + constr.name + "]",
+ Object.prototype.toString.call(a));
+ var desc = Object.getOwnPropertyDescriptor(
+ constr.prototype, Symbol.toStringTag);
+ assertTrue(desc.configurable);
+ assertFalse(desc.enumerable);
+ assertFalse(!!desc.writable);
+ assertFalse(!!desc.set);
+ assertEquals("function", typeof desc.get);
+}
+
+TestTypedArray(Uint8Array, 1, 0xFF);
+TestTypedArray(Int8Array, 1, -0x7F);
+TestTypedArray(Uint16Array, 2, 0xFFFF);
+TestTypedArray(Int16Array, 2, -0x7FFF);
+TestTypedArray(Uint32Array, 4, 0xFFFFFFFF);
+TestTypedArray(Int32Array, 4, -0x7FFFFFFF);
+TestTypedArray(Float32Array, 4, 0.5);
+TestTypedArray(Float64Array, 8, 0.5);
+TestTypedArray(Uint8ClampedArray, 1, 0xFF);
+
+
+function SubarrayTestCase(constructor, item, expectedResultLen,
+ expectedStartIndex, initialLen, start, end) {
+ var a = MakeSharedTypedArray(constructor, initialLen);
+ var s = a.subarray(start, end);
+ assertSame(constructor, s.constructor);
+ assertSame(expectedResultLen, s.length);
+ if (s.length > 0) {
+ s[0] = item;
+ assertSame(item, a[expectedStartIndex]);
+ }
+}
+
+function TestSubArray(constructor, item) {
+ SubarrayTestCase(constructor, item, 512, 512, 1024, 512, 1024);
+ SubarrayTestCase(constructor, item, 512, 512, 1024, 512);
+
+ SubarrayTestCase(constructor, item, 0, undefined, 0, 1, 20);
+ SubarrayTestCase(constructor, item, 100, 0, 100, 0, 100);
+ SubarrayTestCase(constructor, item, 100, 0, 100, 0, 1000);
+ SubarrayTestCase(constructor, item, 0, undefined, 100, 5, 1);
+
+ SubarrayTestCase(constructor, item, 1, 89, 100, -11, -10);
+ SubarrayTestCase(constructor, item, 9, 90, 100, -10, 99);
+ SubarrayTestCase(constructor, item, 0, undefined, 100, -10, 80);
+ SubarrayTestCase(constructor, item, 10,80, 100, 80, -10);
+
+ SubarrayTestCase(constructor, item, 10,90, 100, 90, "100");
+ SubarrayTestCase(constructor, item, 10,90, 100, "90", "100");
+
+ SubarrayTestCase(constructor, item, 0, undefined, 100, 90, "abc");
+ SubarrayTestCase(constructor, item, 10,0, 100, "abc", 10);
+
+ SubarrayTestCase(constructor, item, 10,0, 100, 0.96, 10.96);
+ SubarrayTestCase(constructor, item, 10,0, 100, 0.96, 10.01);
+ SubarrayTestCase(constructor, item, 10,0, 100, 0.01, 10.01);
+ SubarrayTestCase(constructor, item, 10,0, 100, 0.01, 10.96);
+
+
+ SubarrayTestCase(constructor, item, 10,90, 100, 90);
+ SubarrayTestCase(constructor, item, 10,90, 100, -10);
+}
+
+TestSubArray(Uint8Array, 0xFF);
+TestSubArray(Int8Array, -0x7F);
+TestSubArray(Uint16Array, 0xFFFF);
+TestSubArray(Int16Array, -0x7FFF);
+TestSubArray(Uint32Array, 0xFFFFFFFF);
+TestSubArray(Int32Array, -0x7FFFFFFF);
+TestSubArray(Float32Array, 0.5);
+TestSubArray(Float64Array, 0.5);
+TestSubArray(Uint8ClampedArray, 0xFF);
+
+function TestTypedArrayOutOfRange(constructor, value, result) {
+ var a = MakeSharedTypedArray(constructor, 1);
+ a[0] = value;
+ assertSame(result, a[0]);
+}
+
+TestTypedArrayOutOfRange(Uint8Array, 0x1FA, 0xFA);
+TestTypedArrayOutOfRange(Uint8Array, -1, 0xFF);
+
+TestTypedArrayOutOfRange(Int8Array, 0x1FA, 0x7A - 0x80);
+
+TestTypedArrayOutOfRange(Uint16Array, 0x1FFFA, 0xFFFA);
+TestTypedArrayOutOfRange(Uint16Array, -1, 0xFFFF);
+TestTypedArrayOutOfRange(Int16Array, 0x1FFFA, 0x7FFA - 0x8000);
+
+TestTypedArrayOutOfRange(Uint32Array, 0x1FFFFFFFA, 0xFFFFFFFA);
+TestTypedArrayOutOfRange(Uint32Array, -1, 0xFFFFFFFF);
+TestTypedArrayOutOfRange(Int32Array, 0x1FFFFFFFA, 0x7FFFFFFA - 0x80000000);
+
+TestTypedArrayOutOfRange(Uint8ClampedArray, 0x1FA, 0xFF);
+TestTypedArrayOutOfRange(Uint8ClampedArray, -1, 0);
+
+var typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array];
+
+function TestPropertyTypeChecks(constructor) {
+ function CheckProperty(name) {
+ var d = Object.getOwnPropertyDescriptor(constructor.prototype, name);
+ var o = {};
+ assertThrows(function() {d.get.call(o);}, TypeError);
+ for (var i = 0; i < typedArrayConstructors.length; i++) {
+ var ctor = typedArrayConstructors[i];
+ var a = MakeSharedTypedArray(ctor, 10);
+ if (ctor === constructor) {
+ d.get.call(a); // shouldn't throw
+ } else {
+ assertThrows(function() {d.get.call(a);}, TypeError);
+ }
+ }
+ }
+
+ CheckProperty("buffer");
+ CheckProperty("byteOffset");
+ CheckProperty("byteLength");
+ CheckProperty("length");
+}
+
+for(i = 0; i < typedArrayConstructors.length; i++) {
+ TestPropertyTypeChecks(typedArrayConstructors[i]);
+}
+
+function TestTypedArraySet() {
+ // Test array.set in different combinations.
+
+ function assertArrayPrefix(expected, array) {
+ for (var i = 0; i < expected.length; ++i) {
+ assertEquals(expected[i], array[i]);
+ }
+ }
+
+ // SharedTypedArrays don't allow initialization via array-like
+ function initializeFromArray(constructor, array) {
+ var buffer = MakeSharedTypedArray(constructor, array.length);
+ for (var i = 0; i < array.length; ++i) {
+ buffer[i] = array[i];
+ }
+ return buffer;
+ }
+
+ var a11 = initializeFromArray(Int16Array, [1, 2, 3, 4, 0, -1])
+ var a12 = MakeSharedTypedArray(Uint16Array, 15);
+ a12.set(a11, 3)
+ assertArrayPrefix([0, 0, 0, 1, 2, 3, 4, 0, 0xffff, 0, 0], a12)
+ assertThrows(function(){ a11.set(a12) })
+
+ var a21 = [1, undefined, 10, NaN, 0, -1, {valueOf: function() {return 3}}]
+ var a22 = MakeSharedTypedArray(Int32Array, 12)
+ a22.set(a21, 2)
+ assertArrayPrefix([0, 0, 1, 0, 10, 0, 0, -1, 3, 0], a22)
+
+ var a31 = initializeFromArray(Float32Array, [2, 4, 6, 8, 11, NaN, 1/0, -3])
+ var a32 = a31.subarray(2, 6)
+ a31.set(a32, 4)
+ assertArrayPrefix([2, 4, 6, 8, 6, 8, 11, NaN], a31)
+ assertArrayPrefix([6, 8, 6, 8], a32)
+
+ var a4 = initializeFromArray(Uint8ClampedArray, [3,2,5,6])
+ a4.set(a4)
+ assertArrayPrefix([3, 2, 5, 6], a4)
+
+ // Cases with overlapping backing store but different element sizes.
+ var b = new SharedArrayBuffer(4)
+ var a5 = new Int16Array(b)
+ var a50 = new Int8Array(b)
+ var a51 = new Int8Array(b, 0, 2)
+ var a52 = new Int8Array(b, 1, 2)
+ var a53 = new Int8Array(b, 2, 2)
+
+ a5.set([0x5050, 0x0a0a])
+ assertArrayPrefix([0x50, 0x50, 0x0a, 0x0a], a50)
+ assertArrayPrefix([0x50, 0x50], a51)
+ assertArrayPrefix([0x50, 0x0a], a52)
+ assertArrayPrefix([0x0a, 0x0a], a53)
+
+ a50.set([0x50, 0x50, 0x0a, 0x0a])
+ a51.set(a5)
+ assertArrayPrefix([0x50, 0x0a, 0x0a, 0x0a], a50)
+
+ a50.set([0x50, 0x50, 0x0a, 0x0a])
+ a52.set(a5)
+ assertArrayPrefix([0x50, 0x50, 0x0a, 0x0a], a50)
+
+ a50.set([0x50, 0x50, 0x0a, 0x0a])
+ a53.set(a5)
+ assertArrayPrefix([0x50, 0x50, 0x50, 0x0a], a50)
+
+ a50.set([0x50, 0x51, 0x0a, 0x0b])
+ a5.set(a51)
+ assertArrayPrefix([0x0050, 0x0051], a5)
+
+ a50.set([0x50, 0x51, 0x0a, 0x0b])
+ a5.set(a52)
+ assertArrayPrefix([0x0051, 0x000a], a5)
+
+ a50.set([0x50, 0x51, 0x0a, 0x0b])
+ a5.set(a53)
+ assertArrayPrefix([0x000a, 0x000b], a5)
+
+ // Mixed types of same size.
+ var a61 = initializeFromArray(Float32Array, [1.2, 12.3])
+ var a62 = MakeSharedTypedArray(Int32Array, 2)
+ a62.set(a61)
+ assertArrayPrefix([1, 12], a62)
+ a61.set(a62)
+ assertArrayPrefix([1, 12], a61)
+
+ // Invalid source
+ var a = MakeSharedTypedArray(Uint16Array, 50);
+ var expected = [];
+ for (i = 0; i < 50; i++) {
+ a[i] = i;
+ expected.push(i);
+ }
+ a.set({});
+ assertArrayPrefix(expected, a);
+ assertThrows(function() { a.set.call({}) }, TypeError);
+ assertThrows(function() { a.set.call([]) }, TypeError);
+
+ assertThrows(function() { a.set(0); }, TypeError);
+ assertThrows(function() { a.set(0, 1); }, TypeError);
+}
+
+TestTypedArraySet();
+
+function TestTypedArraysWithIllegalIndices() {
+ var a = MakeSharedTypedArray(Int32Array, 100);
+
+ a[-10] = 10;
+ assertEquals(undefined, a[-10]);
+ a["-10"] = 10;
+ assertEquals(undefined, a["-10"]);
+
+ var s = " -10";
+ a[s] = 10;
+ assertEquals(10, a[s]);
+ var s1 = " -10 ";
+ a[s] = 10;
+ assertEquals(10, a[s]);
+
+ a["-1e2"] = 10;
+ assertEquals(10, a["-1e2"]);
+ assertEquals(undefined, a[-1e2]);
+
+ a["-0"] = 256;
+ var s2 = " -0";
+ a[s2] = 255;
+ assertEquals(undefined, a["-0"]);
+ assertEquals(255, a[s2]);
+ assertEquals(0, a[-0]);
+
+ /* Chromium bug: 424619
+ * a[-Infinity] = 50;
+ * assertEquals(undefined, a[-Infinity]);
+ */
+ a[1.5] = 10;
+ assertEquals(undefined, a[1.5]);
+ var nan = Math.sqrt(-1);
+ a[nan] = 5;
+ assertEquals(undefined, a[nan]);
+
+ var x = 0;
+ var y = -0;
+ assertEquals(Infinity, 1/x);
+ assertEquals(-Infinity, 1/y);
+ a[x] = 5;
+ a[y] = 27;
+ assertEquals(27, a[x]);
+ assertEquals(27, a[y]);
+}
+
+TestTypedArraysWithIllegalIndices();
+
+function TestTypedArraysWithIllegalIndicesStrict() {
+ 'use strict';
+ var a = MakeSharedTypedArray(Int32Array, 100);
+
+ a[-10] = 10;
+ assertEquals(undefined, a[-10]);
+ a["-10"] = 10;
+ assertEquals(undefined, a["-10"]);
+
+ var s = " -10";
+ a[s] = 10;
+ assertEquals(10, a[s]);
+ var s1 = " -10 ";
+ a[s] = 10;
+ assertEquals(10, a[s]);
+
+ a["-1e2"] = 10;
+ assertEquals(10, a["-1e2"]);
+ assertEquals(undefined, a[-1e2]);
+
+ a["-0"] = 256;
+ var s2 = " -0";
+ a[s2] = 255;
+ assertEquals(undefined, a["-0"]);
+ assertEquals(255, a[s2]);
+ assertEquals(0, a[-0]);
+
+ /* Chromium bug: 424619
+ * a[-Infinity] = 50;
+ * assertEquals(undefined, a[-Infinity]);
+ */
+ a[1.5] = 10;
+ assertEquals(undefined, a[1.5]);
+ var nan = Math.sqrt(-1);
+ a[nan] = 5;
+ assertEquals(undefined, a[nan]);
+
+ var x = 0;
+ var y = -0;
+ assertEquals(Infinity, 1/x);
+ assertEquals(-Infinity, 1/y);
+ a[x] = 5;
+ a[y] = 27;
+ assertEquals(27, a[x]);
+ assertEquals(27, a[y]);
+}
+
+TestTypedArraysWithIllegalIndicesStrict();
+
+// General tests for properties
+
+// Test property attribute [[Enumerable]]
+function TestEnumerable(func, obj) {
+ function props(x) {
+ var array = [];
+ for (var p in x) array.push(p);
+ return array.sort();
+ }
+ assertArrayEquals([], props(func));
+ assertArrayEquals([], props(func.prototype));
+ if (obj)
+ assertArrayEquals([], props(obj));
+}
+TestEnumerable(ArrayBuffer, new SharedArrayBuffer());
+for(i = 0; i < typedArrayConstructors.length; i++) {
+ TestEnumerable(typedArrayConstructors[i]);
+}
+
+// Test arbitrary properties on ArrayBuffer
+function TestArbitrary(m) {
+ function TestProperty(map, property, value) {
+ map[property] = value;
+ assertEquals(value, map[property]);
+ }
+ for (var i = 0; i < 20; i++) {
+ TestProperty(m, 'key' + i, 'val' + i);
+ TestProperty(m, 'foo' + i, 'bar' + i);
+ }
+}
+TestArbitrary(new SharedArrayBuffer(256));
+for(i = 0; i < typedArrayConstructors.length; i++) {
+ TestArbitrary(MakeSharedTypedArray(typedArrayConstructors[i], 10));
+}
+
+// Test direct constructor call
+assertThrows(function() { SharedArrayBuffer(); }, TypeError);
+for(i = 0; i < typedArrayConstructors.length; i++) {
+ assertThrows(function(i) { typedArrayConstructors[i](); }.bind(this, i),
+ TypeError);
+}
diff --git a/deps/v8/test/mjsunit/harmony/spread-array.js b/deps/v8/test/mjsunit/harmony/spread-array.js
new file mode 100644
index 0000000000..18b72a28c5
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/spread-array.js
@@ -0,0 +1,179 @@
+// Copyright 2015 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-spread-arrays --allow-natives-syntax
+
+(function TestBasics() {
+ var a = [1, 2];
+ var b = [...a];
+ assertArrayEquals([1, 2], b)
+
+ assertArrayEquals(['a', 'b', 'c', 'd', 'e', 'f'],
+ ['a', ...'bc', 'd', ...'ef'])
+})();
+
+
+var log = [];
+
+function* gen(n) {
+ log.push(n, 1);
+ yield 1;
+ log.push(n, 2);
+ yield 2;
+ log.push(n, 3);
+ yield 3;
+ log.push(n, 'done');
+}
+
+function id(v) {
+ log.push(v);
+ return v;
+}
+
+
+(function TestGenerator() {
+ assertArrayEquals([1, 2, 3], [...gen('a')]);
+ assertArrayEquals(['x', 1, 2, 3, 'y', 1, 2, 3, 'z'],
+ ['x', ...gen('a'), 'y', ...gen('b'), 'z']);
+})();
+
+
+(function TestOrderOfExecution() {
+ log = [];
+ assertArrayEquals(['x', 1, 2, 3, 'y', 1, 2, 3, 'z'],
+ [id('x'), ...gen('a'), id('y'), ...gen('b'), id('z')]);
+ assertArrayEquals([
+ 'x', 'a', 1, 'a', 2, 'a', 3, 'a', 'done',
+ 'y', 'b', 1, 'b', 2, 'b', 3, 'b', 'done',
+ 'z'
+ ], log);
+})();
+
+
+(function TestNotIterable() {
+ var a;
+ assertThrows(function() {
+ a = [...42];
+ }, TypeError);
+ assertSame(undefined, a);
+
+
+})();
+
+
+(function TestInvalidIterator() {
+ var iter = {
+ [Symbol.iterator]: 42
+ };
+ var a;
+ assertThrows(function() {
+ a = [...iter];
+ }, TypeError);
+ assertSame(undefined, a);
+})();
+
+
+(function TestIteratorNotAnObject() {
+ var iter = {
+ [Symbol.iterator]() {
+ return 42;
+ }
+ };
+ var a;
+ assertThrows(function() {
+ a = [...iter];
+ }, TypeError);
+ assertSame(undefined, a);
+})();
+
+
+(function TestIteratorNoNext() {
+ var iter = {
+ [Symbol.iterator]() {
+ return {};
+ }
+ };
+ var a;
+ assertThrows(function() {
+ a = [...iter];
+ }, TypeError);
+ assertSame(undefined, a);
+})();
+
+
+(function TestIteratorResultDoneThrows() {
+ function MyError() {}
+ var iter = {
+ [Symbol.iterator]() {
+ return {
+ next() {
+ return {
+ get done() {
+ throw new MyError();
+ }
+ }
+ }
+ };
+ }
+ };
+ var a;
+ assertThrows(function() {
+ a = [...iter];
+ }, MyError);
+ assertSame(undefined, a);
+})();
+
+
+(function TestIteratorResultValueThrows() {
+ function MyError() {}
+ var iter = {
+ [Symbol.iterator]() {
+ return {
+ next() {
+ return {
+ done: false,
+ get value() {
+ throw new MyError();
+ }
+ }
+ }
+ };
+ }
+ };
+ var a;
+ assertThrows(function() {
+ a = [...iter];
+ }, MyError);
+ assertSame(undefined, a);
+})();
+
+
+(function TestOptimize() {
+ function f() {
+ return [...'abc'];
+ }
+ assertArrayEquals(['a', 'b', 'c'], f());
+ %OptimizeFunctionOnNextCall(f);
+ assertArrayEquals(['a', 'b', 'c'], f());
+})();
+
+
+(function TestDeoptimize() {
+ var iter = {
+ [Symbol.iterator]() {
+ var i = 0;
+ return {
+ next() {
+ $DeoptimizeFunction(f);
+ return {value: ++i, done: i === 3};
+ }
+ };
+ }
+ };
+ function f() {
+ return [0, ...iter];
+ }
+
+ assertArrayEquals([0, 1, 2], f());
+});
diff --git a/deps/v8/test/mjsunit/harmony/spread-call-super-property.js b/deps/v8/test/mjsunit/harmony/spread-call-super-property.js
new file mode 100644
index 0000000000..cdf6f2e242
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/spread-call-super-property.js
@@ -0,0 +1,20 @@
+// Copyright 2015 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-spreadcalls --harmony-sloppy --harmony-rest-parameters
+
+(function testCallSuperProperty() {
+ class BaseClass {
+ strict_method(...args) { "use strict"; return [this].concat(args); }
+ sloppy_method(...args) { return [this].concat(args); }
+ }
+ class SubClass extends BaseClass {
+ strict_m(...args) { return super.strict_method(...args); }
+ sloppy_m(...args) { return super.sloppy_method(...args); }
+ }
+
+ var c = new SubClass();
+ assertEquals([c, 1, 2, 3, 4, 5], c.strict_m(1, 2, 3, 4, 5));
+ assertEquals([c, 1, 2, 3, 4, 5], c.sloppy_m(1, 2, 3, 4, 5));
+})();
diff --git a/deps/v8/test/mjsunit/harmony/super.js b/deps/v8/test/mjsunit/harmony/super.js
index 988cef22e2..21b31d96c9 100644
--- a/deps/v8/test/mjsunit/harmony/super.js
+++ b/deps/v8/test/mjsunit/harmony/super.js
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-classes --allow-natives-syntax
+// Flags: --harmony-arrow-functions --allow-natives-syntax
+// Flags: --harmony-spreadcalls
(function TestSuperNamedLoads() {
function Base() { }
@@ -2053,6 +2054,7 @@ TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44);
assertInstanceof(f, Number);
}());
+
(function TestSuperCallErrorCases() {
'use strict';
class T extends Object {
@@ -2064,3 +2066,150 @@ TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44);
T.__proto__ = null;
assertThrows(function() { new T(); }, TypeError);
}());
+
+
+(function TestSuperPropertyInEval() {
+ 'use strict';
+ let y = 3;
+ class Base {
+ m() { return 1; }
+ get x() { return 2; }
+ }
+ class Derived extends Base {
+ evalM() {
+ assertEquals(1, eval('super.m()'));
+ }
+ evalX() {
+ assertEquals(2, eval('super.x'));
+ }
+ globalEval1() {
+ assertThrows('super.x', SyntaxError);
+ assertThrows('super.m()', SyntaxError);
+ }
+ globalEval2() {
+ super.x;
+ assertThrows('super.x', SyntaxError);
+ assertThrows('super.m()', SyntaxError);
+ }
+ }
+ let d = new Derived();
+ d.globalEval1();
+ d.globalEval2();
+ d.evalM();
+ d.evalX();
+})();
+
+
+(function TestSuperPropertyInArrow() {
+ 'use strict';
+ let y = 3;
+ class Base {
+ m() { return 1; }
+ get x() { return 2; }
+ }
+ class Derived extends Base {
+ arrow() {
+ assertSame(super.x, (() => super.x)());
+ assertSame(super.m(), (() => super.m())());
+ return (() => super.m())();
+ }
+ }
+ let d = new Derived();
+ assertSame(1, d.arrow());
+})();
+
+
+(function TestSuperCallInEval() {
+ 'use strict';
+ class Base {
+ constructor(x) {
+ this.x = x;
+ }
+ }
+ class Derived extends Base {
+ constructor(x) {
+ eval('super(x)');
+ }
+ }
+ let d = new Derived(42);
+ assertSame(42, d.x);
+})();
+
+
+(function TestSuperCallInArrow() {
+ 'use strict';
+ class Base {
+ constructor(x) {
+ this.x = x;
+ }
+ }
+ class Derived extends Base {
+ constructor(x) {
+ (() => super(x))();
+ }
+ }
+ let d = new Derived(42);
+ assertSame(42, d.x);
+})();
+
+
+(function TestSuperCallEscapes() {
+ 'use strict';
+ class Base {
+ constructor(x) {
+ this.x = x;
+ }
+ }
+
+ let f;
+ class Derived extends Base {
+ constructor() {
+ f = () => super(2);
+ }
+ }
+ assertThrows(function() {
+ new Derived();
+ }, ReferenceError);
+
+ let o = f();
+ assertEquals(2, o.x);
+ assertInstanceof(o, Derived);
+
+ assertThrows(function() {
+ f();
+ }, ReferenceError);
+})();
+
+
+(function TestSuperCallSpreadInEval() {
+ 'use strict';
+ class Base {
+ constructor(x) {
+ this.x = x;
+ }
+ }
+ class Derived extends Base {
+ constructor(x) {
+ eval('super(...[x])');
+ }
+ }
+ let d = new Derived(42);
+ assertSame(42, d.x);
+})();
+
+
+(function TestSuperCallSpreadInArrow() {
+ 'use strict';
+ class Base {
+ constructor(x) {
+ this.x = x;
+ }
+ }
+ class Derived extends Base {
+ constructor(x) {
+ (() => super(...[x]))();
+ }
+ }
+ let d = new Derived(42);
+ assertSame(42, d.x);
+})();
diff --git a/deps/v8/test/mjsunit/has-own-property-evaluation-order.js b/deps/v8/test/mjsunit/has-own-property-evaluation-order.js
new file mode 100644
index 0000000000..ae02180396
--- /dev/null
+++ b/deps/v8/test/mjsunit/has-own-property-evaluation-order.js
@@ -0,0 +1,13 @@
+// Copyright 2015 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 MyError() {}
+
+assertThrows(function() {
+ Object.prototype.hasOwnProperty.call(null, {
+ toString() {
+ throw new MyError();
+ }
+ });
+}, MyError);
diff --git a/deps/v8/test/mjsunit/json-replacer-number-wrapper-tostring.js b/deps/v8/test/mjsunit/json-replacer-number-wrapper-tostring.js
new file mode 100644
index 0000000000..b4ef7923cf
--- /dev/null
+++ b/deps/v8/test/mjsunit/json-replacer-number-wrapper-tostring.js
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+// http://ecma-international.org/ecma-262/6.0/#sec-json.stringify
+// Step 4.b.iii.5.f.i
+
+var calls = 0;
+
+var num = new Number;
+num.toString = function() {
+ calls++;
+ return '';
+};
+num.valueOf = function() {
+ assertUnreachable();
+};
+
+JSON.stringify('', [num]);
+assertEquals(1, calls);
diff --git a/deps/v8/test/mjsunit/json-replacer-order.js b/deps/v8/test/mjsunit/json-replacer-order.js
new file mode 100644
index 0000000000..8cb64414e7
--- /dev/null
+++ b/deps/v8/test/mjsunit/json-replacer-order.js
@@ -0,0 +1,26 @@
+// Copyright 2015 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.
+
+// http://ecma-international.org/ecma-262/6.0/#sec-json.stringify
+// Step 4.b.iii.5.f.i
+
+var log = [];
+
+var replacer = Object.defineProperty([], 0, {
+ get() {
+ log.push('get 0');
+ }
+});
+var space = Object.defineProperty(new String, 'toString', {
+ value() {
+ log.push('toString');
+ return '';
+ }
+});
+
+JSON.stringify('', replacer, space);
+
+assertEquals(2, log.length);
+assertEquals('get 0', log[0]);
+assertEquals('toString', log[1]);
diff --git a/deps/v8/test/mjsunit/math-abs.js b/deps/v8/test/mjsunit/math-abs.js
index b90ae0917c..4fb72baaa9 100644
--- a/deps/v8/test/mjsunit/math-abs.js
+++ b/deps/v8/test/mjsunit/math-abs.js
@@ -120,3 +120,19 @@ assertEquals(1, foo2());
assertEquals(1, foo2());
%OptimizeFunctionOnNextCall(foo2);
assertEquals(1, foo2());
+
+// Regression test for Integer input of Math.abs on mips64.
+function absHalf(bits) {
+ var x = 1 << (bits - 1);
+ var half = Math.abs(x);
+ return half;
+
+}
+
+// Create minimum integer input for abs() using bitwise operations
+// that should overflow.
+bits = 32;
+assertEquals(2147483648, absHalf(bits));
+assertEquals(2147483648, absHalf(bits));
+%OptimizeFunctionOnNextCall(absHalf);
+assertEquals(2147483648, absHalf(bits));
diff --git a/deps/v8/test/mjsunit/math-floor-negative.js b/deps/v8/test/mjsunit/math-floor-negative.js
index 4cabff577e..e39d5ade4b 100644
--- a/deps/v8/test/mjsunit/math-floor-negative.js
+++ b/deps/v8/test/mjsunit/math-floor-negative.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: --noenable_sse4_1 --allow-natives-syntax
+// Flags: --noenable-sse4-1 --allow-natives-syntax
function test1() {
// Trigger overflow when converting/truncating double to integer.
diff --git a/deps/v8/test/mjsunit/math-floor-of-div-minus-zero.js b/deps/v8/test/mjsunit/math-floor-of-div-minus-zero.js
index 269e96f50b..de0e90bcec 100644
--- a/deps/v8/test/mjsunit/math-floor-of-div-minus-zero.js
+++ b/deps/v8/test/mjsunit/math-floor-of-div-minus-zero.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 --nouse_inlining
+// Flags: --allow-natives-syntax --nouse-inlining
// Test for negative zero that doesn't need bail out
diff --git a/deps/v8/test/mjsunit/math-floor-of-div-nosudiv.js b/deps/v8/test/mjsunit/math-floor-of-div-nosudiv.js
index 3ce966cb29..bf7a4ce38a 100644
--- a/deps/v8/test/mjsunit/math-floor-of-div-nosudiv.js
+++ b/deps/v8/test/mjsunit/math-floor-of-div-nosudiv.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 --nouse_inlining --noenable_sudiv
+// Flags: --allow-natives-syntax --nouse-inlining --noenable-sudiv
// Use this function as reference. Make sure it is not inlined.
function div(a, b) {
diff --git a/deps/v8/test/mjsunit/math-floor-of-div.js b/deps/v8/test/mjsunit/math-floor-of-div.js
index 707f65714e..9769561c1c 100644
--- a/deps/v8/test/mjsunit/math-floor-of-div.js
+++ b/deps/v8/test/mjsunit/math-floor-of-div.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 --nouse_inlining --enable_sudiv
+// Flags: --allow-natives-syntax --nouse-inlining --enable-sudiv
// Use this function as reference. Make sure it is not inlined.
function div(a, b) {
diff --git a/deps/v8/test/mjsunit/messages.js b/deps/v8/test/mjsunit/messages.js
index 73cc15ac40..c30e59f3e1 100644
--- a/deps/v8/test/mjsunit/messages.js
+++ b/deps/v8/test/mjsunit/messages.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
// Flags: --stack-size=100 --harmony --harmony-reflect --harmony-arrays
-// Flags: --harmony-regexps
+// Flags: --harmony-regexps --strong-mode
function test(f, expected, type) {
try {
@@ -62,11 +62,30 @@ test(function() {
Array.prototype.shift.call(null);
}, "Array.prototype.shift called on null or undefined", TypeError);
+// kCannotPreventExtExternalArray
+test(function() {
+ Object.preventExtensions(new Uint16Array(1));
+}, "Cannot prevent extension of an object with external array elements", TypeError);
+
+// kConstAssign
+test(function() {
+ "use strict";
+ const a = 1;
+ a = 2;
+}, "Assignment to constant variable.", TypeError);
+
// kCannotConvertToPrimitive
test(function() {
[].join(Object(Symbol(1)));
}, "Cannot convert object to primitive value", TypeError);
+// kCircularStructure
+test(function() {
+ var o = {};
+ o.o = o;
+ JSON.stringify(o);
+}, "Converting circular structure to JSON", TypeError);
+
// kConstructorNotFunction
test(function() {
Uint16Array(1);
@@ -160,6 +179,11 @@ test(function() {
new Symbol();
}, "Symbol is not a constructor", TypeError);
+// kNotDateObject
+test(function() {
+ Date.prototype.setHours.call(1);
+}, "this is not a Date object.", TypeError);
+
// kNotGeneric
test(function() {
String.prototype.toString.call(1);
@@ -204,6 +228,14 @@ test(function() {
Object.defineProperty({}, "x", { get: 1 });
}, "Getter must be a function: 1", TypeError);
+// kObjectNotExtensible
+test(function() {
+ "use strict";
+ var o = {};
+ Object.freeze(o);
+ o.a = 1;
+}, "Can't add property a, object is not extensible", TypeError);
+
// kObjectSetterExpectingFunction
test(function() {
({}).__defineSetter__("x", 0);
@@ -248,6 +280,34 @@ test(function() {
new Promise(1);
}, "Promise resolver 1 is not a function", TypeError);
+// kStrictDeleteProperty
+test(function() {
+ "use strict";
+ var o = {};
+ Object.defineProperty(o, "p", { value: 1, writable: false });
+ delete o.p;
+}, "Cannot delete property 'p' of #<Object>", TypeError);
+
+// kStrictPoisonPill
+test(function() {
+ "use strict";
+ arguments.callee;
+}, "'caller', 'callee', and 'arguments' properties may not be accessed on " +
+ "strict mode functions or the arguments objects for calls to them",
+ TypeError);
+
+// kStrictReadOnlyProperty
+test(function() {
+ "use strict";
+ (1).a = 1;
+}, "Cannot assign to read only property 'a' of 1", TypeError);
+
+// kStrongImplicitCast
+test(function() {
+ "use strong";
+ "a" + 1;
+}, "In strong mode, implicit conversions are deprecated", TypeError);
+
// kSymbolToPrimitive
test(function() {
1 + Object(Symbol());
@@ -293,15 +353,47 @@ test(function() {
}, "Reflect.construct: Arguments list has wrong type", TypeError);
-//=== SyntaxError ===
+// === SyntaxError ===
+
+// kInvalidRegExpFlags
+test(function() {
+ /a/x.test("a");
+}, "Invalid flags supplied to RegExp constructor 'x'", SyntaxError);
+
+// kMalformedRegExp
+test(function() {
+ /(/.test("a");
+}, "Invalid regular expression: /(/: Unterminated group", SyntaxError);
+// kParenthesisInArgString
test(function() {
new Function(")", "");
}, "Function arg string contains parenthesis", SyntaxError);
+// kUnexpectedEOS
+test(function() {
+ JSON.parse("{")
+}, "Unexpected end of input", SyntaxError);
+
+// kUnexpectedToken
+test(function() {
+ JSON.parse("/")
+}, "Unexpected token /", SyntaxError);
+
+// kUnexpectedTokenNumber
+test(function() {
+ JSON.parse("{ 1")
+}, "Unexpected number", SyntaxError);
+
+// kUnexpectedTokenString
+test(function() {
+ JSON.parse('"""')
+}, "Unexpected string", SyntaxError);
+
// === ReferenceError ===
+// kNotDefined
test(function() {
"use strict";
o;
@@ -313,7 +405,7 @@ test(function() {
test(function() {
"use strict";
Object.defineProperty([], "length", { value: 1E100 });
-}, "defineProperty() array length out of range", RangeError);
+}, "Invalid array length", RangeError);
// kInvalidArrayBufferLength
test(function() {
diff --git a/deps/v8/test/mjsunit/migrations.js b/deps/v8/test/mjsunit/migrations.js
index 6a2ea64a7a..288bc61031 100644
--- a/deps/v8/test/mjsunit/migrations.js
+++ b/deps/v8/test/mjsunit/migrations.js
@@ -278,18 +278,6 @@ var migrations = [
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); },
},
diff --git a/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status
index 71a7de4ec7..6c6a9b9755 100644
--- a/deps/v8/test/mjsunit/mjsunit.status
+++ b/deps/v8/test/mjsunit/mjsunit.status
@@ -118,6 +118,8 @@
'regress/regress-crbug-107996': [PASS, NO_VARIANTS],
'regress/regress-crbug-171715': [PASS, NO_VARIANTS],
'regress/regress-crbug-222893': [PASS, NO_VARIANTS],
+ 'regress/regress-crbug-323936': [PASS, NO_VARIANTS],
+ 'regress/regress-crbug-491943': [PASS, NO_VARIANTS],
'regress/regress-325676': [PASS, NO_VARIANTS],
'debug-evaluate-closure': [PASS, NO_VARIANTS],
'debug-evaluate-with': [PASS, NO_VARIANTS],
@@ -168,18 +170,20 @@
##############################################################################
# Only RegExp stuff tested, no need for extensive optimizing compiler tests.
'regexp-global': [PASS, NO_VARIANTS],
- 'third_party/regexp-pcre': [PASS, NO_VARIANTS],
+ 'third_party/regexp-pcre/regexp-pcre': [PASS, NO_VARIANTS],
##############################################################################
# No need to waste time for this test.
'd8-performance-now': [PASS, NO_VARIANTS],
+ 'regress/regress-crbug-491062': [PASS, NO_VARIANTS],
# 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 == mips64el or arch == mips', TIMEOUT]],
- 'regress/regress-3976': [PASS, NO_VARIANTS, ['arch == arm or arch == android_arm or arch == android_arm64 or arch == mipsel or arch == mips64el or arch == mips', SKIP]],
+ 'unicode-case-overoptimization': [PASS, NO_VARIANTS, ['arch == arm or arch == arm64 or arch == android_arm or arch == android_arm64 or arch == mipsel or arch == mips64el or arch == mips', TIMEOUT]],
+ 'regress/regress-3976': [PASS, NO_VARIANTS, ['arch == arm or arch == arm64 or arch == android_arm or arch == android_arm64 or arch == mipsel or arch == mips64el or arch == mips', SKIP]],
+ 'regress/regress-crbug-482998': [PASS, NO_VARIANTS, ['arch == arm or arch == arm64 or arch == android_arm or arch == android_arm64 or arch == mipsel or arch == mips64el or arch == mips', SKIP]],
##############################################################################
# This test expects to reach a certain recursion depth, which may not work
@@ -242,6 +246,13 @@
'regress/regress-3116': [PASS, ['isolates', FLAKY]],
}], # ALWAYS
+['novfp3 == True', {
+ 'asm/embenchen/box2d': [SKIP],
+ 'asm/embenchen/zlib': [SKIP],
+ 'asm/embenchen/memops': [SKIP],
+ 'asm/embenchen/lua_binarytrees': [SKIP],
+}], # novfp3 == True
+
##############################################################################
['gc_stress == True', {
# Skip tests not suitable for GC stress.
@@ -293,8 +304,8 @@
# Issue 478788.
'es7/object-observe': [SKIP],
- # Issue 3803.
- 'es6/generators-iteration': [PASS, FLAKY],
+ # BUG(v8:4237)
+ 'regress/regress-3976': [SKIP],
}], # 'gc_stress == True'
##############################################################################
@@ -343,9 +354,6 @@
'regress/regress-2185-2': [PASS, TIMEOUT],
'whitespaces': [PASS, TIMEOUT, SLOW],
- # BUG(v8:3147). It works on other architectures by accident.
- 'regress/regress-conditional-position': [FAIL],
-
# BUG(v8:3457).
'deserialize-reference': [PASS, FAIL],
@@ -408,6 +416,9 @@
'big-array-literal': [SKIP],
'big-object-literal': [SKIP],
'regress/regress-crbug-178790': [SKIP],
+
+ # Exception thrown during bootstrapping on ASAN builds, see issue 4236.
+ 'regress/regress-1132': [SKIP],
}], # 'asan == True'
##############################################################################
@@ -630,12 +641,6 @@
}], # 'arch == nacl_ia32 or arch == nacl_x64'
##############################################################################
-['arch == x87', {
- # Currently Turbofan is not supported by x87.
- 'compiler/opt-next-call-turbo': [SKIP],
-}], # 'arch == x87'
-
-##############################################################################
['deopt_fuzzer == True', {
# Skip tests that are not suitable for deoptimization fuzzing.
diff --git a/deps/v8/test/mjsunit/own-symbols.js b/deps/v8/test/mjsunit/own-symbols.js
deleted file mode 100644
index 588a032aa8..0000000000
--- a/deps/v8/test/mjsunit/own-symbols.js
+++ /dev/null
@@ -1,55 +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: --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/proto-accessor.js b/deps/v8/test/mjsunit/proto-accessor.js
index 513a044023..690b10b5f1 100644
--- a/deps/v8/test/mjsunit/proto-accessor.js
+++ b/deps/v8/test/mjsunit/proto-accessor.js
@@ -29,6 +29,24 @@
this.Symbol = typeof Symbol != 'undefined' ? Symbol : String;
+function TestSetProtoValueCyclic() {
+ var objects = [
+ Object.prototype, {},
+ Array.prototype, [],
+ Error.prototype, new TypeError,
+ // etc ...
+ ];
+ for (var i = 0; i < objects.length; i += 2) {
+ var object = objects[i];
+ var value = objects[i + 1];
+ assertThrows(function() {
+ object.__proto__ = value;
+ }, TypeError);
+ }
+};
+TestSetProtoValueCyclic();
+
+
var desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
var getProto = desc.get;
var setProto = desc.set;
diff --git a/deps/v8/test/mjsunit/regexp-sort.js b/deps/v8/test/mjsunit/regexp-sort.js
new file mode 100644
index 0000000000..57d50701cd
--- /dev/null
+++ b/deps/v8/test/mjsunit/regexp-sort.js
@@ -0,0 +1,48 @@
+// Copyright 2015 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(lower, upper) {
+ var lx = lower + "x";
+ var ux = upper + "x";
+ var lp = lower + "|";
+ var uxp = upper + "x|";
+ assertEquals(lx, new RegExp(uxp + lp + lower + "cat", "i").exec(lx) + "");
+ assertEquals(ux, new RegExp(uxp + lp + lower + "cat", "i").exec(ux) + "");
+ assertEquals(lower, new RegExp(lp + uxp + lower + "cat", "i").exec(lx) + "");
+ assertEquals(upper, new RegExp(lp + uxp + lower + "cat", "i").exec(ux) + "");
+}
+
+function TestFail(lower, upper) {
+ var lx = lower + "x";
+ var ux = upper + "x";
+ var lp = lower + "|";
+ var uxp = upper + "x|";
+ assertEquals(lower, new RegExp(uxp + lp + lower + "cat", "i").exec(lx) + "");
+ assertEquals(ux, new RegExp(uxp + lp + lower + "cat", "i").exec(ux) + "");
+ assertEquals(lower, new RegExp(lp + uxp + lower + "cat", "i").exec(lx) + "");
+ assertEquals(ux, new RegExp(lp + uxp + lower + "cat", "i").exec(ux) + "");
+}
+
+Test("a", "A");
+Test("0", "0");
+TestFail("a", "b");
+// Small and capital o-umlaut
+Test(String.fromCharCode(0xf6), String.fromCharCode(0xd6));
+// Small and capital kha.
+Test(String.fromCharCode(0x445), String.fromCharCode(0x425));
+// Small and capital y-umlaut.
+Test(String.fromCharCode(0xff), String.fromCharCode(0x178));
+// Small and large Greek mu.
+Test(String.fromCharCode(0x3bc), String.fromCharCode(0x39c));
+// Micron and large Greek mu.
+Test(String.fromCharCode(0xb5), String.fromCharCode(0x39c));
+// Micron and small Greek mu.
+Test(String.fromCharCode(0xb5), String.fromCharCode(0x3bc));
+// German double s and capital S. These are not equivalent since one is double.
+TestFail(String.fromCharCode(0xdf), "S");
+// Small i and Turkish capital dotted I. These are not equivalent due to
+// 21.2.2.8.2 section 3g. One is below 128 and the other is above 127.
+TestFail("i", String.fromCharCode(0x130));
+// Small dotless i and I. These are not equivalent either.
+TestFail(String.fromCharCode(0x131), "I");
diff --git a/deps/v8/test/mjsunit/regress/poly_count_operation.js b/deps/v8/test/mjsunit/regress/poly_count_operation.js
index 99f041b6f1..a8a1ed2ebc 100644
--- a/deps/v8/test/mjsunit/regress/poly_count_operation.js
+++ b/deps/v8/test/mjsunit/regress/poly_count_operation.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 --turbo-deoptimization
+// Flags: --allow-natives-syntax
var o1 = {x:1};
var o2 = {};
diff --git a/deps/v8/test/mjsunit/regress/regress-1119.js b/deps/v8/test/mjsunit/regress/regress-1119.js
index 5fd8f369b1..24ab49aa95 100644
--- a/deps/v8/test/mjsunit/regress/regress-1119.js
+++ b/deps/v8/test/mjsunit/regress/regress-1119.js
@@ -28,7 +28,7 @@
// Test runtime declaration of properties with var which are intercepted
// by JS accessors.
-// Flags: --es52_globals
+// Flags: --es52-globals
this.__defineSetter__("x", function() { hasBeenInvoked = true; });
this.__defineSetter__("y", function() { throw 'exception'; });
diff --git a/deps/v8/test/mjsunit/regress/regress-1130.js b/deps/v8/test/mjsunit/regress/regress-1130.js
index 07d5e3d467..6ba430b04f 100644
--- a/deps/v8/test/mjsunit/regress/regress-1130.js
+++ b/deps/v8/test/mjsunit/regress/regress-1130.js
@@ -35,6 +35,6 @@ try {
eval("(function() { const x; var x })")();
} catch (e) {
exception = true;
- assertTrue(e instanceof TypeError);
+ assertTrue(e instanceof SyntaxError);
}
assertTrue(exception);
diff --git a/deps/v8/test/mjsunit/regress/regress-1132.js b/deps/v8/test/mjsunit/regress/regress-1132.js
index 3314db8572..a5cb0a1d5f 100644
--- a/deps/v8/test/mjsunit/regress/regress-1132.js
+++ b/deps/v8/test/mjsunit/regress/regress-1132.js
@@ -28,7 +28,7 @@
// Test the case when exception is thrown from the parser when lazy
// compiling a function.
-// Flags: --stack_size=32
+// Flags: --stack-size=46
// NOTE: stack size constant above has been empirically chosen.
// If the test starts to fail in Genesis, consider increasing this constant.
diff --git a/deps/v8/test/mjsunit/regress/regress-115452.js b/deps/v8/test/mjsunit/regress/regress-115452.js
index dc711581e9..d95bba893c 100644
--- a/deps/v8/test/mjsunit/regress/regress-115452.js
+++ b/deps/v8/test/mjsunit/regress/regress-115452.js
@@ -27,7 +27,7 @@
// Test that a function declaration cannot overwrite a read-only property.
-// Flags: --es52_globals
+// Flags: --es52-globals
function foobl() {}
assertTrue(typeof this.foobl == "function");
diff --git a/deps/v8/test/mjsunit/regress/regress-1170187.js b/deps/v8/test/mjsunit/regress/regress-1170187.js
index 3621bc44a8..6aa2896751 100644
--- a/deps/v8/test/mjsunit/regress/regress-1170187.js
+++ b/deps/v8/test/mjsunit/regress/regress-1170187.js
@@ -26,7 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
-// Flags: --turbo-deoptimization
// Make sure that the retreival of local variables are performed correctly even
// when an adapter frame is present.
diff --git a/deps/v8/test/mjsunit/regress/regress-119609.js b/deps/v8/test/mjsunit/regress/regress-119609.js
index 0c85063ac7..99041adaf4 100644
--- a/deps/v8/test/mjsunit/regress/regress-119609.js
+++ b/deps/v8/test/mjsunit/regress/regress-119609.js
@@ -26,7 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
-// Flags: --turbo-deoptimization
Debug = debug.Debug;
diff --git a/deps/v8/test/mjsunit/regress/regress-1199637.js b/deps/v8/test/mjsunit/regress/regress-1199637.js
index 397aeb8762..f77eead315 100644
--- a/deps/v8/test/mjsunit/regress/regress-1199637.js
+++ b/deps/v8/test/mjsunit/regress/regress-1199637.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 --es52_globals
+// Flags: --allow-natives-syntax --es52-globals
// Make sure that we can introduce global variables (using
// both var and const) that shadow even READ_ONLY variables
diff --git a/deps/v8/test/mjsunit/regress/regress-131994.js b/deps/v8/test/mjsunit/regress/regress-131994.js
index 3de3813eac..7f600959da 100644
--- a/deps/v8/test/mjsunit/regress/regress-131994.js
+++ b/deps/v8/test/mjsunit/regress/regress-131994.js
@@ -26,7 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
-// Flags: --turbo-deoptimization
// Test that a variable in the local scope that shadows a context-allocated
// variable is correctly resolved when being evaluated in the debugger.
diff --git a/deps/v8/test/mjsunit/regress/regress-1419.js b/deps/v8/test/mjsunit/regress/regress-1419.js
index 98a8b76b57..55bcd7ccaa 100644
--- a/deps/v8/test/mjsunit/regress/regress-1419.js
+++ b/deps/v8/test/mjsunit/regress/regress-1419.js
@@ -44,4 +44,12 @@ assertEquals(1, f1.length);
var desc = Object.getOwnPropertyDescriptor(f1, 'length');
assertEquals(false, desc.writable);
assertEquals(false, desc.enumerable);
-assertEquals(false, desc.configurable);
+assertEquals(true, desc.configurable);
+
+Object.defineProperty(f1, 'length', {
+ value: 'abc',
+ writable: true
+});
+assertEquals('abc', f1.length);
+f1.length = 42;
+assertEquals(42, f1.length);
diff --git a/deps/v8/test/mjsunit/regress/regress-1586.js b/deps/v8/test/mjsunit/regress/regress-1586.js
index b15e2f2432..9c805a7a4b 100644
--- a/deps/v8/test/mjsunit/regress/regress-1586.js
+++ b/deps/v8/test/mjsunit/regress/regress-1586.js
@@ -43,8 +43,6 @@ function f() {
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
-// Set breakpoint on line 6.
-var bp = Debug.setBreakPoint(f, 6);
function listener(event, exec_state, event_data, data) {
if (event == Debug.DebugEvent.Break) {
@@ -54,6 +52,10 @@ function listener(event, exec_state, event_data, data) {
// Add the debug event listener.
Debug.setListener(listener);
+
+//Set breakpoint on line 6.
+var bp = Debug.setBreakPoint(f, 6);
+
result = -1;
f();
assertEquals(1, result);
diff --git a/deps/v8/test/mjsunit/regress/regress-166553.js b/deps/v8/test/mjsunit/regress/regress-166553.js
index acaf34f4e0..38fc0b5e76 100644
--- a/deps/v8/test/mjsunit/regress/regress-166553.js
+++ b/deps/v8/test/mjsunit/regress/regress-166553.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
+// Flags: --expose-gc
JSON.stringify(String.fromCharCode(1, -11).toString())
gc();
diff --git a/deps/v8/test/mjsunit/regress/regress-2318.js b/deps/v8/test/mjsunit/regress/regress-2318.js
index e31e0f904e..771d195212 100644
--- a/deps/v8/test/mjsunit/regress/regress-2318.js
+++ b/deps/v8/test/mjsunit/regress/regress-2318.js
@@ -56,11 +56,12 @@ function f() {
};
Debug = debug.Debug;
-var bp = Debug.setBreakPoint(f, 0);
function listener(event, exec_state, event_data, data) {
result = exec_state.frame().evaluate("i").value();
};
Debug.setListener(listener);
+var bp = Debug.setBreakPoint(f, 0);
+
assertThrows(function() { f(); }, RangeError);
diff --git a/deps/v8/test/mjsunit/regress/regress-2593.js b/deps/v8/test/mjsunit/regress/regress-2593.js
index b51b41c27e..b9e497f67f 100644
--- a/deps/v8/test/mjsunit/regress/regress-2593.js
+++ b/deps/v8/test/mjsunit/regress/regress-2593.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
+// Flags: --expose-gc
p1 = { };
p2 = { };
diff --git a/deps/v8/test/mjsunit/regress/regress-2653.js b/deps/v8/test/mjsunit/regress/regress-2653.js
index eb0c6315e6..8864df7553 100644
--- a/deps/v8/test/mjsunit/regress/regress-2653.js
+++ b/deps/v8/test/mjsunit/regress/regress-2653.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 --deopt_every_n_garbage_collections=1
+// Flags: --allow-natives-syntax --deopt-every-n-garbage-collections=1
function foo(a, b) {
var l = a.length;
diff --git a/deps/v8/test/mjsunit/regress/regress-325676.js b/deps/v8/test/mjsunit/regress/regress-325676.js
index 7450a6d12c..427bbc38dc 100644
--- a/deps/v8/test/mjsunit/regress/regress-325676.js
+++ b/deps/v8/test/mjsunit/regress/regress-325676.js
@@ -26,7 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
-// Flags: --turbo-deoptimization
// If a function parameter is forced to be context allocated,
// debug evaluate need to resolve it to a context slot instead of
diff --git a/deps/v8/test/mjsunit/regress/regress-360733.js b/deps/v8/test/mjsunit/regress/regress-360733.js
index 28f73ea446..d9abece30d 100644
--- a/deps/v8/test/mjsunit/regress/regress-360733.js
+++ b/deps/v8/test/mjsunit/regress/regress-360733.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: --stack_size=150
+// Flags: --stack-size=150
function f(a) {
f(a + 1);
diff --git a/deps/v8/test/mjsunit/regress/regress-370384.js b/deps/v8/test/mjsunit/regress/regress-370384.js
index 28aea69216..e07cc06082 100644
--- a/deps/v8/test/mjsunit/regress/regress-370384.js
+++ b/deps/v8/test/mjsunit/regress/regress-370384.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: --deopt-every-n-times=1 --no-enable_sse4_1
+// Flags: --deopt-every-n-times=1 --no-enable-sse4-1
function g(f, x, name) {
var v2 = f(x);
diff --git a/deps/v8/test/mjsunit/regress/regress-3718.js b/deps/v8/test/mjsunit/regress/regress-3718.js
new file mode 100644
index 0000000000..26d96d448d
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-3718.js
@@ -0,0 +1,21 @@
+// Copyright 2015 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.
+
+"use strict";
+
+function getTypeName(receiver) {
+ Error.prepareStackTrace = function(e, stack) { return stack; }
+ var stack = (function() { return new Error().stack; }).call(receiver);
+ Error.prepareStackTrace = undefined;
+ return stack[0].getTypeName();
+}
+
+assertNull(getTypeName(undefined));
+assertNull(getTypeName(null));
+assertEquals("Number", getTypeName(1));
+assertEquals("String", getTypeName(""));
+assertEquals("Boolean", getTypeName(false));
+assertEquals("Object", getTypeName({}));
+assertEquals("Array", getTypeName([]));
+assertEquals("Custom", getTypeName(new (function Custom(){})()));
diff --git a/deps/v8/test/mjsunit/regress/regress-3960.js b/deps/v8/test/mjsunit/regress/regress-3960.js
index 4aaab0b067..3bd2dc200d 100644
--- a/deps/v8/test/mjsunit/regress/regress-3960.js
+++ b/deps/v8/test/mjsunit/regress/regress-3960.js
@@ -4,7 +4,7 @@
// Flags: --allow-natives-syntax
-// Test that setting break point is works correctly when the debugger is
+// Test that setting break point works correctly when the debugger is
// activated late, which leads to duplicate shared function infos.
(function() {
diff --git a/deps/v8/test/mjsunit/regress/regress-4121.js b/deps/v8/test/mjsunit/regress/regress-4121.js
index 3d777c26b3..bef0b47ee5 100644
--- a/deps/v8/test/mjsunit/regress/regress-4121.js
+++ b/deps/v8/test/mjsunit/regress/regress-4121.js
@@ -53,3 +53,6 @@ assertTrue(%HasFastObjectElements(second_object_array));
assertFalse(%HasFastSmiElements(second_object_array));
assertTrue(%HaveSameMap(first_object_array, second_object_array));
assertFalse(%HaveSameMap(first_smi_array, second_object_array));
+
+%ClearFunctionTypeFeedback(Loader);
+%ClearFunctionTypeFeedback(Migrator);
diff --git a/deps/v8/test/mjsunit/regress/regress-4169.js b/deps/v8/test/mjsunit/regress/regress-4169.js
new file mode 100644
index 0000000000..df2de03984
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-4169.js
@@ -0,0 +1,9 @@
+// Copyright 2015 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.
+
+with ({}) {
+ eval("var x = 23");
+ assertEquals(23, x);
+}
+assertEquals(23, x);
diff --git a/deps/v8/test/mjsunit/regress/regress-417709a.js b/deps/v8/test/mjsunit/regress/regress-417709a.js
index 7c4d4f728e..d210c10429 100644
--- a/deps/v8/test/mjsunit/regress/regress-417709a.js
+++ b/deps/v8/test/mjsunit/regress/regress-417709a.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: --stack-size=100 --turbo-deoptimization
+// Flags: --stack-size=100
var a = [];
diff --git a/deps/v8/test/mjsunit/regress/regress-4214.js b/deps/v8/test/mjsunit/regress/regress-4214.js
new file mode 100644
index 0000000000..7c28104b8a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-4214.js
@@ -0,0 +1,6 @@
+// Copyright 2015 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 = { eval: function() { return this; } }
+with (o) assertSame(o, eval());
diff --git a/deps/v8/test/mjsunit/regress/regress-4255-1.js b/deps/v8/test/mjsunit/regress/regress-4255-1.js
new file mode 100644
index 0000000000..78fe860290
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-4255-1.js
@@ -0,0 +1,26 @@
+// Copyright 2015 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.
+
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+
+'use strict';
+{
+ let x = function() {};
+ // Trigger OSR.
+ for (var i = 0; i < 1000000; i++);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-4255-2.js b/deps/v8/test/mjsunit/regress/regress-4255-2.js
new file mode 100644
index 0000000000..bae82be512
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-4255-2.js
@@ -0,0 +1,24 @@
+// Copyright 2015 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.
+
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+
+'use strict';
+for (let i = function f() {}; !i;);
+ // Trigger OSR.
+for (var i = 0; i < 1000000; i++);
diff --git a/deps/v8/test/mjsunit/regress/regress-4255-3.js b/deps/v8/test/mjsunit/regress/regress-4255-3.js
new file mode 100644
index 0000000000..531d0a34de
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-4255-3.js
@@ -0,0 +1,24 @@
+// Copyright 2015 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.
+
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+
+'use strict';
+for (let i in [1, 2, 3]) { function f() {} }
+// Trigger OSR.
+for (var i = 0; i < 1000000; i++);
diff --git a/deps/v8/test/mjsunit/regress/regress-4255-4.js b/deps/v8/test/mjsunit/regress/regress-4255-4.js
new file mode 100644
index 0000000000..4de62d905b
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-4255-4.js
@@ -0,0 +1,24 @@
+// Copyright 2015 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.
+
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+// comments to trigger lazy compilation comments to trigger lazy compilation
+
+'use strict';
+class C { constructor() {} }
+// Trigger OSR
+for (var i = 0; i < 1000000; i++);
diff --git a/deps/v8/test/mjsunit/regress/regress-436896.js b/deps/v8/test/mjsunit/regress/regress-436896.js
index 344a7a3049..0ea70523fe 100644
--- a/deps/v8/test/mjsunit/regress/regress-436896.js
+++ b/deps/v8/test/mjsunit/regress/regress-436896.js
@@ -14,4 +14,4 @@ function g(x) {
}
%OptimizeFunctionOnNextCall(g);
-assertThrows(function() { g(42); }, TypeError);
+assertThrows(function() { g(42); }, SyntaxError);
diff --git a/deps/v8/test/mjsunit/regress/regress-479528.js b/deps/v8/test/mjsunit/regress/regress-479528.js
new file mode 100644
index 0000000000..be0dfaff45
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-479528.js
@@ -0,0 +1,13 @@
+// Copyright 2015 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 __v_7 = {"__proto__": this};
+__v_9 = %CreatePrivateSymbol("__v_9");
+this[__v_9] = "moo";
+function __f_5() {
+ __v_7[__v_9] = "bow-wow";
+}
+__f_5();
diff --git a/deps/v8/test/mjsunit/regress/regress-489151.js b/deps/v8/test/mjsunit/regress/regress-489151.js
new file mode 100644
index 0000000000..25a655585b
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-489151.js
@@ -0,0 +1,12 @@
+// Copyright 2015 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.
+
+this.__proto__ = Array.prototype;
+Object.freeze(this);
+function __f_0() {
+ for (var __v_0 = 0; __v_0 < 10; __v_0++) {
+ this.length = 1;
+ }
+}
+ __f_0();
diff --git a/deps/v8/test/mjsunit/regress/regress-491481.js b/deps/v8/test/mjsunit/regress/regress-491481.js
new file mode 100644
index 0000000000..196b6aeb79
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-491481.js
@@ -0,0 +1,15 @@
+// Copyright 2015 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
+
+try {
+%OptimizeFunctionOnNextCall(print);
+try {
+ __f_16();
+} catch(e) { print(e); }
+try {
+ __f_10();
+} catch(e) {; }
+} catch(e) {}
diff --git a/deps/v8/test/mjsunit/regress/regress-491536.js b/deps/v8/test/mjsunit/regress/regress-491536.js
new file mode 100644
index 0000000000..6e6e0c6e14
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-491536.js
@@ -0,0 +1,10 @@
+// Copyright 2015 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
+
+if (this["debug"]) debug.Debug.setListener(function() {});
+var source = "var outer = 0; function test() {'use strict'; outer = 1; } test(); print('ok');";
+function test_function() { eval(source); }
+assertDoesNotThrow(test_function);
diff --git a/deps/v8/test/mjsunit/regress/regress-499790.js b/deps/v8/test/mjsunit/regress/regress-499790.js
new file mode 100644
index 0000000000..ce2cd03f02
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-499790.js
@@ -0,0 +1,14 @@
+// Copyright 2015 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: --enable-slow-asserts
+
+var a = [1];
+a.foo = "bla";
+delete a.foo;
+a[0] = 1.5;
+
+var a2 = [];
+a2.foo = "bla";
+delete a2.foo;
diff --git a/deps/v8/test/mjsunit/regress/regress-500173.js b/deps/v8/test/mjsunit/regress/regress-500173.js
new file mode 100644
index 0000000000..b7083b2c51
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-500173.js
@@ -0,0 +1,12 @@
+// Copyright 2015 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) {
+ a.foo = {};
+ a[0] = 1;
+ a.__defineGetter__('foo', function() {});
+ a[0] = {};
+ a.bar = 0;
+}
+f(new Array());
diff --git a/deps/v8/test/mjsunit/regress/regress-500176.js b/deps/v8/test/mjsunit/regress/regress-500176.js
new file mode 100644
index 0000000000..6700ef0f33
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-500176.js
@@ -0,0 +1,13 @@
+// Copyright 2015 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_0(p) {
+ var __v_0 = -2147483642;
+ for (var __v_1 = 0; __v_1 < 10; __v_1++) {
+ if (__v_1 > 5) { __v_0 = __v_0 + p; break;}
+ }
+}
+for (var __v_2 = 0; __v_2 < 100000; __v_2++) __f_0(42);
+__v_2 = { f: function () { return x + y; },
+ 2: function () { return x - y} };
diff --git a/deps/v8/test/mjsunit/regress/regress-500831.js b/deps/v8/test/mjsunit/regress/regress-500831.js
new file mode 100644
index 0000000000..6d8cfaf05a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-500831.js
@@ -0,0 +1,94 @@
+// Copyright 2015 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
+
+// To reproduce reliably use: --random-seed=-2012454635 --nodebug-code
+
+function deepEquals(a, b) {
+ if (a === b) {;
+ return true;
+ }
+ if (typeof a != typeof b) return false;
+ if (typeof a == "number");
+ if (typeof a !== "object" && typeof a !== "function")
+ return false;
+ var objectClass = classOf();
+ if (b) return false;
+ if (objectClass === "RegExp") {;
+ }
+ if (objectClass === "Function") return false;
+ if (objectClass === "Array") {
+ var elementCount = 0;
+ if (a.length != b.length) {
+ return false;
+ }
+ for (var i = 0; i < a.length; i++) {
+ if (a[i][i]) return false;
+ }
+ return true;
+ }
+ if (objectClass == "String" || objectClass == "Number" ||
+ objectClass == "Boolean" || objectClass == "Date") {
+ if (a.valueOf()) return false;
+ };
+}
+function equals(expected, found, name_opt) {
+ if (!deepEquals(found, expected)) {}
+};
+function instof(obj, type) {
+ if (!(obj instanceof type)) {
+ var actualTypeName = null;
+ var actualConstructor = Object.getPrototypeOf().constructor;
+ if (typeof actualConstructor == "function") {;
+ };
+ }
+};
+var __v_0 = 1;
+var __v_6 = {};
+var __v_9 = {};
+
+function __f_4() {
+ return function() {};
+}
+__v_6 = new Uint8ClampedArray(10);
+
+function __f_6() {
+ __v_6[0] = 0.499;
+ instof(__f_4(), Function);
+ equals();
+ __v_6[0] = 0.5;
+ equals();
+ __v_0[0] = 0.501;
+ equals(__v_6[4294967295]);
+ __v_6[0] = 1.499;
+ equals();
+ __v_6[0] = 1.5;
+ equals();
+ __v_6[0] = 1.501;
+ equals();
+ __v_6[0] = 2.5;
+ equals(__v_6[-1073741824]);
+ __v_6[0] = 3.5;
+ equals();
+ __v_6[0] = 252.5;
+ equals();
+ __v_6[0] = 253.5;
+ equals();
+ __v_6[0] = 254.5;
+ equals();
+ __v_6[0] = 256.5;
+ equals();
+ __v_6[0] = -0.5;
+ equals(__v_6[8]);
+ __v_6[0] = -1.5;
+ equals();
+ __v_6[0] = 1000000000000;
+ equals();
+ __v_9[0] = -1000000000000;
+ equals(__v_6[0]);
+}
+__f_6();
+__f_6(); % OptimizeFunctionOnNextCall(__f_6);
+__f_6();
diff --git a/deps/v8/test/mjsunit/regress/regress-500980.js b/deps/v8/test/mjsunit/regress/regress-500980.js
new file mode 100644
index 0000000000..841d26aa4a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-500980.js
@@ -0,0 +1,7 @@
+// Copyright 2015 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 = "a";
+assertThrows(function() { while (true) a += a; }, RangeError);
+assertThrows(function() { a in a; }, TypeError);
diff --git a/deps/v8/test/mjsunit/regress/regress-503565.js b/deps/v8/test/mjsunit/regress/regress-503565.js
new file mode 100644
index 0000000000..9aebe8d7d1
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-503565.js
@@ -0,0 +1,21 @@
+// Copyright 2015 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.
+
+// Crashes without the fix for bug 503565.
+function f() {}
+function g() {}
+function h() {
+ g()
+}
+(function() {
+ eval("\
+ \"use strict\";\
+ g = (function(x) {\
+ +Math.log(+Math.log((+(+x>0)), f(Math.log())))\
+ })\
+ ")
+})()
+for (var j = 0; j < 999; j++) {
+ h()
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-507980.js b/deps/v8/test/mjsunit/regress/regress-507980.js
new file mode 100644
index 0000000000..d1a1f79f24
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-507980.js
@@ -0,0 +1,8 @@
+// Copyright 2015 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.
+
+__v_1 = new Float64Array(1);
+__v_8 = { valueOf: function() { __v_13.y = "bar"; return 42; }};
+__v_13 = __v_1;
+__v_13[0] = __v_8;
diff --git a/deps/v8/test/mjsunit/regress/regress-581.js b/deps/v8/test/mjsunit/regress/regress-581.js
index 65cd87de01..ab345a9b61 100644
--- a/deps/v8/test/mjsunit/regress/regress-581.js
+++ b/deps/v8/test/mjsunit/regress/regress-581.js
@@ -35,11 +35,13 @@ assertEquals(pow31 + 1, a.length);
assertThrows(function() { a.concat(a); }, RangeError);
var b = [];
-b[pow31 - 2] = 32;
+b[pow31 - 3] = 32;
+b[pow31 - 2] = "out_of_bounds";
var ab = a.concat(b);
assertEquals(2 * pow31 - 1, ab.length);
assertEquals(31, ab[pow31]);
-assertEquals(32, ab[2 * pow31 - 1]);
+assertEquals(32, ab[2 * pow31 - 2]);
+assertEquals(undefined, ab[2 * pow31 - 1]);
var c = [];
c[pow30] = 30;
diff --git a/deps/v8/test/mjsunit/regress/regress-747.js b/deps/v8/test/mjsunit/regress/regress-747.js
index 648c36684c..a3de131483 100644
--- a/deps/v8/test/mjsunit/regress/regress-747.js
+++ b/deps/v8/test/mjsunit/regress/regress-747.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
+// Flags: --expose-gc
// This test makes sure that we do flush code with heap allocated locals.
// This can be a problem if eval is used within the scope.
diff --git a/deps/v8/test/mjsunit/regress/regress-78270.js b/deps/v8/test/mjsunit/regress/regress-78270.js
index 02c4b147c9..b9ce286feb 100644
--- a/deps/v8/test/mjsunit/regress/regress-78270.js
+++ b/deps/v8/test/mjsunit/regress/regress-78270.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: --turbo-deoptimization
-
for (var i = 0; i < 10000; i++) {
try {
var object = { };
diff --git a/deps/v8/test/mjsunit/regress/regress-arguments-gc.js b/deps/v8/test/mjsunit/regress/regress-arguments-gc.js
index baa4e163f5..b5ed608e0e 100644
--- a/deps/v8/test/mjsunit/regress/regress-arguments-gc.js
+++ b/deps/v8/test/mjsunit/regress/regress-arguments-gc.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 --nocleanup_code_caches_at_gc
+// Flags: --expose-gc --nocleanup-code-caches-at-gc
function f(x) {
gc();
diff --git a/deps/v8/test/mjsunit/regress/regress-assignment-in-test-context.js b/deps/v8/test/mjsunit/regress/regress-assignment-in-test-context.js
index bc4098554a..61ca220293 100644
--- a/deps/v8/test/mjsunit/regress/regress-assignment-in-test-context.js
+++ b/deps/v8/test/mjsunit/regress/regress-assignment-in-test-context.js
@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --always-opt
-// Flags: --turbo-filter=* --turbo-deoptimization
+// Flags: --allow-natives-syntax --always-opt --turbo-filter=*
function assertEquals() {}
diff --git a/deps/v8/test/mjsunit/regress/regress-binop-nosse2.js b/deps/v8/test/mjsunit/regress/regress-binop-nosse2.js
deleted file mode 100644
index 29c8a048fc..0000000000
--- a/deps/v8/test/mjsunit/regress/regress-binop-nosse2.js
+++ /dev/null
@@ -1,167 +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.
-
-// Flags: --allow-natives-syntax --noenable-sse2
-
-// general tests
-var e31 = Math.pow(2, 31);
-
-assertEquals(-e31, -1*e31);
-assertEquals(e31, -1*e31*(-1));
-assertEquals(e31, -1*-e31);
-assertEquals(e31, -e31*(-1));
-
-var x = {toString : function() {return 1}}
-function add(a,b){return a+b;}
-add(1,x);
-add(1,x);
-%OptimizeFunctionOnNextCall(add);
-add(1,x);
-x.toString = function() {return "2"};
-
-assertEquals(add(1,x), "12");
-
-// Test the correct placement of the simulates in TruncateToNumber:
-function Checker() {
- this.str = "1";
- var toStringCalled = 0;
- var toStringExpected = 0;
- this.toString = function() {
- toStringCalled++;
- return this.str;
- };
- this.check = function() {
- toStringExpected++;
- assertEquals(toStringExpected, toStringCalled);
- };
-};
-var left = new Checker();
-var right = new Checker();
-
-function test(fun,check_fun,a,b,does_throw) {
- left.str = a;
- right.str = b;
- try {
- assertEquals(check_fun(a,b), fun(left, right));
- assertTrue(!does_throw);
- } catch(e) {
- if (e instanceof TypeError) {
- assertTrue(!!does_throw);
- } else {
- throw e;
- }
- } finally {
- left.check();
- if (!does_throw || does_throw>1) {
- right.check();
- }
- }
-}
-
-function minus(a,b) { return a-b };
-function check_minus(a,b) { return a-b };
-function mod(a,b) { return a%b };
-function check_mod(a,b) { return a%b };
-
-test(minus,check_minus,1,2);
-// Bailout on left
-test(minus,check_minus,1<<30,1);
-// Bailout on right
-test(minus,check_minus,1,1<<30);
-// Bailout on result
-test(minus,check_minus,1<<30,-(1<<30));
-
-// Some more interesting things
-test(minus,check_minus,1,1.4);
-test(minus,check_minus,1.3,4);
-test(minus,check_minus,1.3,1.4);
-test(minus,check_minus,1,2);
-test(minus,check_minus,1,undefined);
-test(minus,check_minus,1,2);
-test(minus,check_minus,1,true);
-test(minus,check_minus,1,2);
-test(minus,check_minus,1,null);
-test(minus,check_minus,1,2);
-test(minus,check_minus,1,"");
-test(minus,check_minus,1,2);
-
-// Throw on left
-test(minus,check_minus,{},1,1);
-// Throw on right
-test(minus,check_minus,1,{},2);
-// Throw both
-test(minus,check_minus,{},{},1);
-
-test(minus,check_minus,1,2);
-
-// Now with optimized code
-test(mod,check_mod,1,2);
-%OptimizeFunctionOnNextCall(mod);
-test(mod,check_mod,1,2);
-
-test(mod,check_mod,1<<30,1);
-%OptimizeFunctionOnNextCall(mod);
-test(mod,check_mod,1<<30,1);
-test(mod,check_mod,1,1<<30);
-%OptimizeFunctionOnNextCall(mod);
-test(mod,check_mod,1,1<<30);
-test(mod,check_mod,1<<30,-(1<<30));
-%OptimizeFunctionOnNextCall(mod);
-test(mod,check_mod,1<<30,-(1<<30));
-
-test(mod,check_mod,1,{},2);
-%OptimizeFunctionOnNextCall(mod);
-test(mod,check_mod,1,{},2);
-
-test(mod,check_mod,1,2);
-
-
-// test oddballs
-function t1(a, b) {return a-b}
-assertEquals(t1(1,2), 1-2);
-assertEquals(t1(2,true), 2-1);
-assertEquals(t1(false,2), 0-2);
-assertEquals(t1(1,2.4), 1-2.4);
-assertEquals(t1(1.3,2.4), 1.3-2.4);
-assertEquals(t1(true,2.4), 1-2.4);
-assertEquals(t1(1,undefined), 1-NaN);
-assertEquals(t1(1,1<<30), 1-(1<<30));
-assertEquals(t1(1,2), 1-2);
-
-function t2(a, b) {return a/b}
-assertEquals(t2(1,2), 1/2);
-assertEquals(t2(null,2), 0/2);
-assertEquals(t2(null,-2), 0/-2);
-assertEquals(t2(2,null), 2/0);
-assertEquals(t2(-2,null), -2/0);
-assertEquals(t2(1,2.4), 1/2.4);
-assertEquals(t2(1.3,2.4), 1.3/2.4);
-assertEquals(t2(null,2.4), 0/2.4);
-assertEquals(t2(1.3,null), 1.3/0);
-assertEquals(t2(undefined,2), NaN/2);
-assertEquals(t2(1,1<<30), 1/(1<<30));
-assertEquals(t2(1,2), 1/2);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-107996.js b/deps/v8/test/mjsunit/regress/regress-crbug-107996.js
index b4907f3bb8..dfe07e59de 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-107996.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-107996.js
@@ -26,7 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
-// Flags: --turbo-deoptimization
Debug = debug.Debug;
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-171715.js b/deps/v8/test/mjsunit/regress/regress-crbug-171715.js
index 309f50a01b..040c381e39 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-171715.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-171715.js
@@ -26,7 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
-// Flags: --turbo-deoptimization
Debug = debug.Debug
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-217858.js b/deps/v8/test/mjsunit/regress/regress-crbug-217858.js
index e61cb9f6d2..d6d6e9feed 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-217858.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-217858.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: --noanalyze_environment_liveness
+// Flags: --noanalyze-environment-liveness
var r = /r/;
function f() {
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-222893.js b/deps/v8/test/mjsunit/regress/regress-crbug-222893.js
index 75e17289fd..39363bc912 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-222893.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-222893.js
@@ -26,7 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
-// Flags: --turbo-deoptimization
Debug = debug.Debug
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-424142.js b/deps/v8/test/mjsunit/regress/regress-crbug-424142.js
index 0a370d4142..b188565fe2 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-424142.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-424142.js
@@ -23,6 +23,7 @@
function sentinel() {}
Debug = debug.Debug;
+Debug.setListener(function(){});
var script = Debug.findScript(sentinel);
var line = 14;
@@ -34,3 +35,5 @@ var actual = Debug.setBreakPointByScriptIdAndPosition(
// the break point.
assertTrue(line_start <= actual);
assertTrue(actual <= line_end);
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-450960.js b/deps/v8/test/mjsunit/regress/regress-crbug-450960.js
index f745522dbe..28db6dff8b 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-450960.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-450960.js
@@ -2,15 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --stack-size=70
+// Flags: --stack-size=100
"a".replace(/a/g, "");
+var count = 0;
function test() {
try {
test();
} catch(e) {
- "b".replace(/(b)/g, new []);
+ if (count < 50) {
+ count++;
+ "b".replace(/(b)/g, new []);
+ }
}
}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-467180.js b/deps/v8/test/mjsunit/regress/regress-crbug-467180.js
new file mode 100644
index 0000000000..fcf5c30294
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-467180.js
@@ -0,0 +1,41 @@
+// Copyright 2015 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
+
+function f() {
+ for (var i = 10; i < 14; i++) { // 1
+ i; // 2
+ }
+} // 3
+
+var state = "conditional";
+var log = [];
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ var label = +exec_state.frame(0).sourceLineText().substr(-1);
+ log.push(label);
+ if (label == 2) log.push(exec_state.frame(0).evaluate("i").value());
+ exec_state.prepareStep(Debug.StepAction.StepNext, 1);
+ } catch (e) {
+ exception = e;
+ print("Caught something. " + e + " " + e.stack);
+ };
+};
+
+
+var Debug = debug.Debug;
+Debug.setListener(listener);
+
+Debug.setBreakPoint(f, 2, 0, "i == 12");
+
+f();
+
+Debug.setListener(null); // 4
+
+assertEquals([2,12,1,1,2,13,1,1,3,4], log);
+assertNull(exception);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-471659.js b/deps/v8/test/mjsunit/regress/regress-crbug-471659.js
new file mode 100644
index 0000000000..fa27baa3e8
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-471659.js
@@ -0,0 +1,22 @@
+// Copyright 2015 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=100
+
+var s = "0123456789ABCDEF";
+for (var i = 0; i < 16; i++) s += s;
+
+var count = 0;
+function f() {
+ try {
+ f();
+ if (count < 10) {
+ f();
+ }
+ } catch(e) {
+ s.replace("+", "-");
+ }
+ count++;
+}
+f();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-474297.js b/deps/v8/test/mjsunit/regress/regress-crbug-474297.js
index 3169c2815a..ce240251bd 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-474297.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-474297.js
@@ -4,4 +4,9 @@
// Flags: --gc-interval=33 --expose-gc --allow-natives-syntax
+var Debug = %GetDebugContext().Debug;
+Debug.setListener(function(){});
+
%DebugGetLoadedScripts();
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-480819.js b/deps/v8/test/mjsunit/regress/regress-crbug-480819.js
index 8d3b7eed60..086f6c84c2 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-480819.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-480819.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: --turbo-filter=* --always-opt --turbo-deoptimization --noanalyze-environment-liveness
+// Flags: --turbo-filter=* --always-opt --noanalyze-environment-liveness
(function() {
"use strict";
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-481896.js b/deps/v8/test/mjsunit/regress/regress-crbug-481896.js
new file mode 100644
index 0000000000..0d5c650f1e
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-481896.js
@@ -0,0 +1,56 @@
+// Copyright 2015 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
+
+function static() {
+ print("> static"); // Break
+}
+
+var Debug = debug.Debug;
+var exception = null;
+var break_count = 0;
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ print("breakpoint hit at " + exec_state.frame(0).sourceLineText());
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// Break") > 0);
+ break_count++;
+ } catch (e) {
+ exception = e;
+ }
+}
+
+Debug.setListener(listener);
+
+function install() {
+ eval("this.dynamic = function dynamic() { \n" +
+ " print(\"> dynamic\"); // Break\n" +
+ "}\n" +
+ "//@ sourceURL=dynamicScript");
+}
+
+install();
+
+var scripts = Debug.scripts();
+var dynamic_script;
+var static_script;
+for (var script of scripts) {
+ if (script.source_url == "dynamicScript") dynamic_script = script;
+ if (script.source_url == "staticScript") static_script = script;
+}
+
+Debug.setScriptBreakPointById(dynamic_script.id, 1);
+Debug.setScriptBreakPointById(static_script.id, 7);
+
+dynamic();
+static();
+
+Debug.setListener(null);
+
+assertNull(exception);
+assertEquals(2, break_count);
+
+//@ sourceURL=staticScript
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-482998.js b/deps/v8/test/mjsunit/regress/regress-crbug-482998.js
new file mode 100644
index 0000000000..80933a7a6d
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-482998.js
@@ -0,0 +1,23 @@
+// Copyright 2015 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.
+
+// Should not time out. Running time 0.5s vs. 120s before the change.
+function collapse(flags) {
+ var src = "(?:";
+ for (var i = 128; i < 0x1000; i++) {
+ src += String.fromCharCode(96 + i % 26) + String.fromCharCode(i) + "|";
+ }
+ src += "aa)";
+ var collapsible = new RegExp(src, flags);
+ var subject = "zzzzzzz" + String.fromCharCode(3000);
+ for (var i = 0; i < 1000; i++) {
+ subject += "xxxxxxx";
+ }
+ for (var i = 0; i < 2000; i++) {
+ assertFalse(collapsible.test(subject));
+ }
+}
+
+collapse("i");
+collapse("");
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-487105.js b/deps/v8/test/mjsunit/regress/regress-crbug-487105.js
new file mode 100644
index 0000000000..160f9b04e0
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-487105.js
@@ -0,0 +1,9 @@
+// Copyright 2015 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.
+
+"use strict";
+function assertThrows() {
+ eval();
+};
+eval("delete this;")
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-487289.js b/deps/v8/test/mjsunit/regress/regress-crbug-487289.js
new file mode 100644
index 0000000000..dbfb4041ca
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-487289.js
@@ -0,0 +1,20 @@
+// Copyright 2015 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
+
+var Debug = debug.Debug;
+var receiver = null;
+
+Debug.setListener(function(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ receiver = exec_state.frame(0).evaluate('this').value();
+});
+
+function f() { debugger; }
+
+var expected = {};
+f.call(expected);
+
+assertEquals(expected, receiver);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-487608.js b/deps/v8/test/mjsunit/regress/regress-crbug-487608.js
new file mode 100644
index 0000000000..c1eafce5ef
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-487608.js
@@ -0,0 +1,22 @@
+// Copyright 2015 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 inlined(a, i) {
+ return a[i + 1];
+}
+
+function foo(index) {
+ var a = [0, 1, 2, 3];
+ var result = 0;
+ result += a[index];
+ result += inlined(a, index);
+ return result;
+}
+
+foo(0);
+foo(0);
+%OptimizeFunctionOnNextCall(foo);
+foo(0);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-489293.js b/deps/v8/test/mjsunit/regress/regress-crbug-489293.js
new file mode 100644
index 0000000000..bcfc702df3
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-489293.js
@@ -0,0 +1,16 @@
+// Copyright 2015 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 --turbo-filter=f
+// Flags: --noanalyze-environment-liveness
+
+function f() {
+ var x = 0;
+ for (var y = 0; y < 0; ++y) {
+ x = (x + y) | 0;
+ }
+ return unbound;
+}
+%OptimizeFunctionOnNextCall(f);
+assertThrows(f, ReferenceError);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-489597.js b/deps/v8/test/mjsunit/regress/regress-crbug-489597.js
new file mode 100644
index 0000000000..b10af92b5f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-489597.js
@@ -0,0 +1,12 @@
+// Copyright 2015 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.
+
+try {
+ load("test/mjsunit/regress/regress-crbug-489597.js-script");
+} catch (e) {
+}
+
+var o = this;
+Error.captureStackTrace(o);
+o.stack;
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-489597.js-script b/deps/v8/test/mjsunit/regress/regress-crbug-489597.js-script
new file mode 100644
index 0000000000..cb4dd84df3
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-489597.js-script
@@ -0,0 +1,5 @@
+// Copyright 2015 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.
+
+throw new Error("boom");
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-490680.js b/deps/v8/test/mjsunit/regress/regress-crbug-490680.js
new file mode 100644
index 0000000000..735f3b7f50
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-490680.js
@@ -0,0 +1,18 @@
+// Copyright 2015 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 sentinel = null;
+
+try {
+ throw { toString: function() { sentinel = "observed"; } };
+} catch (e) {
+}
+
+L: try {
+ throw { toString: function() { sentinel = "observed"; } };
+} finally {
+ break L;
+}
+
+assertNull(sentinel);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-491062.js b/deps/v8/test/mjsunit/regress/regress-crbug-491062.js
new file mode 100644
index 0000000000..d2cd7579bc
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-491062.js
@@ -0,0 +1,22 @@
+// Copyright 2015 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 --stack-size=100
+
+function g() {}
+
+var count = 0;
+function f() {
+ try {
+ f();
+ } catch(e) {
+ print(e.stack);
+ }
+ if (count < 100) {
+ count++;
+ %DebugGetLoadedScripts();
+ }
+}
+f();
+g();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-491943.js b/deps/v8/test/mjsunit/regress/regress-crbug-491943.js
new file mode 100644
index 0000000000..c87d1301b7
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-491943.js
@@ -0,0 +1,25 @@
+// Copyright 2015 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
+
+var Debug = debug.Debug;
+var receiver = null;
+
+Debug.setListener(function(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ receiver = exec_state.frame(0).evaluate('this').value();
+});
+
+
+function f() {
+ var context_local = 1;
+ (function() { return context_local; })();
+ debugger;
+}
+
+var expected = {};
+f.call(expected);
+
+assertEquals(expected, receiver);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-492526.js b/deps/v8/test/mjsunit/regress/regress-crbug-492526.js
new file mode 100644
index 0000000000..e8ea298f8b
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-492526.js
@@ -0,0 +1,7 @@
+// Copyright 2015 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
+
+assertThrows(function() { %FormatMessageString(-1, "", "", ""); });
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-493284.js b/deps/v8/test/mjsunit/regress/regress-crbug-493284.js
new file mode 100644
index 0000000000..64f9463471
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-493284.js
@@ -0,0 +1,10 @@
+// Copyright 2015 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: --invoke-weak-callbacks --omit-quit --no-test
+
+if (this.Intl) {
+ var coll = new Intl.Collator();
+ assertEquals(-1, coll.compare('a', 'c'));
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-493290.js b/deps/v8/test/mjsunit/regress/regress-crbug-493290.js
new file mode 100644
index 0000000000..6ff9fe1a65
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-493290.js
@@ -0,0 +1,9 @@
+// Copyright 2015 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() {
+ throw "boom";
+ try {} catch (e) {}
+}
+assertThrows(f);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-493568.js b/deps/v8/test/mjsunit/regress/regress-crbug-493568.js
new file mode 100644
index 0000000000..081f4937fe
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-493568.js
@@ -0,0 +1,12 @@
+// Copyright 2015 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 --harmony-proxies
+
+var p = Proxy.create({ fix: function() { return {}; } });
+
+var obj = {};
+obj.x = p;
+
+Object.preventExtensions(p);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-493779.js b/deps/v8/test/mjsunit/regress/regress-crbug-493779.js
new file mode 100644
index 0000000000..1071ed23ac
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-493779.js
@@ -0,0 +1,11 @@
+// Copyright 2015 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: --enable-slow-asserts
+
+var s = "\u1234-------";
+for (var i = 0; i < 17; i++) {
+ s += s;
+}
+s.replace(/[\u1234]/g, "");
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-498022.js b/deps/v8/test/mjsunit/regress/regress-crbug-498022.js
new file mode 100644
index 0000000000..cb8e0a460d
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-498022.js
@@ -0,0 +1,15 @@
+// Copyright 2015 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: --debug-code --nouse-gvn
+
+"use strict";
+class Base {
+}
+class Derived extends Base {
+ constructor() {
+ eval();
+ }
+}
+assertThrows("new Derived()", ReferenceError);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-498142.js b/deps/v8/test/mjsunit/regress/regress-crbug-498142.js
new file mode 100644
index 0000000000..fcec5d1bd7
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-498142.js
@@ -0,0 +1,8 @@
+// Copyright 2015 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 --harmony-sharedarraybuffer
+
+var sab = new SharedArrayBuffer(16);
+assertThrows(function() { %ArrayBufferNeuter(sab); });
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-498811.js b/deps/v8/test/mjsunit/regress/regress-crbug-498811.js
new file mode 100644
index 0000000000..53f57b8c17
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-498811.js
@@ -0,0 +1,9 @@
+// Copyright 2015 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.
+
+// NO HARNESS
+
+"use strict";
+let l = 0;
+eval("eval('this')");
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-514268.js b/deps/v8/test/mjsunit/regress/regress-crbug-500435.js
index 75d9970eed..acc17ac5ec 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-514268.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-500435.js
@@ -5,16 +5,15 @@
// Flags: --allow-natives-syntax
function bar(a) {
- a.pop();
+ delete a[1];
}
+
function foo(a) {
- assertEquals(2, a.length);
var d;
for (d in a) {
+ assertFalse(d === undefined);
bar(a);
}
- // If this fails, bar was not called exactly once.
- assertEquals(1, a.length);
}
foo([1,2]);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-500497.js b/deps/v8/test/mjsunit/regress/regress-crbug-500497.js
index 9117440c2c..2d3d40f0f7 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-500497.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-500497.js
@@ -13,6 +13,9 @@ function Ctor() {
}
for (var i = 0; i < 120; i++) {
+ // This print() is important! Without it, in --gc-stress mode, the function
+ // Ctor is optimized too early. No idea why.
+ print(i);
// Make the "a" property long-lived, while everything else is short-lived.
global.push(Ctor().a);
(function FillNewSpace() { new Array(10000); })();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-500824.js b/deps/v8/test/mjsunit/regress/regress-crbug-500824.js
new file mode 100644
index 0000000000..08d0d107ca
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-500824.js
@@ -0,0 +1,23 @@
+// Copyright 2015 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 get_thrower() {
+ "use strict";
+ return Object.getOwnPropertyDescriptor(arguments, "callee").get;
+}
+
+var f = (function(v) {
+ "use asm";
+ function fun() {
+ switch (v) {}
+ }
+ return {
+ fun: fun
+ };
+})(get_thrower()).fun;
+
+%OptimizeFunctionOnNextCall(f);
+f();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-501711.js b/deps/v8/test/mjsunit/regress/regress-crbug-501711.js
new file mode 100644
index 0000000000..f8eda6e8d8
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-501711.js
@@ -0,0 +1,14 @@
+// Copyright 2015 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=100
+
+function f() {
+ try {
+ f();
+ } catch(e) {
+ Realm.create();
+ }
+}
+f();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-501808.js b/deps/v8/test/mjsunit/regress/regress-crbug-501808.js
new file mode 100644
index 0000000000..f9b97841c4
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-501808.js
@@ -0,0 +1,6 @@
+// Copyright 2015 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 r = Realm.create();
+assertEquals(0, "a".localeCompare("a"));
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-501809.js b/deps/v8/test/mjsunit/regress/regress-crbug-501809.js
new file mode 100644
index 0000000000..b348e5d5f6
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-501809.js
@@ -0,0 +1,9 @@
+// Copyright 2015 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-sharedarraybuffer --harmony-atomics
+var sab = new SharedArrayBuffer(8);
+var ta = new Int32Array(sab);
+ta.__defineSetter__('length', function() {;});
+assertThrows(function() { Atomics.compareExchange(ta, 4294967295, 0, 0); });
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-503578.js b/deps/v8/test/mjsunit/regress/regress-crbug-503578.js
new file mode 100644
index 0000000000..1274d91ffe
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-503578.js
@@ -0,0 +1,14 @@
+// Copyright 2015 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.
+
+if (this.Worker) {
+ function __f_0(byteLength) {
+ var __v_1 = new ArrayBuffer(byteLength);
+ var __v_5 = new Uint32Array(__v_1);
+ return __v_5;
+ }
+ var __v_6 = new Worker('onmessage = function() {}');
+ var __v_3 = __f_0(16);
+ __v_6.postMessage(__v_3);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-503698.js b/deps/v8/test/mjsunit/regress/regress-crbug-503698.js
new file mode 100644
index 0000000000..415d1bc81b
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-503698.js
@@ -0,0 +1,9 @@
+// Copyright 2015 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: --invoke-weak-callbacks
+
+if (this.Worker) {
+ var __v_6 = new Worker('');
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-503968.js b/deps/v8/test/mjsunit/regress/regress-crbug-503968.js
new file mode 100644
index 0000000000..78d1c7b98a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-503968.js
@@ -0,0 +1,13 @@
+// Copyright 2015 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.
+
+if (this.Worker) {
+ function __f_0() { this.s = new Object(); }
+ function __f_1() {
+ this.l = [new __f_0, new __f_0];
+ }
+ __v_6 = new __f_1;
+ var __v_9 = new Worker('');
+ __v_9.postMessage(__v_6);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-503991.js b/deps/v8/test/mjsunit/regress/regress-crbug-503991.js
new file mode 100644
index 0000000000..6a3b0de759
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-503991.js
@@ -0,0 +1,9 @@
+// Copyright 2015 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.
+
+if (this.Worker) {
+ __v_3 = "";
+ var __v_6 = new Worker('');
+ __v_6.postMessage(__v_3);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-504136.js b/deps/v8/test/mjsunit/regress/regress-crbug-504136.js
new file mode 100644
index 0000000000..4ed6843544
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-504136.js
@@ -0,0 +1,9 @@
+// Copyright 2015 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.
+
+if (this.Worker) {
+ var __v_10 = new Worker('');
+ __v_10.terminate();
+ __v_10.getMessage();
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-504727.js b/deps/v8/test/mjsunit/regress/regress-crbug-504727.js
new file mode 100644
index 0000000000..16d8ff16cd
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-504727.js
@@ -0,0 +1,9 @@
+// Copyright 2015 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: --no-test
+
+if (this.Worker) {
+ var __v_2 = new Worker('');
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-504729.js b/deps/v8/test/mjsunit/regress/regress-crbug-504729.js
new file mode 100644
index 0000000000..435cafee87
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-504729.js
@@ -0,0 +1,9 @@
+// Copyright 2015 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.
+
+if (this.Worker) {
+ Function.prototype.toString = "foo";
+ function __f_7() {}
+ assertThrows(function() { var __v_5 = new Worker(__f_7.toString()); });
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-504787.js b/deps/v8/test/mjsunit/regress/regress-crbug-504787.js
new file mode 100644
index 0000000000..66274bc6b9
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-504787.js
@@ -0,0 +1,15 @@
+// Copyright 2015 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: --noturbo-osr
+
+function f() {
+ "use asm";
+ function g() {
+ function f() {};
+ }
+ return g;
+}
+
+f()();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-505007-1.js b/deps/v8/test/mjsunit/regress/regress-crbug-505007-1.js
new file mode 100644
index 0000000000..6012577aaa
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-505007-1.js
@@ -0,0 +1,14 @@
+// Copyright 2015 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=100 --allow-natives-syntax
+
+function f() {
+ try {
+ f();
+ } catch(e) {
+ %GetDebugContext();
+ }
+}
+f();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-505007-2.js b/deps/v8/test/mjsunit/regress/regress-crbug-505007-2.js
new file mode 100644
index 0000000000..dfa34ae6ad
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-505007-2.js
@@ -0,0 +1,15 @@
+// Copyright 2015 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=100 --allow-natives-syntax
+
+function g() {}
+function f() {
+ try {
+ f();
+ } catch(e) {
+ %ExecuteInDebugContext(g);
+ }
+}
+f();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-505354.js b/deps/v8/test/mjsunit/regress/regress-crbug-505354.js
new file mode 100644
index 0000000000..61c40c44da
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-505354.js
@@ -0,0 +1,14 @@
+// Copyright 2015 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 --turbo-filter=f
+
+function f() {
+ "use strict";
+ try {
+ for (let i = 0; i < 10; i++) {}
+ } catch(e) {}
+}
+%OptimizeFunctionOnNextCall(f);
+f();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-505370.js b/deps/v8/test/mjsunit/regress/regress-crbug-505370.js
new file mode 100644
index 0000000000..f67d82b66f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-505370.js
@@ -0,0 +1,22 @@
+// Copyright 2015 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 = {
+ get 0() { reference_error; },
+ get length() { return 1; }
+};
+
+var method_name;
+
+try {
+ o[0];
+} catch (e) {
+ thrown = true;
+ Error.prepareStackTrace = function(exception, frames) { return frames; };
+ var frames = e.stack;
+ Error.prepareStackTrace = undefined;
+ method_name = frames[0].getMethodName();
+}
+
+assertEquals("0", method_name);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-505778.js b/deps/v8/test/mjsunit/regress/regress-crbug-505778.js
new file mode 100644
index 0000000000..74d96ab094
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-505778.js
@@ -0,0 +1,8 @@
+// Copyright 2015 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.
+
+if (this.Worker) {
+ var __v_7 = new Worker('onmessage = function() {}');
+ __v_7.postMessage("");
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-506443.js b/deps/v8/test/mjsunit/regress/regress-crbug-506443.js
new file mode 100644
index 0000000000..13cbac6769
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-506443.js
@@ -0,0 +1,89 @@
+// Copyright 2015 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
+
+assertSame = function assertSame() {
+ if (found === expected) {
+ if (1 / expected) return;
+ } else if ((expected !== expected) && (found !== found)) {
+ return;
+ };
+};
+assertEquals = function assertEquals() {
+ if (expected) {;
+ }
+};
+assertArrayEquals = function assertArrayEquals() {
+ var start = "";
+ if (name_opt) {
+ start = name_opt + " - ";
+ };
+ if (expected.length == found.length) {
+ for (var i = 0; i < expected.length; ++i) {;
+ }
+ }
+};
+assertPropertiesEqual = function assertPropertiesEqual() {
+ if (found) {;
+ }
+};
+assertToStringEquals = function assertToStringEquals() {
+ if (found) {;
+ }
+};
+assertTrue = function assertTrue() {;
+};
+assertFalse = function assertFalse() {;
+};
+assertUnreachable = function assertUnreachable() {
+ var message = "Fail" + "ure: unreachable";
+ if (name_opt) {
+ message += " - " + name_opt;
+ }
+};
+OptimizationStatus = function() {}
+assertUnoptimized = function assertUnoptimized() {;
+}
+assertOptimized = function assertOptimized() {;
+}
+triggerAssertFalse = function() {}
+var __v_2 = {};
+var __v_3 = {};
+var __v_4 = {};
+var __v_5 = {};
+var __v_6 = 1073741823;
+var __v_7 = {};
+var __v_8 = {};
+var __v_9 = {};
+var __v_10 = {};
+var __v_11 = 2147483648;
+var __v_12 = 1073741823;
+var __v_13 = {};
+var __v_14 = {};
+var __v_15 = -2147483648;
+var __v_16 = {};
+var __v_17 = {};
+var __v_19 = {};
+var __v_20 = {};
+var __v_21 = {};
+var __v_22 = {};
+var __v_23 = {};
+var __v_24 = {};
+try {
+ (function() {
+ var Debug = %GetDebugContext().Debug;
+
+ function __f_0() {}
+ for (var __v_0 = 0; __v_0 < 3; __v_0++) {
+ var __v_2 = function() {
+ a = 1;
+ }
+ Debug.setListener(__f_0);
+ if (__v_0 < 2) Debug.setBreakPoint(__v_2);
+ }
+ })();
+} catch (e) {
+ print();
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-debug-code-recompilation.js b/deps/v8/test/mjsunit/regress/regress-debug-code-recompilation.js
index 4723ec1307..2f81d0cb54 100644
--- a/deps/v8/test/mjsunit/regress/regress-debug-code-recompilation.js
+++ b/deps/v8/test/mjsunit/regress/regress-debug-code-recompilation.js
@@ -29,6 +29,7 @@
// Flags: --expose-debug-as debug
Debug = debug.Debug
+Debug.setListener(function(){});
function f() {a=1;b=2};
function g() {
@@ -46,3 +47,5 @@ Debug.clearBreakPoint(bp);
%OptimizeFunctionOnNextCall(Debug.setBreakPoint);
bp = Debug.setBreakPoint(f, 0, 0);
Debug.clearBreakPoint(bp);
+
+Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/regress/regress-debug-deopt-while-recompile.js b/deps/v8/test/mjsunit/regress/regress-debug-deopt-while-recompile.js
index ce5220a2b8..52c32e9cc3 100644
--- a/deps/v8/test/mjsunit/regress/regress-debug-deopt-while-recompile.js
+++ b/deps/v8/test/mjsunit/regress/regress-debug-deopt-while-recompile.js
@@ -26,7 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug --allow-natives-syntax
-// Flags: --turbo-deoptimization
Debug = debug.Debug;
diff --git a/deps/v8/test/mjsunit/regress/regress-eval-context.js b/deps/v8/test/mjsunit/regress/regress-eval-context.js
new file mode 100644
index 0000000000..e376282461
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-eval-context.js
@@ -0,0 +1,20 @@
+// Copyright 2015 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() {
+ 'use strict';
+ var x = 0;
+
+ {
+ let x = 1;
+ assertEquals(1, eval("x"));
+ }
+
+ {
+ let y = 2;
+ assertEquals(0, eval("x"));
+ }
+
+ assertEquals(0, eval("x"));
+})();
diff --git a/deps/v8/test/mjsunit/regress/regress-existing-shared-function-info.js b/deps/v8/test/mjsunit/regress/regress-existing-shared-function-info.js
new file mode 100644
index 0000000000..a53014c034
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-existing-shared-function-info.js
@@ -0,0 +1,18 @@
+// Copyright 2015 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
+
+function f() {
+ return function g() {
+ return function h() {}
+ }
+}
+
+var h = f()();
+
+// Make sure code has been flushed.
+for (var i of Array(10)) gc();
+
+f()();
diff --git a/deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js b/deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js
index 5cbaabca55..c637be5497 100644
--- a/deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js
+++ b/deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js
@@ -27,7 +27,6 @@
// Flags: --expose-debug-as debug --allow-natives-syntax
// Flags: --concurrent-recompilation --block-concurrent-recompilation
-// Flags: --turbo-deoptimization
if (!%IsConcurrentRecompilationSupported()) {
print("Concurrent recompilation is disabled. Skipping this test.");
diff --git a/deps/v8/test/mjsunit/regress/regress-osr-context.js b/deps/v8/test/mjsunit/regress/regress-osr-context.js
new file mode 100644
index 0000000000..8ceb79119a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-osr-context.js
@@ -0,0 +1,19 @@
+// Copyright 2015 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 --context-specialization --turbo-filter=f
+
+(function() {
+ "use strict";
+ var a = 23;
+ function f() {
+ for (let i = 0; i < 5; ++i) {
+ a--; // Make sure {a} is non-immutable, hence context allocated.
+ function g() { return i } // Make sure block has a context.
+ if (i == 2) %OptimizeOsr();
+ }
+ return a;
+ }
+ assertEquals(18, f());
+})();
diff --git a/deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js b/deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js
index 0aedcab015..0673220e4a 100644
--- a/deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js
+++ b/deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js
@@ -54,8 +54,10 @@ foo();
// and (shared) unoptimized code on foo, and sets both to lazy-compile builtin.
// Clear the break point immediately after to deactivate the debugger.
// Do all of this after compile graph has been created.
+Debug.setListener(function(){});
Debug.setBreakPoint(bar, 0, 0);
Debug.clearAllBreakPoints();
+Debug.setListener(null);
// At this point, concurrent recompilation is still blocked.
assertUnoptimized(foo, "no sync");
diff --git a/deps/v8/test/mjsunit/regress/regress-regexp-codeflush.js b/deps/v8/test/mjsunit/regress/regress-regexp-codeflush.js
index 5fa42bf8dc..8e7b0396e8 100644
--- a/deps/v8/test/mjsunit/regress/regress-regexp-codeflush.js
+++ b/deps/v8/test/mjsunit/regress/regress-regexp-codeflush.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: --gc_global
+// Flags: --gc-global
// Regression test for regexp that has multiple matches and which
// internally calls RegExpImpl::IrregexpExecOnce more than once without
diff --git a/deps/v8/test/mjsunit/regress/regress-splice-large-index.js b/deps/v8/test/mjsunit/regress/regress-splice-large-index.js
index 5da17eecf1..1f4eb9ce59 100644
--- a/deps/v8/test/mjsunit/regress/regress-splice-large-index.js
+++ b/deps/v8/test/mjsunit/regress/regress-splice-large-index.js
@@ -30,6 +30,7 @@ a[0xfffffffe] = 10;
assertThrows("a.unshift(1);", RangeError);
assertEquals(0xffffffff, a.length);
assertEquals(10, a[0xffffffff]);
+assertEquals(0xffffffff, a.length);
assertEquals(undefined, a[0xfffffffe]);
a = [1,2,3];
diff --git a/deps/v8/test/mjsunit/regress/regress-x87.js b/deps/v8/test/mjsunit/regress/regress-x87.js
index 60380a8fcb..c5edb709f8 100644
--- a/deps/v8/test/mjsunit/regress/regress-x87.js
+++ b/deps/v8/test/mjsunit/regress/regress-x87.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 --noenable-sse2
+// Flags: --allow-natives-syntax
// Regression for register allocation.
var x;
diff --git a/deps/v8/test/mjsunit/regress/string-set-char-deopt.js b/deps/v8/test/mjsunit/regress/string-set-char-deopt.js
index 03100a3505..8956e287db 100644
--- a/deps/v8/test/mjsunit/regress/string-set-char-deopt.js
+++ b/deps/v8/test/mjsunit/regress/string-set-char-deopt.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 --turbo-deoptimization
+// Flags: --allow-natives-syntax
(function OneByteSeqStringSetCharDeoptOsr() {
function deopt() {
diff --git a/deps/v8/test/mjsunit/samevalue.js b/deps/v8/test/mjsunit/samevalue.js
index 36a7dea3ea..229db0db4c 100644
--- a/deps/v8/test/mjsunit/samevalue.js
+++ b/deps/v8/test/mjsunit/samevalue.js
@@ -26,7 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --expose-natives_as natives
+// Flags: --expose-natives-as natives
// Test the SameValue internal method.
var obj1 = {x: 10, y: 11, z: "test"};
diff --git a/deps/v8/test/mjsunit/strict-mode.js b/deps/v8/test/mjsunit/strict-mode.js
index 326e725774..d9939765fc 100644
--- a/deps/v8/test/mjsunit/strict-mode.js
+++ b/deps/v8/test/mjsunit/strict-mode.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: --turbo-deoptimization
-
function CheckStrictMode(code, exception) {
assertDoesNotThrow(code);
assertThrows("'use strict';\n" + code, exception);
diff --git a/deps/v8/test/mjsunit/string-normalize.js b/deps/v8/test/mjsunit/string-normalize.js
new file mode 100644
index 0000000000..f88f193a09
--- /dev/null
+++ b/deps/v8/test/mjsunit/string-normalize.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.
+
+assertEquals('', ''.normalize());
+assertTrue(delete Array.prototype.indexOf);
+assertEquals('', ''.normalize());
+
+assertThrows(function() { ''.normalize('invalid'); }, RangeError);
+assertTrue(delete Array.prototype.join);
+assertThrows(function() { ''.normalize('invalid'); }, RangeError);
diff --git a/deps/v8/test/mjsunit/strong/classes.js b/deps/v8/test/mjsunit/strong/classes.js
index c329043ae1..c8d261760d 100644
--- a/deps/v8/test/mjsunit/strong/classes.js
+++ b/deps/v8/test/mjsunit/strong/classes.js
@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --strong-mode
-// Flags: --harmony-classes --harmony-arrow-functions
+// Flags: --strong-mode --harmony-arrow-functions
'use strong';
diff --git a/deps/v8/test/mjsunit/strong/declaration-after-use.js b/deps/v8/test/mjsunit/strong/declaration-after-use.js
index 020067c1e5..5f3ef2a79c 100644
--- a/deps/v8/test/mjsunit/strong/declaration-after-use.js
+++ b/deps/v8/test/mjsunit/strong/declaration-after-use.js
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --strong-mode --harmony_rest_parameters --harmony_arrow_functions --harmony_classes --harmony_computed-property_names
+// Flags: --strong-mode --harmony-rest-parameters --harmony-arrow-functions
+// Flags: --harmony-computed-property-names
// Note that it's essential for these tests that the reference is inside dead
// code (because we already produce ReferenceErrors for run-time unresolved
@@ -192,10 +193,6 @@ function assertThrowsHelper(code) {
i;
}
- let var6 = [1, 2];
- // The second var6 resolves to outside (not to the first var6).
- for (let var6 of var6) { var6; }
-
try {
throw "error";
} catch (e) {
@@ -211,13 +208,14 @@ function assertThrowsHelper(code) {
func2;
function func4(p, ...rest) { p; rest; this; func2; }
- func4();
+ // TODO(arv): The arity checking is not correct with rest parameters.
+ func4(1, 2);
let func5 = (p1, p2) => { p1; p2; };
- func5();
+ func5(1, 2);
let func5b = p1 => p1;
- func5b();
+ func5b(1);
function func6() {
var1, var2a, var2b, var2c;
diff --git a/deps/v8/test/mjsunit/strong/function-arity.js b/deps/v8/test/mjsunit/strong/function-arity.js
new file mode 100644
index 0000000000..4d8833564c
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/function-arity.js
@@ -0,0 +1,355 @@
+// Copyright 2015 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: --strong-mode --harmony-arrow-functions --harmony-reflect
+// Flags: --harmony-spreadcalls --harmony-rest-parameters --allow-natives-syntax
+
+'use strict';
+
+
+function generateArguments(n, prefix) {
+ let a = [];
+ if (prefix) {
+ a.push(prefix);
+ }
+ for (let i = 0; i < n; i++) {
+ a.push(String(i));
+ }
+
+ return a.join(', ');
+}
+
+
+function generateParams(n) {
+ let a = [];
+ for (let i = 0; i < n; i++) {
+ a[i] = `p${i}`;
+ }
+ return a.join(', ');
+}
+
+function generateParamsWithRest(n) {
+ let a = [];
+ let i = 0;
+ for (; i < n; i++) {
+ a[i] = `p${i}`;
+ }
+ a.push(`...p${i}`)
+ return a.join(', ');
+}
+
+
+function generateSpread(n) {
+ return `...[${generateArguments(n)}]`;
+}
+
+
+(function FunctionCall() {
+ for (let parameterCount = 0; parameterCount < 3; parameterCount++) {
+ let defs = [
+ `'use strong'; function f(${generateParams(parameterCount)}) {}`,
+ `'use strong'; function f(${generateParamsWithRest(parameterCount)}) {}`,
+ `'use strong'; function* f(${generateParams(parameterCount)}) {}`,
+ `'use strong'; function* f(${generateParamsWithRest(parameterCount)}) {}`,
+ `'use strong'; let f = (${generateParams(parameterCount)}) => {}`,
+ `function f(${generateParams(parameterCount)}) { 'use strong'; }`,
+ `function* f(${generateParams(parameterCount)}) { 'use strong'; }`,
+ `let f = (${generateParams(parameterCount)}) => { 'use strong'; }`,
+ ];
+ for (let def of defs) {
+ for (let argumentCount = 0; argumentCount < 3; argumentCount++) {
+ let calls = [
+ `f(${generateArguments(argumentCount)})`,
+ `f(${generateSpread(argumentCount)})`,
+ `f.call(${generateArguments(argumentCount, 'undefined')})`,
+ `f.call(undefined, ${generateSpread(argumentCount)})`,
+ `f.apply(undefined, [${generateArguments(argumentCount)}])`,
+ `f.bind(undefined)(${generateArguments(argumentCount)})`,
+ `%_CallFunction(${generateArguments(argumentCount, 'undefined')},
+ f)`,
+ `%Call(${generateArguments(argumentCount, 'undefined')}, f)`,
+ `%Apply(f, undefined, [${generateArguments(argumentCount)}], 0,
+ ${argumentCount})`,
+ ];
+
+ for (let call of calls) {
+ let code = `'use strict'; ${def}; ${call};`;
+ if (argumentCount < parameterCount) {
+ assertThrows(code, TypeError);
+ } else {
+ assertDoesNotThrow(code);
+ }
+ }
+ }
+
+ let calls = [
+ `f.call()`,
+ `f.apply()`,
+ `f.apply(undefined)`,
+ ];
+ for (let call of calls) {
+ let code = `'use strict'; ${def}; ${call};`;
+ if (parameterCount > 0) {
+ assertThrows(code, TypeError);
+ } else {
+ assertDoesNotThrow(code);
+ }
+ }
+ }
+ }
+})();
+
+
+(function MethodCall() {
+ for (let genParams of [generateParams, generateParamsWithRest]) {
+ for (let parameterCount = 0; parameterCount < 3; parameterCount++) {
+ let defs = [
+ `let o = new class {
+ m(${genParams(parameterCount)}) { 'use strong'; }
+ }`,
+ `let o = new class {
+ *m(${genParams(parameterCount)}) { 'use strong'; }
+ }`,
+ `let o = { m(${genParams(parameterCount)}) { 'use strong'; } }`,
+ `let o = { *m(${genParams(parameterCount)}) { 'use strong'; } }`,
+ `'use strong';
+ let o = new class { m(${genParams(parameterCount)}) {} }`,
+ `'use strong';
+ let o = new class { *m(${genParams(parameterCount)}) {} }`,
+ `'use strong'; let o = { m(${genParams(parameterCount)}) {} }`,
+ `'use strong'; let o = { *m(${genParams(parameterCount)}) {} }`,
+ ];
+ for (let def of defs) {
+ for (let argumentCount = 0; argumentCount < 3; argumentCount++) {
+ let calls = [
+ `o.m(${generateArguments(argumentCount)})`,
+ `o.m(${generateSpread(argumentCount)})`,
+ `o.m.call(${generateArguments(argumentCount, 'o')})`,
+ `o.m.call(o, ${generateSpread(argumentCount)})`,
+ `o.m.apply(o, [${generateArguments(argumentCount)}])`,
+ `o.m.bind(o)(${generateArguments(argumentCount)})`,
+ `%_CallFunction(${generateArguments(argumentCount, 'o')}, o.m)`,
+ `%Call(${generateArguments(argumentCount, 'o')}, o.m)`,
+ `%Apply(o.m, o, [${generateArguments(argumentCount)}], 0,
+ ${argumentCount})`,
+ ];
+
+ for (let call of calls) {
+ let code = `'use strict'; ${def}; ${call};`;
+ if (argumentCount < parameterCount) {
+ assertThrows(code, TypeError);
+ } else {
+ assertDoesNotThrow(code);
+ }
+ }
+ }
+
+ let calls = [
+ `o.m.call()`,
+ `o.m.apply()`,
+ `o.m.apply(o)`,
+ ];
+ for (let call of calls) {
+ let code = `'use strict'; ${def}; ${call};`;
+ if (parameterCount > 0) {
+ assertThrows(code, TypeError);
+ } else {
+ assertDoesNotThrow(code);
+ }
+ }
+ }
+ }
+ }
+})();
+
+
+(function Constructor() {
+ for (let genParams of [generateParams, generateParamsWithRest]) {
+ for (let argumentCount = 0; argumentCount < 3; argumentCount++) {
+ for (let parameterCount = 0; parameterCount < 3; parameterCount++) {
+ let defs = [
+ `'use strong';
+ class C { constructor(${genParams(parameterCount)}) {} }`,
+ `'use strict';
+ class C {
+ constructor(${genParams(parameterCount)}) { 'use strong'; }
+ }`,
+ ];
+ for (let def of defs) {
+ let calls = [
+ `new C(${generateArguments(argumentCount)})`,
+ `new C(${generateSpread(argumentCount)})`,
+ `Reflect.construct(C, [${generateArguments(argumentCount)}])`,
+ ];
+ for (let call of calls) {
+ let code = `${def}; ${call};`;
+ if (argumentCount < parameterCount) {
+ assertThrows(code, TypeError);
+ } else {
+ assertDoesNotThrow(code);
+ }
+ }
+ }
+ }
+ }
+ }
+})();
+
+
+(function DerivedConstructor() {
+ for (let genParams of [generateParams, generateParamsWithRest]) {
+ for (let genArgs of [generateArguments, generateSpread]) {
+ for (let argumentCount = 0; argumentCount < 3; argumentCount++) {
+ for (let parameterCount = 0; parameterCount < 3; parameterCount++) {
+ let defs = [
+ `'use strong';
+ class B {
+ constructor(${genParams(parameterCount)}) {}
+ }
+ class C extends B {
+ constructor() {
+ super(${genArgs(argumentCount)});
+ }
+ }`,
+ `'use strict';
+ class B {
+ constructor(${genParams(parameterCount)}) { 'use strong'; }
+ }
+ class C extends B {
+ constructor() {
+ super(${genArgs(argumentCount)});
+ }
+ }`,
+ ];
+ for (let def of defs) {
+ let code = `${def}; new C();`;
+ if (argumentCount < parameterCount) {
+ assertThrows(code, TypeError);
+ } else {
+ assertDoesNotThrow(code);
+ }
+ }
+ }
+ }
+ }
+ }
+})();
+
+
+(function DerivedConstructorDefaultConstructorInDerivedClass() {
+ for (let genParams of [generateParams, generateParamsWithRest]) {
+ for (let genArgs of [generateArguments, generateSpread]) {
+ for (let argumentCount = 0; argumentCount < 3; argumentCount++) {
+ for (let parameterCount = 0; parameterCount < 3; parameterCount++) {
+ let defs = [
+ `'use strong';
+ class B {
+ constructor(${genParams(parameterCount)}) {}
+ }
+ class C extends B {}`,
+ `'use strict';
+ class B {
+ constructor(${genParams(parameterCount)}) { 'use strong'; }
+ }
+ class C extends B {}`,
+ ];
+ for (let def of defs) {
+ let code = `${def}; new C(${genArgs(argumentCount)})`;
+ if (argumentCount < parameterCount) {
+ assertThrows(code, TypeError);
+ } else {
+ assertDoesNotThrow(code);
+ }
+ }
+ }
+ }
+ }
+ }
+})();
+
+
+(function TestOptimized() {
+ function f(x, y) { 'use strong'; }
+
+ assertThrows(f, TypeError);
+ %OptimizeFunctionOnNextCall(f);
+ assertThrows(f, TypeError);
+
+ function g() {
+ f(1);
+ }
+ assertThrows(g, TypeError);
+ %OptimizeFunctionOnNextCall(g);
+ assertThrows(g, TypeError);
+
+ f(1, 2);
+ %OptimizeFunctionOnNextCall(f);
+ f(1, 2);
+})();
+
+
+(function TestOptimized2() {
+ 'use strong';
+ function f(x, y) {}
+
+ assertThrows(f, TypeError);
+ %OptimizeFunctionOnNextCall(f);
+ assertThrows(f, TypeError);
+
+ function g() {
+ f(1);
+ }
+ assertThrows(g, TypeError);
+ %OptimizeFunctionOnNextCall(g);
+ assertThrows(g, TypeError);
+
+ f(1, 2);
+ %OptimizeFunctionOnNextCall(f);
+ f(1, 2);
+})();
+
+
+(function TestOptimized3() {
+ function f(x, y) {}
+ function g() {
+ 'use strong';
+ f(1);
+ }
+
+ g();
+ %OptimizeFunctionOnNextCall(f);
+ g();
+})();
+
+
+(function ParametersSuper() {
+ for (let genArgs of [generateArguments, generateSpread]) {
+ for (let argumentCount = 0; argumentCount < 3; argumentCount++) {
+ for (let parameterCount = 0; parameterCount < 3; parameterCount++) {
+ let defs = [
+ `'use strict';
+ class B {
+ m(${generateParams(parameterCount)} ){ 'use strong' }
+ }`,
+ `'use strong'; class B { m(${generateParams(parameterCount)}) {} }`,
+ ];
+ for (let def of defs) {
+ let code = `${def};
+ class D extends B {
+ m() {
+ super.m(${genArgs(argumentCount)});
+ }
+ }
+ new D().m()`;
+ print('\n\n' + code);
+ if (argumentCount < parameterCount) {
+ assertThrows(code, TypeError);
+ } else {
+ assertDoesNotThrow(code);
+ }
+ }
+ }
+ }
+ }
+})();
diff --git a/deps/v8/test/mjsunit/strong/functions.js b/deps/v8/test/mjsunit/strong/functions.js
index 6956462e5d..a237270977 100644
--- a/deps/v8/test/mjsunit/strong/functions.js
+++ b/deps/v8/test/mjsunit/strong/functions.js
@@ -47,8 +47,8 @@ function* g() {}
(function LexicalBindings(global) {
assertEquals('function', typeof f);
assertEquals('function', typeof g);
- assertEquals(undefined, global.f);
- assertEquals(undefined, global.g);
+ assertFalse(global.hasOwnProperty("f"));
+ assertFalse(global.hasOwnProperty("g"));
})(this);
(function ImmutableBindings() {
diff --git a/deps/v8/test/mjsunit/strong/implicit-conversions-constants.js b/deps/v8/test/mjsunit/strong/implicit-conversions-constants.js
new file mode 100644
index 0000000000..c24056299f
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/implicit-conversions-constants.js
@@ -0,0 +1,203 @@
+// Copyright 2015 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: --strong-mode --allow-natives-syntax
+
+"use strict";
+
+function getTestFuncs() {
+ "use strong";
+ return [
+ function(x){return 1 + true;},
+ function(x){return 1 - true;},
+ function(x){return 1 * true;},
+ function(x){return 1 / true;},
+ function(x){return 1 % true;},
+ function(x){return 1 | true;},
+ function(x){return 1 & true;},
+ function(x){return 1 ^ true;},
+ function(x){return 1 << true;},
+ function(x){return 1 >> true;},
+ function(x){return 1 >>> true;},
+ function(x){return 1 < true;},
+ function(x){return 1 > true;},
+ function(x){return 1 <= true;},
+ function(x){return 1 >= true;},
+ function(x){return 1 + undefined;},
+ function(x){return 1 - undefined;},
+ function(x){return 1 * undefined;},
+ function(x){return 1 / undefined;},
+ function(x){return 1 % undefined;},
+ function(x){return 1 | undefined;},
+ function(x){return 1 & undefined;},
+ function(x){return 1 ^ undefined;},
+ function(x){return 1 << undefined;},
+ function(x){return 1 >> undefined;},
+ function(x){return 1 >>> undefined;},
+ function(x){return 1 < undefined;},
+ function(x){return 1 > undefined;},
+ function(x){return 1 <= undefined;},
+ function(x){return 1 >= undefined;},
+ function(x){return 1 + null;},
+ function(x){return 1 - null;},
+ function(x){return 1 * null;},
+ function(x){return 1 / null;},
+ function(x){return 1 % null;},
+ function(x){return 1 | null;},
+ function(x){return 1 & null;},
+ function(x){return 1 ^ null;},
+ function(x){return 1 << null;},
+ function(x){return 1 >> null;},
+ function(x){return 1 >>> null;},
+ function(x){return 1 < null;},
+ function(x){return 1 > null;},
+ function(x){return 1 <= null;},
+ function(x){return 1 >= null;},
+ function(x){return NaN + true;},
+ function(x){return NaN - true;},
+ function(x){return NaN * true;},
+ function(x){return NaN / true;},
+ function(x){return NaN % true;},
+ function(x){return NaN | true;},
+ function(x){return NaN & true;},
+ function(x){return NaN ^ true;},
+ function(x){return NaN << true;},
+ function(x){return NaN >> true;},
+ function(x){return NaN >>> true;},
+ function(x){return NaN < true;},
+ function(x){return NaN > true;},
+ function(x){return NaN <= true;},
+ function(x){return NaN >= true;},
+ function(x){return NaN + undefined;},
+ function(x){return NaN - undefined;},
+ function(x){return NaN * undefined;},
+ function(x){return NaN / undefined;},
+ function(x){return NaN % undefined;},
+ function(x){return NaN | undefined;},
+ function(x){return NaN & undefined;},
+ function(x){return NaN ^ undefined;},
+ function(x){return NaN << undefined;},
+ function(x){return NaN >> undefined;},
+ function(x){return NaN >>> undefined;},
+ function(x){return NaN < undefined;},
+ function(x){return NaN > undefined;},
+ function(x){return NaN <= undefined;},
+ function(x){return NaN >= undefined;},
+ function(x){return NaN + null;},
+ function(x){return NaN - null;},
+ function(x){return NaN * null;},
+ function(x){return NaN / null;},
+ function(x){return NaN % null;},
+ function(x){return NaN | null;},
+ function(x){return NaN & null;},
+ function(x){return NaN ^ null;},
+ function(x){return NaN << null;},
+ function(x){return NaN >> null;},
+ function(x){return NaN >>> null;},
+ function(x){return NaN < null;},
+ function(x){return NaN > null;},
+ function(x){return NaN <= null;},
+ function(x){return NaN >= null;},
+ function(x){return true + 1;},
+ function(x){return true - 1;},
+ function(x){return true * 1;},
+ function(x){return true / 1;},
+ function(x){return true % 1;},
+ function(x){return true | 1;},
+ function(x){return true & 1;},
+ function(x){return true ^ 1;},
+ function(x){return true << 1;},
+ function(x){return true >> 1;},
+ function(x){return true >>> 1;},
+ function(x){return true < 1;},
+ function(x){return true > 1;},
+ function(x){return true <= 1;},
+ function(x){return true >= 1;},
+ function(x){return undefined + 1;},
+ function(x){return undefined - 1;},
+ function(x){return undefined * 1;},
+ function(x){return undefined / 1;},
+ function(x){return undefined % 1;},
+ function(x){return undefined | 1;},
+ function(x){return undefined & 1;},
+ function(x){return undefined ^ 1;},
+ function(x){return undefined << 1;},
+ function(x){return undefined >> 1;},
+ function(x){return undefined >>> 1;},
+ function(x){return undefined < 1;},
+ function(x){return undefined > 1;},
+ function(x){return undefined <= 1;},
+ function(x){return undefined >= 1;},
+ function(x){return null + 1;},
+ function(x){return null - 1;},
+ function(x){return null * 1;},
+ function(x){return null / 1;},
+ function(x){return null % 1;},
+ function(x){return null | 1;},
+ function(x){return null & 1;},
+ function(x){return null ^ 1;},
+ function(x){return null << 1;},
+ function(x){return null >> 1;},
+ function(x){return null >>> 1;},
+ function(x){return null < 1;},
+ function(x){return null > 1;},
+ function(x){return null <= 1;},
+ function(x){return null >= 1;},
+ function(x){return true + NaN;},
+ function(x){return true - NaN;},
+ function(x){return true * NaN;},
+ function(x){return true / NaN;},
+ function(x){return true % NaN;},
+ function(x){return true | NaN;},
+ function(x){return true & NaN;},
+ function(x){return true ^ NaN;},
+ function(x){return true << NaN;},
+ function(x){return true >> NaN;},
+ function(x){return true >>> NaN;},
+ function(x){return true < NaN;},
+ function(x){return true > NaN;},
+ function(x){return true <= NaN;},
+ function(x){return true >= NaN;},
+ function(x){return undefined + NaN;},
+ function(x){return undefined - NaN;},
+ function(x){return undefined * NaN;},
+ function(x){return undefined / NaN;},
+ function(x){return undefined % NaN;},
+ function(x){return undefined | NaN;},
+ function(x){return undefined & NaN;},
+ function(x){return undefined ^ NaN;},
+ function(x){return undefined << NaN;},
+ function(x){return undefined >> NaN;},
+ function(x){return undefined >>> NaN;},
+ function(x){return undefined < NaN;},
+ function(x){return undefined > NaN;},
+ function(x){return undefined <= NaN;},
+ function(x){return undefined >= NaN;},
+ function(x){return null + NaN;},
+ function(x){return null - NaN;},
+ function(x){return null * NaN;},
+ function(x){return null / NaN;},
+ function(x){return null % NaN;},
+ function(x){return null | NaN;},
+ function(x){return null & NaN;},
+ function(x){return null ^ NaN;},
+ function(x){return null << NaN;},
+ function(x){return null >> NaN;},
+ function(x){return null >>> NaN;},
+ function(x){return null < NaN;},
+ function(x){return null > NaN;},
+ function(x){return null <= NaN;},
+ function(x){return null >= NaN;}
+ ];
+}
+
+for (let func of getTestFuncs()) {
+ assertThrows(func, TypeError);
+ assertThrows(func, TypeError);
+ assertThrows(func, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(func, TypeError);
+ %DeoptimizeFunction(func);
+ assertThrows(func, TypeError);
+}
diff --git a/deps/v8/test/mjsunit/strong/implicit-conversions-count.js b/deps/v8/test/mjsunit/strong/implicit-conversions-count.js
new file mode 100644
index 0000000000..88ed3c2068
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/implicit-conversions-count.js
@@ -0,0 +1,168 @@
+// Copyright 2015 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: --strong-mode --allow-natives-syntax
+
+"use strict";
+
+function pre_inc(x) {
+ return ++x;
+}
+
+function post_inc(x) {
+ return x++;
+}
+
+function pre_dec(x) {
+ return --x;
+}
+
+function post_dec(x) {
+ return x--;
+}
+
+function getTestFuncs() {
+ return [
+ function(x){
+ "use strong";
+ let y = x;
+ assertEquals(++y, pre_inc(x));
+ try {
+ assertEquals(x+1, y)
+ } catch (e) {
+ assertUnreachable();
+ }
+ },
+ function(x){
+ "use strong";
+ let y = x;
+ assertEquals(y++, post_inc(x));
+ try {
+ assertEquals(x+1, y)
+ } catch (e) {
+ assertUnreachable();
+ }
+ },
+ function(x){
+ "use strong";
+ let y = x;
+ assertEquals(--y, pre_dec(x));
+ try {
+ assertEquals(x-1, y)
+ } catch (e) {
+ assertUnreachable();
+ }
+ },
+ function(x){
+ "use strong";
+ let y = x;
+ assertEquals(y--, post_dec(x));
+ try {
+ assertEquals(x-1, y)
+ } catch (e) {
+ assertUnreachable();
+ }
+ },
+ function(x){
+ "use strong";
+ let obj = { foo: x };
+ let y = ++obj.foo;
+ assertEquals(y, pre_inc(x));
+ try {
+ assertEquals(x+1, obj.foo)
+ } catch (e) {
+ assertUnreachable();
+ }
+ },
+ function(x){
+ "use strong";
+ let obj = { foo: x };
+ let y = obj.foo++;
+ assertEquals(y, post_inc(x));
+ try {
+ assertEquals(x+1, obj.foo)
+ } catch (e) {
+ assertUnreachable();
+ }
+ },
+ function(x){
+ "use strong";
+ let obj = { foo: x };
+ let y = --obj.foo;
+ assertEquals(y, pre_dec(x));
+ try {
+ assertEquals(x-1, obj.foo)
+ } catch (e) {
+ assertUnreachable();
+ }
+ },
+ function(x){
+ "use strong";
+ let obj = { foo: x };
+ let y = obj.foo--;
+ assertEquals(y, post_dec(x));
+ try {
+ assertEquals(x-1, obj.foo)
+ } catch (e) {
+ assertUnreachable();
+ }
+ },
+ ];
+}
+
+let nonNumberValues = [
+ {},
+ (function(){}),
+ [],
+ (class Foo {}),
+ "",
+ "foo",
+ "NaN",
+ Object(""),
+ false,
+ null,
+ undefined
+];
+
+// Check prior input of None works
+for (let func of getTestFuncs()) {
+ for (let value of nonNumberValues) {
+ assertThrows(function(){func(value)}, TypeError);
+ assertThrows(function(){func(value)}, TypeError);
+ assertThrows(function(){func(value)}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(value)}, TypeError);
+ %DeoptimizeFunction(func);
+ }
+}
+
+// Check prior input of Smi works
+for (let func of getTestFuncs()) {
+ func(1);
+ func(1);
+ func(1);
+ for (let value of nonNumberValues) {
+ assertThrows(function(){func(value)}, TypeError);
+ assertThrows(function(){func(value)}, TypeError);
+ assertThrows(function(){func(value)}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(value)}, TypeError);
+ %DeoptimizeFunction(func);
+ }
+}
+
+// Check prior input of Number works
+for (let func of getTestFuncs()) {
+ func(9999999999999);
+ func(9999999999999);
+ func(9999999999999);
+ for (let value of nonNumberValues) {
+ assertThrows(function(){func(value)}, TypeError);
+ assertThrows(function(){func(value)}, TypeError);
+ assertThrows(function(){func(value)}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(value)}, TypeError);
+ %DeoptimizeFunction(func);
+ }
+}
diff --git a/deps/v8/test/mjsunit/strong/implicit-conversions-inlining.js b/deps/v8/test/mjsunit/strong/implicit-conversions-inlining.js
index f1cb9cd36d..15997a37aa 100644
--- a/deps/v8/test/mjsunit/strong/implicit-conversions-inlining.js
+++ b/deps/v8/test/mjsunit/strong/implicit-conversions-inlining.js
@@ -6,6 +6,8 @@
"use strict";
+//******************************************************************************
+// Number function declarations
function inline_add_strong(x, y) {
"use strong";
return x + y;
@@ -105,6 +107,42 @@ function inline_sar_strong_outer(x, y) {
return inline_sar_strong(x, y);
}
+function inline_less_strong(x, y) {
+ "use strong";
+ return x < y;
+}
+
+function inline_less_strong_outer(x, y) {
+ return inline_less_strong(x, y);
+}
+
+function inline_greater_strong(x, y) {
+ "use strong";
+ return x > y;
+}
+
+function inline_greater_strong_outer(x, y) {
+ return inline_greater_strong(x, y);
+}
+
+function inline_less_equal_strong(x, y) {
+ "use strong";
+ return x <= y;
+}
+
+function inline_less_equal_strong_outer(x, y) {
+ return inline_less_equal_strong(x, y);
+}
+
+function inline_greater_equal_strong(x, y) {
+ "use strong";
+ return x >= y;
+}
+
+function inline_greater_equal_strong_outer(x, y) {
+ return inline_greater_equal_strong(x, y);
+}
+
function inline_add(x, y) {
return x + y;
}
@@ -204,19 +242,170 @@ function inline_sar_outer_strong(x, y) {
return inline_sar(x, y);
}
-let strong_inner_funcs = [inline_add_strong_outer, inline_sub_strong_outer,
- inline_mul_strong_outer, inline_div_strong_outer,
- inline_mod_strong_outer, inline_or_strong_outer,
- inline_and_strong_outer, inline_xor_strong_outer,
- inline_shl_strong_outer, inline_shr_strong_outer];
+function inline_less(x, y) {
+ return x < y;
+}
+
+function inline_less_outer_strong(x, y) {
+ "use strong";
+ return inline_less(x, y);
+}
+
+function inline_greater(x, y) {
+ return x > y;
+}
+
+function inline_greater_outer_strong(x, y) {
+ "use strong";
+ return inline_greater(x, y);
+}
-let strong_outer_funcs = [inline_add_outer_strong, inline_sub_outer_strong,
- inline_mul_outer_strong, inline_div_outer_strong,
- inline_mod_outer_strong, inline_or_outer_strong,
- inline_and_outer_strong, inline_xor_outer_strong,
- inline_shl_outer_strong, inline_shr_outer_strong];
+function inline_less_equal(x, y) {
+ return x <= y;
+}
+
+function inline_less_equal_outer_strong(x, y) {
+ "use strong";
+ return inline_less_equal(x, y);
+}
+
+function inline_greater_equal(x, y) {
+ return x >>> y;
+}
+
+function inline_greater_equal_outer_strong(x, y) {
+ "use strong";
+ return inline_greater_equal(x, y);
+}
+
+//******************************************************************************
+// String function declarations
+function inline_add_string_strong(x, y) {
+ "use strong";
+ return x + y;
+}
+
+function inline_add_string_strong_outer(x, y) {
+ return inline_add_string_strong(x, y);
+}
+
+function inline_less_string_strong(x, y) {
+ "use strong";
+ return x < y;
+}
+
+function inline_less_string_strong_outer(x, y) {
+ return inline_less_string_strong(x, y);
+}
-for (let strong_inner_func of strong_inner_funcs) {
+function inline_greater_string_strong(x, y) {
+ "use strong";
+ return x > y;
+}
+
+function inline_greater_string_strong_outer(x, y) {
+ return inline_greater_string_strong(x, y);
+}
+
+function inline_less_equal_string_strong(x, y) {
+ "use strong";
+ return x <= y;
+}
+
+function inline_less_equal_string_strong_outer(x, y) {
+ return inline_less_equal_string_strong(x, y);
+}
+
+function inline_greater_equal_string_strong(x, y) {
+ "use strong";
+ return x >= y;
+}
+
+function inline_greater_equal_string_strong_outer(x, y) {
+ return inline_greater_equal_string_strong(x, y);
+}
+
+function inline_add_string(x, y) {
+ return x + y;
+}
+
+function inline_add_string_outer_strong(x, y) {
+ "use strong";
+ return inline_add_string(x, y);
+}
+
+function inline_less_string(x, y) {
+ return x < y;
+}
+
+function inline_less_string_outer_strong(x, y) {
+ "use strong";
+ return inline_less_string(x, y);
+}
+
+function inline_greater_string(x, y) {
+ return x > y;
+}
+
+function inline_greater_string_outer_strong(x, y) {
+ "use strong";
+ return inline_greater_string(x, y);
+}
+
+function inline_less_equal_string(x, y) {
+ return x <= y;
+}
+
+function inline_less_equal_string_outer_strong(x, y) {
+ "use strong";
+ return inline_less_equal_string(x, y);
+}
+
+function inline_greater_equal_string(x, y) {
+ return x >= y;
+}
+
+function inline_greater_equal_string_outer_strong(x, y) {
+ "use strong";
+ return inline_greater_equal_string(x, y);
+}
+
+
+//******************************************************************************
+// Testing
+let strong_inner_funcs_num = [inline_add_strong_outer, inline_sub_strong_outer,
+ inline_mul_strong_outer, inline_div_strong_outer,
+ inline_mod_strong_outer, inline_or_strong_outer,
+ inline_and_strong_outer, inline_xor_strong_outer,
+ inline_shl_strong_outer, inline_shr_strong_outer,
+ inline_less_strong_outer,
+ inline_greater_strong_outer,
+ inline_less_equal_strong_outer,
+ inline_greater_equal_strong_outer];
+
+let strong_outer_funcs_num = [inline_add_outer_strong, inline_sub_outer_strong,
+ inline_mul_outer_strong, inline_div_outer_strong,
+ inline_mod_outer_strong, inline_or_outer_strong,
+ inline_and_outer_strong, inline_xor_outer_strong,
+ inline_shl_outer_strong, inline_shr_outer_strong,
+ inline_less_outer_strong,
+ inline_greater_outer_strong,
+ inline_less_equal_outer_strong,
+ inline_greater_equal_outer_strong];
+
+let strong_inner_funcs_string = [inline_add_string_strong_outer,
+ inline_less_string_strong_outer,
+ inline_greater_string_strong_outer,
+ inline_less_equal_string_strong_outer,
+ inline_greater_equal_string_strong_outer];
+
+let strong_outer_funcs_string = [inline_add_string_outer_strong,
+ inline_less_string_outer_strong,
+ inline_greater_string_outer_strong,
+ inline_less_equal_string_outer_strong,
+ inline_greater_equal_string_outer_strong];
+
+for (let strong_inner_func of strong_inner_funcs_num) {
assertThrows(function(){strong_inner_func(1, {})}, TypeError);
for (var i = 0; i < 100; i++) {
strong_inner_func(1, 2);
@@ -225,7 +414,7 @@ for (let strong_inner_func of strong_inner_funcs) {
assertThrows(function(){strong_inner_func(1, {})}, TypeError);
}
-for (let strong_outer_func of strong_outer_funcs) {
+for (let strong_outer_func of strong_outer_funcs_num) {
assertDoesNotThrow(function(){strong_outer_func(1, {})});
for (var i = 0; i < 100; i++) {
strong_outer_func(1, 2);
@@ -233,3 +422,21 @@ for (let strong_outer_func of strong_outer_funcs) {
%OptimizeFunctionOnNextCall(strong_outer_func);
assertDoesNotThrow(function(){strong_outer_func(1, {})});
}
+
+for (let strong_inner_func of strong_inner_funcs_string) {
+ assertThrows(function(){strong_inner_func("foo", {})}, TypeError);
+ for (var i = 0; i < 100; i++) {
+ strong_inner_func("foo", "bar");
+ }
+ %OptimizeFunctionOnNextCall(strong_inner_func);
+ assertThrows(function(){strong_inner_func("foo", {})}, TypeError);
+}
+
+for (let strong_outer_func of strong_outer_funcs_string) {
+ assertDoesNotThrow(function(){strong_outer_func("foo", {})});
+ for (var i = 0; i < 100; i++) {
+ strong_outer_func("foo", "bar");
+ }
+ %OptimizeFunctionOnNextCall(strong_outer_func);
+ assertDoesNotThrow(function(){strong_outer_func("foo", {})});
+}
diff --git a/deps/v8/test/mjsunit/strong/implicit-conversions.js b/deps/v8/test/mjsunit/strong/implicit-conversions.js
index c13953583f..cd8acf7085 100644
--- a/deps/v8/test/mjsunit/strong/implicit-conversions.js
+++ b/deps/v8/test/mjsunit/strong/implicit-conversions.js
@@ -6,22 +6,26 @@
"use strict";
-// TODO(conradw): Implement other strong operators
+// Boolean indicates whether an operator can be part of a compound assignment.
let strongNumberBinops = [
- "-",
- "*",
- "/",
- "%",
- "|",
- "&",
- "^",
- "<<",
- ">>",
- ">>>",
+ ["-", true],
+ ["*", true],
+ ["/", true],
+ ["%", true],
+ ["|", true],
+ ["&", true],
+ ["^", true],
+ ["<<", true],
+ [">>", true],
+ [">>>", true]
];
let strongStringOrNumberBinops = [
- "+"
+ ["+", true],
+ ["<", false],
+ [">", false],
+ ["<=", false],
+ [">=", false]
];
let strongBinops = strongNumberBinops.concat(strongStringOrNumberBinops);
@@ -33,6 +37,8 @@ let strongUnops = [
];
let nonStringOrNumberValues = [
+ "null",
+ "undefined",
"{}",
"false",
"(function(){})",
@@ -55,23 +61,17 @@ let numberValues = [
"0",
"(-0)",
"1",
- "0.79",
- "(-0.79)",
- "4294967295",
- "4294967296",
"(-4294967295)",
"(-4294967296)",
"9999999999999",
"(-9999999999999)",
- "1.5e10",
- "(-1.5e10)",
- "0xFFF",
- "(-0xFFF)",
"NaN",
"Infinity",
"(-Infinity)"
];
+//******************************************************************************
+// Relational comparison function declarations
function add_strong(x, y) {
"use strong";
return x + y;
@@ -132,6 +132,46 @@ function sar_strong(x, y) {
return x >>> y;
}
+function less_strong(x, y) {
+ "use strong";
+ return x < y;
+}
+
+function less_num_strong(x, y) {
+ "use strong";
+ return x < y;
+}
+
+function greater_strong(x, y) {
+ "use strong";
+ return x > y;
+}
+
+function greater_num_strong(x, y) {
+ "use strong";
+ return x > y;
+}
+
+function less_equal_strong(x, y) {
+ "use strong";
+ return x <= y;
+}
+
+function less_equal_num_strong(x, y) {
+ "use strong";
+ return x <= y;
+}
+
+function greater_equal_strong(x, y) {
+ "use strong";
+ return x >= y;
+}
+
+function greater_equal_num_strong(x, y) {
+ "use strong";
+ return x >= y;
+}
+
function typed_add_strong(x, y) {
"use strong";
return (+x) + (+y);
@@ -187,15 +227,52 @@ function typed_sar_strong(x, y) {
return (+x) >>> (+y);
}
+function typed_less_strong(x, y) {
+ "use strong";
+ return (+x) < (+y);
+}
+
+function typed_greater_strong(x, y) {
+ "use strong";
+ return (+x) > (+y);
+}
+
+function typed_less_equal_strong(x, y) {
+ "use strong";
+ return (+x) <= (+y);
+}
+
+function typed_greater_equal_strong(x, y) {
+ "use strong";
+ return (+x) >= (+y);
+}
+
+//******************************************************************************
+// (in)equality function declarations
+function str_equal_strong(x, y) {
+ "use strong";
+ return x === y;
+}
+
+function str_ineq_strong(x, y) {
+ "use strong";
+ return x !== y;
+}
+
let strongNumberFuncs = [add_num_strong, sub_strong, mul_strong, div_strong,
mod_strong, or_strong, and_strong, xor_strong,
- shl_strong, shr_strong, sar_strong, typed_add_strong,
+ shl_strong, shr_strong, sar_strong, less_num_strong,
+ greater_num_strong, less_equal_num_strong,
+ greater_equal_num_strong, typed_add_strong,
typed_sub_strong, typed_mul_strong, typed_div_strong,
typed_mod_strong, typed_or_strong, typed_and_strong,
typed_xor_strong, typed_shl_strong, typed_shr_strong,
- typed_sar_strong];
+ typed_sar_strong, typed_less_strong,
+ typed_greater_strong, typed_less_equal_strong,
+ typed_greater_equal_strong];
-let strongStringOrNumberFuncs = [add_strong];
+let strongStringOrNumberFuncs = [add_strong, less_strong, greater_strong,
+ less_equal_strong, greater_equal_strong];
let strongFuncs = strongNumberFuncs.concat(strongStringOrNumberFuncs);
@@ -214,16 +291,20 @@ function assertStrongThrowBehaviour(expr) {
function checkArgumentCombinations(op, leftList, rightList, willThrow) {
for (let v1 of leftList) {
- let assignExpr = "foo " + op + "= " + v1 + ";";
+ let assignExpr = "foo " + op[0] + "= " + v1 + ";";
for (let v2 of rightList) {
let compoundAssignment = "'use strong'; let foo = " + v2 + "; " +
assignExpr;
- if(willThrow) {
- assertThrows(compoundAssignment, TypeError);
- assertStrongThrowBehaviour("(" + v1 + op + v2 + ")");
+ if (willThrow) {
+ if (op[1]) {
+ assertThrows(compoundAssignment, TypeError);
+ }
+ assertStrongThrowBehaviour("(" + v1 + op[0] + v2 + ")");
} else {
- assertDoesNotThrow(compoundAssignment);
- assertStrongNonThrowBehaviour("(" + v1 + op + v2 + ")");
+ if (op[1]) {
+ assertDoesNotThrow(compoundAssignment);
+ }
+ assertStrongNonThrowBehaviour("(" + v1 + op[0] + v2 + ")");
}
}
}
@@ -257,44 +338,75 @@ for (let op of strongUnops) {
for (let func of strongNumberFuncs) {
// Check IC None*None->None throws
- assertThrows(function(){func(2, "foo");}, TypeError);
- %OptimizeFunctionOnNextCall(func);
- assertThrows(function(){func(2, "foo");}, TypeError);
- %DeoptimizeFunction(func);
+ for (let v of nonNumberValues) {
+ let value = eval(v);
+ assertThrows(function(){func(2, value);}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(2, value);}, TypeError);
+ %DeoptimizeFunction(func);
+ }
func(4, 5);
func(4, 5);
// Check IC Smi*Smi->Smi throws
- assertThrows(function(){func(2, "foo");}, TypeError);
- %OptimizeFunctionOnNextCall(func);
- assertThrows(function(){func(2, "foo");}, TypeError);
- %DeoptimizeFunction(func);
+ for (let v of nonNumberValues) {
+ let value = eval(v);
+ assertThrows(function(){func(2, value);}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(2, value);}, TypeError);
+ %DeoptimizeFunction(func);
+ }
func(NaN, NaN);
func(NaN, NaN);
// Check IC Number*Number->Number throws
- assertThrows(function(){func(2, "foo");}, TypeError);
- %OptimizeFunctionOnNextCall(func);
- assertThrows(function(){func(2, "foo");}, TypeError);
- %DeoptimizeFunction(func);
+ for (let v of nonNumberValues) {
+ let value = eval(v);
+ assertThrows(function(){func(2, value);}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(2, value);}, TypeError);
+ %DeoptimizeFunction(func);
+ }
}
for (let func of strongStringOrNumberFuncs) {
// Check IC None*None->None throws
- assertThrows(function(){func(2, "foo");}, TypeError);
- %OptimizeFunctionOnNextCall(func);
- assertThrows(function(){func(2, "foo");}, TypeError);
- %DeoptimizeFunction(func);
+ for (let v of nonNumberValues) {
+ let value = eval(v);
+ assertThrows(function(){func(2, value);}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(2, value);}, TypeError);
+ %DeoptimizeFunction(func);
+ }
func("foo", "bar");
func("foo", "bar");
// Check IC String*String->String throws
- assertThrows(function(){func(2, "foo");}, TypeError);
- %OptimizeFunctionOnNextCall(func);
- assertThrows(function(){func(2, "foo");}, TypeError);
- %DeoptimizeFunction(func);
+ for (let v of nonNumberValues) {
+ let value = eval(v);
+ assertThrows(function(){func(2, value);}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(2, value);}, TypeError);
+ %DeoptimizeFunction(func);
+ }
func(NaN, NaN);
func(NaN, NaN);
// Check IC Generic*Generic->Generic throws
- assertThrows(function(){func(2, "foo");}, TypeError);
+ for (let v of nonNumberValues) {
+ let value = eval(v);
+ assertThrows(function(){func(2, value);}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(2, value);}, TypeError);
+ %DeoptimizeFunction(func);
+ }
+}
+
+for (let func of [str_equal_strong, str_ineq_strong]) {
+ assertDoesNotThrow(function(){func(2, undefined)});
+ assertDoesNotThrow(function(){func(2, undefined)});
+ %OptimizeFunctionOnNextCall(func);
+ assertDoesNotThrow(function(){func(2, undefined)});
+ %DeoptimizeFunction(func);
+ assertDoesNotThrow(function(){func(true, {})});
+ assertDoesNotThrow(function(){func(true, {})});
%OptimizeFunctionOnNextCall(func);
- assertThrows(function(){func(2, "foo");}, TypeError);
+ assertDoesNotThrow(function(){func(true, {})});
%DeoptimizeFunction(func);
}
diff --git a/deps/v8/test/mjsunit/strong/literals.js b/deps/v8/test/mjsunit/strong/literals.js
new file mode 100644
index 0000000000..73129e7a09
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/literals.js
@@ -0,0 +1,352 @@
+// Copyright 2015 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: --strong-mode --allow-natives-syntax
+// Flags: --harmony-arrow-functions --harmony-rest-parameters
+// Flags: --harmony-destructuring --harmony-spread-arrays
+
+'use strict';
+
+(function WeakObjectLiterals() {
+ function assertWeakObject(x) {
+ assertFalse(%IsStrong(x));
+ assertSame(Object.prototype, Object.getPrototypeOf(x));
+ }
+ assertWeakObject({});
+ assertWeakObject({a: 0, b: 0});
+ assertWeakObject({a: [], b: {}});
+ assertWeakObject({a: [], b: {}}.b);
+ assertWeakObject({a: {b: {c: {}}}}.a);
+ assertWeakObject({a: {b: {c: {}}}}.a.b);
+ assertWeakObject({a: {b: {c: {}}}}.a.b.c);
+ assertWeakObject([[1], {}, [[3]]][1]);
+ assertWeakObject({f: function(){}});
+ assertWeakObject(
+ Realm.eval(Realm.current(), "({f: function(){}})"));
+})();
+
+(function StrongObjectLiterals() {
+ 'use strong';
+ function assertStrongObject(x) {
+ assertTrue(%IsStrong(x));
+ assertSame(Object.prototype, Object.getPrototypeOf(x));
+ }
+ assertStrongObject({});
+ assertStrongObject({a: 0, b: 0});
+ assertStrongObject({a: [], b: {}});
+ assertStrongObject({a: [], b: {}}.b);
+ assertStrongObject({a: {b: {c: {}}}}.a);
+ assertStrongObject({a: {b: {c: {}}}}.a.b);
+ assertStrongObject({a: {b: {c: {}}}}.a.b.c);
+ // Maps for literals with too many properties are not cached.
+ assertStrongObject({
+ x001: 0, x002: 0, x003: 0, x004: 0, x005: 0,
+ x006: 0, x007: 0, x008: 0, x009: 0, x010: 0,
+ x011: 0, x012: 0, x013: 0, x014: 0, x015: 0,
+ x016: 0, x017: 0, x018: 0, x019: 0, x020: 0,
+ x021: 0, x022: 0, x023: 0, x024: 0, x025: 0,
+ x026: 0, x027: 0, x028: 0, x029: 0, x030: 0,
+ x031: 0, x032: 0, x033: 0, x034: 0, x035: 0,
+ x036: 0, x037: 0, x038: 0, x039: 0, x040: 0,
+ x041: 0, x042: 0, x043: 0, x044: 0, x045: 0,
+ x046: 0, x047: 0, x048: 0, x049: 0, x050: 0,
+ x051: 0, x052: 0, x053: 0, x054: 0, x055: 0,
+ x056: 0, x057: 0, x058: 0, x059: 0, x060: 0,
+ x061: 0, x062: 0, x063: 0, x064: 0, x065: 0,
+ x066: 0, x067: 0, x068: 0, x069: 0, x070: 0,
+ x071: 0, x072: 0, x073: 0, x074: 0, x075: 0,
+ x076: 0, x077: 0, x078: 0, x079: 0, x080: 0,
+ x081: 0, x082: 0, x083: 0, x084: 0, x085: 0,
+ x086: 0, x087: 0, x088: 0, x089: 0, x090: 0,
+ x091: 0, x092: 0, x093: 0, x094: 0, x095: 0,
+ x096: 0, x097: 0, x098: 0, x099: 0, x100: 0,
+ x101: 0, x102: 0, x103: 0, x104: 0, x105: 0,
+ x106: 0, x107: 0, x108: 0, x109: 0, x110: 0,
+ x111: 0, x112: 0, x113: 0, x114: 0, x115: 0,
+ x116: 0, x117: 0, x118: 0, x119: 0, x120: 0,
+ x121: 0, x122: 0, x123: 0, x124: 0, x125: 0,
+ x126: 0, x127: 0, x128: 0, x129: 0, x130: 0,
+ x131: 0, x132: 0, x133: 0, x134: 0, x135: 0,
+ x136: 0, x137: 0, x138: 0, x139: 0, x140: 0,
+ x141: 0, x142: 0, x143: 0, x144: 0, x145: 0,
+ x146: 0, x147: 0, x148: 0, x149: 0, x150: 0,
+ x151: 0, x152: 0, x153: 0, x154: 0, x155: 0,
+ x156: 0, x157: 0, x158: 0, x159: 0, x160: 0,
+ x161: 0, x162: 0, x163: 0, x164: 0, x165: 0,
+ x166: 0, x167: 0, x168: 0, x169: 0, x170: 0,
+ x171: 0, x172: 0, x173: 0, x174: 0, x175: 0,
+ x176: 0, x177: 0, x178: 0, x179: 0, x180: 0,
+ x181: 0, x182: 0, x183: 0, x184: 0, x185: 0,
+ x186: 0, x187: 0, x188: 0, x189: 0, x190: 0,
+ x191: 0, x192: 0, x193: 0, x194: 0, x195: 0,
+ x196: 0, x197: 0, x198: 0, x199: 0, x200: 0,
+ });
+ assertStrongObject([[1], {}, [[3]]][1]);
+ assertStrongObject({[Date() + ""]: 0, [Symbol()]: 0});
+ assertStrongObject({m() { super.m() }});
+ assertTrue(%IsStrong({__proto__: {}, get a() {}, set b(x) {}}));
+ // Object literals with constant functions are treated specially,
+ // but currently only on the toplevel (using Realm.eval to emulate that).
+ assertStrongObject({f: function(){}});
+ assertStrongObject(
+ Realm.eval(Realm.current(), "'use strong'; ({f: function(){}})"));
+})();
+
+(function WeakArrayLiterals(...args) {
+ function assertWeakArray(x) {
+ assertFalse(%IsStrong(x));
+ assertSame(Array.prototype, Object.getPrototypeOf(x));
+ }
+ let [...r] = [];
+ assertWeakArray(args);
+ assertWeakArray(r);
+ assertWeakArray([]);
+ assertWeakArray([1, 2, 3]);
+ assertWeakArray([1, 2, ...[3, 4], 5]);
+ assertWeakArray([[[]]]);
+ assertWeakArray([[1], {}, [[3]]]);
+ assertWeakArray([[1], {}, [[3]]][0]);
+ assertWeakArray([[1], {}, [[3]]][2]);
+ assertWeakArray([[1], {}, [[3]]][2][0]);
+ assertWeakArray({a: [], b: {}}.a);
+})();
+
+(function StrongArrayLiterals(...args) {
+ 'use strong';
+ function assertStrongArray(x) {
+ assertTrue(%IsStrong(x));
+ assertSame(Array.prototype, Object.getPrototypeOf(x));
+ }
+ let [...r] = [];
+ assertStrongArray(args);
+ assertStrongArray(r);
+ assertStrongArray([]);
+ assertStrongArray([1, 2, 3]);
+ assertStrongArray([1, 2, ...[3, 4], 5]);
+ assertStrongArray([[[]]]);
+ assertStrongArray([[1], {}, [[3]]]);
+ assertStrongArray([[1], {}, [[3]]][0]);
+ assertStrongArray([[1], {}, [[3]]][2]);
+ assertStrongArray([[1], {}, [[3]]][2][0]);
+ assertStrongArray({a: [], b: {}}.a);
+})();
+
+(function WeakFunctionLiterals() {
+ function assertWeakFunction(x) {
+ assertFalse(%IsStrong(x));
+ assertFalse(%IsStrong(x.prototype));
+ assertSame(Function.prototype, Object.getPrototypeOf(x));
+ }
+ function f() {}
+ assertWeakFunction(f);
+ assertWeakFunction(function(){});
+ assertWeakFunction(function f(){});
+ assertWeakFunction(() => {});
+ assertWeakFunction(x => x);
+ assertWeakFunction({m(){}}.m);
+ assertWeakFunction(Object.getOwnPropertyDescriptor(
+ {get a(){}}, 'a').get);
+ assertWeakFunction(Object.getOwnPropertyDescriptor(
+ {set a(x){}}, 'a').set);
+ assertWeakFunction((class {static m(){}}).m);
+ assertWeakFunction(Object.getOwnPropertyDescriptor(
+ class {static get a(){}}, 'a').get);
+ assertWeakFunction(Object.getOwnPropertyDescriptor(
+ class {static set a(x){}}, 'a').set);
+ assertWeakFunction((new class {m(){}}).m);
+ assertWeakFunction(Object.getOwnPropertyDescriptor(
+ (class {get a(){}}).prototype, 'a').get);
+ assertWeakFunction(Object.getOwnPropertyDescriptor(
+ (class {set a(x){}}).prototype, 'a').set);
+})();
+
+(function StrongFunctionLiterals() {
+ 'use strong';
+ function assertStrongFunction(x) {
+ assertTrue(%IsStrong(x));
+ assertFalse('prototype' in x);
+ assertSame(Function.prototype, Object.getPrototypeOf(x));
+ }
+ function f() {}
+ assertStrongFunction(f);
+ assertStrongFunction(function(){});
+ assertStrongFunction(function f(){});
+ assertStrongFunction(() => {});
+ assertStrongFunction(x => x);
+ assertStrongFunction({m(){}}.m);
+ assertStrongFunction(Object.getOwnPropertyDescriptor(
+ {get a(){}}, 'a').get);
+ assertStrongFunction(Object.getOwnPropertyDescriptor(
+ {set a(x){}}, 'a').set);
+ assertStrongFunction((class {static m(){}}).m);
+ assertStrongFunction(Object.getOwnPropertyDescriptor(
+ class {static get a(){}}, 'a').get);
+ assertStrongFunction(Object.getOwnPropertyDescriptor(
+ class {static set a(x){}}, 'a').set);
+ assertStrongFunction((new class {m(){}}).m);
+ assertStrongFunction(Object.getOwnPropertyDescriptor(
+ (class {get a(){}}).prototype, 'a').get);
+ assertStrongFunction(Object.getOwnPropertyDescriptor(
+ (class {set a(x){}}).prototype, 'a').set);
+})();
+
+(function SelfStrongFunctionLiterals() {
+ function assertStrongFunction(x) {
+ assertTrue(%IsStrong(x));
+ assertFalse('prototype' in x);
+ assertSame(Function.prototype, Object.getPrototypeOf(x));
+ }
+ function f() {'use strong'}
+ assertStrongFunction(f);
+ assertStrongFunction(function(){'use strong'});
+ assertStrongFunction(function f(){'use strong'});
+ assertStrongFunction(() => {'use strong'});
+ assertStrongFunction(x => {'use strong'});
+ assertStrongFunction({m(){'use strong'}}.m);
+ assertStrongFunction(Object.getOwnPropertyDescriptor(
+ {get a(){'use strong'}}, 'a').get);
+ assertStrongFunction(Object.getOwnPropertyDescriptor(
+ {set a(x){'use strong'}}, 'a').set);
+ assertStrongFunction((class {static m(){'use strong'}}).m);
+ assertStrongFunction(Object.getOwnPropertyDescriptor(
+ class {static get a(){'use strong'}}, 'a').get);
+ assertStrongFunction(Object.getOwnPropertyDescriptor(
+ class {static set a(x){'use strong'}}, 'a').set);
+ assertStrongFunction((new class {m(){'use strong'}}).m);
+ assertStrongFunction(Object.getOwnPropertyDescriptor(
+ (class {get a(){'use strong'}}).prototype, 'a').get);
+ assertStrongFunction(Object.getOwnPropertyDescriptor(
+ (class {set a(x){'use strong'}}).prototype, 'a').set);
+})();
+
+let GeneratorPrototype = (function*(){}).__proto__;
+
+(function WeakGeneratorLiterals() {
+ function assertWeakGenerator(x) {
+ assertFalse(%IsStrong(x));
+ assertFalse(%IsStrong(x.prototype));
+ assertSame(GeneratorPrototype, Object.getPrototypeOf(x));
+ assertFalse(%IsStrong(x()));
+ }
+ function* g() {}
+ assertWeakGenerator(g);
+ assertWeakGenerator(function*(){});
+ assertWeakGenerator(function* g(){});
+ assertWeakGenerator({*m(){}}.m);
+ assertWeakGenerator((class {static *m(){}}).m);
+ assertWeakGenerator((new class {*m(){}}).m);
+})();
+
+(function StrongGeneratorLiterals() {
+ 'use strong';
+ function assertStrongGenerator(x) {
+ assertTrue(%IsStrong(x));
+ // TODO(rossberg): strongify generator prototypes
+ // assertTrue(%IsStrong(x.prototype));
+ assertSame(GeneratorPrototype, Object.getPrototypeOf(x));
+ // TODO(rossberg): strongify generator instances
+ // assertTrue(%IsStrong(x()));
+ }
+ function* g() {}
+ assertStrongGenerator(g);
+ assertStrongGenerator(function*(){});
+ assertStrongGenerator(function* g(){});
+ assertStrongGenerator({*m(){}}.m);
+ assertStrongGenerator((class {static *m(){}}).m);
+ assertStrongGenerator((new class {*m(){}}).m);
+})();
+
+(function SelfStrongGeneratorLiterals() {
+ function assertStrongGenerator(x) {
+ assertTrue(%IsStrong(x));
+ // TODO(rossberg): strongify generator prototypes
+ // assertTrue(%IsStrong(x.prototype));
+ assertSame(GeneratorPrototype, Object.getPrototypeOf(x));
+ // TODO(rossberg): strongify generator instances
+ // assertTrue(%IsStrong(x()));
+ }
+ function* g() {'use strong'}
+ assertStrongGenerator(g);
+ assertStrongGenerator(function*(){'use strong'});
+ assertStrongGenerator(function* g(){'use strong'});
+ assertStrongGenerator({*m(){'use strong'}}.m);
+ assertStrongGenerator((class {static *m(){'use strong'}}).m);
+ assertStrongGenerator((new class {*m(){'use strong'}}).m);
+})();
+
+(function WeakClassLiterals() {
+ function assertWeakClass(x) {
+ assertFalse(%IsStrong(x));
+ assertFalse(%IsStrong(x.prototype));
+ assertFalse(%IsStrong(new x));
+ }
+ class C {};
+ class D extends C {};
+ class E extends Object {};
+ // class F extends null {};
+ const S = (() => {'use strong'; return class {}})();
+ class G extends S {};
+ assertWeakClass(C);
+ assertWeakClass(D);
+ assertWeakClass(E);
+ // assertWeakClass(F);
+ assertWeakClass(G);
+ assertWeakClass(class {});
+ assertWeakClass(class extends Object {});
+ // assertWeakClass(class extends null {});
+ assertWeakClass(class extends C {});
+ assertWeakClass(class extends S {});
+ assertWeakClass(class extends class {} {});
+ assertWeakClass(class C {});
+ assertWeakClass(class D extends Object {});
+ // assertWeakClass(class D extends null {});
+ assertWeakClass(class D extends C {});
+ assertWeakClass(class D extends S {});
+ assertWeakClass(class D extends class {} {});
+})();
+
+(function StrongClassLiterals() {
+ 'use strong';
+ function assertStrongClass(x) {
+ assertTrue(%IsStrong(x));
+ // TODO(rossberg): strongify class prototype and instance
+ // assertTrue(%IsStrong(x.prototype));
+ // assertTrue(%IsStrong(new x));
+ }
+ class C {};
+ class D extends C {};
+ class E extends Object {};
+ const W = (1, eval)(() => {'use strict'; return class {}})();
+ class G extends W {};
+ assertStrongClass(C);
+ assertStrongClass(D);
+ assertStrongClass(E);
+ assertStrongClass(G);
+ assertStrongClass(class {});
+ assertStrongClass(class extends Object {});
+ assertStrongClass(class extends C {});
+ assertStrongClass(class extends W {});
+ assertStrongClass(class extends class {} {});
+ assertStrongClass(class C {});
+ assertStrongClass(class D extends Object {});
+ assertStrongClass(class D extends C {});
+ assertStrongClass(class D extends W {});
+ assertStrongClass(class D extends class {} {});
+})();
+
+(function WeakRegExpLiterals() {
+ function assertWeakRegExp(x) {
+ assertFalse(%IsStrong(x));
+ }
+ assertWeakRegExp(/abc/);
+})();
+
+(function StrongRegExpLiterals() {
+ 'use strong';
+ function assertStrongRegExp(x) {
+ // TODO(rossberg): strongify regexps
+ // assertTrue(%IsStrong(x));
+ }
+ assertStrongRegExp(/abc/);
+})();
diff --git a/deps/v8/test/mjsunit/strong/load-builtins.js b/deps/v8/test/mjsunit/strong/load-builtins.js
new file mode 100644
index 0000000000..6638ff3332
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/load-builtins.js
@@ -0,0 +1,42 @@
+// Copyright 2015 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: --strong-mode
+
+function getGlobal() {
+ return this;
+}
+
+function polluteGlobal() {
+ bar = 0;
+}
+
+(function() {
+ "use strict";
+
+ let builtins = [
+ Array,
+ Object,
+ Function,
+ getGlobal()
+ ];
+
+ for (let builtin of builtins) {
+ assertThrows(function(){"use strong"; builtin.foo}, TypeError);
+ assertThrows(function(){"use strong"; builtin[0]}, TypeError);
+ assertThrows(function(){"use strong"; builtin[10000]}, TypeError);
+ builtin.foo = 1;
+ assertDoesNotThrow(function(){"use strong"; builtin.foo});
+ assertThrows(function(){"use strong"; builtin.bar});
+ assertThrows(function(){"use strong"; builtin[0]}, TypeError);
+ assertThrows(function(){"use strong"; builtin[10000]}, TypeError);
+ builtin[0] = 1;
+ assertDoesNotThrow(function(){"use strong"; builtin.foo});
+ assertThrows(function(){"use strong"; builtin.bar});
+ assertDoesNotThrow(function(){"use strong"; builtin[0]});
+ assertThrows(function(){"use strong"; builtin[10000]}, TypeError);
+ }
+ polluteGlobal();
+ assertDoesNotThrow(function(){"use strong"; getGlobal().bar});
+})();
diff --git a/deps/v8/test/mjsunit/strong/load-element-mutate-backing-store.js b/deps/v8/test/mjsunit/strong/load-element-mutate-backing-store.js
new file mode 100644
index 0000000000..f3465028b7
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/load-element-mutate-backing-store.js
@@ -0,0 +1,239 @@
+// Copyright 2015 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: --strong-mode --allow-natives-syntax
+
+function getSloppyArguments() {
+ return arguments;
+}
+
+function getObjects() {
+ "use strict";
+ return [
+ {},
+ Object(""),
+ [],
+ (function(){}),
+ (class Foo {}),
+ getSloppyArguments(),
+ arguments,
+ new Date(),
+ ];
+}
+
+// TODO(conradw): add tests for non-inheritance once semantics are implemented.
+function getNonInheritingObjects() {
+ "use strong";
+ return [
+ Object(""),
+ [],
+ // TODO(conradw): uncomment and correct test once Object.defineProperty is
+ // fixed.
+ // new Uint32Array(0)
+ ];
+}
+
+function readFromObjectElementSloppy(o) {
+ return o[0];
+}
+
+function readFromObjectElementSparseSloppy(o) {
+ return o[100000];
+}
+
+function readFromObjectElementNonSmiSloppy(o) {
+ return o[3000000000];
+}
+
+function readFromObjectNonIndexSloppy(o) {
+ return o[5000000000];
+}
+
+function readFromObjectElementVarSloppy(o) {
+ var a = 0;
+ return o[a];
+}
+
+function readFromObjectElementSparseVarSloppy(o) {
+ var a = 100000;
+ return o[a];
+}
+
+function readFromObjectElementNonSmiVarSloppy(o) {
+ var a = 3000000000;
+ return o[a];
+}
+
+function readFromObjectNonIndexVarSloppy(o) {
+ var a = 5000000000;
+ return o[a];
+}
+
+function readFromObjectElementStrong(o) {
+ "use strong";
+ return o[0];
+}
+
+function readFromObjectElementSparseStrong(o) {
+ "use strong";
+ return o[100000];
+}
+
+function readFromObjectElementNonSmiStrong(o) {
+ "use strong";
+ return o[3000000000];
+}
+
+function readFromObjectNonIndexStrong(o) {
+ "use strong";
+ return o[5000000000];
+}
+
+function readFromObjectElementLetStrong(o) {
+ "use strong";
+ let a = 0;
+ return o[a];
+}
+
+function readFromObjectElementSparseLetStrong(o) {
+ "use strong";
+ let a = 100000;
+ return o[a];
+}
+
+function readFromObjectElementNonSmiLetStrong(o) {
+ "use strong";
+ let a = 3000000000;
+ return o[a];
+}
+
+function readFromObjectNonIndexLetStrong(o) {
+ "use strong";
+ let a = 5000000000;
+ return o[a];
+}
+
+function getDescs(x) {
+ return [
+ {value: x},
+ {configurable: true, enumerable: true, writable: true, value: x},
+ {configurable: true, enumerable: true, get: (function() {return x}) },
+ ];
+}
+
+function assertStrongSemantics(func, object) {
+ %DeoptimizeFunction(func);
+ %ClearFunctionTypeFeedback(func);
+ assertThrows(function(){func(object)}, TypeError);
+ assertThrows(function(){func(object)}, TypeError);
+ assertThrows(function(){func(object)}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(object)}, TypeError);
+ %DeoptimizeFunction(func);
+ assertThrows(function(){func(object)}, TypeError);
+}
+
+function assertSloppySemantics(func, object) {
+ %DeoptimizeFunction(func);
+ %ClearFunctionTypeFeedback(func);
+ assertDoesNotThrow(function(){func(object)});
+ assertDoesNotThrow(function(){func(object)});
+ assertDoesNotThrow(function(){func(object)});
+ %OptimizeFunctionOnNextCall(func);
+ assertDoesNotThrow(function(){func(object)});
+ %DeoptimizeFunction(func);
+ assertDoesNotThrow(function(){func(object)});
+}
+
+(function () {
+ "use strict";
+
+ let goodKeys = [
+ "0",
+ "100000",
+ "3000000000",
+ "5000000000"
+ ]
+
+ let badKeys = [
+ "bar",
+ "1",
+ "100001",
+ "3000000001",
+ "5000000001"
+ ];
+
+ let values = [
+ "string",
+ 1,
+ 100001,
+ 30000000001,
+ 50000000001,
+ NaN,
+ {},
+ undefined
+ ];
+
+ let badAccessorDescs = [
+ { set: (function(){}) },
+ { configurable: true, enumerable: true, set: (function(){}) }
+ ];
+
+ let readSloppy = [
+ readFromObjectElementSloppy,
+ readFromObjectElementSparseSloppy,
+ readFromObjectElementNonSmiSloppy,
+ readFromObjectNonIndexSloppy,
+ readFromObjectElementVarSloppy,
+ readFromObjectElementSparseVarSloppy,
+ readFromObjectElementNonSmiVarSloppy,
+ readFromObjectNonIndexVarSloppy
+ ];
+
+ let readStrong = [
+ readFromObjectElementStrong,
+ readFromObjectElementSparseStrong,
+ readFromObjectElementNonSmiStrong,
+ readFromObjectNonIndexStrong,
+ readFromObjectElementLetStrong,
+ readFromObjectElementSparseLetStrong,
+ readFromObjectElementNonSmiLetStrong,
+ readFromObjectNonIndexLetStrong
+ ];
+
+ let dummyProto = {};
+ for (let key of goodKeys) {
+ Object.defineProperty(dummyProto, key, { value: undefined });
+ }
+
+ // After altering the backing store, accessing a missing property should still
+ // throw.
+ for (let key of badKeys) {
+ for (let value of values) {
+ for (let desc of getDescs(value)) {
+ let objects = getObjects();
+ let nonInheritingObjects = getNonInheritingObjects();
+ for (let object of objects.concat(nonInheritingObjects)) {
+ Object.defineProperty(object, key, desc);
+ for (let func of readStrong) {
+ assertStrongSemantics(func, object);
+ }
+ for (let func of readSloppy) {
+ assertSloppySemantics(func, object);
+ }
+ }
+ for (let object of objects) {
+ // Accessing a property which is on the prototype chain of the object
+ // should not throw.
+ object.__proto__ = dummyProto;
+ for (let key of goodKeys) {
+ for (let func of readStrong.concat(readSloppy)) {
+ assertSloppySemantics(func, object);
+ }
+ }
+ }
+ }
+ }
+ }
+})();
diff --git a/deps/v8/test/mjsunit/strong/load-element.js b/deps/v8/test/mjsunit/strong/load-element.js
new file mode 100644
index 0000000000..4007b7db61
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/load-element.js
@@ -0,0 +1,267 @@
+// Copyright 2015 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: --strong-mode --allow-natives-syntax
+
+function getSloppyArguments() {
+ return arguments;
+}
+
+function getObjects() {
+ "use strict";
+ return [
+ {},
+ Object(""),
+ [],
+ (function(){}),
+ (class Foo {}),
+ getSloppyArguments(),
+ arguments,
+ new Date()
+ ];
+}
+
+//TODO(conradw): add tests for non-inheritance once semantics are implemented.
+function getNonInheritingObjects() {
+ "use strong";
+ return [
+ Object(""),
+ [],
+ new Uint32Array(0)
+ ];
+}
+
+function readFromObjectElementSloppy(o) {
+ return o[0];
+}
+
+function readFromObjectElementSparseSloppy(o) {
+ return o[100000];
+}
+
+function readFromObjectElementNonSmiSloppy(o) {
+ return o[3000000000];
+}
+
+function readFromObjectNonIndexSloppy(o) {
+ return o[5000000000];
+}
+
+function readFromObjectElementVarSloppy(o) {
+ var a = 0;
+ return o[a];
+}
+
+function readFromObjectElementSparseVarSloppy(o) {
+ var a = 100000;
+ return o[a];
+}
+
+function readFromObjectElementNonSmiVarSloppy(o) {
+ var a = 3000000000;
+ return o[a];
+}
+
+function readFromObjectNonIndexVarSloppy(o) {
+ var a = 5000000000;
+ return o[a];
+}
+
+function readFromObjectElementStrong(o) {
+ "use strong";
+ return o[0];
+}
+
+function readFromObjectElementSparseStrong(o) {
+ "use strong";
+ return o[100000];
+}
+
+function readFromObjectElementNonSmiStrong(o) {
+ "use strong";
+ return o[3000000000];
+}
+
+function readFromObjectNonIndexStrong(o) {
+ "use strong";
+ return o[5000000000];
+}
+
+function readFromObjectElementLetStrong(o) {
+ "use strong";
+ let a = 0;
+ return o[a];
+}
+
+function readFromObjectElementSparseLetStrong(o) {
+ "use strong";
+ let a = 100000;
+ return o[a];
+}
+
+function readFromObjectElementNonSmiLetStrong(o) {
+ "use strong";
+ let a = 3000000000;
+ return o[a];
+}
+
+function readFromObjectNonIndexLetStrong(o) {
+ "use strong";
+ let a = 5000000000;
+ return o[a];
+}
+
+function getDescs(x) {
+ return [
+ {value: x},
+ {configurable: true, enumerable: true, writable: true, value: x},
+ {configurable: true, enumerable: true, get: (function() {return x}) },
+ ];
+}
+
+function assertStrongSemantics(func, object) {
+ %DeoptimizeFunction(func);
+ %ClearFunctionTypeFeedback(func);
+ assertThrows(function(){func(object)}, TypeError);
+ assertThrows(function(){func(object)}, TypeError);
+ assertThrows(function(){func(object)}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(object)}, TypeError);
+ %DeoptimizeFunction(func);
+ assertThrows(function(){func(object)}, TypeError);
+}
+
+function assertSloppySemantics(func, object) {
+ %DeoptimizeFunction(func);
+ %ClearFunctionTypeFeedback(func);
+ assertDoesNotThrow(function(){func(object)});
+ assertDoesNotThrow(function(){func(object)});
+ assertDoesNotThrow(function(){func(object)});
+ %OptimizeFunctionOnNextCall(func);
+ assertDoesNotThrow(function(){func(object)});
+ %DeoptimizeFunction(func);
+ assertDoesNotThrow(function(){func(object)});
+}
+
+(function () {
+ "use strict";
+
+ let goodKeys = [
+ "0",
+ "100000",
+ "3000000000",
+ "5000000000"
+ ]
+
+ let badKeys = [
+ "bar",
+ "1",
+ "100001",
+ "3000000001",
+ "5000000001"
+ ];
+
+ let values = [
+ "string",
+ 1,
+ 100001,
+ 30000000001,
+ 50000000001,
+ NaN,
+ {},
+ undefined
+ ];
+
+ let literals = [0, NaN, true, ""];
+
+ let badAccessorDescs = [
+ { set: (function(){}) },
+ { configurable: true, enumerable: true, set: (function(){}) }
+ ];
+
+ let readSloppy = [
+ readFromObjectElementSloppy,
+ readFromObjectElementSparseSloppy,
+ readFromObjectElementNonSmiSloppy,
+ readFromObjectNonIndexSloppy,
+ readFromObjectElementVarSloppy,
+ readFromObjectElementSparseVarSloppy,
+ readFromObjectElementNonSmiVarSloppy,
+ readFromObjectNonIndexVarSloppy
+ ];
+
+ let readStrong = [
+ readFromObjectElementStrong,
+ readFromObjectElementSparseStrong,
+ readFromObjectElementNonSmiStrong,
+ readFromObjectNonIndexStrong,
+ readFromObjectElementLetStrong,
+ readFromObjectElementSparseLetStrong,
+ readFromObjectElementNonSmiLetStrong,
+ readFromObjectNonIndexLetStrong
+ ];
+
+ let dummyProto = {};
+ for (let key of goodKeys) {
+ Object.defineProperty(dummyProto, key, { value: undefined });
+ }
+
+ let dummyAccessorProto = {};
+ for (let key of goodKeys) {
+ Object.defineProperty(dummyAccessorProto, key, { set: (function(){}) })
+ }
+
+ // String literals/objects should not throw on character index access
+ assertDoesNotThrow(function() {"use strong"; return "string"[0]; });
+ assertDoesNotThrow(function() {"use strong"; return Object("string")[0]; });
+
+ // Attempting to access a property on an object with no defined properties
+ // should throw.
+ for (let object of getObjects().concat(getNonInheritingObjects(), literals)) {
+ for (let func of readStrong) {
+ assertStrongSemantics(func, object);
+ }
+ for (let func of readSloppy) {
+ assertSloppySemantics(func, object);
+ }
+ }
+ for (let object of getObjects()) {
+ // Accessing a property which is on the prototype chain of the object should
+ // not throw.
+ object.__proto__ = dummyProto;
+ for (let key of goodKeys) {
+ for (let func of readStrong.concat(readSloppy)) {
+ assertSloppySemantics(func, object);
+ }
+ }
+ }
+ // Properties with accessor descriptors missing 'get' should throw on access.
+ for (let desc of badAccessorDescs) {
+ for (let key of goodKeys) {
+ for (let object of getObjects()) {
+ Object.defineProperty(object, key, desc);
+ for (let func of readStrong) {
+ assertStrongSemantics(func, object);
+ }
+ for (let func of readSloppy) {
+ assertSloppySemantics(func, object);
+ }
+ }
+ }
+ }
+ // The same behaviour should be expected for bad accessor properties on the
+ // prototype chain.
+ for (let object of getObjects()) {
+ object.__proto__ = dummyAccessorProto;
+ for (let func of readStrong) {
+ assertStrongSemantics(func, object);
+ }
+ for (let func of readSloppy) {
+ assertSloppySemantics(func, object);
+ }
+ }
+ assertThrows(function(){"use strong"; typeof ({})[1];}, TypeError);
+ assertThrows(
+ function(){"use strong"; typeof ({})[1] === "undefined"}, TypeError);
+})();
diff --git a/deps/v8/test/mjsunit/strong/load-property-mutate-backing-store.js b/deps/v8/test/mjsunit/strong/load-property-mutate-backing-store.js
new file mode 100644
index 0000000000..5ed45530c4
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/load-property-mutate-backing-store.js
@@ -0,0 +1,174 @@
+// Copyright 2015 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: --strong-mode --allow-natives-syntax
+
+function getSloppyArguments() {
+ return arguments;
+}
+
+function getObjects() {
+ "use strict";
+ return [
+ {},
+ Object(""),
+ [],
+ (function(){}),
+ (class Foo {}),
+ getSloppyArguments(),
+ arguments,
+ new Date(),
+ // TODO(conradw): uncomment once Object.defineProperty is fixed.
+ // new Uint32Array(0)
+ ];
+}
+
+function readFromObjectSloppy(o) {
+ return o.foo;
+}
+
+function readFromObjectKeyedSloppy(o) {
+ return o["foo"];
+}
+
+function readFromObjectKeyedVarSloppy(o) {
+ var a = "foo";
+ return o[a];
+}
+
+function readFromObjectKeyedComputedSloppy(o) {
+ var a = "o";
+ return o["fo" + a];
+}
+
+function readFromObjectStrong(o) {
+ "use strong";
+ return o.foo;
+}
+
+function readFromObjectKeyedStrong(o) {
+ "use strong";
+ return o["foo"];
+}
+
+function readFromObjectKeyedLetStrong(o) {
+ "use strong";
+ let a = "foo";
+ return o[a];
+}
+
+function readFromObjectKeyedComputedStrong(o) {
+ "use strong";
+ let a = "o";
+ return o["fo" + a];
+}
+
+function getDescs(x) {
+ return [
+ {value: x},
+ {configurable: true, enumerable: true, writable: true, value: x},
+ {configurable: true, enumerable: true, get: (function() {return x}) },
+ ];
+}
+
+function assertStrongSemantics(func, object) {
+ %DeoptimizeFunction(func);
+ %ClearFunctionTypeFeedback(func);
+ assertThrows(function(){func(object)}, TypeError);
+ assertThrows(function(){func(object)}, TypeError);
+ assertThrows(function(){func(object)}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(object)}, TypeError);
+ %DeoptimizeFunction(func);
+ assertThrows(function(){func(object)}, TypeError);
+}
+
+function assertSloppySemantics(func, object) {
+ %DeoptimizeFunction(func);
+ %ClearFunctionTypeFeedback(func);
+ assertDoesNotThrow(function(){func(object)});
+ assertDoesNotThrow(function(){func(object)});
+ assertDoesNotThrow(function(){func(object)});
+ %OptimizeFunctionOnNextCall(func);
+ assertDoesNotThrow(function(){func(object)});
+ %DeoptimizeFunction(func);
+ assertDoesNotThrow(function(){func(object)});
+}
+
+(function () {
+ "use strict";
+
+ let goodKeys = [
+ "foo"
+ ]
+
+ let badKeys = [
+ "bar",
+ "1",
+ "100001",
+ "3000000001",
+ "5000000001"
+ ];
+
+ let values = [
+ "string",
+ 1,
+ 100001,
+ 30000000001,
+ 50000000001,
+ NaN,
+ {},
+ undefined
+ ];
+
+ let badAccessorDescs = [
+ { set: (function(){}) },
+ { configurable: true, enumerable: true, set: (function(){}) }
+ ];
+
+ let readSloppy = [
+ readFromObjectSloppy,
+ readFromObjectKeyedSloppy,
+ readFromObjectKeyedVarSloppy,
+ readFromObjectKeyedComputedSloppy
+ ];
+
+ let readStrong = [
+ readFromObjectStrong,
+ readFromObjectKeyedStrong,
+ readFromObjectKeyedLetStrong,
+ readFromObjectKeyedComputedStrong
+ ];
+
+ let dummyProto = {};
+ for (let key of goodKeys) {
+ Object.defineProperty(dummyProto, key, { value: undefined });
+ }
+
+ // After altering the backing store, accessing a missing property should still
+ // throw.
+ for (let key of badKeys) {
+ for (let value of values) {
+ for (let desc of getDescs(value)) {
+ for (let object of getObjects()) {
+ Object.defineProperty(object, key, desc);
+ for (let func of readStrong) {
+ assertStrongSemantics(func, object);
+ }
+ for (let func of readSloppy) {
+ assertSloppySemantics(func, object);
+ }
+ // Accessing a property which is on the prototype chain of the object
+ // should not throw.
+ object.__proto__ = dummyProto;
+ for (let key of goodKeys) {
+ for (let func of readStrong.concat(readSloppy)) {
+ assertSloppySemantics(func, object);
+ }
+ }
+ }
+ }
+ }
+ }
+})();
diff --git a/deps/v8/test/mjsunit/strong/load-property.js b/deps/v8/test/mjsunit/strong/load-property.js
new file mode 100644
index 0000000000..ddbcbb67fb
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/load-property.js
@@ -0,0 +1,203 @@
+// Copyright 2015 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: --strong-mode --allow-natives-syntax
+
+function getSloppyArguments() {
+ return arguments;
+}
+
+function getObjects() {
+ "use strict";
+ return [
+ {},
+ Object(""),
+ [],
+ (function(){}),
+ (class Foo {}),
+ getSloppyArguments(),
+ arguments,
+ new Date(),
+ new Uint32Array(0)
+ ];
+}
+
+function readFromObjectSloppy(o) {
+ return o.foo;
+}
+
+function readFromObjectKeyedSloppy(o) {
+ return o["foo"];
+}
+
+function readFromObjectKeyedVarSloppy(o) {
+ var a = "foo";
+ return o[a];
+}
+
+function readFromObjectKeyedComputedSloppy(o) {
+ var a = "o";
+ return o["fo" + a];
+}
+
+function readFromObjectStrong(o) {
+ "use strong";
+ return o.foo;
+}
+
+function readFromObjectKeyedStrong(o) {
+ "use strong";
+ return o["foo"];
+}
+
+function readFromObjectKeyedLetStrong(o) {
+ "use strong";
+ let a = "foo";
+ return o[a];
+}
+
+function readFromObjectKeyedComputedStrong(o) {
+ "use strong";
+ let a = "o";
+ return o["fo" + a];
+}
+
+function getDescs(x) {
+ return [
+ {value: x},
+ {configurable: true, enumerable: true, writable: true, value: x},
+ {configurable: true, enumerable: true, get: (function() {return x}) },
+ ];
+}
+
+function assertStrongSemantics(func, object) {
+ %DeoptimizeFunction(func);
+ %ClearFunctionTypeFeedback(func);
+ assertThrows(function(){func(object)}, TypeError);
+ assertThrows(function(){func(object)}, TypeError);
+ assertThrows(function(){func(object)}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(object)}, TypeError);
+ %DeoptimizeFunction(func);
+ assertThrows(function(){func(object)}, TypeError);
+}
+
+function assertSloppySemantics(func, object) {
+ %DeoptimizeFunction(func);
+ %ClearFunctionTypeFeedback(func);
+ assertDoesNotThrow(function(){func(object)});
+ assertDoesNotThrow(function(){func(object)});
+ assertDoesNotThrow(function(){func(object)});
+ %OptimizeFunctionOnNextCall(func);
+ assertDoesNotThrow(function(){func(object)});
+ %DeoptimizeFunction(func);
+ assertDoesNotThrow(function(){func(object)});
+}
+
+(function () {
+ "use strict";
+
+ let goodKeys = [
+ "foo"
+ ]
+
+ let badKeys = [
+ "bar",
+ "1",
+ "100001",
+ "3000000001",
+ "5000000001"
+ ];
+
+ let values = [
+ "string",
+ 1,
+ 100001,
+ 30000000001,
+ 50000000001,
+ NaN,
+ {},
+ undefined
+ ];
+
+ let literals = [0, NaN, true, "string"];
+
+ let badAccessorDescs = [
+ { set: (function(){}) },
+ { configurable: true, enumerable: true, set: (function(){}) }
+ ];
+
+ let readSloppy = [
+ readFromObjectSloppy,
+ readFromObjectKeyedSloppy,
+ readFromObjectKeyedVarSloppy,
+ readFromObjectKeyedComputedSloppy
+ ];
+
+ let readStrong = [
+ readFromObjectStrong,
+ readFromObjectKeyedStrong,
+ readFromObjectKeyedLetStrong,
+ readFromObjectKeyedComputedStrong
+ ];
+
+ let dummyProto = {};
+ for (let key of goodKeys) {
+ Object.defineProperty(dummyProto, key, { value: undefined });
+ }
+
+ let dummyAccessorProto = {};
+ for (let key of goodKeys) {
+ Object.defineProperty(dummyAccessorProto, key, { set: (function(){}) })
+ }
+
+ // Attempting to access a property on an object with no defined properties
+ // should throw.
+ for (let object of getObjects().concat(literals)) {
+ for (let func of readStrong) {
+ assertStrongSemantics(func, object);
+ }
+ for (let func of readSloppy) {
+ assertSloppySemantics(func, object);
+ }
+ }
+ for (let object of getObjects()) {
+ // Accessing a property which is on the prototype chain of the object should
+ // not throw.
+ object.__proto__ = dummyProto;
+ for (let key of goodKeys) {
+ for (let func of readStrong.concat(readSloppy)) {
+ assertSloppySemantics(func, object);
+ }
+ }
+ }
+ // Properties with accessor descriptors missing 'get' should throw on access.
+ for (let desc of badAccessorDescs) {
+ for (let key of goodKeys) {
+ for (let object of getObjects()) {
+ Object.defineProperty(object, key, desc);
+ for (let func of readStrong) {
+ assertStrongSemantics(func, object);
+ }
+ for (let func of readSloppy) {
+ assertSloppySemantics(func, object);
+ }
+ }
+ }
+ }
+ // The same behaviour should be expected for bad accessor properties on the
+ // prototype chain.
+ for (let object of getObjects()) {
+ object.__proto__ = dummyAccessorProto;
+ for (let func of readStrong) {
+ assertStrongSemantics(func, object);
+ }
+ for (let func of readSloppy) {
+ assertSloppySemantics(func, object);
+ }
+ }
+ assertThrows(function(){"use strong"; typeof ({}).foo;}, TypeError);
+ assertThrows(
+ function(){"use strong"; typeof ({}).foo === "undefined"}, TypeError);
+})();
diff --git a/deps/v8/test/mjsunit/strong/load-proxy.js b/deps/v8/test/mjsunit/strong/load-proxy.js
new file mode 100644
index 0000000000..98a3238c4e
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/load-proxy.js
@@ -0,0 +1,98 @@
+// Copyright 2015 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-proxies --strong-mode
+
+// Forwarding proxies adapted from proposal definition
+function handlerMaker1(obj) {
+ return {
+ getPropertyDescriptor: function(name) {
+ var desc;
+ var searchObj = obj;
+ while (desc === undefined && searchObj != null) {
+ desc = Object.getOwnPropertyDescriptor(searchObj, name);
+ searchObj = searchObj.__proto__;
+ }
+ // a trapping proxy's properties must always be configurable
+ if (desc !== undefined) { desc.configurable = true; }
+ return desc;
+ },
+ fix: function() {
+ if (Object.isFrozen(obj)) {
+ var result = {};
+ Object.getOwnPropertyNames(obj).forEach(function(name) {
+ result[name] = Object.getOwnPropertyDescriptor(obj, name);
+ });
+ return result;
+ }
+ // As long as obj is not frozen, the proxy won't allow itself to be fixed
+ return undefined; // will cause a TypeError to be thrown
+ }
+ };
+}
+function handlerMaker2(obj) {
+ return {
+ get: function(receiver, name) {
+ return obj[name];
+ },
+ fix: function() {
+ if (Object.isFrozen(obj)) {
+ var result = {};
+ Object.getOwnPropertyNames(obj).forEach(function(name) {
+ result[name] = Object.getOwnPropertyDescriptor(obj, name);
+ });
+ return result;
+ }
+ // As long as obj is not frozen, the proxy won't allow itself to be fixed
+ return undefined; // will cause a TypeError to be thrown
+ }
+ };
+}
+var baseObj = {};
+var proxy1 = Proxy.create(handlerMaker1(baseObj));
+var proxy2 = Proxy.create(handlerMaker2(baseObj));
+var childObj1 = { __proto__: proxy1 };
+var childObj2 = { __proto__: proxy2 };
+var childObjAccessor1 = { set foo(_){}, set "1"(_){}, __proto__: proxy1 };
+var childObjAccessor2 = { set foo(_){}, set "1"(_){}, __proto__: proxy2 };
+
+(function() {
+ "use strong";
+ // TODO(conradw): These asserts are sanity checking V8's proxy implementation.
+ // Strong mode semantics for ES6 proxies still need to be explored.
+ assertDoesNotThrow(function(){proxy1.foo});
+ assertDoesNotThrow(function(){proxy1[1]});
+ assertDoesNotThrow(function(){proxy2.foo});
+ assertDoesNotThrow(function(){proxy2[1]});
+ assertDoesNotThrow(function(){childObj1.foo});
+ assertDoesNotThrow(function(){childObj1[1]});
+ assertDoesNotThrow(function(){childObj2.foo});
+ assertDoesNotThrow(function(){childObj2[1]});
+ assertThrows(function(){baseObj.foo}, TypeError);
+ assertThrows(function(){baseObj[1]}, TypeError);
+ assertThrows(function(){childObjAccessor1.foo}, TypeError);
+ assertThrows(function(){childObjAccessor1[1]}, TypeError);
+ assertThrows(function(){childObjAccessor2.foo}, TypeError);
+ assertThrows(function(){childObjAccessor2[1]}, TypeError);
+
+ // Once the proxy is no longer trapping, property access should have strong
+ // semantics.
+ Object.freeze(baseObj);
+
+ Object.freeze(proxy1);
+ assertThrows(function(){proxy1.foo}, TypeError);
+ assertThrows(function(){proxy1[1]}, TypeError);
+ assertThrows(function(){childObj1.foo}, TypeError);
+ assertThrows(function(){childObj1[1]}, TypeError);
+ assertThrows(function(){childObjAccessor1.foo}, TypeError);
+ assertThrows(function(){childObjAccessor1[1]}, TypeError);
+
+ Object.freeze(proxy2);
+ assertThrows(function(){proxy2.foo}, TypeError);
+ assertThrows(function(){proxy2[1]}, TypeError);
+ assertThrows(function(){childObj2.foo}, TypeError);
+ assertThrows(function(){childObj2[1]}, TypeError);
+ assertThrows(function(){childObjAccessor2.foo}, TypeError);
+ assertThrows(function(){childObjAccessor2[1]}, TypeError);
+})();
diff --git a/deps/v8/test/mjsunit/strong/load-super.js b/deps/v8/test/mjsunit/strong/load-super.js
new file mode 100644
index 0000000000..4aa91c222a
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/load-super.js
@@ -0,0 +1,102 @@
+// Copyright 2015 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: --strong-mode
+
+"use strong";
+
+function testSuper(object) {
+ assertEquals(0, object.validLoad());
+ assertThrows(function(){ return object.propertyLoad() }, TypeError);
+ assertThrows(function(){ return object.elementLoad() }, TypeError);
+ assertThrows(function(){ return object.accessorLoad() }, TypeError);
+}
+
+class A {
+ constructor() {}
+ foo() {
+ return 0;
+ }
+ get bar() {
+ return 0;
+ }
+ set baz(_) {
+ return;
+ }
+}
+
+class B extends A {
+ constructor() {
+ super();
+ }
+ validLoad() {
+ return super.foo() + super.bar;
+ }
+ propertyLoad() {
+ return super.x;
+ }
+ elementLoad() {
+ return super[1];
+ }
+ accessorLoad() {
+ return super.baz;
+ }
+}
+
+class C extends A {
+ constructor() {
+ super();
+ this[1] = 0;
+ this.x = 0;
+ }
+ get baz() {
+ return 0;
+ }
+ validLoad() {
+ return super.foo() + super.bar;
+ }
+ propertyLoad() {
+ return super.x;
+ }
+ elementLoad() {
+ return super[1];
+ }
+ accessorLoad() {
+ return super.baz;
+ }
+}
+
+let b = new B();
+let c = new C();
+testSuper(b);
+testSuper(c);
+
+let d = {
+ "0": 0,
+ foo: 0,
+ bar: (function(){return 0}),
+ get baz(){return 0},
+ set qux(_){return}
+}
+
+let e = {
+ __proto__: d,
+ "1": 0,
+ x: 0,
+ get baz(){return 0},
+ validLoad() {
+ return super[0] + super.foo + super.bar() + super.baz;
+ },
+ propertyLoad() {
+ return super.x;
+ },
+ elementLoad() {
+ return super[1];
+ },
+ accessorLoad() {
+ return super.qux;
+ }
+}
+
+testSuper(e);
diff --git a/deps/v8/test/mjsunit/strong/object-delete.js b/deps/v8/test/mjsunit/strong/object-delete.js
new file mode 100644
index 0000000000..a655b65c78
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/object-delete.js
@@ -0,0 +1,255 @@
+// Copyright 2015 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: --strong-mode --allow-natives-syntax
+
+// TODO(conradw): Track implementation of strong bit for other objects, add
+// tests.
+
+function getSloppyObjects() {
+ return [(function(){}), ({})];
+}
+
+function getStrictObjects() {
+ "use strict";
+ return [(function(){}), ({})];
+}
+
+function getWeakObjects() {
+ return getSloppyObjects().concat(getStrictObjects());
+}
+
+function getStrongObjects() {
+ "use strong";
+// Strong functions can't have properties added to them, and will be tested as a
+// special case.
+ return [({})];
+}
+
+function strongFunction() {
+ "use strong";
+}
+
+function deleteFromObjectSloppy(o) {
+ return delete o.foo;
+}
+
+function deleteFromObjectKeyedSloppy(o) {
+ return delete o["foo"];
+}
+
+function deleteFromObjectKeyedVarSloppy(o) {
+ var a = "foo";
+ return delete o[a];
+}
+
+function deleteFromObjectKeyedComputedSloppy(o) {
+ var a = "o";
+ return delete o["fo" + a];
+}
+
+function deleteFromObjectWith(o) {
+ with (o) {
+ return delete foo;
+ }
+}
+
+function deleteFromObjectElementSloppy(o) {
+ return delete o[0];
+}
+
+function deleteFromObjectElementVarSloppy(o) {
+ var a = 0;
+ return delete o[a];
+}
+
+function deleteFromObjectElementSparseSloppy(o) {
+ return delete o[100000];
+}
+
+function deleteFromObjectElementVarSloppy(o) {
+ var a = 0;
+ return delete o[a];
+}
+
+function deleteFromObjectElementSparseVarSloppy(o) {
+ var a = 100000;
+ return delete o[a];
+}
+
+function deleteFromObjectStrict(o) {
+ "use strict";
+ return delete o.foo;
+}
+
+function deleteFromObjectKeyedStrict(o) {
+ "use strict";
+ return delete o["foo"];
+}
+
+function deleteFromObjectKeyedVarStrict(o) {
+ "use strict";
+ var a = "foo";
+ return delete o[a];
+}
+
+function deleteFromObjectKeyedComputedStrict(o) {
+ "use strict";
+ var a = "o";
+ return delete o["fo" + a];
+}
+
+function deleteFromObjectElementStrict(o) {
+ "use strict";
+ return delete o[0];
+}
+
+function deleteFromObjectElementSparseStrict(o) {
+ "use strict";
+ return delete o[100000];
+}
+
+function deleteFromObjectElementVarStrict(o) {
+ "use strict";
+ var a = 0;
+ return delete o[a];
+}
+
+function deleteFromObjectElementSparseVarStrict(o) {
+ "use strict";
+ var a = 100000;
+ return delete o[a];
+}
+
+function testStrongObjectDelete() {
+ "use strict";
+
+ let deletePropertyFuncsSloppy = [
+ deleteFromObjectSloppy,
+ deleteFromObjectKeyedSloppy,
+ deleteFromObjectKeyedVarSloppy,
+ deleteFromObjectKeyedComputedSloppy,
+ deleteFromObjectWith
+ ];
+ let deletePropertyFuncsStrict = [
+ deleteFromObjectStrict,
+ deleteFromObjectKeyedStrict,
+ deleteFromObjectKeyedVarStrict,
+ deleteFromObjectKeyedComputedStrict
+ ];
+ let deleteElementFuncsSloppy = [
+ deleteFromObjectElementSloppy,
+ deleteFromObjectElementVarSloppy
+ ];
+ let deleteElementSparseFuncsSloppy = [
+ deleteFromObjectElementSparseSloppy,
+ deleteFromObjectElementSparseVarSloppy
+ ];
+ let deleteElementFuncsStrict = [
+ deleteFromObjectElementStrict,
+ deleteFromObjectElementVarStrict
+ ];
+ let deleteElementSparseFuncsStrict = [
+ deleteFromObjectElementSparseStrict,
+ deleteFromObjectElementSparseVarStrict
+ ];
+ let deleteFuncs = deletePropertyFuncsSloppy.concat(
+ deletePropertyFuncsStrict, deleteElementFuncsSloppy,
+ deleteElementSparseFuncsSloppy, deleteElementFuncsStrict,
+ deleteElementSparseFuncsStrict);
+
+ for (let deleteFunc of deleteFuncs) {
+ assertTrue(deleteFunc(strongFunction));
+ }
+
+ let testCasesSloppy = [
+ [deletePropertyFuncsSloppy, "foo"],
+ [deleteElementFuncsSloppy, "0"],
+ [deleteElementSparseFuncsSloppy, "100000"]
+ ];
+
+ let testCasesStrict = [
+ [deletePropertyFuncsStrict, "foo"],
+ [deleteElementFuncsStrict, "0"],
+ [deleteElementSparseFuncsStrict, "100000"]
+ ];
+
+ let propDescs = [
+ {configurable: true, value: "bar"},
+ {configurable: true, value: 1},
+ {configurable: true, enumerable: true, writable: true, value: "bar"},
+ {configurable: true, enumerable: true, writable: true, value: 1},
+ {configurable: true, get: (function(){return 0}), set: (function(x){})}
+ ];
+
+ for (let propDesc of propDescs) {
+ for (let testCase of testCasesSloppy) {
+ let name = testCase[1];
+ for (let deleteFunc of testCase[0]) {
+ for (let o of getWeakObjects()) {
+ Object.defineProperty(o, name, propDesc);
+ assertTrue(delete o["bar"]);
+ assertTrue(delete o[5000]);
+ assertTrue(deleteFunc(o));
+ assertFalse(o.hasOwnProperty(name));
+ %OptimizeFunctionOnNextCall(deleteFunc);
+ Object.defineProperty(o, name, propDesc);
+ assertTrue(deleteFunc(o));
+ assertFalse(o.hasOwnProperty(name));
+ %DeoptimizeFunction(deleteFunc);
+ Object.defineProperty(o, name, propDesc);
+ assertTrue(deleteFunc(o));
+ assertFalse(o.hasOwnProperty(name));
+ }
+ for (let o of getStrongObjects()) {
+ Object.defineProperty(o, name, propDesc);
+ assertTrue(delete o["bar"]);
+ assertTrue(delete o[5000]);
+ assertFalse(deleteFunc(o));
+ assertTrue(o.hasOwnProperty(name));
+ %OptimizeFunctionOnNextCall(deleteFunc);
+ assertFalse(deleteFunc(o));
+ assertTrue(o.hasOwnProperty(name));
+ %DeoptimizeFunction(deleteFunc);
+ assertFalse(deleteFunc(o));
+ assertTrue(o.hasOwnProperty(name));
+ }
+ }
+ }
+ for (let testCase of testCasesStrict) {
+ let name = testCase[1];
+ for (let deleteFunc of testCase[0]) {
+ for (let o of getWeakObjects()) {
+ Object.defineProperty(o, name, propDesc);
+ assertTrue(delete o["bar"]);
+ assertTrue(delete o[5000]);
+ assertTrue(deleteFunc(o));
+ assertFalse(o.hasOwnProperty(name));
+ %OptimizeFunctionOnNextCall(deleteFunc);
+ Object.defineProperty(o, name, propDesc);
+ assertTrue(deleteFunc(o));
+ assertFalse(o.hasOwnProperty(name));
+ %DeoptimizeFunction(deleteFunc);
+ Object.defineProperty(o, name, propDesc);
+ assertTrue(deleteFunc(o));
+ assertFalse(o.hasOwnProperty(name));
+ }
+ for (let o of getStrongObjects()) {
+ Object.defineProperty(o, name, propDesc);
+ assertTrue(delete o["bar"]);
+ assertTrue(delete o[5000]);
+ assertThrows(function(){deleteFunc(o)}, TypeError);
+ assertTrue(o.hasOwnProperty(name));
+ %OptimizeFunctionOnNextCall(deleteFunc);
+ assertThrows(function(){deleteFunc(o)}, TypeError);
+ assertTrue(o.hasOwnProperty(name));
+ %DeoptimizeFunction(deleteFunc);
+ assertThrows(function(){deleteFunc(o)}, TypeError);
+ assertTrue(o.hasOwnProperty(name));
+ }
+ }
+ }
+ }
+}
+testStrongObjectDelete();
diff --git a/deps/v8/test/mjsunit/strong/object-freeze-property.js b/deps/v8/test/mjsunit/strong/object-freeze-property.js
new file mode 100644
index 0000000000..e76af1bfc6
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/object-freeze-property.js
@@ -0,0 +1,75 @@
+// Copyright 2015 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: --strong-mode --allow-natives-syntax
+
+// TODO(conradw): Track implementation of strong bit for other objects, add
+// tests.
+
+function getSloppyObjects() {
+ return [(function(){}), ({})];
+}
+
+function getStrictObjects() {
+ "use strict";
+ return [(function(){}), ({})];
+}
+
+function getStrongObjects() {
+ "use strong";
+ // Strong functions can't have properties added to them.
+ return [{}];
+}
+
+(function testStrongObjectFreezePropValid() {
+ "use strict";
+ let strongObjects = getStrongObjects();
+
+ for (let o of strongObjects) {
+ Object.defineProperty(o, "foo", { configurable: true, writable: true });
+ assertDoesNotThrow(
+ function() {
+ "use strong";
+ Object.defineProperty(o, "foo", {configurable: true, writable: false });
+ });
+ }
+})();
+
+(function testStrongObjectFreezePropInvalid() {
+ "use strict";
+ let sloppyObjects = getSloppyObjects();
+ let strictObjects = getStrictObjects();
+ let strongObjects = getStrongObjects();
+ let weakObjects = sloppyObjects.concat(strictObjects);
+
+ for (let o of weakObjects) {
+ Object.defineProperty(o, "foo", { writable: true });
+ assertDoesNotThrow(
+ function() {
+ "use strong";
+ Object.defineProperty(o, "foo", { writable: false });
+ });
+ }
+ for (let o of strongObjects) {
+ function defProp(o) {
+ Object.defineProperty(o, "foo", { writable: false });
+ }
+ function defProps(o) {
+ Object.defineProperties(o, { "foo": { writable: false } });
+ }
+ function freezeProp(o) {
+ Object.freeze(o);
+ }
+ Object.defineProperty(o, "foo", { writable: true });
+ for (let func of [defProp, defProps, freezeProp]) {
+ assertThrows(function(){func(o)}, TypeError);
+ assertThrows(function(){func(o)}, TypeError);
+ assertThrows(function(){func(o)}, TypeError);
+ %OptimizeFunctionOnNextCall(func);
+ assertThrows(function(){func(o)}, TypeError);
+ %DeoptimizeFunction(func);
+ assertThrows(function(){func(o)}, TypeError);
+ }
+ }
+})();
diff --git a/deps/v8/test/mjsunit/strong/object-set-prototype.js b/deps/v8/test/mjsunit/strong/object-set-prototype.js
new file mode 100644
index 0000000000..53706df1ee
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/object-set-prototype.js
@@ -0,0 +1,83 @@
+// Copyright 2015 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: --strong-mode --allow-natives-syntax
+
+// TODO(conradw): Track implementation of strong bit for other objects, add
+// tests.
+
+function getSloppyObjects() {
+ return [(function(){}), ({})];
+}
+
+function getStrictObjects() {
+ "use strict";
+ return [(function(){}), ({})];
+}
+
+function getStrongObjects() {
+ "use strong";
+ return [(function(){}), ({})];
+}
+
+function declareObjectLiteralWithProtoSloppy() {
+ return {__proto__: {}};
+}
+
+function declareObjectLiteralWithProtoStrong() {
+ "use strong";
+ return {__proto__: {}};
+}
+
+function testStrongObjectSetProto() {
+ "use strict";
+ let sloppyObjects = getSloppyObjects();
+ let strictObjects = getStrictObjects();
+ let strongObjects = getStrongObjects();
+ let weakObjects = sloppyObjects.concat(strictObjects);
+
+ for (let o of weakObjects) {
+ let setProtoBuiltin = function(o){Object.setPrototypeOf(o, {})};
+ let setProtoProperty = function(o){o.__proto__ = {}};
+ for (let setProtoFunc of [setProtoBuiltin, setProtoProperty]) {
+ assertDoesNotThrow(function(){setProtoFunc(o)});
+ assertDoesNotThrow(function(){setProtoFunc(o)});
+ assertDoesNotThrow(function(){setProtoFunc(o)});
+ %OptimizeFunctionOnNextCall(setProtoFunc);
+ assertDoesNotThrow(function(){setProtoFunc(o)});
+ %DeoptimizeFunction(setProtoFunc);
+ assertDoesNotThrow(function(){setProtoFunc(o)});
+ }
+ }
+ for (let o of strongObjects) {
+ let setProtoBuiltin = function(o){Object.setPrototypeOf(o, {})};
+ let setProtoProperty = function(o){o.__proto__ = {}};
+ for (let setProtoFunc of [setProtoBuiltin, setProtoProperty]) {
+ assertThrows(function(){setProtoFunc(o)}, TypeError);
+ assertThrows(function(){setProtoFunc(o)}, TypeError);
+ assertThrows(function(){setProtoFunc(o)}, TypeError);
+ %OptimizeFunctionOnNextCall(setProtoFunc);
+ assertThrows(function(){setProtoFunc(o)}, TypeError);
+ %DeoptimizeFunction(setProtoFunc);
+ assertThrows(function(){setProtoFunc(o)}, TypeError);
+ }
+ }
+
+ assertDoesNotThrow(declareObjectLiteralWithProtoSloppy);
+ assertDoesNotThrow(declareObjectLiteralWithProtoSloppy);
+ assertDoesNotThrow(declareObjectLiteralWithProtoSloppy);
+ %OptimizeFunctionOnNextCall(declareObjectLiteralWithProtoSloppy);
+ assertDoesNotThrow(declareObjectLiteralWithProtoSloppy);
+ %DeoptimizeFunction(declareObjectLiteralWithProtoSloppy);
+ assertDoesNotThrow(declareObjectLiteralWithProtoSloppy);
+
+ assertDoesNotThrow(declareObjectLiteralWithProtoStrong);
+ assertDoesNotThrow(declareObjectLiteralWithProtoStrong);
+ assertDoesNotThrow(declareObjectLiteralWithProtoStrong);
+ %OptimizeFunctionOnNextCall(declareObjectLiteralWithProtoStrong);
+ assertDoesNotThrow(declareObjectLiteralWithProtoStrong);
+ %DeoptimizeFunction(declareObjectLiteralWithProtoStrong);
+ assertDoesNotThrow(declareObjectLiteralWithProtoStrong);
+}
+testStrongObjectSetProto();
diff --git a/deps/v8/test/mjsunit/strong/super.js b/deps/v8/test/mjsunit/strong/super.js
new file mode 100644
index 0000000000..bd289f204f
--- /dev/null
+++ b/deps/v8/test/mjsunit/strong/super.js
@@ -0,0 +1,62 @@
+// Copyright 2015 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: --strong-mode --allow-natives-syntax
+
+'use strong';
+
+
+function desc(obj, n) {
+ return Object.getOwnPropertyDescriptor(obj, n);
+}
+
+
+(function TestClass() {
+ class C {
+ m() {
+ super.x;
+ }
+ get x() {
+ super.x;
+ }
+ set y(_) {
+ super.x;
+ }
+ static m() {
+ super.x;
+ }
+ static get x() {
+ super.x;
+ }
+ static set y(_) {
+ super.x;
+ }
+ }
+
+ assertEquals(C.prototype, C.prototype.m[%HomeObjectSymbol()]);
+ assertEquals(C.prototype, desc(C.prototype, 'x').get[%HomeObjectSymbol()]);
+ assertEquals(C.prototype, desc(C.prototype, 'y').set[%HomeObjectSymbol()]);
+ assertEquals(C, C.m[%HomeObjectSymbol()]);
+ assertEquals(C, desc(C, 'x').get[%HomeObjectSymbol()]);
+ assertEquals(C, desc(C, 'y').set[%HomeObjectSymbol()]);
+})();
+
+
+(function TestObjectLiteral() {
+ let o = {
+ m() {
+ super.x;
+ },
+ get x() {
+ super.x;
+ },
+ set y(_) {
+ super.x;
+ }
+ };
+
+ assertEquals(o, o.m[%HomeObjectSymbol()]);
+ assertEquals(o, desc(o, 'x').get[%HomeObjectSymbol()]);
+ assertEquals(o, desc(o, 'y').set[%HomeObjectSymbol()]);
+})();
diff --git a/deps/v8/test/mjsunit/testcfg.py b/deps/v8/test/mjsunit/testcfg.py
index 8389696f49..cf4b6276e4 100644
--- a/deps/v8/test/mjsunit/testcfg.py
+++ b/deps/v8/test/mjsunit/testcfg.py
@@ -35,6 +35,7 @@ FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
FILES_PATTERN = re.compile(r"//\s+Files:(.*)")
SELF_SCRIPT_PATTERN = re.compile(r"//\s+Env: TEST_FILE_NAME")
MODULE_PATTERN = re.compile(r"^// MODULE$", flags=re.MULTILINE)
+NO_HARNESS_PATTERN = re.compile(r"^// NO HARNESS$", flags=re.MULTILINE)
class MjsunitTestSuite(testsuite.TestSuite):
@@ -79,7 +80,7 @@ class MjsunitTestSuite(testsuite.TestSuite):
env = ["-e", "TEST_FILE_NAME=\"%s\"" % testfilename.replace("\\", "\\\\")]
files = env + files
- if not context.no_harness:
+ if not context.no_harness and not NO_HARNESS_PATTERN.search(source):
files.append(os.path.join(self.root, "mjsunit.js"))
if MODULE_PATTERN.search(source):
diff --git a/deps/v8/test/mjsunit/third_party/object-keys/LICENSE b/deps/v8/test/mjsunit/third_party/object-keys/LICENSE
new file mode 100644
index 0000000000..67002b4400
--- /dev/null
+++ b/deps/v8/test/mjsunit/third_party/object-keys/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following
+disclaimer in the documentation and/or other materials provided
+with the distribution.
+
+3. Neither the name of the copyright holder(s) nor the names of any
+contributors may be used to endorse or promote products derived
+from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/deps/v8/test/mjsunit/third_party/object-keys.js b/deps/v8/test/mjsunit/third_party/object-keys/object-keys.js
index c8003745c4..c8003745c4 100644
--- a/deps/v8/test/mjsunit/third_party/object-keys.js
+++ b/deps/v8/test/mjsunit/third_party/object-keys/object-keys.js
diff --git a/deps/v8/test/mjsunit/third_party/regexp-pcre/LICENSE b/deps/v8/test/mjsunit/third_party/regexp-pcre/LICENSE
new file mode 100644
index 0000000000..4baa7d83a1
--- /dev/null
+++ b/deps/v8/test/mjsunit/third_party/regexp-pcre/LICENSE
@@ -0,0 +1,68 @@
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Release 7 of PCRE is distributed under the terms of the "BSD" licence, as
+specified below. The documentation for PCRE, supplied in the "doc"
+directory, is distributed under the same terms as the software itself.
+
+The basic library functions are written in C and are freestanding. Also
+included in the distribution is a set of C++ wrapper functions.
+
+
+THE BASIC LIBRARY FUNCTIONS
+---------------------------
+
+Written by: Philip Hazel
+Email local part: ph10
+Email domain: cam.ac.uk
+
+University of Cambridge Computing Service,
+Cambridge, England.
+
+Copyright (c) 1997-2007 University of Cambridge
+All rights reserved.
+
+
+THE C++ WRAPPER FUNCTIONS
+-------------------------
+
+Contributed by: Google Inc.
+
+Copyright (c) 2007, Google Inc.
+All rights reserved.
+
+
+THE "BSD" LICENCE
+-----------------
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the name of Google
+ Inc. nor the names of their contributors may be used to endorse or
+ promote products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+End
diff --git a/deps/v8/test/mjsunit/third_party/regexp-pcre.js b/deps/v8/test/mjsunit/third_party/regexp-pcre/regexp-pcre.js
index c049fb4d09..c049fb4d09 100644
--- a/deps/v8/test/mjsunit/third_party/regexp-pcre.js
+++ b/deps/v8/test/mjsunit/third_party/regexp-pcre/regexp-pcre.js
diff --git a/deps/v8/test/mjsunit/this-dynamic-lookup.js b/deps/v8/test/mjsunit/this-dynamic-lookup.js
new file mode 100644
index 0000000000..c5fa7a2c79
--- /dev/null
+++ b/deps/v8/test/mjsunit/this-dynamic-lookup.js
@@ -0,0 +1,10 @@
+// Copyright 2015 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
+// NO HARNESS
+
+var globalEval = eval;
+globalEval("this; eval('42')");
+globalEval("eval('42'); this");
diff --git a/deps/v8/test/mjsunit/unbox-double-field-indexed.js b/deps/v8/test/mjsunit/unbox-double-field-indexed.js
new file mode 100644
index 0000000000..29dfc79205
--- /dev/null
+++ b/deps/v8/test/mjsunit/unbox-double-field-indexed.js
@@ -0,0 +1,23 @@
+// Copyright 2015 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(x) {
+ this.x = x;
+}
+
+var f = new Foo(1.25);
+var g = new Foo(2.25);
+
+function add(a, b) {
+ var name = "x";
+ return a[name] + b[name];
+}
+
+assertEquals(3.5, add(f, g));
+assertEquals(3.5, add(g, f));
+%OptimizeFunctionOnNextCall(add);
+assertEquals(3.5, add(f, g));
+assertEquals(3.5, add(g, f));
diff --git a/deps/v8/test/mjsunit/unbox-double-field.js b/deps/v8/test/mjsunit/unbox-double-field.js
new file mode 100644
index 0000000000..9fb5479be7
--- /dev/null
+++ b/deps/v8/test/mjsunit/unbox-double-field.js
@@ -0,0 +1,22 @@
+// Copyright 2015 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(x) {
+ this.x = x;
+}
+
+var f = new Foo(1.25);
+var g = new Foo(2.25);
+
+function add(a, b) {
+ return a.x + b.x;
+}
+
+assertEquals(3.5, add(f, g));
+assertEquals(3.5, add(g, f));
+%OptimizeFunctionOnNextCall(add);
+assertEquals(3.5, add(f, g));
+assertEquals(3.5, add(g, f));
diff --git a/deps/v8/test/mjsunit/unbox-smi-field-indexed.js b/deps/v8/test/mjsunit/unbox-smi-field-indexed.js
new file mode 100644
index 0000000000..9e77da03ed
--- /dev/null
+++ b/deps/v8/test/mjsunit/unbox-smi-field-indexed.js
@@ -0,0 +1,23 @@
+// Copyright 2015 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(x) {
+ this.x = x;
+}
+
+var f = new Foo(1);
+var g = new Foo(2);
+
+function add(a, b) {
+ var name = "x";
+ return a[name] + b[name];
+}
+
+assertEquals(3, add(f, g));
+assertEquals(3, add(g, f));
+%OptimizeFunctionOnNextCall(add);
+assertEquals(3, add(f, g));
+assertEquals(3, add(g, f));
diff --git a/deps/v8/test/mjsunit/unbox-smi-field.js b/deps/v8/test/mjsunit/unbox-smi-field.js
new file mode 100644
index 0000000000..361911800b
--- /dev/null
+++ b/deps/v8/test/mjsunit/unbox-smi-field.js
@@ -0,0 +1,22 @@
+// Copyright 2015 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(x) {
+ this.x = x;
+}
+
+var f = new Foo(1);
+var g = new Foo(2);
+
+function add(a, b) {
+ return a.x + b.x;
+}
+
+assertEquals(3, add(f, g));
+assertEquals(3, add(g, f));
+%OptimizeFunctionOnNextCall(add);
+assertEquals(3, add(f, g));
+assertEquals(3, add(g, f));
diff --git a/deps/v8/test/mjsunit/undetectable-compare.js b/deps/v8/test/mjsunit/undetectable-compare.js
new file mode 100644
index 0000000000..fbfbbe1051
--- /dev/null
+++ b/deps/v8/test/mjsunit/undetectable-compare.js
@@ -0,0 +1,96 @@
+// Copyright 2015 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 undetectable = %GetUndetectable();
+
+var tests = [
+ true, false,
+ false, false,
+ null, true,
+ void 0, true,
+ 0, false,
+ 0.0, false,
+ -0, false,
+ "", false,
+ -1, false,
+ -1.25, false,
+ 1, false,
+ 1.25, false,
+ -2147483648, false,
+ 2147483648, false,
+ Infinity, false,
+ -Infinity, false,
+ NaN, false
+];
+
+var func = (function eq(a) { return a == undetectable; });
+var left_funcs = [
+ (function eq_L0() { return true == undetectable; }),
+ (function eq_L1() { return false == undetectable; }),
+ (function eq_L2() { return null == undetectable; }),
+ (function eq_L3() { return void 0 == undetectable; }),
+ (function eq_L4() { return 0 == undetectable; }),
+ (function eq_L5() { return 0.0 == undetectable; }),
+ (function eq_L6() { return -0 == undetectable; }),
+ (function eq_L7() { return "" == undetectable; }),
+ (function eq_L8() { return -1 == undetectable; }),
+ (function eq_L9() { return -1.25 == undetectable; }),
+ (function eq_L10() { return 1 == undetectable; }),
+ (function eq_L11() { return 1.25 == undetectable; }),
+ (function eq_L12() { return -2147483648 == undetectable; }),
+ (function eq_L13() { return 2147483648 == undetectable; }),
+ (function eq_L14() { return Infinity == undetectable; }),
+ (function eq_L15() { return -Infinity == undetectable; }),
+ (function eq_L16() { return NaN == undetectable; })
+];
+
+var right_funcs = [
+ (function eq_R0() { return undetectable == true; }),
+ (function eq_R1() { return undetectable == false; }),
+ (function eq_R2() { return undetectable == null; }),
+ (function eq_R3() { return undetectable == void 0; }),
+ (function eq_R4() { return undetectable == 0; }),
+ (function eq_R5() { return undetectable == 0.0; }),
+ (function eq_R6() { return undetectable == -0; }),
+ (function eq_R7() { return undetectable == ""; }),
+ (function eq_R8() { return undetectable == -1; }),
+ (function eq_R9() { return undetectable == -1.25; }),
+ (function eq_R10() { return undetectable == 1; }),
+ (function eq_R11() { return undetectable == 1.25; }),
+ (function eq_R12() { return undetectable == -2147483648; }),
+ (function eq_R13() { return undetectable == 2147483648; }),
+ (function eq_R14() { return undetectable == Infinity; }),
+ (function eq_R15() { return undetectable == -Infinity; }),
+ (function eq_R16() { return undetectable == NaN; })
+];
+
+function test() {
+ for (var i = 0; i < tests.length; i += 2) {
+ var val = tests[i];
+ var eq = tests[i + 1];
+
+ assertEquals(eq, val == undetectable);
+ assertEquals(eq, undetectable == val);
+
+ assertFalse(val === undetectable);
+ assertFalse(undetectable === val);
+
+ assertEquals(eq, left_funcs[i/2]());
+ assertEquals(eq, right_funcs[i/2]());
+ }
+
+ assertTrue(undetectable == undetectable);
+ assertTrue(undetectable === undetectable);
+
+}
+
+for (var i = 0; i < 5; i++) {
+ test();
+}
+
+
+assertFalse(undetectable == %GetUndetectable());
+assertFalse(undetectable === %GetUndetectable());
diff --git a/deps/v8/test/mjsunit/undetectable.js b/deps/v8/test/mjsunit/undetectable.js
new file mode 100644
index 0000000000..f4871f995c
--- /dev/null
+++ b/deps/v8/test/mjsunit/undetectable.js
@@ -0,0 +1,87 @@
+// Copyright 2015 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 = %GetUndetectable();
+
+function shouldNotBeTaken() {
+ fail("Undetectable branch should not be taken", "branch was taken");
+}
+
+function shouldBeTaken() {
+ fail("Inverted Undetectable branch should be taken", "branch was not taken");
+}
+
+function testCompares() {
+ assertTrue(!obj);
+ assertFalse(!!obj);
+ assertFalse(obj == true);
+ assertFalse(obj == false);
+ assertFalse(obj === true);
+ assertFalse(obj === false);
+ assertEquals(2, obj ? 1 : 2);
+ assertEquals(obj, true && obj);
+ assertEquals(obj, false || obj);
+}
+
+function testIfs() {
+ if (obj) {
+ shouldNotBeTaken();
+ }
+
+ if (obj) {
+ shouldNotBeTaken();
+ } else {
+ // do nothing
+ }
+
+ if (!obj) {
+ // do nothing
+ } else {
+ shouldBeTaken();
+ }
+}
+
+function testWhiles() {
+ while (obj) {
+ shouldNotBeTaken();
+ }
+
+ var i = 0;
+ while (!obj) {
+ i++;
+ break;
+ }
+
+ assertEquals(1, i);
+}
+
+function testFors() {
+ for (var i = 0; obj; i++) {
+ shouldNotBeTaken();
+ }
+
+ var j = 0;
+ for (var i = 0; !obj; i++) {
+ j++;
+ break;
+ }
+
+ assertEquals(1, j);
+}
+
+for (var j = 0; j < 5; j++) {
+ testCompares();
+ testIfs();
+ testWhiles();
+ testFors();
+
+ if (j == 3) {
+ %OptimizeFunctionOnNextCall(testCompares);
+ %OptimizeFunctionOnNextCall(testIfs);
+ %OptimizeFunctionOnNextCall(testWhiles);
+ %OptimizeFunctionOnNextCall(testFors);
+ }
+}
diff --git a/deps/v8/test/mjsunit/uri.js b/deps/v8/test/mjsunit/uri.js
index fae349f439..862e420f89 100644
--- a/deps/v8/test/mjsunit/uri.js
+++ b/deps/v8/test/mjsunit/uri.js
@@ -88,3 +88,13 @@ test("\u1234\u0123\uabcd");
test("abcd");
test("ab<\u1234\u0123");
test("ab\u1234<\u0123");
+
+
+(function TestDeleteCharCodeAt() {
+ assertEquals('abc', encodeURI('abc'));
+ assertEquals('abc', decodeURI('abc'));
+ assertTrue(delete String.prototype.charCodeAt);
+ assertTrue(delete String.prototype.charAt);
+ assertEquals('abc', encodeURI('abc'));
+ assertEquals('abc', decodeURI('abc'));
+})();
diff --git a/deps/v8/test/mozilla/mozilla.status b/deps/v8/test/mozilla/mozilla.status
index 109efb78e2..94278e39b3 100644
--- a/deps/v8/test/mozilla/mozilla.status
+++ b/deps/v8/test/mozilla/mozilla.status
@@ -63,6 +63,7 @@
'ecma_3/Statements/regress-74474-002': [PASS, NO_VARIANTS],
'ecma_3/Statements/regress-74474-003': [PASS, NO_VARIANTS],
'js1_5/Regress/regress-111557': [PASS, NO_VARIANTS],
+ 'js1_5/Regress/regress-155081': [PASS, NO_VARIANTS],
'js1_5/Regress/regress-155081-2': [PASS, NO_VARIANTS],
'js1_5/Regress/regress-451322': [PASS, NO_VARIANTS],
diff --git a/deps/v8/test/simdjs/SimdJs.json b/deps/v8/test/simdjs/SimdJs.json
new file mode 100644
index 0000000000..b671ac4cb8
--- /dev/null
+++ b/deps/v8/test/simdjs/SimdJs.json
@@ -0,0 +1,315 @@
+{
+ "flags": [
+ "--harmony-object",
+ "test/simdjs/harness-adapt.js"
+ ],
+ "name": "SIMDJS",
+ "path": [
+ "../../"
+ ],
+ "resources": [
+ "test/simdjs/data/src/benchmarks/base.js",
+ "test/simdjs/data/src/ecmascript_simd.js",
+ "test/simdjs/harness-adapt.js",
+ "test/simdjs/harness-finish.js",
+ "test/simdjs/data/src/benchmarks/kernel-template.js",
+ "test/simdjs/data/src/benchmarks/averageFloat32x4.js",
+ "test/simdjs/data/src/benchmarks/averageFloat32x4LoadFromInt8Array.js",
+ "test/simdjs/data/src/benchmarks/averageFloat32x4LoadX.js",
+ "test/simdjs/data/src/benchmarks/averageFloat32x4LoadXY.js",
+ "test/simdjs/data/src/benchmarks/averageFloat32x4LoadXYZ.js",
+ "test/simdjs/data/src/benchmarks/averageFloat64x2.js",
+ "test/simdjs/data/src/benchmarks/averageFloat64x2Load.js",
+ "test/simdjs/data/src/benchmarks/mandelbrot.js",
+ "test/simdjs/data/src/benchmarks/matrix-multiplication.js",
+ "test/simdjs/data/src/benchmarks/transform.js",
+ "test/simdjs/data/src/benchmarks/shiftrows.js",
+ "test/simdjs/data/src/benchmarks/transpose4x4.js",
+ "test/simdjs/data/src/benchmarks/inverse4x4.js",
+ "test/simdjs/data/src/benchmarks/sinx4.js",
+ "test/simdjs/data/src/benchmarks/memset.js",
+ "test/simdjs/data/src/benchmarks/memcpy.js"
+ ],
+ "run_count": 5,
+ "run_count_android_arm": 1,
+ "run_count_android_arm64": 3,
+ "run_count_arm": 3,
+ "tests": [
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/kernel-template.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "kernel-template",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/averageFloat32x4.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "averageFloat32x4",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/averageFloat32x4LoadFromInt8Array.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "averageFloat32x4LoadFromInt8Array",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/averageFloat32x4LoadX.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "averageFloat32x4LoadX",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/averageFloat32x4LoadXY.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "averageFloat32x4LoadXY",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/averageFloat32x4LoadXYZ.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "averageFloat32x4LoadXYZ",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/averageFloat64x2.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "averageFloat64x2",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/averageFloat64x2Load.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "averageFloat64x2Load",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/mandelbrot.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "mandelbrot",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/matrix-multiplication.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "matrix-multiplication",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/transform.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "transform",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/shiftrows.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "shiftrows",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/transpose4x4.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "transpose4x4",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/inverse4x4.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "inverse4x4",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/sinx4.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "sinx4",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/memset.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "memset",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ },
+ {
+ "flags": [
+ "test/simdjs/data/src/benchmarks/memcpy.js"
+ ],
+ "main": "test/simdjs/harness-finish.js",
+ "name": "memcpy",
+ "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)",
+ "tests": [
+ {
+ "name": "SIMD"
+ },
+ {
+ "name": "Non-SIMD"
+ }
+ ]
+ }
+ ],
+ "timeout_android_arm": 180,
+ "timeout_android_arm64": 120,
+ "timeout_arm": 120,
+ "units": "ms"
+} \ No newline at end of file
diff --git a/deps/v8/test/simdjs/generate.py b/deps/v8/test/simdjs/generate.py
new file mode 100755
index 0000000000..b100a94ae6
--- /dev/null
+++ b/deps/v8/test/simdjs/generate.py
@@ -0,0 +1,61 @@
+#!/usr/bin/python
+# Copyright 2015 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.
+
+# Script to re-generate SimdJs.json from a SimdJs.json.template.
+
+import json
+import os
+import re
+
+SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
+
+SKIP_FILES = [
+ '../ecmascript_simd',
+ 'base',
+ # TODO(bradnelson): Drop these when tests are fixed upstream.
+ 'aobench',
+ 'averageFloat32x4Load',
+ 'matrix-multiplication-load',
+]
+
+run_js = open(
+ os.path.join(SCRIPT_DIR, 'data', 'src', 'benchmarks', 'run.js')).read()
+tests = re.findall("load \\(\\'([^']+)[.]js\\'\\)", run_js)
+tests = [t for t in tests if t not in SKIP_FILES]
+
+output = {
+ 'name': 'SIMDJS',
+ 'run_count': 5,
+ 'run_count_arm': 3,
+ 'run_count_android_arm': 1,
+ 'run_count_android_arm64': 3,
+ 'timeout_arm': 120,
+ 'timeout_android_arm': 180,
+ 'timeout_android_arm64': 120,
+ 'units': 'ms',
+ 'resources': [
+ 'test/simdjs/data/src/benchmarks/base.js',
+ 'test/simdjs/data/src/ecmascript_simd.js',
+ 'test/simdjs/harness-adapt.js',
+ 'test/simdjs/harness-finish.js'
+ ] + ['test/simdjs/data/src/benchmarks/%s.js' % t for t in tests],
+ 'flags': ['--harmony-object', 'test/simdjs/harness-adapt.js'],
+ 'path': ['../../'],
+ 'tests': [
+ {
+ 'name': test,
+ 'main': 'test/simdjs/harness-finish.js',
+ 'flags': ['test/simdjs/data/src/benchmarks/%s.js' % test],
+ 'results_regexp': '%s\\([ ]*([0-9.]+)(ms)?\\)',
+ 'tests': [
+ {'name': 'SIMD'},
+ {'name': 'Non-SIMD'},
+ ]
+ }
+ for test in tests],
+}
+
+with open(os.path.join(SCRIPT_DIR, 'SimdJs.json'), 'w') as fh:
+ fh.write(json.dumps(output, separators=(',',': '), indent=2, sort_keys=True))
diff --git a/deps/v8/test/simdjs/harness-adapt.js b/deps/v8/test/simdjs/harness-adapt.js
new file mode 100644
index 0000000000..a2ca2372c4
--- /dev/null
+++ b/deps/v8/test/simdjs/harness-adapt.js
@@ -0,0 +1,29 @@
+// Copyright 2015 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() {
+
+"use strict";
+
+var _oldLoad = load;
+
+// Filter load paths in the ecmascript_simd tests that
+// assume the test is run with a current working directory
+// set to the directory containing the test.
+load = function(filename) {
+ // Decide if this is the compliance test or the benchmarks.
+ if (filename === 'ecmascript_simd.js' ||
+ filename === 'ecmascript_simd_tests.js') {
+ _oldLoad('test/simdjs/data/src/' + filename);
+ } else {
+ _oldLoad('test/simdjs/data/src/benchmarks/' + filename);
+ }
+};
+
+// TODO(bbudge): Drop when polyfill is not needed.
+load('ecmascript_simd.js');
+
+load('base.js');
+
+})();
diff --git a/deps/v8/test/simdjs/harness-finish.js b/deps/v8/test/simdjs/harness-finish.js
new file mode 100644
index 0000000000..9df611085c
--- /dev/null
+++ b/deps/v8/test/simdjs/harness-finish.js
@@ -0,0 +1,26 @@
+// Copyright 2015 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() {
+
+"use strict";
+
+function printResult (str) {
+ print (str);
+}
+
+function printError (str) {
+ print (str);
+}
+
+function printScore (str) {
+ print (str);
+}
+
+benchmarks.runAll ({notifyResult: printResult,
+ notifyError: printError,
+ notifyScore: printScore},
+ true);
+
+})();
diff --git a/deps/v8/test/simdjs/simdjs.status b/deps/v8/test/simdjs/simdjs.status
new file mode 100644
index 0000000000..99ce8865e5
--- /dev/null
+++ b/deps/v8/test/simdjs/simdjs.status
@@ -0,0 +1,26 @@
+# Copyright 2015 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.
+
+# --------------------------------------------------------------------
+# If you add a test case to this file, please try to provide
+# an explanation of why the test fails; this may ease future
+# debugging.
+# --------------------------------------------------------------------
+
+[
+[ALWAYS, {
+ # TODO(bradnelson): Drop when test is fixed upstream.
+ 'benchmarks/aobench': SKIP,
+
+ # TODO(bbudge): Drop this when simd implementation is faster.
+ 'benchmarks/memcpy': SKIP,
+}],
+
+######################################################################
+['byteorder == big', {
+ # shell_test_runner requires little-endian, skip it on big-endian.
+ 'shell_test_runner': [SKIP],
+}], # 'byteorder == big'
+
+]
diff --git a/deps/v8/test/simdjs/testcfg.py b/deps/v8/test/simdjs/testcfg.py
new file mode 100644
index 0000000000..c0390afd65
--- /dev/null
+++ b/deps/v8/test/simdjs/testcfg.py
@@ -0,0 +1,101 @@
+# 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 hashlib
+import os
+import shutil
+import sys
+import tarfile
+import imp
+
+from testrunner.local import testsuite
+from testrunner.local import utils
+from testrunner.objects import testcase
+
+SIMDJS_ARCHIVE_REVISION = "07e2713e0c9ea19feb0732d5bd84770c87310d79"
+SIMDJS_ARCHIVE_MD5 = "cf6bddf99f18800b68e782054268ee3c"
+SIMDJS_URL = (
+ "https://github.com/johnmccutchan/ecmascript_simd/archive/%s.tar.gz")
+
+SIMDJS_SUITE_PATH = ["data", "src"]
+
+
+class SimdJsTestSuite(testsuite.TestSuite):
+
+ def __init__(self, name, root):
+ super(SimdJsTestSuite, self).__init__(name, root)
+ self.testroot = os.path.join(self.root, *SIMDJS_SUITE_PATH)
+ self.ParseTestRecord = None
+
+ def ListTests(self, context):
+ tests = [
+ testcase.TestCase(self, 'shell_test_runner'),
+ ]
+ for filename in os.listdir(os.path.join(self.testroot, 'benchmarks')):
+ if (not filename.endswith('.js') or
+ filename in ['run.js', 'run_browser.js', 'base.js']):
+ continue
+ name = filename.rsplit('.')[0]
+ tests.append(
+ testcase.TestCase(self, 'benchmarks/' + name))
+ return tests
+
+ def GetFlagsForTestCase(self, testcase, context):
+ return (testcase.flags + context.mode_flags +
+ [os.path.join(self.root, "harness-adapt.js"),
+ "--harmony",
+ os.path.join(self.testroot, testcase.path + ".js"),
+ os.path.join(self.root, "harness-finish.js")])
+
+ def GetSourceForTest(self, testcase):
+ filename = os.path.join(self.testroot, testcase.path + ".js")
+ with open(filename) as f:
+ return f.read()
+
+ def IsNegativeTest(self, testcase):
+ return False
+
+ def IsFailureOutput(self, output, testpath):
+ if output.exit_code != 0:
+ return True
+ return "FAILED!" in output.stdout
+
+ def DownloadData(self):
+ revision = SIMDJS_ARCHIVE_REVISION
+ archive_url = SIMDJS_URL % revision
+ archive_name = os.path.join(
+ self.root, "ecmascript_simd-%s.tar.gz" % revision)
+ directory_name = os.path.join(self.root, "data")
+ 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
+ utils.URLRetrieve(archive_url, archive_name)
+ if os.path.exists(directory_name):
+ if os.path.exists(directory_old_name):
+ shutil.rmtree(directory_old_name)
+ os.rename(directory_name, directory_old_name)
+ if not os.path.exists(directory_name):
+ print "Extracting ecmascript_simd-%s.tar.gz ..." % revision
+ md5 = hashlib.md5()
+ with open(archive_name, "rb") as f:
+ for chunk in iter(lambda: f.read(8192), ""):
+ md5.update(chunk)
+ print "MD5 hash is %s" % md5.hexdigest()
+ if md5.hexdigest() != SIMDJS_ARCHIVE_MD5:
+ os.remove(archive_name)
+ print "MD5 expected %s" % SIMDJS_ARCHIVE_MD5
+ raise Exception("MD5 hash mismatch of test data file")
+ archive = tarfile.open(archive_name, "r:gz")
+ if sys.platform in ("win32", "cygwin"):
+ # Magic incantation to allow longer path names on Windows.
+ archive.extractall(u"\\\\?\\%s" % self.root)
+ else:
+ archive.extractall(self.root)
+ os.rename(os.path.join(self.root, "ecmascript_simd-%s" % revision),
+ directory_name)
+
+
+def GetSuite(name, root):
+ return SimdJsTestSuite(name, root)
diff --git a/deps/v8/test/test262-es6/README b/deps/v8/test/test262-es6/README
index 531189719b..fe3ab232ba 100644
--- a/deps/v8/test/test262-es6/README
+++ b/deps/v8/test/test262-es6/README
@@ -4,13 +4,13 @@ tests from
https://github.com/tc39/test262
-at hash 43acf61 (2015/03/31 revision) as 'data' in this directory. Using later
+at hash c6ac390 (2015/07/06 revision) as 'data' in this directory. Using later
version may be possible but the tests are only known to pass (and indeed run)
with that revision.
git clone https://github.com/tc39/test262 data
cd data
- git checkout 43acf61
+ git checkout c6ac390
If you do update to a newer revision you may have to change the test
harness adapter code since it uses internal functionality from the
diff --git a/deps/v8/test/test262-es6/test262-es6.status b/deps/v8/test/test262-es6/test262-es6.status
index 31bb60bd22..65ded6d3f5 100644
--- a/deps/v8/test/test262-es6/test262-es6.status
+++ b/deps/v8/test/test262-es6/test262-es6.status
@@ -33,6 +33,30 @@
'intl402/11.2.3_b': [FAIL],
'intl402/12.2.3_b': [FAIL],
+ # BUG(v8:4267)
+ 'built-ins/Object/defineProperty/15.2.3.6-4-116': [FAIL],
+ 'built-ins/Object/defineProperty/15.2.3.6-4-117': [FAIL],
+ 'built-ins/Object/defineProperty/15.2.3.6-4-168': [FAIL],
+ 'built-ins/Object/defineProperty/15.2.3.6-4-169': [FAIL],
+ 'built-ins/Object/defineProperty/15.2.3.6-4-170': [FAIL],
+ 'built-ins/Object/defineProperty/15.2.3.6-4-172': [FAIL],
+ 'built-ins/Object/defineProperty/15.2.3.6-4-173': [FAIL],
+ 'built-ins/Object/defineProperty/15.2.3.6-4-174': [FAIL],
+ 'built-ins/Object/defineProperty/15.2.3.6-4-176': [FAIL],
+ 'built-ins/Object/defineProperty/15.2.3.6-4-177': [FAIL],
+ 'built-ins/Object/defineProperties/15.2.3.7-6-a-112': [FAIL],
+ 'built-ins/Object/defineProperties/15.2.3.7-6-a-113': [FAIL],
+ 'built-ins/Object/defineProperties/15.2.3.7-6-a-164': [FAIL],
+ 'built-ins/Object/defineProperties/15.2.3.7-6-a-165': [FAIL],
+ 'built-ins/Object/defineProperties/15.2.3.7-6-a-166': [FAIL],
+ 'built-ins/Object/defineProperties/15.2.3.7-6-a-168': [FAIL],
+ 'built-ins/Object/defineProperties/15.2.3.7-6-a-169': [FAIL],
+ 'built-ins/Object/defineProperties/15.2.3.7-6-a-170': [FAIL],
+ 'built-ins/Object/defineProperties/15.2.3.7-6-a-172': [FAIL],
+ 'built-ins/Object/defineProperties/15.2.3.7-6-a-173': [FAIL],
+ 'built-ins/Object/defineProperties/15.2.3.7-6-a-175': [FAIL],
+ 'built-ins/Object/defineProperties/15.2.3.7-6-a-176': [FAIL],
+
# Unicode canonicalization is not available with i18n turned off.
'built-ins/String/prototype/localeCompare/15.5.4.9_CE': [['no_i18n', SKIP]],
@@ -50,141 +74,222 @@
###################### MISSING ES6 FEATURES #######################
- # Array.fill (currently requires --harmony-arrays)
- 'built-ins/Array/prototype/fill/S22.1.3.6_T1': [FAIL],
-
- # Array.find (currently requires --harmony-arrays)
- 'built-ins/Array/of/S22.1.2.3_T1': [FAIL],
- 'built-ins/Array/of/S22.1.2.3_T2': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_empty-array-undefined': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_length-property': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_modify-after-start': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_non-returning-predicate': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_predicate-arguments': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_push-after-start': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_remove-after-start': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_return-found-value': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_skip-empty': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_this-defined': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_this-is-object': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_this-undefined': [FAIL],
-
- # Array.from
- 'built-ins/Array/from/S22.1.2.1_T1': [FAIL],
- 'built-ins/Array/from/S22.1.2.1_T2': [FAIL],
-
- # Direct proxies
- 'built-ins/Array/prototype/find/Array.prototype.find_callable-predicate': [FAIL],
-
- # --harmony-computed-property-names is not yet enabled
- 'language/computed-property-names/class/accessor/getter': [FAIL],
- 'language/computed-property-names/class/accessor/getter-duplicates': [FAIL],
- 'language/computed-property-names/class/accessor/setter': [FAIL],
- 'language/computed-property-names/class/accessor/setter-duplicates': [FAIL],
- 'language/computed-property-names/class/method/constructor': [FAIL],
- 'language/computed-property-names/class/method/generator': [FAIL],
- 'language/computed-property-names/class/method/number': [FAIL],
- 'language/computed-property-names/class/method/string': [FAIL],
- 'language/computed-property-names/class/method/symbol': [FAIL],
- 'language/computed-property-names/class/static/method-number': [FAIL],
- 'language/computed-property-names/class/static/method-string': [FAIL],
- 'language/computed-property-names/class/static/method-symbol': [FAIL],
- 'language/computed-property-names/to-name-side-effects/class': [FAIL],
- 'language/computed-property-names/to-name-side-effects/numbers-class': [FAIL],
-
- # Number.prototype is a plain object in ES6
+ # Class, let, const in sloppy mode.
+ # https://code.google.com/p/v8/issues/detail?id=3305
+ 'built-ins/Array/prototype/concat/Array.prototype.concat_non-array': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/finally-block-let-declaration-only-shadows-outer-parameter-value-1': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/finally-block-let-declaration-only-shadows-outer-parameter-value-2': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/for-loop-block-let-declaration-only-shadows-outer-parameter-value-1': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/for-loop-block-let-declaration-only-shadows-outer-parameter-value-2': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/nested-block-let-declaration-only-shadows-outer-parameter-value-1': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/nested-block-let-declaration-only-shadows-outer-parameter-value-2': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/outermost-binding-updated-in-catch-block-nested-block-let-declaration-unseen-outside-of-block': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/try-block-let-declaration-only-shadows-outer-parameter-value-1': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/try-block-let-declaration-only-shadows-outer-parameter-value-2': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/verify-context-in-finally-block': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/verify-context-in-for-loop-block': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/verify-context-in-labelled-block': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/verify-context-in-try-block': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/x-after-break-to-label': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/leave/x-before-continue': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/return-from/block-let': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/shadowing/catch-parameter-shadowing-let-declaration': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/shadowing/const-declaration-shadowing-catch-parameter': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/shadowing/const-declarations-shadowing-parameter-name-let-const-and-var-variables': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/shadowing/dynamic-lookup-from-closure': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/shadowing/dynamic-lookup-in-and-through-block-contexts': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/shadowing/let-declaration-shadowing-catch-parameter': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/shadowing/let-declarations-shadowing-parameter-name-let-const-and-var': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/shadowing/lookup-from-closure': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/shadowing/lookup-in-and-through-block-contexts': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/shadowing/parameter-name-shadowing-parameter-name-let-const-and-var': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/syntax/for-in/acquire-properties-from-array': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/syntax/for-in/acquire-properties-from-object': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/syntax/for-in/mixed-values-in-iteration': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/syntax/redeclaration-in-block/attempt-to-redeclare-function-declaration-with-function-declaration': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/syntax/redeclaration-in-block/attempt-to-redeclare-function-declaration-with-var': [PASS, FAIL_SLOPPY],
+ 'language/block-scope/syntax/redeclaration-in-block/attempt-to-redeclare-var-with-function-declaration': [PASS, FAIL_SLOPPY],
+ 'language/class/definition/ClassDeclaration_restricted-properties': [PASS, FAIL_SLOPPY],
+ 'language/class/definition/ClassExpression_restricted-properties': [PASS, FAIL_SLOPPY],
+ 'language/class/definition/ClassMethod_restricted-properties': [PASS, FAIL_SLOPPY],
+ 'language/class/method-definition/generator-no-yield': [PASS, FAIL_SLOPPY],
+ 'language/class/method-definition/generator-return': [PASS, FAIL_SLOPPY],
+ 'language/class/method-definition/yield-as-expression-with-rhs': [PASS, FAIL_SLOPPY],
+ 'language/class/method-definition/yield-as-expression-without-rhs': [PASS, FAIL_SLOPPY],
+ 'language/class/method-definition/yield-as-generator-method-binding-identifier': [PASS, FAIL_SLOPPY],
+ 'language/class/method-definition/yield-as-literal-property-name': [PASS, FAIL_SLOPPY],
+ 'language/class/method-definition/yield-as-property-name': [PASS, FAIL_SLOPPY],
+ 'language/class/method-definition/yield-as-statement': [PASS, FAIL_SLOPPY],
+ 'language/class/method-definition/yield-as-yield-operand': [PASS, FAIL_SLOPPY],
+ 'language/class/method-definition/yield-newline': [PASS, FAIL_SLOPPY],
+ 'language/class/method-definition/yield-star-before-newline': [PASS, FAIL_SLOPPY],
+ 'language/computed-property-names/class/accessor/*': [PASS, FAIL_SLOPPY],
+ 'language/computed-property-names/class/method/*': [PASS, FAIL_SLOPPY],
+ 'language/computed-property-names/class/static/generator-constructor': [PASS, FAIL_SLOPPY],
+ 'language/computed-property-names/class/static/generator-prototype': [PASS, FAIL_SLOPPY],
+ 'language/computed-property-names/class/static/getter-constructor': [PASS, FAIL_SLOPPY],
+ 'language/computed-property-names/class/static/getter-prototype': [PASS, FAIL_SLOPPY],
+ 'language/computed-property-names/class/static/method-constructor': [PASS, FAIL_SLOPPY],
+ 'language/computed-property-names/class/static/method-prototype': [PASS, FAIL_SLOPPY],
+ 'language/computed-property-names/class/static/setter-constructor': [PASS, FAIL_SLOPPY],
+ 'language/computed-property-names/class/static/setter-prototype': [PASS, FAIL_SLOPPY],
+ 'language/computed-property-names/to-name-side-effects/class': [PASS, FAIL_SLOPPY],
+ 'language/computed-property-names/to-name-side-effects/numbers-class': [PASS, FAIL_SLOPPY],
+ 'language/expressions/arrow-function/lexical-super-call-from-within-constructor':[PASS, FAIL_SLOPPY],
+ 'language/expressions/arrow-function/lexical-super-property-from-within-constructor': [PASS, FAIL_SLOPPY],
+ 'language/expressions/arrow-function/lexical-super-property': [PASS, FAIL_SLOPPY],
+ 'language/expressions/arrow-function/lexical-supercall-from-immediately-invoked-arrow': [PASS, FAIL_SLOPPY],
+ 'language/expressions/object/method-definition/generator-param-redecl-const': [PASS, FAIL_SLOPPY],
+ 'language/expressions/object/method-definition/generator-shadow-parameter-const': [PASS, FAIL_SLOPPY],
+ 'language/rest-parameters/with-new-target': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/arguments/access': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/arguments/default-constructor': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/accessors': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/constructable-but-no-prototype': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/constructor-property': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/constructor-strict-by-default': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/constructor': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/getters-2': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/getters': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/implicit-constructor': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/invalid-extends': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/methods-named-eval-arguments': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/methods': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/numeric-property-names': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/prototype-getter': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/prototype-property': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/prototype-setter': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/prototype-wiring': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/setters-2': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/setters': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/side-effects-in-extends': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/side-effects-in-property-define': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/this-access-restriction-2': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/this-access-restriction': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/definition/this-check-ordering': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/name-binding/basic': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/name-binding/const': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/name-binding/expression': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/strict-mode/arguments-caller': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/binding': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/builtins': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/class-definition-evaluation-empty-constructor-heritage-present': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/class-definition-null-proto-contains-return-override': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/class-definition-null-proto-missing-return-override': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/class-definition-null-proto': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/class-definition-superclass-generator': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/default-constructor-2': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/default-constructor': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/derived-class-return-override-with-boolean': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/derived-class-return-override-with-empty': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/derived-class-return-override-with-null': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/derived-class-return-override-with-number': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/derived-class-return-override-with-object': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/derived-class-return-override-with-string': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/derived-class-return-override-with-symbol': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/derived-class-return-override-with-this': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/derived-class-return-override-with-undefined': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/superclass-prototype-setter-constructor': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/superclass-prototype-setter-method-override': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/subclass/superclass-static-method-override': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/super/in-constructor': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/super/in-getter': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/super/in-methods': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/super/in-setter': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/super/in-static-getter': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/super/in-static-methods': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/super/in-static-setter': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/syntax/class-body-has-direct-super-class-heritage': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/syntax/class-body-method-definition-super-property': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/syntax/class-declaration-binding-identifier-class-element-list': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/syntax/class-declaration-computed-method-definition': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/syntax/class-declaration-computed-method-generator-definition': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/syntax/class-declaration-heritage-identifier-reference-class-element-list': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/syntax/class-expression-binding-identifier-opt-class-element-list': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/syntax/class-expression-heritage-identifier-reference': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/syntax/class-expression': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/syntax/class-method-propname-constructor': [PASS, FAIL_SLOPPY],
+ 'language/statements/class/syntax/early-errors/class-body-constructor-empty-missing-class-heritage': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/block-local-closure-get-before-initialization': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/block-local-use-before-initialization-in-declaration-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/block-local-use-before-initialization-in-prior-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/function-local-closure-get-before-initialization': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/function-local-use-before-initialization-in-declaration-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/function-local-use-before-initialization-in-prior-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/global-closure-get-before-initialization': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/global-use-before-initialization-in-declaration-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/global-use-before-initialization-in-prior-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/block-scope-syntax-const-declarations-mixed-with-without-initialiser': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/block-scope-syntax-const-declarations-mixed-without-with-initialiser': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/block-scope-syntax-const-declarations-without-initialiser': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/const-invalid-assignment-statement-body-for-in': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/const-invalid-assignment-statement-body-for-of': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/const-outer-inner-let-bindings': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/const': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/with-initializer-do-statement-while-expression': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/with-initializer-for-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/with-initializer-if-expression-statement-else-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/with-initializer-if-expression-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/with-initializer-label-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/with-initializer-while-expression-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/without-initializer-case-expression-statement-list': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/without-initializer-default-statement-list': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/without-initializer-do-statement-while-expression': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/without-initializer-for-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/without-initializer-if-expression-statement-else-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/without-initializer-if-expression-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/without-initializer-label-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/const/syntax/without-initializer-while-expression-statement': [PASS, FAIL_SLOPPY],
+ 'language/statements/continue/labeled-continue': [PASS, FAIL_SLOPPY],
+ 'language/statements/continue/nested-let-bound-for-loops-inner-continue': [PASS, FAIL_SLOPPY],
+ 'language/statements/continue/nested-let-bound-for-loops-labeled-continue': [PASS, FAIL_SLOPPY],
+ 'language/statements/continue/nested-let-bound-for-loops-outer-continue': [PASS, FAIL_SLOPPY],
+ 'language/statements/continue/no-label-continue': [PASS, FAIL_SLOPPY],
+ 'language/statements/continue/shadowing-loop-variable-in-same-scope-as-continue': [PASS, FAIL_SLOPPY],
+ 'language/statements/continue/simple-and-labeled': [PASS, FAIL_SLOPPY],
+ 'language/statements/for-in/const-fresh-binding-per-iteration-for-in': [PASS, FAIL_SLOPPY],
+ 'language/statements/for-in/let-fresh-binding-per-iteration-for-in': [PASS, FAIL_SLOPPY],
+ 'language/statements/for-of/const-fresh-binding-per-iteration-for-of': [PASS, FAIL_SLOPPY],
+ 'language/statements/for-of/let-fresh-binding-per-iteration-for-of': [PASS, FAIL_SLOPPY],
+ 'language/statements/for/const-fresh-binding-per-iteration-for': [PASS, FAIL_SLOPPY],
+ 'language/statements/for/let-fresh-binding-per-iteration-for': [PASS, FAIL_SLOPPY],
+ 'language/statements/let/syntax/let-closure-inside-condition': [PASS, FAIL_SLOPPY],
+ 'language/statements/let/syntax/let-closure-inside-initialization': [PASS, FAIL_SLOPPY],
+ 'language/statements/let/syntax/let-closure-inside-next-expression': [PASS, FAIL_SLOPPY],
+ 'language/statements/let/syntax/let-iteration-variable-is-freshly-allocated-for-each-iteration-multi-let-binding': [PASS, FAIL_SLOPPY],
+ 'language/statements/let/syntax/let-iteration-variable-is-freshly-allocated-for-each-iteration-single-let-binding': [PASS, FAIL_SLOPPY],
+ 'language/statements/let/syntax/let-outer-inner-let-bindings': [PASS, FAIL_SLOPPY],
+ 'language/statements/let/syntax/let': [PASS, FAIL_SLOPPY],
+ 'language/statements/let/syntax/with-initialisers-in-statement-positions-case-expression-statement-list': [PASS, FAIL_SLOPPY],
+ 'language/statements/let/syntax/with-initialisers-in-statement-positions-default-statement-list': [PASS, FAIL_SLOPPY],
+ 'language/statements/let/syntax/without-initialisers-in-statement-positions-case-expression-statement-list': [PASS, FAIL_SLOPPY],
+ 'language/statements/let/syntax/without-initialisers-in-statement-positions-default-statement-list': [PASS, FAIL_SLOPPY],
+
+ # https://code.google.com/p/v8/issues/detail?id=3305
+ # This times out in sloppy mode because sloppy const assignment does not throw.
+ 'language/statements/const/syntax/const-invalid-assignment-next-expression-for': [PASS, FAIL, TIMEOUT],
+
+ # Number/Boolean.prototype is a plain object in ES6
+ # https://code.google.com/p/v8/issues/detail?id=4001
'built-ins/Number/15.7.4-1': [FAIL],
- 'built-ins/Number/prototype/S15.7.3.1_A2_T1': [FAIL],
- 'built-ins/Number/prototype/S15.7.3.1_A2_T2': [FAIL],
+ 'built-ins/Number/prototype/S15.7.3.1_A2_*': [FAIL],
'built-ins/Number/prototype/S15.7.3.1_A3': [FAIL],
'built-ins/Number/prototype/S15.7.4_A1': [FAIL],
'built-ins/Number/prototype/toFixed/S15.7.4.5_A1.1_T01': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A1_T01': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A1_T02': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A1_T03': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T01': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T02': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T03': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T04': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T05': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T06': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T07': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T08': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T09': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T10': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T11': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T12': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T13': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T14': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T15': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T16': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T17': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T18': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T19': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T20': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T21': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T22': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T23': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T24': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T25': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T26': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T27': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T28': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T29': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T30': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T31': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T32': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T33': [FAIL],
- 'built-ins/Number/prototype/toString/S15.7.4.2_A2_T34': [FAIL],
- 'built-ins/Number/prototype/valueOf/S15.7.4.4_A1_T01': [FAIL],
- 'built-ins/Number/prototype/valueOf/S15.7.4.4_A1_T02': [FAIL],
-
- ######################## OBSOLETED BY ES6 ###########################
-
- # ES6 allows duplicate properties
- 'language/expressions/object/11.1.5-4-4-a-1-s': [FAIL],
- 'language/expressions/object/11.1.5_4-4-b-1': [FAIL],
- 'language/expressions/object/11.1.5_4-4-b-2': [FAIL],
- 'language/expressions/object/11.1.5_4-4-c-1': [FAIL],
- 'language/expressions/object/11.1.5_4-4-c-2': [FAIL],
- 'language/expressions/object/11.1.5_4-4-d-1': [FAIL],
- 'language/expressions/object/11.1.5_4-4-d-2': [FAIL],
- 'language/expressions/object/11.1.5_4-4-d-3': [FAIL],
- 'language/expressions/object/11.1.5_4-4-d-4': [FAIL],
-
- ######################## NEEDS INVESTIGATION ###########################
+ 'built-ins/Number/prototype/toString/S15.7.4.2_A1_*': [FAIL],
+ 'built-ins/Number/prototype/toString/S15.7.4.2_A2_*': [FAIL],
+ 'built-ins/Number/prototype/valueOf/S15.7.4.4_A1_*': [FAIL],
+ 'built-ins/Boolean/prototype/S15.6.3.1_A1': [FAIL],
+ 'built-ins/Boolean/prototype/S15.6.4_A1': [FAIL],
+ 'built-ins/Boolean/prototype/toString/S15.6.4.2_A1_T1': [FAIL],
+ 'built-ins/Boolean/prototype/toString/S15.6.4.2_A1_T2': [FAIL],
+ 'built-ins/Boolean/prototype/valueOf/S15.6.4.3_A1_T1': [FAIL],
+ 'built-ins/Boolean/prototype/valueOf/S15.6.4.3_A1_T2': [FAIL],
- # These test failures are specific to the intl402 suite and need investigation
- # to be either marked as bugs with issues filed for them or as deliberate
- # incompatibilities if the test cases turn out to be broken or ambiguous.
- 'intl402/6.2.3': [FAIL],
- 'intl402/9.2.1_2': [FAIL],
- 'intl402/9.2.6_2': [FAIL],
- 'intl402/10.1.1_a': [FAIL],
- 'intl402/10.1.1_19_c': [PASS, FAIL, NO_VARIANTS],
- 'intl402/10.1.2.1_4': [FAIL],
- 'intl402/10.2.3_b': [PASS, FAIL],
- 'intl402/10.3_a': [FAIL],
- 'intl402/11.1.1_17': [PASS, FAIL],
- 'intl402/11.1.1_19': [PASS, FAIL],
- 'intl402/11.1.1_20_c': [FAIL],
- 'intl402/11.1.1_a': [FAIL],
- 'intl402/11.1.2.1_4': [FAIL],
- 'intl402/11.3.2_FN_2': [PASS, FAIL],
- 'intl402/11.3.2_TRF': [PASS, FAIL],
- 'intl402/11.3_a': [FAIL],
- 'intl402/12.1.1_a': [FAIL],
- 'intl402/12.1.2.1_4': [FAIL],
- 'intl402/12.3.2_FDT_7_a_iv': [FAIL],
- 'intl402/12.3.3': [FAIL],
- 'intl402/12.3_a': [FAIL],
+ # https://code.google.com/p/v8/issues/detail?id=4118
+ 'built-ins/Object/getOwnPropertyNames/15.2.3.4-4-44': [FAIL],
- # Test 262 update 2015-03-11
- 'built-ins/Array/isArray/15.4.3.2-0-5': [FAIL],
- 'built-ins/Array/prototype/S15.4.3.1_A5': [FAIL],
- 'built-ins/Array/prototype/S15.4.4_A1.1_T2': [FAIL],
- 'built-ins/Array/prototype/S15.4.4_A1.2_T1': [FAIL],
- 'built-ins/Array/prototype/S15.4.4_A1.3_T1': [FAIL],
+ # https://code.google.com/p/v8/issues/detail?id=3087
'built-ins/Array/prototype/every/15.4.4.16-3-12': [FAIL],
'built-ins/Array/prototype/every/15.4.4.16-3-14': [FAIL],
'built-ins/Array/prototype/every/15.4.4.16-3-25': [FAIL],
@@ -194,11 +299,6 @@
'built-ins/Array/prototype/filter/15.4.4.20-3-12': [FAIL],
'built-ins/Array/prototype/filter/15.4.4.20-3-25': [FAIL],
'built-ins/Array/prototype/filter/15.4.4.20-3-7': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_callable-Proxy-1': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_callable-Proxy-2': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_callable-arrowfunction': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_callable-forEach': [FAIL],
- 'built-ins/Array/prototype/find/Array.prototype.find_this-global': [FAIL],
'built-ins/Array/prototype/forEach/15.4.4.18-3-12': [FAIL],
'built-ins/Array/prototype/forEach/15.4.4.18-3-25': [FAIL],
'built-ins/Array/prototype/forEach/15.4.4.18-3-7': [FAIL],
@@ -250,26 +350,51 @@
'built-ins/Array/prototype/splice/S15.4.4.12_A3_T1': [FAIL],
'built-ins/Array/prototype/splice/S15.4.4.12_A3_T3': [FAIL],
'built-ins/Array/prototype/unshift/S15.4.4.13_A3_T2': [FAIL],
- 'built-ins/Boolean/prototype/S15.6.3.1_A1': [FAIL],
- 'built-ins/Boolean/prototype/S15.6.4_A1': [FAIL],
- 'built-ins/Boolean/prototype/toString/S15.6.4.2_A1_T1': [FAIL],
- 'built-ins/Boolean/prototype/toString/S15.6.4.2_A1_T2': [FAIL],
- 'built-ins/Boolean/prototype/valueOf/S15.6.4.3_A1_T1': [FAIL],
- 'built-ins/Boolean/prototype/valueOf/S15.6.4.3_A1_T2': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=1543
+ 'built-ins/Proxy/*': [FAIL],
+ 'built-ins/Array/prototype/find/Array.prototype.find_callable-Proxy-1': [FAIL],
+ 'built-ins/Array/prototype/find/Array.prototype.find_callable-Proxy-2': [FAIL],
+ 'built-ins/Object/assign/source-own-prop-desc-missing': [FAIL],
+ 'built-ins/Object/assign/source-own-prop-error': [FAIL],
+ 'built-ins/Object/assign/source-own-prop-keys-error': [FAIL],
+ 'built-ins/Object/setPrototypeOf/set-error': [FAIL],
+ 'language/expressions/object/prop-def-id-eval-error-2': [FAIL],
+ 'language/statements/for-of/iterator-as-proxy': [FAIL],
+ 'language/statements/for-of/iterator-next-result-type': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4093
+ 'built-ins/Array/symbol-species': [FAIL],
+ 'built-ins/ArrayBuffer/symbol-species': [FAIL],
+ 'built-ins/Map/symbol-species': [FAIL],
+ 'built-ins/Promise/symbol-species': [FAIL],
+ 'built-ins/RegExp/symbol-species': [FAIL],
+ 'built-ins/Set/symbol-species': [FAIL],
+ 'built-ins/Symbol/species/basic': [FAIL],
+ 'built-ins/Symbol/species/builtin-getter-name': [FAIL],
+ 'built-ins/Symbol/species/subclassing': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4242
'built-ins/Date/15.9.1.15-1': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4004
'built-ins/Date/prototype/setFullYear/15.9.5.40_1': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4002
'built-ins/Error/prototype/S15.11.4_A2': [FAIL],
- 'built-ins/Object/defineProperty/15.2.3.6-4-293-4': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4163
+ 'built-ins/GeneratorPrototype/next/context-constructor-invocation': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=3566
+ 'built-ins/Set/set-iterator-close-after-add-failure': [FAIL],
+ 'built-ins/WeakSet/iterator-close-after-add-failure': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=3715
'built-ins/Object/getOwnPropertyDescriptor/15.2.3.3-4-212': [FAIL],
'built-ins/Object/getOwnPropertyDescriptor/15.2.3.3-4-213': [FAIL],
'built-ins/Object/getOwnPropertyDescriptor/15.2.3.3-4-214': [FAIL],
'built-ins/Object/getOwnPropertyDescriptor/15.2.3.3-4-215': [FAIL],
- 'built-ins/Promise/S25.4.3.1_A5.1_T2': [FAIL],
- 'built-ins/Promise/prototype/then/S25.4.2.1_A3.1_T2': [FAIL],
- 'built-ins/Promise/prototype/then/S25.4.2.1_A3.2_T2': [FAIL],
- 'built-ins/Promise/race/S25.4.4.3_A3.1_T2': [FAIL],
- 'built-ins/Promise/reject/S25.4.4.4_A3.1_T1': [FAIL],
- 'built-ins/RegExp/prototype/15.10.6': [FAIL],
'built-ins/RegExp/prototype/global/15.10.7.2-1': [FAIL],
'built-ins/RegExp/prototype/global/15.10.7.2-2': [FAIL],
'built-ins/RegExp/prototype/global/S15.10.7.2_A9': [FAIL],
@@ -284,302 +409,330 @@
'built-ins/RegExp/prototype/source/15.10.7.1-1': [FAIL],
'built-ins/RegExp/prototype/source/15.10.7.1-2': [FAIL],
'built-ins/RegExp/prototype/source/S15.10.7.1_A9': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4243
+ 'built-ins/Promise/race/S25.4.4.3_A3.1_T2': [FAIL],
+ 'built-ins/Promise/reject/S25.4.4.4_A3.1_T1': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4119
+ 'built-ins/RegExp/15.10.4.1-1': [FAIL],
+ 'built-ins/RegExp/S15.10.3.1_A2_T1': [FAIL],
+ 'built-ins/RegExp/S15.10.3.1_A2_T2': [FAIL],
+ 'built-ins/RegExp/S15.10.4.1_A2_T1': [FAIL],
+ 'built-ins/RegExp/S15.10.4.1_A2_T2': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4003
+ 'built-ins/RegExp/prototype/15.10.6': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4244
+ 'built-ins/RegExp/prototype/exec/S15.10.6.2_A5_T3': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4006
'built-ins/String/prototype/S15.5.4_A1': [FAIL],
'built-ins/String/prototype/S15.5.4_A2': [FAIL],
'built-ins/String/prototype/S15.5.4_A3': [FAIL],
+ 'language/expressions/property-accessors/S11.2.1_A4_T5': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4245
'built-ins/String/prototype/split/S15.5.4.14_A2_T37': [FAIL],
- 'intl402/10.1_L15': [FAIL],
- 'intl402/10.2.2_L15': [FAIL],
- 'intl402/10.3.2_1_a_L15': [FAIL],
- 'intl402/10.3.2_L15': [FAIL],
- 'intl402/10.3.3_L15': [FAIL],
- 'intl402/11.1_L15': [FAIL],
- 'intl402/11.2.2_L15': [FAIL],
- 'intl402/11.3.2_1_a_L15': [FAIL],
- 'intl402/11.3.2_L15': [FAIL],
- 'intl402/11.3.3_L15': [FAIL],
- 'intl402/12.1_L15': [FAIL],
- 'intl402/12.2.2_L15': [FAIL],
- 'intl402/12.3.2_1_a_L15': [FAIL],
- 'intl402/12.3.2_L15': [FAIL],
- 'intl402/12.3.3_L15': [FAIL],
- 'intl402/13.1.1_L15': [FAIL],
- 'intl402/13.2.1_L15': [FAIL],
- 'intl402/13.3.1_L15': [FAIL],
- 'intl402/13.3.2_L15': [FAIL],
- 'intl402/13.3.3_L15': [FAIL],
- 'language/arrow-function/Arrow-Function_rules-for-prototype': [FAIL],
- 'language/arrow-function/Arrow-Function_semantics': [FAIL],
- 'language/arrow-function/Arrow-Function_syntax-variations': [FAIL],
- 'language/class/arguments/access': [FAIL],
- 'language/class/arguments/default-constructor': [FAIL],
- 'language/class/definition/accessors': [FAIL],
- 'language/class/definition/basics': [FAIL],
- 'language/class/definition/constructable-but-no-prototype': [FAIL],
- 'language/class/definition/constructor': [FAIL],
- 'language/class/definition/constructor-property': [FAIL],
- 'language/class/definition/constructor-strict-by-default': [FAIL],
- 'language/class/definition/getters': [FAIL],
- 'language/class/definition/getters-2': [FAIL],
- 'language/class/definition/implicit-constructor': [FAIL],
- 'language/class/definition/invalid-extends': [FAIL],
- 'language/class/definition/methods': [FAIL],
- 'language/class/definition/methods-named-eval-arguments': [FAIL],
- 'language/class/definition/numeric-property-names': [FAIL],
- 'language/class/definition/prototype-getter': [FAIL],
- 'language/class/definition/prototype-property': [FAIL],
- 'language/class/definition/prototype-setter': [FAIL],
- 'language/class/definition/prototype-wiring': [FAIL],
- 'language/class/definition/setters': [FAIL],
- 'language/class/definition/setters-2': [FAIL],
- 'language/class/definition/side-effects-in-extends': [FAIL],
- 'language/class/definition/side-effects-in-property-define': [FAIL],
- 'language/class/definition/this-access-restriction': [FAIL],
- 'language/class/definition/this-access-restriction-2': [FAIL],
- 'language/class/definition/this-check-ordering': [FAIL],
- 'language/class/name-binding/basic': [FAIL],
- 'language/class/name-binding/const': [FAIL],
- 'language/class/name-binding/expression': [FAIL],
- 'language/class/strict-mode/arguments-caller': [FAIL],
- 'language/class/subclass/binding': [FAIL],
- 'language/class/subclass/builtins': [FAIL],
- 'language/class/subclass/default-constructor': [FAIL],
- 'language/class/subclass/default-constructor-2': [FAIL],
- 'language/class/subclass/null': [FAIL],
- 'language/class/subclass/superclass-prototype-setter-constructor': [FAIL],
- 'language/class/subclass/superclass-prototype-setter-method-override': [FAIL],
- 'language/class/subclass/superclass-static-method-override': [FAIL],
- 'language/class/super/in-constructor': [FAIL],
- 'language/class/super/in-getter': [FAIL],
- 'language/class/super/in-methods': [FAIL],
- 'language/class/super/in-setter': [FAIL],
- 'language/class/super/in-static-getter': [FAIL],
- 'language/class/super/in-static-methods': [FAIL],
- 'language/class/super/in-static-setter': [FAIL],
- 'language/expressions/assignment/S11.13.1_A5_T1': [FAIL],
- 'language/expressions/assignment/S11.13.1_A5_T2': [FAIL],
- 'language/expressions/assignment/S11.13.1_A5_T3': [FAIL],
- 'language/expressions/assignment/S11.13.1_A5_T4': [FAIL],
- 'language/expressions/assignment/S11.13.1_A5_T5': [FAIL],
- 'language/expressions/assignment/S11.13.1_A6_T1': [FAIL],
- 'language/expressions/assignment/S11.13.1_A6_T2': [FAIL],
- 'language/expressions/assignment/S11.13.1_A6_T3': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.10_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.10_T2': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.10_T3': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.10_T4': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.10_T5': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.11_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.11_T2': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.11_T3': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.11_T4': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.11_T5': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.1_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.1_T2': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.1_T3': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.1_T4': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.1_T5': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.2_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.2_T2': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.2_T3': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.2_T4': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.2_T5': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.3_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.3_T2': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.3_T3': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.3_T4': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.3_T5': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.4_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.4_T2': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.4_T3': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.4_T4': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.4_T5': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.5_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.5_T2': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.5_T3': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.5_T4': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.5_T5': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.6_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.6_T2': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.6_T3': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.6_T4': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.6_T5': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.7_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.7_T2': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.7_T3': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.7_T4': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.7_T5': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.8_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.8_T2': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.8_T3': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.8_T4': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.8_T5': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.9_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.9_T2': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.9_T3': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.9_T4': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A5.9_T5': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A6.10_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A6.11_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A6.1_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A6.2_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A6.3_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A6.4_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A6.5_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A6.6_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A6.7_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A6.8_T1': [FAIL],
- 'language/expressions/compound-assignment/S11.13.2_A6.9_T1': [FAIL],
- 'language/expressions/postfix-decrement/S11.3.2_A5_T1': [FAIL],
- 'language/expressions/postfix-decrement/S11.3.2_A5_T2': [FAIL],
- 'language/expressions/postfix-decrement/S11.3.2_A5_T3': [FAIL],
- 'language/expressions/postfix-decrement/S11.3.2_A5_T4': [FAIL],
- 'language/expressions/postfix-decrement/S11.3.2_A5_T5': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=3088
+ 'built-ins/Symbol/auto-boxing-strict': [FAIL],
+
+ # The order of adding the name property is wrong
+ # https://code.google.com/p/v8/issues/detail?id=4199
+ 'language/computed-property-names/class/static/method-number': [FAIL, FAIL_SLOPPY],
+ 'language/computed-property-names/class/static/method-symbol': [FAIL, FAIL_SLOPPY],
+ 'language/computed-property-names/class/static/method-string': [FAIL, FAIL_SLOPPY],
+
+ # new.target
+ # https://code.google.com/p/v8/issues/detail?id=3887
+ 'language/expressions/arrow-function/lexical-new.target': [FAIL],
+ 'language/expressions/arrow-function/lexical-new.target-closure-returned': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=2160
+ 'language/expressions/arrow-function/syntax/arrowparameters-cover-initialize-1': [FAIL],
+ 'language/expressions/arrow-function/syntax/arrowparameters-cover-initialize-2': [FAIL],
+ 'language/expressions/object/method-definition/generator-super-prop-param': [FAIL],
+ 'language/expressions/object/method-definition/name-param-init-yield': [FAIL],
+ 'language/expressions/object/method-definition/name-super-prop-param': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=3673
+ 'language/statements/class/definition/basics': [FAIL],
+
+ # Destructuring
+ # https://code.google.com/p/v8/issues/detail?id=811
+ 'language/statements/for-of/body-dstr-assign': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=3566
+ 'language/statements/for-of/body-dstr-assign-error': [FAIL],
+ 'language/statements/for-of/body-put-error': [FAIL],
+ 'language/statements/for-of/generator-close-via-break': [FAIL],
+ 'language/statements/for-of/generator-close-via-return': [FAIL],
+ 'language/statements/for-of/generator-close-via-throw': [FAIL],
+ 'language/statements/for-of/iterator-close-get-method-error': [FAIL],
+ 'language/statements/for-of/iterator-close-non-object': [FAIL],
+ 'language/statements/for-of/iterator-close-via-break': [FAIL],
+ 'language/statements/for-of/iterator-close-via-return': [FAIL],
+ 'language/statements/for-of/iterator-close-via-throw': [FAIL],
+
+ # We do not expose Array.prototype.values
+ # https://code.google.com/p/v8/issues/detail?id=4247
+ 'built-ins/Array/prototype/Symbol.iterator': [FAIL],
+
+ #https://code.google.com/p/v8/issues/detail?id=3983
+ 'language/expressions/generators/yield-as-function-expression-binding-identifier': [FAIL],
+ 'language/expressions/generators/yield-as-generator-expression-binding-identifier': [FAIL],
+ 'language/expressions/object/method-definition/generator-argSuperProperty': [FAIL],
+ 'language/expressions/object/method-definition/yield-as-function-expression-binding-identifier': [FAIL],
+ 'language/statements/generators/yield-as-function-expression-binding-identifier': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=3566
+ 'built-ins/GeneratorPrototype/return/from-state-completed': [FAIL],
+ 'built-ins/GeneratorPrototype/return/from-state-suspended-start': [FAIL],
+ 'built-ins/GeneratorPrototype/return/property-descriptor': [FAIL],
+ 'built-ins/GeneratorPrototype/return/try-catch-before-try': [FAIL],
+ 'built-ins/GeneratorPrototype/return/try-catch-following-catch': [FAIL],
+ 'built-ins/GeneratorPrototype/return/try-catch-within-catch': [FAIL],
+ 'built-ins/GeneratorPrototype/return/try-catch-within-try': [FAIL],
+ 'built-ins/GeneratorPrototype/return/try-finally-before-try': [FAIL],
+ 'built-ins/GeneratorPrototype/return/try-finally-following-finally': [FAIL],
+ 'built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-catch': [FAIL],
+ 'built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-finally': [FAIL],
+ 'built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-inner-try': [FAIL],
+ 'built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-after-nested': [FAIL],
+ 'built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-before-nested': [FAIL],
+ 'built-ins/GeneratorPrototype/return/try-finally-within-finally': [FAIL],
+ 'built-ins/GeneratorPrototype/return/try-finally-within-try': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4177
+ 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-2': [FAIL],
+ 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-3': [FAIL],
+ 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-4': [FAIL],
+ 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-2': [FAIL],
+ 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-3': [FAIL],
+ 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-4': [FAIL],
+ 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-3': [FAIL],
+ 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-4': [FAIL],
+ 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-5': [FAIL],
+ 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-2': [FAIL],
+ 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-3': [FAIL],
+ 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-4': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=811
+ 'language/expressions/assignment/destructuring/array-elem-elision': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-init-assignment': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-init-evaluation': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-init-in': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-init-let': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-init-order': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-init-simple-no-strict': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-init-yield-expr': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-init-yield-ident-valid': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-array': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-array-null': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-array-undefined': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-array-undefined-hole': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-array-undefined-own': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-array-yield-expr': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-array-yield-ident-valid': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-obj': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-obj-null': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-obj-undefined': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-obj-undefined-hole': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-obj-undefined-own': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-obj-yield-expr': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-nested-obj-yield-ident-valid': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-put-const': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-put-let': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-put-prop-ref': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-put-prop-ref-no-get': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-put-prop-ref-user-err': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-put-unresolvable-no-strict': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-put-unresolvable-strict': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-target-identifier': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-target-simple-no-strict': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-target-yield-expr': [FAIL],
+ 'language/expressions/assignment/destructuring/array-elem-target-yield-valid': [FAIL],
+ 'language/expressions/assignment/destructuring/array-empty': [FAIL],
+ 'language/expressions/assignment/destructuring/array-iteration': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-after-element': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-after-elision': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-elision': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-iteration': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-array': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-array-null': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-array-undefined': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-array-undefined-hole': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-array-undefined-own': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-array-yield-expr': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-array-yield-ident-valid': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-obj': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-obj-null': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-obj-undefined': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-obj-undefined-hole': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-obj-undefined-own': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-obj-yield-expr': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-nested-obj-yield-ident-valid': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-put-const': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-put-let': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-put-prop-ref': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-put-prop-ref-no-get': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-put-prop-ref-user-err': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-put-unresolvable-no-strict': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-put-unresolvable-strict': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-yield-expr': [FAIL],
+ 'language/expressions/assignment/destructuring/array-rest-yield-ident-valid': [FAIL],
+ 'language/expressions/assignment/destructuring/array-sparse': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-identifier-resolution': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-identifier-yield-ident-valid': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-init-assignment': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-init-evaluation': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-init-in': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-init-let': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-init-order': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-init-simple-no-strict': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-init-yield-expr': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-init-yield-ident-valid': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-put-const': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-put-let': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-put-unresolvable-no-strict': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-put-unresolvable-strict': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-id-simple-no-strict': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-elem-init-assignment': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-elem-init-evaluation': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-elem-init-in': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-elem-init-let': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-elem-init-yield-expr': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-elem-init-yield-ident-valid': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-elem-target-yield-expr': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-elem-target-yield-ident-valid': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-identifier-resolution': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-name-evaluation': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-name-evaluation-error': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-nested-array': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-nested-array-null': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-nested-array-undefined': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-nested-array-undefined-own': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-nested-array-yield-expr': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-nested-array-yield-ident-valid': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-nested-obj': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-nested-obj-null': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-nested-obj-undefined': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-nested-obj-undefined-own': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-nested-obj-yield-expr': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-nested-obj-yield-ident-valid': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-put-const': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-put-let': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-put-order': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-put-prop-ref': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-put-prop-ref-no-get': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-put-prop-ref-user-err': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-put-unresolvable-no-strict': [FAIL],
+ 'language/expressions/assignment/destructuring/obj-prop-put-unresolvable-strict': [FAIL],
+ 'language/expressions/assignment/destructuring/object-empty': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4248
+ 'language/expressions/compound-assignment/S11.13.2_A5.*': [FAIL],
+ 'language/expressions/compound-assignment/S11.13.2_A6.*': [FAIL],
+ 'language/expressions/compound-assignment/S11.13.2_A7.10_T4': [FAIL],
+ 'language/expressions/compound-assignment/S11.13.2_A7.11_T4': [FAIL],
+ 'language/expressions/compound-assignment/S11.13.2_A7.1_T4': [FAIL],
+ 'language/expressions/compound-assignment/S11.13.2_A7.2_T4': [FAIL],
+ 'language/expressions/compound-assignment/S11.13.2_A7.3_T4': [FAIL],
+ 'language/expressions/compound-assignment/S11.13.2_A7.4_T4': [FAIL],
+ 'language/expressions/compound-assignment/S11.13.2_A7.5_T4': [FAIL],
+ 'language/expressions/compound-assignment/S11.13.2_A7.6_T4': [FAIL],
+ 'language/expressions/compound-assignment/S11.13.2_A7.7_T4': [FAIL],
+ 'language/expressions/compound-assignment/S11.13.2_A7.8_T4': [FAIL],
+ 'language/expressions/compound-assignment/S11.13.2_A7.9_T4': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4249
+ 'language/expressions/assignment/S11.13.1_A7_T1': [FAIL],
+ 'language/expressions/assignment/S11.13.1_A7_T2': [FAIL],
+ 'language/expressions/assignment/S11.13.1_A7_T3': [FAIL],
+ 'language/expressions/postfix-increment/S11.3.1_A6_T3': [FAIL],
+ 'language/expressions/postfix-decrement/S11.3.2_A6_T3': [FAIL],
+ 'language/expressions/prefix-decrement/S11.4.5_A6_T3': [FAIL],
+ 'language/expressions/prefix-increment/S11.4.4_A6_T3': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4250
+ 'language/expressions/assignment/S11.13.1_A5*': [FAIL],
+ 'language/expressions/assignment/S11.13.1_A6*': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=3699
+ 'language/expressions/generators/implicit-name': [FAIL],
+ 'language/expressions/generators/name-property-descriptor': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4251
'language/expressions/postfix-increment/S11.3.1_A5_T1': [FAIL],
'language/expressions/postfix-increment/S11.3.1_A5_T2': [FAIL],
'language/expressions/postfix-increment/S11.3.1_A5_T3': [FAIL],
'language/expressions/postfix-increment/S11.3.1_A5_T4': [FAIL],
'language/expressions/postfix-increment/S11.3.1_A5_T5': [FAIL],
- 'language/expressions/prefix-decrement/S11.4.5_A5_T1': [FAIL],
- 'language/expressions/prefix-decrement/S11.4.5_A5_T2': [FAIL],
- 'language/expressions/prefix-decrement/S11.4.5_A5_T3': [FAIL],
- 'language/expressions/prefix-decrement/S11.4.5_A5_T4': [FAIL],
- 'language/expressions/prefix-decrement/S11.4.5_A5_T5': [FAIL],
- 'language/expressions/prefix-increment/S11.4.4_A5_T1': [FAIL],
- 'language/expressions/prefix-increment/S11.4.4_A5_T2': [FAIL],
- 'language/expressions/prefix-increment/S11.4.4_A5_T3': [FAIL],
- 'language/expressions/prefix-increment/S11.4.4_A5_T4': [FAIL],
- 'language/expressions/prefix-increment/S11.4.4_A5_T5': [FAIL],
- 'language/expressions/property-accessors/S11.2.1_A4_T5': [FAIL],
- 'language/generators/generator.declareMethod.argSuperProperty': [FAIL],
- 'language/generators/generator.declareMethod.shadow-parameter-const': [FAIL],
- 'language/generators/generator.expression.implicit-name': [FAIL],
-
- # Test 262 update 2015-03-31
- 'built-ins/Array/prototype/concat/Array.prototype.concat_array-like': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-to-string-throws': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-value-of-throws': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_array-like-negative-length': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_array-like-primitive-non-number-length': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_array-like-string-length': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_array-like-to-length-throws': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_holey-sloppy-arguments': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_large-typed-array': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_length-throws': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_non-array': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-throws': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-with-dupes': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_small-typed-array': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-boolean-wrapper': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-function': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-getter-throws': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-number-wrapper': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-reg-exp': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-sparse-object': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-string-wrapper': [FAIL],
- 'built-ins/Array/prototype/concat/Array.prototype.concat_strict-arguments': [FAIL],
- 'built-ins/Symbol/species/Symbol.species.builtin-getter-name': [FAIL],
- 'built-ins/Symbol/species/Symbol.species.exists': [FAIL],
- 'built-ins/Symbol/species/Symbol.species.in_Array': [FAIL],
- 'built-ins/Symbol/species/Symbol.species.in_ArrayBuffer': [FAIL],
- 'built-ins/Symbol/species/Symbol.species.in_Map': [FAIL],
- 'built-ins/Symbol/species/Symbol.species.in_Promise': [FAIL],
- 'built-ins/Symbol/species/Symbol.species.in_RegExp': [FAIL],
- 'built-ins/Symbol/species/Symbol.species.in_Set': [FAIL],
- 'built-ins/Symbol/species/Symbol.species.notChangedByExtends': [FAIL],
+ 'language/expressions/postfix-decrement/S11.3.2_A5_*': [FAIL],
+ 'language/expressions/prefix-decrement/S11.4.5_A5_*': [FAIL],
+ 'language/expressions/prefix-increment/S11.4.4_A5_*': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=4253
'language/asi/S7.9_A5.7_T1': [PASS, FAIL_OK],
- 'language/block-scope/leave/finally-block-let-declaration-only-shadows-outer-parameter-value-1': [FAIL],
- 'language/block-scope/leave/finally-block-let-declaration-only-shadows-outer-parameter-value-2': [FAIL],
- 'language/block-scope/leave/for-loop-block-let-declaration-only-shadows-outer-parameter-value-1': [FAIL],
- 'language/block-scope/leave/for-loop-block-let-declaration-only-shadows-outer-parameter-value-2': [FAIL],
- 'language/block-scope/leave/nested-block-let-declaration-only-shadows-outer-parameter-value-1': [FAIL],
- 'language/block-scope/leave/nested-block-let-declaration-only-shadows-outer-parameter-value-2': [FAIL],
- 'language/block-scope/leave/outermost-binding-updated-in-catch-block-nested-block-let-declaration-unseen-outside-of-block': [FAIL],
- 'language/block-scope/leave/try-block-let-declaration-only-shadows-outer-parameter-value-1': [FAIL],
- 'language/block-scope/leave/try-block-let-declaration-only-shadows-outer-parameter-value-2': [FAIL],
- 'language/block-scope/leave/verify-context-in-finally-block': [FAIL],
- 'language/block-scope/leave/verify-context-in-for-loop-block': [FAIL],
- 'language/block-scope/leave/verify-context-in-labelled-block': [FAIL],
- 'language/block-scope/leave/verify-context-in-try-block': [FAIL],
- 'language/block-scope/leave/x-after-break-to-label': [FAIL],
- 'language/block-scope/leave/x-before-continue': [FAIL],
- 'language/block-scope/return-from/block-let': [FAIL],
- 'language/block-scope/semantics/const/block-local-closure-get-before-initialization': [FAIL],
- 'language/block-scope/semantics/const/block-local-use-before-initialization-in-declaration-statement': [FAIL],
- 'language/block-scope/semantics/const/block-local-use-before-initialization-in-prior-statement': [FAIL],
- 'language/block-scope/semantics/const/function-local-closure-get-before-initialization': [FAIL],
- 'language/block-scope/semantics/const/function-local-use-before-initialization-in-declaration-statement': [FAIL],
- 'language/block-scope/semantics/const/function-local-use-before-initialization-in-prior-statement': [FAIL],
- 'language/block-scope/semantics/const/global-closure-get-before-initialization': [FAIL],
- 'language/block-scope/semantics/const/global-use-before-initialization-in-declaration-statement': [FAIL],
- 'language/block-scope/semantics/const/global-use-before-initialization-in-prior-statement': [FAIL],
- 'language/block-scope/shadowing/catch-parameter-shadowing-let-declaration': [FAIL],
- 'language/block-scope/shadowing/const-declaration-shadowing-catch-parameter': [FAIL],
- 'language/block-scope/shadowing/const-declarations-shadowing-parameter-name-let-const-and-var-variables': [FAIL],
- 'language/block-scope/shadowing/dynamic-lookup-from-closure': [FAIL],
- 'language/block-scope/shadowing/dynamic-lookup-in-and-through-block-contexts': [FAIL],
- 'language/block-scope/shadowing/let-declaration-shadowing-catch-parameter': [FAIL],
- 'language/block-scope/shadowing/let-declarations-shadowing-parameter-name-let-const-and-var': [FAIL],
- 'language/block-scope/shadowing/lookup-from-closure': [FAIL],
- 'language/block-scope/shadowing/lookup-in-and-through-block-contexts': [FAIL],
- 'language/block-scope/shadowing/parameter-name-shadowing-parameter-name-let-const-and-var': [FAIL],
- 'language/block-scope/syntax/const-declaration/block-scope-syntax-const-declarations-mixed-with-without-initialiser': [FAIL],
- 'language/block-scope/syntax/const-declaration/block-scope-syntax-const-declarations-mixed-without-with-initialiser': [FAIL],
- 'language/block-scope/syntax/const-declaration/block-scope-syntax-const-declarations-without-initialiser': [FAIL],
- 'language/block-scope/syntax/const-declaration/with-initializer-do-statement-while-expression': [FAIL],
- 'language/block-scope/syntax/const-declaration/with-initializer-for-statement': [FAIL],
- 'language/block-scope/syntax/const-declaration/with-initializer-if-expression-statement': [FAIL],
- 'language/block-scope/syntax/const-declaration/with-initializer-if-expression-statement-else-statement': [FAIL],
- 'language/block-scope/syntax/const-declaration/with-initializer-label-statement': [FAIL],
- 'language/block-scope/syntax/const-declaration/with-initializer-while-expression-statement': [FAIL],
- 'language/block-scope/syntax/const-declaration/without-initializer-case-expression-statement-list': [FAIL],
- 'language/block-scope/syntax/const-declaration/without-initializer-default-statement-list': [FAIL],
- 'language/block-scope/syntax/const-declaration/without-initializer-do-statement-while-expression': [FAIL],
- 'language/block-scope/syntax/const-declaration/without-initializer-for-statement': [FAIL],
- 'language/block-scope/syntax/const-declaration/without-initializer-if-expression-statement': [FAIL],
- 'language/block-scope/syntax/const-declaration/without-initializer-if-expression-statement-else-statement': [FAIL],
- 'language/block-scope/syntax/const-declaration/without-initializer-label-statement': [FAIL],
- 'language/block-scope/syntax/const-declaration/without-initializer-while-expression-statement': [FAIL],
- 'language/block-scope/syntax/for-in/acquire-properties-from-array': [FAIL],
- 'language/block-scope/syntax/for-in/acquire-properties-from-object': [FAIL],
- 'language/block-scope/syntax/for-in/missing-identifier-let-disallowed-as-bound-name': [FAIL],
- 'language/block-scope/syntax/for-loop/const-invalid-assignment-next-expression': [SKIP], # iloops
- 'language/block-scope/syntax/for-loop/const-outer-inner-let-bindings': [FAIL],
- 'language/block-scope/syntax/for-loop/let-closure-inside-condition': [FAIL],
- 'language/block-scope/syntax/for-loop/let-closure-inside-initialization': [FAIL],
- 'language/block-scope/syntax/for-loop/let-closure-inside-next-expression': [FAIL],
- 'language/block-scope/syntax/for-loop/let-iteration-variable-is-freshly-allocated-for-each-iteration-multi-let-binding': [FAIL],
- 'language/block-scope/syntax/for-loop/let-iteration-variable-is-freshly-allocated-for-each-iteration-single-let-binding': [FAIL],
- 'language/block-scope/syntax/for-loop/let-outer-inner-let-bindings': [FAIL],
- 'language/block-scope/syntax/function-declarations/in-statement-position-do-statement-while-expression': [FAIL],
- 'language/block-scope/syntax/function-declarations/in-statement-position-for-statement': [FAIL],
- 'language/block-scope/syntax/function-declarations/in-statement-position-if-expression-statement': [FAIL],
- 'language/block-scope/syntax/function-declarations/in-statement-position-if-expression-statement-else-statement': [FAIL],
- 'language/block-scope/syntax/function-declarations/in-statement-position-while-expression-statement': [FAIL],
- 'language/block-scope/syntax/global-and-block/const': [FAIL],
- 'language/block-scope/syntax/global-and-block/let': [FAIL],
- 'language/block-scope/syntax/let-declarations/with-initialisers-in-statement-positions-case-expression-statement-list': [FAIL],
- 'language/block-scope/syntax/let-declarations/with-initialisers-in-statement-positions-default-statement-list': [FAIL],
- 'language/block-scope/syntax/redeclaration-in-block/attempt-to-redeclare-function-declaration-with-function-declaration': [FAIL],
- 'language/block-scope/syntax/redeclaration-in-block/attempt-to-redeclare-function-declaration-with-var': [FAIL],
- 'language/block-scope/syntax/redeclaration-in-block/attempt-to-redeclare-var-with-function-declaration': [FAIL],
- 'language/computed-property-names/class/method/constructor-can-be-generator': [FAIL],
- 'language/computed-property-names/class/method/constructor-can-be-getter': [FAIL],
- 'language/computed-property-names/class/method/constructor-can-be-setter': [FAIL],
- 'language/computed-property-names/class/method/constructor-duplicate-1': [FAIL],
- 'language/computed-property-names/class/method/constructor-duplicate-2': [FAIL],
- 'language/computed-property-names/class/method/constructor-duplicate-3': [FAIL],
- 'language/computed-property-names/class/static/generator-constructor': [FAIL],
- 'language/computed-property-names/class/static/generator-prototype': [FAIL],
- 'language/computed-property-names/class/static/getter-constructor': [FAIL],
- 'language/computed-property-names/class/static/getter-prototype': [FAIL],
- 'language/computed-property-names/class/static/method-constructor': [FAIL],
- 'language/computed-property-names/class/static/method-prototype': [FAIL],
- 'language/computed-property-names/class/static/setter-constructor': [FAIL],
- 'language/computed-property-names/class/static/setter-prototype': [FAIL],
- 'language/for-of/iterator-as-proxy': [FAIL],
- 'language/for-of/iterator-next-result-type': [FAIL],
+
+ # https://code.google.com/p/v8/issues/detail?id=3761
+ 'language/expressions/object/method-definition/generator-name-prop-symbol': [FAIL],
+ 'language/expressions/object/method-definition/name-name-prop-symbol': [FAIL],
+
+ ######################## NEEDS INVESTIGATION ###########################
+
+ # These test failures are specific to the intl402 suite and need investigation
+ # to be either marked as bugs with issues filed for them or as deliberate
+ # incompatibilities if the test cases turn out to be broken or ambiguous.
+ 'intl402/6.2.3': [FAIL],
+ 'intl402/9.2.1_2': [FAIL],
+ 'intl402/9.2.6_2': [FAIL],
+ 'intl402/10.1.1_a': [FAIL],
+ 'intl402/10.1.2.1_4': [FAIL],
+ 'intl402/10.1.2_a': [PASS, FAIL],
+ 'intl402/10.2.3_b': [PASS, FAIL],
+ 'intl402/10.3.2_1_c': [PASS, FAIL],
+ 'intl402/10.3.2_CS_b_NN': [PASS, FAIL],
+ 'intl402/10.3.2_CS_c_NN': [PASS, FAIL],
+ 'intl402/10.3.2_CS_d_NN': [PASS, FAIL],
+ 'intl402/10.3_a': [FAIL],
+ 'intl402/11.1.1_20_c': [FAIL],
+ 'intl402/11.1.1_a': [FAIL],
+ 'intl402/11.1.2': [PASS, FAIL],
+ 'intl402/11.1.2.1_4': [FAIL],
+ 'intl402/11.3_a': [FAIL],
+ 'intl402/12.1.1_a': [FAIL],
+ 'intl402/12.1.2': [PASS, FAIL],
+ 'intl402/12.1.2.1_4': [FAIL],
+ 'intl402/12.3.2_FDT_7_a_iv': [FAIL],
+ 'intl402/12.3.3': [FAIL],
+ 'intl402/12.3_a': [FAIL],
+ 'intl402/13.1.1_7': [PASS, FAIL],
+ 'intl402/13.2.1_5': [PASS, FAIL],
+ 'intl402/13.3.0_7': [PASS, FAIL],
+
+ # These tests fail in nosnap in strict mode
+ # https://code.google.com/p/v8/issues/detail?id=4198
+ 'built-ins/String/S15.5.1.1_A1_T6': [PASS, FAIL_OK],
+ 'built-ins/eval/S15.1.2.1_A1.1_T1': [PASS, FAIL_OK],
+ 'built-ins/eval/S15.1.2.1_A1.1_T2': [PASS, FAIL_OK],
+ 'built-ins/eval/S15.1.2.1_A4.3': [PASS, FAIL_OK],
+ 'built-ins/eval/S15.1.2.1_A4.4': [PASS, FAIL_OK],
+ 'language/eval-code/10.4.2-1-1': [PASS, FAIL_OK],
+ 'language/eval-code/10.4.2-1-2': [PASS, FAIL_OK],
+ 'language/eval-code/10.4.2-1-3': [PASS, FAIL_OK],
+ 'language/eval-code/10.4.2-1-5': [PASS, FAIL_OK],
+ 'language/eval-code/S10.4.2.1_A1': [PASS, FAIL_OK],
+ 'language/function-code/10.4.3-1-19-s': [PASS, FAIL_OK],
+ 'language/function-code/10.4.3-1-19gs': [PASS, FAIL_OK],
+ 'language/function-code/10.4.3-1-20-s': [PASS, FAIL_OK],
+ 'language/function-code/10.4.3-1-20gs': [PASS, FAIL_OK],
+ 'language/statements/variable/12.2.1-10-s': [PASS, FAIL_OK],
+ 'language/statements/variable/12.2.1-20-s': [PASS, FAIL_OK],
+ 'language/statements/variable/12.2.1-21-s': [PASS, FAIL_OK],
+ 'language/statements/variable/12.2.1-9-s': [PASS, FAIL_OK],
##################### DELIBERATE INCOMPATIBILITIES #####################
@@ -614,38 +767,25 @@
'built-ins/Object/keys/15.2.3.14-1-2': [PASS, FAIL_OK],
'built-ins/Object/keys/15.2.3.14-1-3': [PASS, FAIL_OK],
- # # String.prototype.contains renamed to 'S.p.includes'
- # 'es6/String.prototype.contains/String.prototype.contains_FailBadLocation' : [FAIL_OK],
- # 'es6/String.prototype.contains/String.prototype.contains_FailLocation' : [FAIL_OK],
- # 'es6/String.prototype.contains/String.prototype.contains_FailMissingLetter' : [FAIL_OK],
- # 'es6/String.prototype.contains/String.prototype.contains_lengthProp' : [FAIL_OK],
- # 'es6/String.prototype.contains/String.prototype.contains_Success' : [FAIL_OK],
- # 'es6/String.prototype.contains/String.prototype.contains_SuccessNoLocation' : [FAIL_OK],
-
- # Function restricted "caller" and "arguments" properties are defined only on
- # the intrinsic %FunctionPrototype% (and sloppy functions) in ES6
- 'language/statements/function/13.2-29-s': [FAIL_OK],
- 'language/statements/function/13.2-30-s': [FAIL_OK],
- 'language/statements/function/13.2-31-s': [FAIL_OK],
- 'language/statements/function/13.2-32-s': [FAIL_OK],
- 'language/statements/function/13.2-33-s': [FAIL_OK],
- 'language/statements/function/13.2-34-s': [FAIL_OK],
- 'language/statements/function/13.2-35-s': [FAIL_OK],
- 'language/statements/function/13.2-36-s': [FAIL_OK],
- 'language/statements/function/S13.2.3_A1': [FAIL_OK],
- 'built-ins/Function/prototype/bind/15.3.4.5-20-1': [FAIL_OK],
- 'built-ins/Function/prototype/bind/15.3.4.5-20-4': [FAIL_OK],
- 'built-ins/Function/prototype/bind/15.3.4.5-20-5': [FAIL_OK],
- 'built-ins/Function/prototype/bind/15.3.4.5-21-1': [FAIL_OK],
- 'built-ins/Function/prototype/bind/15.3.4.5-21-4': [FAIL_OK],
- 'built-ins/Function/prototype/bind/15.3.4.5-21-5': [FAIL_OK],
-
-
############################ SKIPPED TESTS #############################
- # These tests take a looong time to run in debug mode.
- 'built-ins/decodeURI/S15.1.3.1_A2.5_T1': [PASS, ['mode == debug', SKIP]],
- 'built-ins/decodeURIComponent/S15.1.3.2_A2.5_T1': [PASS, ['mode == debug', SKIP]],
+ # These tests take a looong time to run.
+ 'built-ins/decodeURI/S15.1.3.1_A1.10_T1': [SKIP],
+ 'built-ins/decodeURI/S15.1.3.1_A1.11_T1': [SKIP],
+ 'built-ins/decodeURI/S15.1.3.1_A1.11_T2': [SKIP],
+ 'built-ins/decodeURI/S15.1.3.1_A1.12_T1': [SKIP],
+ 'built-ins/decodeURI/S15.1.3.1_A1.12_T2': [SKIP],
+ 'built-ins/decodeURI/S15.1.3.1_A2.5_T1': [SKIP],
+ 'built-ins/decodeURIComponent/S15.1.3.2_A1.11_T1': [SKIP],
+ 'built-ins/decodeURIComponent/S15.1.3.2_A1.12_T1': [SKIP],
+ 'built-ins/decodeURIComponent/S15.1.3.2_A2.5_T1': [SKIP],
+ 'built-ins/RegExp/S15.10.2.12_A3_T1': [SKIP],
+ 'intl402/9.2.6_4_b': [SKIP],
+ 'language/literals/regexp/S7.8.5_A1.1_T2': [SKIP],
+ 'language/literals/regexp/S7.8.5_A1.4_T2': [SKIP],
+ 'language/literals/regexp/S7.8.5_A2.1_T2': [SKIP],
+ 'language/literals/regexp/S7.8.5_A2.4_T2': [SKIP],
+ 'language/statements/const/syntax/const-invalid-assignment-next-expression-for': [SKIP],
}], # ALWAYS
['system == macos', {
diff --git a/deps/v8/test/test262-es6/testcfg.py b/deps/v8/test/test262-es6/testcfg.py
index 0519dc0e0e..91491b3907 100644
--- a/deps/v8/test/test262-es6/testcfg.py
+++ b/deps/v8/test/test262-es6/testcfg.py
@@ -33,12 +33,14 @@ import sys
import tarfile
import imp
+from testrunner.local import statusfile
from testrunner.local import testsuite
from testrunner.local import utils
from testrunner.objects import testcase
-TEST_262_ARCHIVE_REVISION = "43acf61" # This is the 2015-03-31 revision.
-TEST_262_ARCHIVE_MD5 = "a77a0352a0462be98e50522a15b7a3c4"
+# The revision hash needs to be 7 characters?
+TEST_262_ARCHIVE_REVISION = "c6ac390" # This is the 2015-07-06 revision.
+TEST_262_ARCHIVE_MD5 = "e1393ef330f38e9cb1bfa4e3eada5ba8"
TEST_262_URL = "https://github.com/tc39/test262/tarball/%s"
TEST_262_HARNESS_FILES = ["sta.js", "assert.js"]
@@ -79,6 +81,16 @@ class Test262TestSuite(testsuite.TestSuite):
self.GetIncludesForTest(testcase) + ["--harmony"] +
[os.path.join(self.testroot, testcase.path + ".js")])
+ def VariantFlags(self, testcase, default_flags):
+ flags = super(Test262TestSuite, self).VariantFlags(testcase, default_flags)
+ test_record = self.GetTestRecord(testcase)
+ if "noStrict" in test_record:
+ return flags
+ strict_flags = [f + ["--use-strict"] for f in flags]
+ if "onlyStrict" in test_record:
+ return strict_flags
+ return flags + strict_flags
+
def LoadParseTestRecord(self):
if not self.ParseTestRecord:
root = os.path.join(self.root, *TEST_262_TOOLS_PATH)
@@ -125,12 +137,30 @@ class Test262TestSuite(testsuite.TestSuite):
return True
return "FAILED!" in output.stdout
+ def HasUnexpectedOutput(self, testcase):
+ outcome = self.GetOutcome(testcase)
+ if (statusfile.FAIL_SLOPPY in testcase.outcomes and
+ "--use-strict" not in testcase.flags):
+ return outcome != statusfile.FAIL
+ return not outcome in (testcase.outcomes or [statusfile.PASS])
+
def DownloadData(self):
revision = TEST_262_ARCHIVE_REVISION
archive_url = TEST_262_URL % revision
archive_name = os.path.join(self.root, "tc39-test262-%s.tar.gz" % revision)
directory_name = os.path.join(self.root, "data")
directory_old_name = os.path.join(self.root, "data.old")
+
+ # Clobber if the test is in an outdated state, i.e. if there are any other
+ # archive files present.
+ archive_files = [f for f in os.listdir(self.root)
+ if f.startswith("tc39-test262-")]
+ if (len(archive_files) > 1 or
+ os.path.basename(archive_name) not in archive_files):
+ print "Clobber outdated test archives ..."
+ for f in archive_files:
+ os.remove(os.path.join(self.root, f))
+
if not os.path.exists(archive_name):
print "Downloading test data from %s ..." % archive_url
utils.URLRetrieve(archive_url, archive_name)
diff --git a/deps/v8/test/test262/test262.status b/deps/v8/test/test262/test262.status
index 4ae13dacdd..feed1a3206 100644
--- a/deps/v8/test/test262/test262.status
+++ b/deps/v8/test/test262/test262.status
@@ -36,6 +36,30 @@
'11.2.3_b': [FAIL],
'12.2.3_b': [FAIL],
+ # BUG(v8:4267)
+ '15.2.3.6-4-116': [FAIL],
+ '15.2.3.6-4-117': [FAIL],
+ '15.2.3.6-4-168': [FAIL],
+ '15.2.3.6-4-169': [FAIL],
+ '15.2.3.6-4-170': [FAIL],
+ '15.2.3.6-4-172': [FAIL],
+ '15.2.3.6-4-173': [FAIL],
+ '15.2.3.6-4-174': [FAIL],
+ '15.2.3.6-4-176': [FAIL],
+ '15.2.3.6-4-177': [FAIL],
+ '15.2.3.7-6-a-112': [FAIL],
+ '15.2.3.7-6-a-113': [FAIL],
+ '15.2.3.7-6-a-164': [FAIL],
+ '15.2.3.7-6-a-165': [FAIL],
+ '15.2.3.7-6-a-166': [FAIL],
+ '15.2.3.7-6-a-168': [FAIL],
+ '15.2.3.7-6-a-169': [FAIL],
+ '15.2.3.7-6-a-170': [FAIL],
+ '15.2.3.7-6-a-172': [FAIL],
+ '15.2.3.7-6-a-173': [FAIL],
+ '15.2.3.7-6-a-175': [FAIL],
+ '15.2.3.7-6-a-176': [FAIL],
+
############################### ES6 ###################################
# ES6 allows block-local functions.
'Sbp_A1_T1': [PASS, FAIL_OK],
@@ -197,6 +221,7 @@
'S15.9.5.7_A3_T2': [FAIL],
'S15.9.5.8_A3_T2': [FAIL],
'S15.9.5.9_A3_T2': [FAIL],
+ '15.3.4.5-15-2': [FAIL],
# Object.getPrototypeOf wraps primitive values in ES6.
'15.2.3.2-1': [FAIL],
diff --git a/deps/v8/test/test262/testcfg.py b/deps/v8/test/test262/testcfg.py
index de3c9ad7b9..a0c2cd6568 100644
--- a/deps/v8/test/test262/testcfg.py
+++ b/deps/v8/test/test262/testcfg.py
@@ -95,6 +95,17 @@ class Test262TestSuite(testsuite.TestSuite):
archive_name = os.path.join(self.root, "tc39-test262-%s.tar.gz" % revision)
directory_name = os.path.join(self.root, "data")
directory_old_name = os.path.join(self.root, "data.old")
+
+ # Clobber if the test is in an outdated state, i.e. if there are any other
+ # archive files present.
+ archive_files = [f for f in os.listdir(self.root)
+ if f.startswith("tc39-test262-")]
+ if (len(archive_files) > 1 or
+ os.path.basename(archive_name) not in archive_files):
+ print "Clobber outdated test archives ..."
+ for f in archive_files:
+ os.remove(os.path.join(self.root, f))
+
if not os.path.exists(archive_name):
print "Downloading test data from %s ..." % archive_url
utils.URLRetrieve(archive_url, archive_name)
@@ -108,8 +119,10 @@ class Test262TestSuite(testsuite.TestSuite):
with open(archive_name, "rb") as f:
for chunk in iter(lambda: f.read(8192), ""):
md5.update(chunk)
+ print "MD5 hash is %s" % md5.hexdigest()
if md5.hexdigest() != TEST_262_ARCHIVE_MD5:
os.remove(archive_name)
+ print "MD5 expected %s" % TEST_262_ARCHIVE_MD5
raise Exception("Hash mismatch of test data file")
archive = tarfile.open(archive_name, "r:gz")
if sys.platform in ("win32", "cygwin"):
diff --git a/deps/v8/test/unittests/base/bits-unittest.cc b/deps/v8/test/unittests/base/bits-unittest.cc
index 9caba8484e..3d17a050db 100644
--- a/deps/v8/test/unittests/base/bits-unittest.cc
+++ b/deps/v8/test/unittests/base/bits-unittest.cc
@@ -255,6 +255,25 @@ TEST(Bits, SignedMod32) {
}
+TEST(Bits, UnsignedAddOverflow32) {
+ uint32_t val = 0;
+ EXPECT_FALSE(UnsignedAddOverflow32(0, 0, &val));
+ EXPECT_EQ(0u, val);
+ EXPECT_TRUE(
+ UnsignedAddOverflow32(std::numeric_limits<uint32_t>::max(), 1u, &val));
+ EXPECT_EQ(std::numeric_limits<uint32_t>::min(), val);
+ EXPECT_TRUE(UnsignedAddOverflow32(std::numeric_limits<uint32_t>::max(),
+ std::numeric_limits<uint32_t>::max(),
+ &val));
+ TRACED_FORRANGE(uint32_t, i, 1, 50) {
+ TRACED_FORRANGE(uint32_t, j, 1, i) {
+ EXPECT_FALSE(UnsignedAddOverflow32(i, j, &val));
+ EXPECT_EQ(i + j, val);
+ }
+ }
+}
+
+
TEST(Bits, UnsignedDiv32) {
TRACED_FORRANGE(uint32_t, i, 0, 50) {
EXPECT_EQ(0u, UnsignedDiv32(i, 0));
diff --git a/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc b/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
index 744f18f0bd..7e67b31616 100644
--- a/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
+++ b/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
@@ -47,7 +47,7 @@ Node* BuildConstant(InstructionSelectorTest::StreamBuilder& m, MachineType type,
int64_t value) {
switch (type) {
case kMachInt32:
- return m.Int32Constant(value);
+ return m.Int32Constant(static_cast<int32_t>(value));
break;
case kMachInt64:
@@ -642,7 +642,9 @@ TEST_F(InstructionSelectorTest, AddShiftByImmediateOnLeft) {
if (shift.mi.machine_type != kMachInt32) continue;
if (shift.mi.arch_opcode == kArm64Ror32) continue;
- TRACED_FORRANGE(int, imm, 0, 31) {
+ // The available shift operand range is `0 <= imm < 32`, but we also test
+ // that immediates outside this range are handled properly (modulo-32).
+ TRACED_FORRANGE(int, imm, -32, 63) {
StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
m.Return((m.Int32Add)(
(m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm)),
@@ -663,7 +665,9 @@ TEST_F(InstructionSelectorTest, AddShiftByImmediateOnLeft) {
if (shift.mi.machine_type != kMachInt64) continue;
if (shift.mi.arch_opcode == kArm64Ror) continue;
- TRACED_FORRANGE(int, imm, 0, 63) {
+ // The available shift operand range is `0 <= imm < 64`, but we also test
+ // that immediates outside this range are handled properly (modulo-64).
+ TRACED_FORRANGE(int, imm, -64, 127) {
StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
m.Return((m.Int64Add)(
(m.*shift.mi.constructor)(m.Parameter(1), m.Int64Constant(imm)),
@@ -1641,6 +1645,102 @@ TEST_F(InstructionSelectorTest, Int32MulWithImmediate) {
EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
EXPECT_EQ(1U, s[0]->OutputCount());
}
+ // x * (2^k + 1) + c -> x + (x << k) + c
+ TRACED_FORRANGE(int32_t, k, 1, 30) {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ m.Return(
+ m.Int32Add(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)),
+ m.Parameter(1)));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Add32, s[1]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ // (2^k + 1) * x + c -> x + (x << k) + c
+ TRACED_FORRANGE(int32_t, k, 1, 30) {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ m.Return(
+ m.Int32Add(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)),
+ m.Parameter(1)));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Add32, s[1]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ // c + x * (2^k + 1) -> c + x + (x << k)
+ TRACED_FORRANGE(int32_t, k, 1, 30) {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ m.Return(
+ m.Int32Add(m.Parameter(0),
+ m.Int32Mul(m.Parameter(1), m.Int32Constant((1 << k) + 1))));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Add32, s[1]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ // c + (2^k + 1) * x -> c + x + (x << k)
+ TRACED_FORRANGE(int32_t, k, 1, 30) {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ m.Return(
+ m.Int32Add(m.Parameter(0),
+ m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(1))));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Add32, s[1]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ // c - x * (2^k + 1) -> c - x + (x << k)
+ TRACED_FORRANGE(int32_t, k, 1, 30) {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ m.Return(
+ m.Int32Sub(m.Parameter(0),
+ m.Int32Mul(m.Parameter(1), m.Int32Constant((1 << k) + 1))));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Sub32, s[1]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ // c - (2^k + 1) * x -> c - x + (x << k)
+ TRACED_FORRANGE(int32_t, k, 1, 30) {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ m.Return(
+ m.Int32Sub(m.Parameter(0),
+ m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(1))));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Sub32, s[1]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
}
@@ -1671,6 +1771,102 @@ TEST_F(InstructionSelectorTest, Int64MulWithImmediate) {
EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
EXPECT_EQ(1U, s[0]->OutputCount());
}
+ // x * (2^k + 1) + c -> x + (x << k) + c
+ TRACED_FORRANGE(int64_t, k, 1, 62) {
+ StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
+ m.Return(
+ m.Int64Add(m.Int64Mul(m.Parameter(0), m.Int64Constant((1L << k) + 1)),
+ m.Parameter(1)));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Add, s[1]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ // (2^k + 1) * x + c -> x + (x << k) + c
+ TRACED_FORRANGE(int64_t, k, 1, 62) {
+ StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
+ m.Return(
+ m.Int64Add(m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(0)),
+ m.Parameter(1)));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Add, s[1]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ // c + x * (2^k + 1) -> c + x + (x << k)
+ TRACED_FORRANGE(int64_t, k, 1, 62) {
+ StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
+ m.Return(
+ m.Int64Add(m.Parameter(0),
+ m.Int64Mul(m.Parameter(1), m.Int64Constant((1L << k) + 1))));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Add, s[1]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ // c + (2^k + 1) * x -> c + x + (x << k)
+ TRACED_FORRANGE(int64_t, k, 1, 62) {
+ StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
+ m.Return(
+ m.Int64Add(m.Parameter(0),
+ m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(1))));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Add, s[1]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ // c - x * (2^k + 1) -> c - x + (x << k)
+ TRACED_FORRANGE(int64_t, k, 1, 62) {
+ StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
+ m.Return(
+ m.Int64Sub(m.Parameter(0),
+ m.Int64Mul(m.Parameter(1), m.Int64Constant((1L << k) + 1))));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Sub, s[1]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ // c - (2^k + 1) * x -> c - x + (x << k)
+ TRACED_FORRANGE(int64_t, k, 1, 62) {
+ StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
+ m.Return(
+ m.Int64Sub(m.Parameter(0),
+ m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(1))));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Sub, s[1]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
}
@@ -2041,6 +2237,190 @@ TEST_F(InstructionSelectorTest, Word64EqualWithZero) {
}
+TEST_F(InstructionSelectorTest, Word32EqualWithWord32Shift) {
+ TRACED_FOREACH(Shift, shift, kShiftInstructions) {
+ // Skip non 32-bit shifts or ror operations.
+ if (shift.mi.machine_type != kMachInt32 ||
+ shift.mi.arch_opcode == kArm64Ror32) {
+ continue;
+ }
+
+ TRACED_FORRANGE(int32_t, imm, -32, 63) {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm));
+ m.Return(m.Word32Equal(p0, r));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ EXPECT_EQ(shift.mode, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ }
+ TRACED_FORRANGE(int32_t, imm, -32, 63) {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm));
+ m.Return(m.Word32Equal(r, p0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ EXPECT_EQ(shift.mode, s[0]->addressing_mode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ }
+ }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32EqualWithUnsignedExtendByte) {
+ {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* r = m.Word32And(p1, m.Int32Constant(0xff));
+ m.Return(m.Word32Equal(p0, r));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ }
+ {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* r = m.Word32And(p1, m.Int32Constant(0xff));
+ m.Return(m.Word32Equal(r, p0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32EqualWithUnsignedExtendHalfword) {
+ {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* r = m.Word32And(p1, m.Int32Constant(0xffff));
+ m.Return(m.Word32Equal(p0, r));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ }
+ {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* r = m.Word32And(p1, m.Int32Constant(0xffff));
+ m.Return(m.Word32Equal(r, p0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32EqualWithSignedExtendByte) {
+ {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* r =
+ m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(24)), m.Int32Constant(24));
+ m.Return(m.Word32Equal(p0, r));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ }
+ {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* r =
+ m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(24)), m.Int32Constant(24));
+ m.Return(m.Word32Equal(r, p0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32EqualWithSignedExtendHalfword) {
+ {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* r =
+ m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(16)), m.Int32Constant(16));
+ m.Return(m.Word32Equal(p0, r));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ }
+ {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* r =
+ m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(16)), m.Int32Constant(16));
+ m.Return(m.Word32Equal(r, p0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ }
+}
+
+
// -----------------------------------------------------------------------------
// Miscellaneous
@@ -2202,14 +2582,17 @@ TEST_F(InstructionSelectorTest, Word64XorMinusOneWithParameter) {
TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediate) {
- TRACED_FORRANGE(int32_t, lsb, 1, 31) {
+ // The available shift operand range is `0 <= imm < 32`, but we also test
+ // that immediates outside this range are handled properly (modulo-32).
+ TRACED_FORRANGE(int32_t, shift, -32, 63) {
+ int32_t lsb = shift & 0x1f;
TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
uint32_t jnk = rng()->NextInt();
- jnk >>= 32 - lsb;
+ jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0;
uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
StreamBuilder m(this, kMachInt32, kMachInt32);
m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)),
- m.Int32Constant(lsb)));
+ m.Int32Constant(shift)));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
@@ -2218,14 +2601,15 @@ TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediate) {
EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
}
}
- TRACED_FORRANGE(int32_t, lsb, 1, 31) {
+ TRACED_FORRANGE(int32_t, shift, -32, 63) {
+ int32_t lsb = shift & 0x1f;
TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
uint32_t jnk = rng()->NextInt();
- jnk >>= 32 - lsb;
+ jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0;
uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
StreamBuilder m(this, kMachInt32, kMachInt32);
m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)),
- m.Int32Constant(lsb)));
+ m.Int32Constant(shift)));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
@@ -2238,15 +2622,18 @@ TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediate) {
TEST_F(InstructionSelectorTest, Word64ShrWithWord64AndWithImmediate) {
- TRACED_FORRANGE(int32_t, lsb, 1, 63) {
+ // The available shift operand range is `0 <= imm < 64`, but we also test
+ // that immediates outside this range are handled properly (modulo-64).
+ TRACED_FORRANGE(int32_t, shift, -64, 127) {
+ int32_t lsb = shift & 0x3f;
TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) {
uint64_t jnk = rng()->NextInt64();
- jnk >>= 64 - lsb;
+ jnk = (lsb > 0) ? (jnk >> (64 - lsb)) : 0;
uint64_t msk =
((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk;
StreamBuilder m(this, kMachInt64, kMachInt64);
m.Return(m.Word64Shr(m.Word64And(m.Parameter(0), m.Int64Constant(msk)),
- m.Int64Constant(lsb)));
+ m.Int64Constant(shift)));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
@@ -2255,15 +2642,16 @@ TEST_F(InstructionSelectorTest, Word64ShrWithWord64AndWithImmediate) {
EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2)));
}
}
- TRACED_FORRANGE(int32_t, lsb, 1, 63) {
+ TRACED_FORRANGE(int32_t, shift, -64, 127) {
+ int32_t lsb = shift & 0x3f;
TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) {
uint64_t jnk = rng()->NextInt64();
- jnk >>= 64 - lsb;
+ jnk = (lsb > 0) ? (jnk >> (64 - lsb)) : 0;
uint64_t msk =
((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk;
StreamBuilder m(this, kMachInt64, kMachInt64);
m.Return(m.Word64Shr(m.Word64And(m.Int64Constant(msk), m.Parameter(0)),
- m.Int64Constant(lsb)));
+ m.Int64Constant(shift)));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
@@ -2276,11 +2664,14 @@ TEST_F(InstructionSelectorTest, Word64ShrWithWord64AndWithImmediate) {
TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) {
- TRACED_FORRANGE(int32_t, lsb, 1, 31) {
+ // The available shift operand range is `0 <= imm < 32`, but we also test
+ // that immediates outside this range are handled properly (modulo-32).
+ TRACED_FORRANGE(int32_t, shift, -32, 63) {
+ int32_t lsb = shift & 0x1f;
TRACED_FORRANGE(int32_t, width, 1, 31) {
uint32_t msk = (1 << width) - 1;
StreamBuilder m(this, kMachInt32, kMachInt32);
- m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)),
+ m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)),
m.Int32Constant(msk)));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@@ -2291,12 +2682,14 @@ TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) {
EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2)));
}
}
- TRACED_FORRANGE(int32_t, lsb, 1, 31) {
+ TRACED_FORRANGE(int32_t, shift, -32, 63) {
+ int32_t lsb = shift & 0x1f;
TRACED_FORRANGE(int32_t, width, 1, 31) {
uint32_t msk = (1 << width) - 1;
StreamBuilder m(this, kMachInt32, kMachInt32);
- m.Return(m.Word32And(m.Int32Constant(msk),
- m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb))));
+ m.Return(
+ m.Word32And(m.Int32Constant(msk),
+ m.Word32Shr(m.Parameter(0), m.Int32Constant(shift))));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
@@ -2310,11 +2703,14 @@ TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) {
TEST_F(InstructionSelectorTest, Word64AndWithImmediateWithWord64Shr) {
- TRACED_FORRANGE(int64_t, lsb, 1, 63) {
+ // The available shift operand range is `0 <= imm < 64`, but we also test
+ // that immediates outside this range are handled properly (modulo-64).
+ TRACED_FORRANGE(int64_t, shift, -64, 127) {
+ int64_t lsb = shift & 0x3f;
TRACED_FORRANGE(int64_t, width, 1, 63) {
uint64_t msk = (V8_UINT64_C(1) << width) - 1;
StreamBuilder m(this, kMachInt64, kMachInt64);
- m.Return(m.Word64And(m.Word64Shr(m.Parameter(0), m.Int64Constant(lsb)),
+ m.Return(m.Word64And(m.Word64Shr(m.Parameter(0), m.Int64Constant(shift)),
m.Int64Constant(msk)));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@@ -2325,12 +2721,14 @@ TEST_F(InstructionSelectorTest, Word64AndWithImmediateWithWord64Shr) {
EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2)));
}
}
- TRACED_FORRANGE(int64_t, lsb, 1, 63) {
+ TRACED_FORRANGE(int64_t, shift, -64, 127) {
+ int64_t lsb = shift & 0x3f;
TRACED_FORRANGE(int64_t, width, 1, 63) {
uint64_t msk = (V8_UINT64_C(1) << width) - 1;
StreamBuilder m(this, kMachInt64, kMachInt64);
- m.Return(m.Word64And(m.Int64Constant(msk),
- m.Word64Shr(m.Parameter(0), m.Int64Constant(lsb))));
+ m.Return(
+ m.Word64And(m.Int64Constant(msk),
+ m.Word64Shr(m.Parameter(0), m.Int64Constant(shift))));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
@@ -2365,6 +2763,87 @@ TEST_F(InstructionSelectorTest, Int32MulHighWithParameters) {
}
+TEST_F(InstructionSelectorTest, Int32MulHighWithSar) {
+ TRACED_FORRANGE(int32_t, shift, -32, 63) {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n = m.Word32Sar(m.Int32MulHigh(p0, p1), m.Int32Constant(shift));
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Smull, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(kArm64Asr, s[1]->arch_opcode());
+ ASSERT_EQ(2U, s[1]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
+ EXPECT_EQ((shift & 0x1f) + 32, s.ToInt64(s[1]->InputAt(1)));
+ ASSERT_EQ(1U, s[1]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output()));
+ }
+}
+
+
+TEST_F(InstructionSelectorTest, Int32MulHighWithAdd) {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const a = m.Int32Add(m.Int32MulHigh(p0, p1), p0);
+ // Test only one shift constant here, as we're only interested in it being a
+ // 32-bit operation; the shift amount is irrelevant.
+ Node* const n = m.Word32Sar(a, m.Int32Constant(1));
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(3U, s.size());
+ EXPECT_EQ(kArm64Smull, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(kArm64Add, s[1]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_ASR_I, s[1]->addressing_mode());
+ ASSERT_EQ(3U, s[1]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[1]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(1)));
+ EXPECT_EQ(32, s.ToInt64(s[1]->InputAt(2)));
+ ASSERT_EQ(1U, s[1]->OutputCount());
+ EXPECT_EQ(kArm64Asr32, s[2]->arch_opcode());
+ ASSERT_EQ(2U, s[2]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(0)));
+ EXPECT_EQ(1, s.ToInt64(s[2]->InputAt(1)));
+ ASSERT_EQ(1U, s[2]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[2]->Output()));
+}
+
+
+TEST_F(InstructionSelectorTest, Uint32MulHighWithShr) {
+ TRACED_FORRANGE(int32_t, shift, -32, 63) {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n =
+ m.Word32Shr(m.Uint32MulHigh(p0, p1), m.Int32Constant(shift));
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Umull, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(kArm64Lsr, s[1]->arch_opcode());
+ ASSERT_EQ(2U, s[1]->InputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
+ EXPECT_EQ((shift & 0x1f) + 32, s.ToInt64(s[1]->InputAt(1)));
+ ASSERT_EQ(1U, s[1]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output()));
+ }
+}
+
+
TEST_F(InstructionSelectorTest, Word32SarWithWord32Shl) {
TRACED_FORRANGE(int32_t, shift, 1, 31) {
StreamBuilder m(this, kMachInt32, kMachInt32);
@@ -2429,6 +2908,40 @@ TEST_F(InstructionSelectorTest, Word32ShrWithWord32Shl) {
}
+TEST_F(InstructionSelectorTest, Word32ShlWithWord32And) {
+ TRACED_FORRANGE(int32_t, shift, 1, 30) {
+ StreamBuilder m(this, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const r =
+ m.Word32Shl(m.Word32And(p0, m.Int32Constant((1 << (31 - shift)) - 1)),
+ m.Int32Constant(shift));
+ m.Return(r);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Ubfiz32, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+ }
+ TRACED_FORRANGE(int32_t, shift, 0, 30) {
+ StreamBuilder m(this, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const r =
+ m.Word32Shl(m.Word32And(p0, m.Int32Constant((1 << (31 - shift)) - 1)),
+ m.Int32Constant(shift + 1));
+ m.Return(r);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Lsl32, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+ }
+}
+
+
TEST_F(InstructionSelectorTest, Word32Clz) {
StreamBuilder m(this, kMachUint32, kMachUint32);
Node* const p0 = m.Parameter(0);
diff --git a/deps/v8/test/unittests/compiler/common-operator-reducer-unittest.cc b/deps/v8/test/unittests/compiler/common-operator-reducer-unittest.cc
index d6822e8b09..13d2d6707a 100644
--- a/deps/v8/test/unittests/compiler/common-operator-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/common-operator-reducer-unittest.cc
@@ -4,14 +4,16 @@
#include "src/compiler/common-operator.h"
#include "src/compiler/common-operator-reducer.h"
-#include "src/compiler/js-graph.h"
-#include "src/compiler/js-operator.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/machine-type.h"
#include "src/compiler/operator.h"
+#include "src/compiler/simplified-operator.h"
+#include "test/unittests/compiler/graph-reducer-unittest.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"
+using testing::StrictMock;
+
namespace v8 {
namespace internal {
namespace compiler {
@@ -19,23 +21,30 @@ namespace compiler {
class CommonOperatorReducerTest : public GraphTest {
public:
explicit CommonOperatorReducerTest(int num_parameters = 1)
- : GraphTest(num_parameters), machine_(zone()) {}
+ : GraphTest(num_parameters), machine_(zone()), simplified_(zone()) {}
~CommonOperatorReducerTest() override {}
protected:
- Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags =
- MachineOperatorBuilder::kNoFlags) {
- JSOperatorBuilder javascript(zone());
+ Reduction Reduce(
+ AdvancedReducer::Editor* editor, Node* node,
+ MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags) {
MachineOperatorBuilder machine(zone(), kMachPtr, flags);
- JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine);
- CommonOperatorReducer reducer(&jsgraph);
+ CommonOperatorReducer reducer(editor, graph(), common(), &machine);
return reducer.Reduce(node);
}
+ Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags =
+ MachineOperatorBuilder::kNoFlags) {
+ StrictMock<MockAdvancedReducerEditor> editor;
+ return Reduce(&editor, node, flags);
+ }
+
MachineOperatorBuilder* machine() { return &machine_; }
+ SimplifiedOperatorBuilder* simplified() { return &simplified_; }
private:
MachineOperatorBuilder machine_;
+ SimplifiedOperatorBuilder simplified_;
};
@@ -58,32 +67,213 @@ const Operator kOp0(0, Operator::kNoProperties, "Op0", 0, 0, 0, 1, 1, 0);
// -----------------------------------------------------------------------------
+// Branch
+
+
+TEST_F(CommonOperatorReducerTest, BranchWithInt32ZeroConstant) {
+ TRACED_FOREACH(BranchHint, hint, kBranchHints) {
+ Node* const control = graph()->start();
+ Node* const branch =
+ graph()->NewNode(common()->Branch(hint), Int32Constant(0), control);
+ Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Replace(if_true, IsDead()));
+ EXPECT_CALL(editor, Replace(if_false, control));
+ Reduction const r = Reduce(&editor, branch);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+}
+
+
+TEST_F(CommonOperatorReducerTest, BranchWithInt32OneConstant) {
+ TRACED_FOREACH(BranchHint, hint, kBranchHints) {
+ Node* const control = graph()->start();
+ Node* const branch =
+ graph()->NewNode(common()->Branch(hint), Int32Constant(1), control);
+ Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Replace(if_true, control));
+ EXPECT_CALL(editor, Replace(if_false, IsDead()));
+ Reduction const r = Reduce(&editor, branch);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+}
+
+
+TEST_F(CommonOperatorReducerTest, BranchWithInt64ZeroConstant) {
+ TRACED_FOREACH(BranchHint, hint, kBranchHints) {
+ Node* const control = graph()->start();
+ Node* const branch =
+ graph()->NewNode(common()->Branch(hint), Int64Constant(0), control);
+ Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Replace(if_true, IsDead()));
+ EXPECT_CALL(editor, Replace(if_false, control));
+ Reduction const r = Reduce(&editor, branch);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+}
+
+
+TEST_F(CommonOperatorReducerTest, BranchWithInt64OneConstant) {
+ TRACED_FOREACH(BranchHint, hint, kBranchHints) {
+ Node* const control = graph()->start();
+ Node* const branch =
+ graph()->NewNode(common()->Branch(hint), Int64Constant(1), control);
+ Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Replace(if_true, control));
+ EXPECT_CALL(editor, Replace(if_false, IsDead()));
+ Reduction const r = Reduce(&editor, branch);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+}
+
+
+TEST_F(CommonOperatorReducerTest, BranchWithFalseConstant) {
+ TRACED_FOREACH(BranchHint, hint, kBranchHints) {
+ Node* const control = graph()->start();
+ Node* const branch =
+ graph()->NewNode(common()->Branch(hint), FalseConstant(), control);
+ Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Replace(if_true, IsDead()));
+ EXPECT_CALL(editor, Replace(if_false, control));
+ Reduction const r = Reduce(&editor, branch);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+}
+
+
+TEST_F(CommonOperatorReducerTest, BranchWithTrueConstant) {
+ TRACED_FOREACH(BranchHint, hint, kBranchHints) {
+ Node* const control = graph()->start();
+ Node* const branch =
+ graph()->NewNode(common()->Branch(hint), TrueConstant(), control);
+ Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Replace(if_true, control));
+ EXPECT_CALL(editor, Replace(if_false, IsDead()));
+ Reduction const r = Reduce(&editor, branch);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+}
+
+
+TEST_F(CommonOperatorReducerTest, BranchWithBooleanNot) {
+ Node* const value = Parameter(0);
+ TRACED_FOREACH(BranchHint, hint, kBranchHints) {
+ Node* const control = graph()->start();
+ Node* const branch = graph()->NewNode(
+ common()->Branch(hint),
+ graph()->NewNode(simplified()->BooleanNot(), value), control);
+ Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Reduction const r = Reduce(branch);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(branch, r.replacement());
+ EXPECT_THAT(branch, IsBranch(value, control));
+ EXPECT_THAT(if_false, IsIfTrue(branch));
+ EXPECT_THAT(if_true, IsIfFalse(branch));
+ EXPECT_EQ(NegateBranchHint(hint), BranchHintOf(branch->op()));
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+// Merge
+
+
+TEST_F(CommonOperatorReducerTest, MergeOfUnusedDiamond0) {
+ Node* const value = Parameter(0);
+ Node* const control = graph()->start();
+ Node* const branch = graph()->NewNode(common()->Branch(), value, control);
+ Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Reduction const r =
+ Reduce(graph()->NewNode(common()->Merge(2), if_true, if_false));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(control, r.replacement());
+ EXPECT_THAT(branch, IsDead());
+}
+
+
+TEST_F(CommonOperatorReducerTest, MergeOfUnusedDiamond1) {
+ Node* const value = Parameter(0);
+ Node* const control = graph()->start();
+ Node* const branch = graph()->NewNode(common()->Branch(), value, control);
+ Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Reduction const r =
+ Reduce(graph()->NewNode(common()->Merge(2), if_false, if_true));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(control, r.replacement());
+ EXPECT_THAT(branch, IsDead());
+}
+
+
+// -----------------------------------------------------------------------------
// EffectPhi
-TEST_F(CommonOperatorReducerTest, RedundantEffectPhi) {
+TEST_F(CommonOperatorReducerTest, EffectPhiWithMerge) {
const int kMaxInputs = 64;
Node* inputs[kMaxInputs];
Node* const input = graph()->NewNode(&kOp0);
TRACED_FORRANGE(int, input_count, 2, kMaxInputs - 1) {
int const value_input_count = input_count - 1;
for (int i = 0; i < value_input_count; ++i) {
+ inputs[i] = graph()->start();
+ }
+ Node* const merge = graph()->NewNode(common()->Merge(value_input_count),
+ value_input_count, inputs);
+ for (int i = 0; i < value_input_count; ++i) {
inputs[i] = input;
}
- inputs[value_input_count] = graph()->start();
- Reduction r = Reduce(graph()->NewNode(
- common()->EffectPhi(value_input_count), input_count, inputs));
+ inputs[value_input_count] = merge;
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Revisit(merge));
+ Reduction r =
+ Reduce(&editor, graph()->NewNode(common()->EffectPhi(value_input_count),
+ input_count, inputs));
ASSERT_TRUE(r.Changed());
EXPECT_EQ(input, r.replacement());
}
}
+TEST_F(CommonOperatorReducerTest, EffectPhiWithLoop) {
+ Node* const e0 = graph()->NewNode(&kOp0);
+ Node* const loop =
+ graph()->NewNode(common()->Loop(2), graph()->start(), graph()->start());
+ loop->ReplaceInput(1, loop);
+ Node* const ephi = graph()->NewNode(common()->EffectPhi(2), e0, e0, loop);
+ ephi->ReplaceInput(1, ephi);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Revisit(loop));
+ Reduction const r = Reduce(&editor, ephi);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(e0, r.replacement());
+}
+
+
// -----------------------------------------------------------------------------
// Phi
-TEST_F(CommonOperatorReducerTest, RedundantPhi) {
+TEST_F(CommonOperatorReducerTest, PhiWithMerge) {
const int kMaxInputs = 64;
Node* inputs[kMaxInputs];
Node* const input = graph()->NewNode(&kOp0);
@@ -93,14 +283,17 @@ TEST_F(CommonOperatorReducerTest, RedundantPhi) {
for (int i = 0; i < value_input_count; ++i) {
inputs[i] = graph()->start();
}
- Node* merge = graph()->NewNode(common()->Merge(value_input_count),
- value_input_count, inputs);
+ Node* const merge = graph()->NewNode(common()->Merge(value_input_count),
+ value_input_count, inputs);
for (int i = 0; i < value_input_count; ++i) {
inputs[i] = input;
}
inputs[value_input_count] = merge;
- Reduction r = Reduce(graph()->NewNode(
- common()->Phi(type, value_input_count), input_count, inputs));
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Revisit(merge));
+ Reduction r = Reduce(
+ &editor, graph()->NewNode(common()->Phi(type, value_input_count),
+ input_count, inputs));
ASSERT_TRUE(r.Changed());
EXPECT_EQ(input, r.replacement());
}
@@ -108,6 +301,22 @@ TEST_F(CommonOperatorReducerTest, RedundantPhi) {
}
+TEST_F(CommonOperatorReducerTest, PhiWithLoop) {
+ Node* const p0 = Parameter(0);
+ Node* const loop =
+ graph()->NewNode(common()->Loop(2), graph()->start(), graph()->start());
+ loop->ReplaceInput(1, loop);
+ Node* const phi =
+ graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p0, loop);
+ phi->ReplaceInput(1, phi);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Revisit(loop));
+ Reduction const r = Reduce(&editor, phi);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(p0, r.replacement());
+}
+
+
TEST_F(CommonOperatorReducerTest, PhiToFloat32Abs) {
Node* p0 = Parameter(0);
Node* c0 = Float32Constant(0.0);
@@ -120,7 +329,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat32Abs) {
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi =
graph()->NewNode(common()->Phi(kMachFloat32, 2), vtrue, vfalse, merge);
- Reduction r = Reduce(phi);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Revisit(merge));
+ Reduction r = Reduce(&editor, phi);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat32Abs(p0));
}
@@ -138,7 +349,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat64Abs) {
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi =
graph()->NewNode(common()->Phi(kMachFloat64, 2), vtrue, vfalse, merge);
- Reduction r = Reduce(phi);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Revisit(merge));
+ Reduction r = Reduce(&editor, phi);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat64Abs(p0));
}
@@ -153,7 +366,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat32Max) {
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi = graph()->NewNode(common()->Phi(kMachFloat32, 2), p1, p0, merge);
- Reduction r = Reduce(phi, MachineOperatorBuilder::kFloat32Max);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Revisit(merge));
+ Reduction r = Reduce(&editor, phi, MachineOperatorBuilder::kFloat32Max);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat32Max(p1, p0));
}
@@ -168,7 +383,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat64Max) {
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi = graph()->NewNode(common()->Phi(kMachFloat64, 2), p1, p0, merge);
- Reduction r = Reduce(phi, MachineOperatorBuilder::kFloat64Max);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Revisit(merge));
+ Reduction r = Reduce(&editor, phi, MachineOperatorBuilder::kFloat64Max);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat64Max(p1, p0));
}
@@ -183,7 +400,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat32Min) {
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi = graph()->NewNode(common()->Phi(kMachFloat32, 2), p0, p1, merge);
- Reduction r = Reduce(phi, MachineOperatorBuilder::kFloat32Min);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Revisit(merge));
+ Reduction r = Reduce(&editor, phi, MachineOperatorBuilder::kFloat32Min);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat32Min(p0, p1));
}
@@ -198,17 +417,48 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat64Min) {
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi = graph()->NewNode(common()->Phi(kMachFloat64, 2), p0, p1, merge);
- Reduction r = Reduce(phi, MachineOperatorBuilder::kFloat64Min);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Revisit(merge));
+ Reduction r = Reduce(&editor, phi, MachineOperatorBuilder::kFloat64Min);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat64Min(p0, p1));
}
// -----------------------------------------------------------------------------
+// Return
+
+
+TEST_F(CommonOperatorReducerTest, ReturnWithPhiAndEffectPhiAndMerge) {
+ Node* cond = Parameter(2);
+ Node* branch = graph()->NewNode(common()->Branch(), cond, graph()->start());
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* etrue = graph()->start();
+ Node* vtrue = Parameter(0);
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* efalse = graph()->start();
+ Node* vfalse = Parameter(1);
+ Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+ Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
+ Node* phi =
+ graph()->NewNode(common()->Phi(kMachAnyTagged, 2), vtrue, vfalse, merge);
+ Node* ret = graph()->NewNode(common()->Return(), phi, ephi, merge);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Replace(merge, IsDead()));
+ Reduction const r = Reduce(&editor, ret);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ EXPECT_THAT(graph()->end(), IsEnd(ret, IsReturn(vtrue, etrue, if_true),
+ IsReturn(vfalse, efalse, if_false)));
+}
+
+
+// -----------------------------------------------------------------------------
// Select
-TEST_F(CommonOperatorReducerTest, RedundantSelect) {
+TEST_F(CommonOperatorReducerTest, SelectWithSameThenAndElse) {
Node* const input = graph()->NewNode(&kOp0);
TRACED_FOREACH(BranchHint, hint, kBranchHints) {
TRACED_FOREACH(MachineType, type, kMachineTypes) {
@@ -221,6 +471,50 @@ TEST_F(CommonOperatorReducerTest, RedundantSelect) {
}
+TEST_F(CommonOperatorReducerTest, SelectWithInt32ZeroConstant) {
+ Node* p0 = Parameter(0);
+ Node* p1 = Parameter(1);
+ Node* select = graph()->NewNode(common()->Select(kMachAnyTagged),
+ Int32Constant(0), p0, p1);
+ Reduction r = Reduce(select);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(p1, r.replacement());
+}
+
+
+TEST_F(CommonOperatorReducerTest, SelectWithInt32OneConstant) {
+ Node* p0 = Parameter(0);
+ Node* p1 = Parameter(1);
+ Node* select = graph()->NewNode(common()->Select(kMachAnyTagged),
+ Int32Constant(1), p0, p1);
+ Reduction r = Reduce(select);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(p0, r.replacement());
+}
+
+
+TEST_F(CommonOperatorReducerTest, SelectWithInt64ZeroConstant) {
+ Node* p0 = Parameter(0);
+ Node* p1 = Parameter(1);
+ Node* select = graph()->NewNode(common()->Select(kMachAnyTagged),
+ Int64Constant(0), p0, p1);
+ Reduction r = Reduce(select);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(p1, r.replacement());
+}
+
+
+TEST_F(CommonOperatorReducerTest, SelectWithInt64OneConstant) {
+ Node* p0 = Parameter(0);
+ Node* p1 = Parameter(1);
+ Node* select = graph()->NewNode(common()->Select(kMachAnyTagged),
+ Int64Constant(1), p0, p1);
+ Reduction r = Reduce(select);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(p0, r.replacement());
+}
+
+
TEST_F(CommonOperatorReducerTest, SelectWithFalseConstant) {
Node* p0 = Parameter(0);
Node* p1 = Parameter(1);
diff --git a/deps/v8/test/unittests/compiler/common-operator-unittest.cc b/deps/v8/test/unittests/compiler/common-operator-unittest.cc
index 4f4d9f70d0..8765c13271 100644
--- a/deps/v8/test/unittests/compiler/common-operator-unittest.cc
+++ b/deps/v8/test/unittests/compiler/common-operator-unittest.cc
@@ -48,15 +48,13 @@ const SharedOperator kSharedOperators[] = {
value_input_count, effect_input_count, control_input_count, \
value_output_count, effect_output_count, control_output_count \
}
- SHARED(Dead, Operator::kFoldable, 0, 0, 0, 0, 0, 1),
- SHARED(End, Operator::kKontrol, 0, 0, 1, 0, 0, 0),
+ SHARED(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1),
SHARED(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
SHARED(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
SHARED(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
- SHARED(IfException, Operator::kKontrol, 0, 0, 1, 1, 0, 1),
SHARED(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1),
SHARED(Return, Operator::kNoThrow, 1, 1, 1, 0, 0, 1),
- SHARED(Terminate, Operator::kNoThrow, 0, 1, 1, 0, 0, 1)
+ SHARED(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1)
#undef SHARED
};
@@ -162,6 +160,9 @@ const double kDoubleValues[] = {-std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::signaling_NaN()};
+const size_t kInputCounts[] = {3, 4, 100, 255, 1024, 65000};
+
+
const int32_t kInt32Values[] = {
std::numeric_limits<int32_t>::min(), -1914954528, -1698749618, -1578693386,
-1577976073, -1573998034, -1529085059, -1499540537, -1299205097,
@@ -176,14 +177,31 @@ const int32_t kInt32Values[] = {
2008792749, 2045320228, std::numeric_limits<int32_t>::max()};
-const BranchHint kHints[] = {BranchHint::kNone, BranchHint::kTrue,
- BranchHint::kFalse};
+const BranchHint kBranchHints[] = {BranchHint::kNone, BranchHint::kTrue,
+ BranchHint::kFalse};
} // namespace
+TEST_F(CommonOperatorTest, End) {
+ TRACED_FOREACH(size_t, input_count, kInputCounts) {
+ const Operator* const op = common()->End(input_count);
+ EXPECT_EQ(IrOpcode::kEnd, op->opcode());
+ EXPECT_EQ(Operator::kKontrol, op->properties());
+ EXPECT_EQ(0, op->ValueInputCount());
+ EXPECT_EQ(0, op->EffectInputCount());
+ EXPECT_EQ(input_count, static_cast<uint32_t>(op->ControlInputCount()));
+ EXPECT_EQ(input_count, static_cast<uint32_t>(
+ OperatorProperties::GetTotalInputCount(op)));
+ EXPECT_EQ(0, op->ValueOutputCount());
+ EXPECT_EQ(0, op->EffectOutputCount());
+ EXPECT_EQ(0, op->ControlOutputCount());
+ }
+}
+
+
TEST_F(CommonOperatorTest, Branch) {
- TRACED_FOREACH(BranchHint, hint, kHints) {
+ TRACED_FOREACH(BranchHint, hint, kBranchHints) {
const Operator* const op = common()->Branch(hint);
EXPECT_EQ(IrOpcode::kBranch, op->opcode());
EXPECT_EQ(Operator::kKontrol, op->properties());
@@ -199,6 +217,24 @@ TEST_F(CommonOperatorTest, Branch) {
}
+TEST_F(CommonOperatorTest, IfException) {
+ static const IfExceptionHint kIfExceptionHints[] = {
+ IfExceptionHint::kLocallyCaught, IfExceptionHint::kLocallyUncaught};
+ TRACED_FOREACH(IfExceptionHint, hint, kIfExceptionHints) {
+ const Operator* const op = common()->IfException(hint);
+ EXPECT_EQ(IrOpcode::kIfException, op->opcode());
+ EXPECT_EQ(Operator::kKontrol, op->properties());
+ EXPECT_EQ(0, op->ValueInputCount());
+ EXPECT_EQ(1, op->EffectInputCount());
+ EXPECT_EQ(1, op->ControlInputCount());
+ EXPECT_EQ(2, OperatorProperties::GetTotalInputCount(op));
+ EXPECT_EQ(1, op->ValueOutputCount());
+ EXPECT_EQ(1, op->EffectOutputCount());
+ EXPECT_EQ(1, op->ControlOutputCount());
+ }
+}
+
+
TEST_F(CommonOperatorTest, Switch) {
TRACED_FOREACH(size_t, cases, kCases) {
const Operator* const op = common()->Switch(cases);
@@ -238,7 +274,7 @@ TEST_F(CommonOperatorTest, Select) {
kMachInt32, kMachUint32, kMachInt64, kMachUint64,
kMachFloat32, kMachFloat64, kMachAnyTagged};
TRACED_FOREACH(MachineType, type, kTypes) {
- TRACED_FOREACH(BranchHint, hint, kHints) {
+ TRACED_FOREACH(BranchHint, hint, kBranchHints) {
const Operator* const op = common()->Select(type, hint);
EXPECT_EQ(IrOpcode::kSelect, op->opcode());
EXPECT_EQ(Operator::kPure, op->properties());
diff --git a/deps/v8/test/unittests/compiler/control-equivalence-unittest.cc b/deps/v8/test/unittests/compiler/control-equivalence-unittest.cc
index 515bd061ef..47be5407f7 100644
--- a/deps/v8/test/unittests/compiler/control-equivalence-unittest.cc
+++ b/deps/v8/test/unittests/compiler/control-equivalence-unittest.cc
@@ -27,7 +27,7 @@ class ControlEquivalenceTest : public GraphTest {
protected:
void ComputeEquivalence(Node* node) {
- graph()->SetEnd(graph()->NewNode(common()->End(), node));
+ graph()->SetEnd(graph()->NewNode(common()->End(1), node));
if (FLAG_trace_turbo) {
OFStream os(stdout);
os << AsDOT(*graph());
@@ -41,7 +41,7 @@ class ControlEquivalenceTest : public GraphTest {
}
bool IsEquivalenceClass(size_t length, Node** nodes) {
- BitVector in_class(graph()->NodeCount(), zone());
+ BitVector in_class(static_cast<int>(graph()->NodeCount()), zone());
size_t expected_class = classes_[nodes[0]->id()];
for (size_t i = 0; i < length; ++i) {
in_class.Add(nodes[i]->id());
@@ -79,7 +79,7 @@ class ControlEquivalenceTest : public GraphTest {
}
Node* End(Node* control) {
- return Store(graph()->NewNode(common()->End(), control));
+ return Store(graph()->NewNode(common()->End(1), control));
}
private:
diff --git a/deps/v8/test/unittests/compiler/control-flow-optimizer-unittest.cc b/deps/v8/test/unittests/compiler/control-flow-optimizer-unittest.cc
index 190930edac..444f5f5fee 100644
--- a/deps/v8/test/unittests/compiler/control-flow-optimizer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/control-flow-optimizer-unittest.cc
@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "src/compiler/control-flow-optimizer.h"
-#include "src/compiler/js-graph.h"
#include "src/compiler/js-operator.h"
#include "src/compiler/machine-operator.h"
#include "test/unittests/compiler/graph-unittest.h"
@@ -21,28 +20,21 @@ namespace compiler {
class ControlFlowOptimizerTest : public GraphTest {
public:
explicit ControlFlowOptimizerTest(int num_parameters = 3)
- : GraphTest(num_parameters),
- machine_(zone()),
- javascript_(zone()),
- jsgraph_(isolate(), graph(), common(), javascript(), machine()) {}
+ : GraphTest(num_parameters), machine_(zone()), javascript_(zone()) {}
~ControlFlowOptimizerTest() override {}
protected:
void Optimize() {
- ControlFlowOptimizer optimizer(jsgraph(), zone());
+ ControlFlowOptimizer optimizer(graph(), common(), machine(), zone());
optimizer.Optimize();
}
- Node* EmptyFrameState() { return jsgraph()->EmptyFrameState(); }
-
- JSGraph* jsgraph() { return &jsgraph_; }
JSOperatorBuilder* javascript() { return &javascript_; }
MachineOperatorBuilder* machine() { return &machine_; }
private:
MachineOperatorBuilder machine_;
JSOperatorBuilder javascript_;
- JSGraph jsgraph_;
};
@@ -62,7 +54,7 @@ TEST_F(ControlFlowOptimizerTest, BuildSwitch1) {
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* merge =
graph()->NewNode(common()->Merge(3), if_true0, if_true1, if_false1);
- graph()->SetEnd(graph()->NewNode(common()->End(), merge));
+ graph()->SetEnd(graph()->NewNode(common()->End(1), merge));
Optimize();
Capture<Node*> switch_capture;
EXPECT_THAT(end(),
@@ -77,7 +69,7 @@ TEST_F(ControlFlowOptimizerTest, BuildSwitch2) {
Node* input = Parameter(0);
Node* context = Parameter(1);
Node* index = graph()->NewNode(javascript()->ToNumber(), input, context,
- EmptyFrameState(), start(), start());
+ start(), start(), start());
Node* if_success = graph()->NewNode(common()->IfSuccess(), index);
Node* branch0 = graph()->NewNode(
common()->Branch(),
@@ -93,7 +85,7 @@ TEST_F(ControlFlowOptimizerTest, BuildSwitch2) {
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* merge =
graph()->NewNode(common()->Merge(3), if_true0, if_true1, if_false1);
- graph()->SetEnd(graph()->NewNode(common()->End(), merge));
+ graph()->SetEnd(graph()->NewNode(common()->End(1), merge));
Optimize();
Capture<Node*> switch_capture;
EXPECT_THAT(
@@ -119,7 +111,7 @@ TEST_F(ControlFlowOptimizerTest, CloneBranch) {
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
- graph()->SetEnd(graph()->NewNode(common()->End(), merge));
+ graph()->SetEnd(graph()->NewNode(common()->End(1), merge));
Optimize();
Capture<Node*> branch1_capture, branch2_capture;
EXPECT_THAT(
diff --git a/deps/v8/test/unittests/compiler/control-reducer-unittest.cc b/deps/v8/test/unittests/compiler/control-reducer-unittest.cc
deleted file mode 100644
index 2f65caadc3..0000000000
--- a/deps/v8/test/unittests/compiler/control-reducer-unittest.cc
+++ /dev/null
@@ -1,326 +0,0 @@
-// Copyright 2015 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/control-reducer.h"
-#include "src/compiler/diamond.h"
-#include "src/compiler/graph-visualizer.h"
-#include "src/compiler/js-graph.h"
-#include "src/compiler/js-operator.h"
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/node.h"
-#include "test/unittests/compiler/graph-unittest.h"
-#include "test/unittests/compiler/node-test-utils.h"
-#include "testing/gmock-support.h"
-
-using testing::_;
-using testing::AllOf;
-using testing::Capture;
-using testing::CaptureEq;
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class ControlReducerTest : public TypedGraphTest {
- public:
- ControlReducerTest()
- : TypedGraphTest(1),
- machine_(zone()),
- javascript_(zone()),
- jsgraph_(isolate(), graph(), common(), &javascript_, &machine_) {}
-
- protected:
- MachineOperatorBuilder machine_;
- JSOperatorBuilder javascript_;
- JSGraph jsgraph_;
-
- void ReduceGraph(int max_phis_for_select = 0) {
- if (FLAG_trace_turbo_graph) {
- OFStream os(stdout);
- os << "-- Graph before control reduction" << std::endl;
- os << AsRPO(*graph());
- }
- ControlReducer::ReduceGraph(zone(), jsgraph(), max_phis_for_select);
- if (FLAG_trace_turbo_graph) {
- OFStream os(stdout);
- os << "-- Graph after control reduction" << std::endl;
- os << AsRPO(*graph());
- }
- }
-
- JSGraph* jsgraph() { return &jsgraph_; }
-};
-
-
-TEST_F(ControlReducerTest, NonTerminatingLoop) {
- Node* loop = graph()->NewNode(common()->Loop(2), graph()->start());
- loop->AppendInput(graph()->zone(), loop);
- ReduceGraph();
- EXPECT_THAT(
- graph()->end(),
- IsEnd(IsMerge(graph()->start(),
- IsTerminate(graph()->start(),
- AllOf(loop, IsLoop(graph()->start(), loop))))));
-}
-
-
-TEST_F(ControlReducerTest, NonTerminatingLoopWithEffectPhi) {
- Node* loop = graph()->NewNode(common()->Loop(2), graph()->start());
- loop->AppendInput(graph()->zone(), loop);
- Node* ephi = graph()->NewNode(common()->EffectPhi(2), graph()->start());
- ephi->AppendInput(graph()->zone(), ephi);
- ephi->AppendInput(graph()->zone(), loop);
- ReduceGraph();
- EXPECT_THAT(
- graph()->end(),
- IsEnd(IsMerge(
- graph()->start(),
- IsTerminate(AllOf(ephi, IsEffectPhi(graph()->start(), ephi, loop)),
- AllOf(loop, IsLoop(graph()->start(), loop))))));
-}
-
-
-TEST_F(ControlReducerTest, NonTerminatingLoopWithTwoEffectPhis) {
- Node* loop = graph()->NewNode(common()->Loop(2), graph()->start());
- loop->AppendInput(graph()->zone(), loop);
- Node* ephi1 = graph()->NewNode(common()->EffectPhi(2), graph()->start());
- ephi1->AppendInput(graph()->zone(), ephi1);
- ephi1->AppendInput(graph()->zone(), loop);
- Node* ephi2 = graph()->NewNode(common()->EffectPhi(2), graph()->start());
- ephi2->AppendInput(graph()->zone(), ephi2);
- ephi2->AppendInput(graph()->zone(), loop);
- ReduceGraph();
- EXPECT_THAT(
- graph()->end(),
- IsEnd(IsMerge(
- graph()->start(),
- IsTerminate(
- IsEffectSet(
- AllOf(ephi1, IsEffectPhi(graph()->start(), ephi1, loop)),
- AllOf(ephi2, IsEffectPhi(graph()->start(), ephi2, loop))),
- AllOf(loop, IsLoop(graph()->start(), loop))))));
-}
-
-
-TEST_F(ControlReducerTest, NonTerminatingLoopWithDeadEnd) {
- Node* loop = graph()->NewNode(common()->Loop(2), graph()->start());
- loop->AppendInput(graph()->zone(), loop);
- graph()->end()->ReplaceInput(0, graph()->NewNode(common()->Dead()));
- ReduceGraph();
- EXPECT_THAT(graph()->end(),
- IsEnd(IsTerminate(graph()->start(),
- AllOf(loop, IsLoop(graph()->start(), loop)))));
-}
-
-
-TEST_F(ControlReducerTest, PhiAsInputToBranch_true) {
- Node* p0 = Parameter(0);
- Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start());
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
- Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
- Node* phi1 = graph()->NewNode(common()->Phi(kMachInt32, 2),
- jsgraph()->Int32Constant(1),
- jsgraph()->Int32Constant(2), merge1);
-
- Node* branch2 = graph()->NewNode(common()->Branch(), phi1, merge1);
- Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
- Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
- Node* merge2 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
- Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2),
- jsgraph()->Int32Constant(11),
- jsgraph()->Int32Constant(22), merge2);
-
- Node* ret =
- graph()->NewNode(common()->Return(), result, graph()->start(), merge2);
- graph()->end()->ReplaceInput(0, ret);
-
- ReduceGraph();
-
- // First diamond is not reduced.
- EXPECT_THAT(merge1, IsMerge(IsIfTrue(branch1), IsIfFalse(branch1)));
-
- // Second diamond should be folded away.
- EXPECT_THAT(graph()->end(),
- IsEnd(IsReturn(IsInt32Constant(11), graph()->start(), merge1)));
-}
-
-
-TEST_F(ControlReducerTest, PhiAsInputToBranch_false) {
- Node* p0 = Parameter(0);
- Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start());
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
- Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
- Node* phi1 = graph()->NewNode(common()->Phi(kMachInt32, 2),
- jsgraph()->Int32Constant(0),
- jsgraph()->BooleanConstant(false), merge1);
-
- Node* branch2 = graph()->NewNode(common()->Branch(), phi1, merge1);
- Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
- Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
- Node* merge2 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
- Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2),
- jsgraph()->Int32Constant(11),
- jsgraph()->Int32Constant(22), merge2);
-
- Node* ret =
- graph()->NewNode(common()->Return(), result, graph()->start(), merge2);
- graph()->end()->ReplaceInput(0, ret);
-
- ReduceGraph();
-
- // First diamond is not reduced.
- EXPECT_THAT(merge1, IsMerge(IsIfTrue(branch1), IsIfFalse(branch1)));
-
- // Second diamond should be folded away.
- EXPECT_THAT(graph()->end(),
- IsEnd(IsReturn(IsInt32Constant(22), graph()->start(), merge1)));
-}
-
-
-TEST_F(ControlReducerTest, PhiAsInputToBranch_unknown_true) {
- Node* p0 = Parameter(0);
- Node* phi0 = graph()->NewNode(common()->Phi(kMachInt32, 2), p0,
- jsgraph()->Int32Constant(1), graph()->start());
- Node* branch1 = graph()->NewNode(common()->Branch(), phi0, graph()->start());
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
- Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
- Node* phi1 = graph()->NewNode(common()->Phi(kMachInt32, 2),
- jsgraph()->Int32Constant(111),
- jsgraph()->Int32Constant(222), merge1);
-
- Node* ret =
- graph()->NewNode(common()->Return(), phi1, graph()->start(), merge1);
- graph()->end()->ReplaceInput(0, ret);
-
- ReduceGraph();
-
- // Branch should not be folded.
- EXPECT_THAT(phi1,
- IsPhi(kMachInt32, IsInt32Constant(111), IsInt32Constant(222),
- IsMerge(IsIfTrue(branch1), IsIfFalse(branch1))));
- EXPECT_THAT(graph()->end(), IsEnd(IsReturn(phi1, graph()->start(), merge1)));
-}
-
-
-TEST_F(ControlReducerTest, RangeAsInputToBranch_true1) {
- Node* p0 = Parameter(Type::Range(1, 2, zone()), 0);
- Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start());
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
- Node* merge1 = graph()->NewNode(common()->Merge(1), if_true1, if_false1);
- Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2),
- jsgraph()->Int32Constant(11),
- jsgraph()->Int32Constant(44), merge1);
-
- Node* ret =
- graph()->NewNode(common()->Return(), result, graph()->start(), merge1);
- graph()->end()->ReplaceInput(0, ret);
-
- ReduceGraph();
-
- // Diamond should be folded away.
- EXPECT_THAT(
- graph()->end(),
- IsEnd(IsReturn(IsInt32Constant(11), graph()->start(), graph()->start())));
-}
-
-
-TEST_F(ControlReducerTest, RangeAsInputToBranch_true2) {
- Node* p0 = Parameter(Type::Range(-2, -1, zone()), 0);
- Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start());
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
- Node* merge1 = graph()->NewNode(common()->Merge(1), if_true1, if_false1);
- Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2),
- jsgraph()->Int32Constant(11),
- jsgraph()->Int32Constant(44), merge1);
-
- Node* ret =
- graph()->NewNode(common()->Return(), result, graph()->start(), merge1);
- graph()->end()->ReplaceInput(0, ret);
-
- ReduceGraph();
-
- // Diamond should be folded away.
- EXPECT_THAT(
- graph()->end(),
- IsEnd(IsReturn(IsInt32Constant(11), graph()->start(), graph()->start())));
-}
-
-
-TEST_F(ControlReducerTest, SelectPhi) {
- Node* p0 = Parameter(0);
- const MachineType kType = kMachInt32;
- Diamond d(graph(), common(), p0);
- Node* phi =
- d.Phi(kType, jsgraph()->Int32Constant(1), jsgraph()->Int32Constant(2));
-
- Node* ret =
- graph()->NewNode(common()->Return(), phi, graph()->start(), d.merge);
- graph()->end()->ReplaceInput(0, ret);
-
- ReduceGraph(1);
-
- // Phi should be replaced with a select.
- EXPECT_THAT(graph()->end(),
- IsEnd(IsReturn(
- IsSelect(kType, p0, IsInt32Constant(1), IsInt32Constant(2)),
- graph()->start(), graph()->start())));
-}
-
-
-TEST_F(ControlReducerTest, SelectPhis_fail) {
- Node* p0 = Parameter(0);
- const MachineType kType = kMachInt32;
- Diamond d(graph(), common(), p0);
- Node* phi =
- d.Phi(kType, jsgraph()->Int32Constant(1), jsgraph()->Int32Constant(2));
- Node* phi2 =
- d.Phi(kType, jsgraph()->Int32Constant(11), jsgraph()->Int32Constant(22));
- USE(phi2);
- Node* ret =
- graph()->NewNode(common()->Return(), phi, graph()->start(), d.merge);
- graph()->end()->ReplaceInput(0, ret);
-
- ReduceGraph(1);
-
- // Diamond should not be replaced with a select (too many phis).
- EXPECT_THAT(ret, IsReturn(phi, graph()->start(), d.merge));
- EXPECT_THAT(graph()->end(), IsEnd(ret));
-}
-
-
-TEST_F(ControlReducerTest, SelectTwoPhis) {
- Node* p0 = Parameter(0);
- const MachineType kType = kMachInt32;
- Diamond d(graph(), common(), p0);
- Node* phi1 =
- d.Phi(kType, jsgraph()->Int32Constant(1), jsgraph()->Int32Constant(2));
- Node* phi2 =
- d.Phi(kType, jsgraph()->Int32Constant(2), jsgraph()->Int32Constant(3));
- MachineOperatorBuilder machine(zone());
- Node* add = graph()->NewNode(machine.Int32Add(), phi1, phi2);
- Node* ret =
- graph()->NewNode(common()->Return(), add, graph()->start(), d.merge);
- graph()->end()->ReplaceInput(0, ret);
-
- ReduceGraph(2);
-
- // Phis should be replaced with two selects.
- EXPECT_THAT(
- ret,
- IsReturn(IsInt32Add(
- IsSelect(kType, p0, IsInt32Constant(1), IsInt32Constant(2)),
- IsSelect(kType, p0, IsInt32Constant(2), IsInt32Constant(3))),
- graph()->start(), graph()->start()));
- EXPECT_THAT(graph()->end(), IsEnd(ret));
-}
-
-
-} // namespace compiler
-} // namespace internal
-} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/dead-code-elimination-unittest.cc b/deps/v8/test/unittests/compiler/dead-code-elimination-unittest.cc
new file mode 100644
index 0000000000..8284fd8775
--- /dev/null
+++ b/deps/v8/test/unittests/compiler/dead-code-elimination-unittest.cc
@@ -0,0 +1,375 @@
+// Copyright 2015 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/common-operator.h"
+#include "src/compiler/dead-code-elimination.h"
+#include "test/unittests/compiler/graph-reducer-unittest.h"
+#include "test/unittests/compiler/graph-unittest.h"
+#include "test/unittests/compiler/node-test-utils.h"
+#include "testing/gmock-support.h"
+
+using testing::StrictMock;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class DeadCodeEliminationTest : public GraphTest {
+ public:
+ explicit DeadCodeEliminationTest(int num_parameters = 4)
+ : GraphTest(num_parameters) {}
+ ~DeadCodeEliminationTest() override {}
+
+ protected:
+ Reduction Reduce(AdvancedReducer::Editor* editor, Node* node) {
+ DeadCodeElimination reducer(editor, graph(), common());
+ return reducer.Reduce(node);
+ }
+
+ Reduction Reduce(Node* node) {
+ StrictMock<MockAdvancedReducerEditor> editor;
+ return Reduce(&editor, node);
+ }
+};
+
+
+namespace {
+
+const MachineType kMachineTypes[] = {
+ kMachFloat32, kMachFloat64, kMachInt8, kMachUint8, kMachInt16,
+ kMachUint16, kMachInt32, kMachUint32, kMachInt64, kMachUint64,
+ kMachPtr, kMachAnyTagged, kRepBit, kRepWord8, kRepWord16,
+ kRepWord32, kRepWord64, kRepFloat32, kRepFloat64, kRepTagged};
+
+
+const int kMaxInputs = 16;
+
+
+const Operator kOp0(0, Operator::kNoProperties, "Op0", 1, 1, 1, 1, 1, 1);
+
+} // namespace
+
+
+// -----------------------------------------------------------------------------
+// General dead propagation
+
+
+TEST_F(DeadCodeEliminationTest, GeneralDeadPropagation) {
+ Node* const value = Parameter(0);
+ Node* const effect = graph()->start();
+ Node* const dead = graph()->NewNode(common()->Dead());
+ Node* const node = graph()->NewNode(&kOp0, value, effect, dead);
+ Reduction const r = Reduce(node);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+}
+
+
+// -----------------------------------------------------------------------------
+// Branch
+
+
+TEST_F(DeadCodeEliminationTest, BranchWithDeadControlInput) {
+ BranchHint const kHints[] = {BranchHint::kNone, BranchHint::kTrue,
+ BranchHint::kFalse};
+ TRACED_FOREACH(BranchHint, hint, kHints) {
+ Reduction const r =
+ Reduce(graph()->NewNode(common()->Branch(hint), Parameter(0),
+ graph()->NewNode(common()->Dead())));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+// IfTrue
+
+
+TEST_F(DeadCodeEliminationTest, IfTrueWithDeadInput) {
+ Reduction const r = Reduce(
+ graph()->NewNode(common()->IfTrue(), graph()->NewNode(common()->Dead())));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+}
+
+
+// -----------------------------------------------------------------------------
+// IfFalse
+
+
+TEST_F(DeadCodeEliminationTest, IfFalseWithDeadInput) {
+ Reduction const r = Reduce(graph()->NewNode(
+ common()->IfFalse(), graph()->NewNode(common()->Dead())));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+}
+
+
+// -----------------------------------------------------------------------------
+// IfSuccess
+
+
+TEST_F(DeadCodeEliminationTest, IfSuccessWithDeadInput) {
+ Reduction const r = Reduce(graph()->NewNode(
+ common()->IfSuccess(), graph()->NewNode(common()->Dead())));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+}
+
+
+// -----------------------------------------------------------------------------
+// IfException
+
+
+TEST_F(DeadCodeEliminationTest, IfExceptionWithDeadControlInput) {
+ IfExceptionHint const kHints[] = {IfExceptionHint::kLocallyCaught,
+ IfExceptionHint::kLocallyUncaught};
+ TRACED_FOREACH(IfExceptionHint, hint, kHints) {
+ Reduction const r =
+ Reduce(graph()->NewNode(common()->IfException(hint), graph()->start(),
+ graph()->NewNode(common()->Dead())));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+// End
+
+
+TEST_F(DeadCodeEliminationTest, EndWithDeadAndStart) {
+ Node* const dead = graph()->NewNode(common()->Dead());
+ Node* const start = graph()->start();
+ Reduction const r = Reduce(graph()->NewNode(common()->End(2), dead, start));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsEnd(start));
+}
+
+
+TEST_F(DeadCodeEliminationTest, EndWithOnlyDeadInputs) {
+ Node* inputs[kMaxInputs];
+ TRACED_FORRANGE(int, input_count, 1, kMaxInputs - 1) {
+ for (int i = 0; i < input_count; ++i) {
+ inputs[i] = graph()->NewNode(common()->Dead());
+ }
+ Reduction const r = Reduce(
+ graph()->NewNode(common()->End(input_count), input_count, inputs));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+// Merge
+
+
+TEST_F(DeadCodeEliminationTest, MergeWithOnlyDeadInputs) {
+ Node* inputs[kMaxInputs + 1];
+ TRACED_FORRANGE(int, input_count, 1, kMaxInputs - 1) {
+ for (int i = 0; i < input_count; ++i) {
+ inputs[i] = graph()->NewNode(common()->Dead());
+ }
+ Reduction const r = Reduce(
+ graph()->NewNode(common()->Merge(input_count), input_count, inputs));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+}
+
+
+TEST_F(DeadCodeEliminationTest, MergeWithOneLiveAndOneDeadInput) {
+ Node* const v0 = Parameter(0);
+ Node* const v1 = Parameter(1);
+ Node* const c0 =
+ graph()->NewNode(&kOp0, v0, graph()->start(), graph()->start());
+ Node* const c1 = graph()->NewNode(common()->Dead());
+ Node* const e0 = graph()->NewNode(&kOp0, v0, graph()->start(), c0);
+ Node* const e1 = graph()->NewNode(&kOp0, v1, graph()->start(), c1);
+ Node* const merge = graph()->NewNode(common()->Merge(2), c0, c1);
+ Node* const phi =
+ graph()->NewNode(common()->Phi(kMachAnyTagged, 2), v0, v1, merge);
+ Node* const ephi = graph()->NewNode(common()->EffectPhi(2), e0, e1, merge);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Replace(phi, v0));
+ EXPECT_CALL(editor, Replace(ephi, e0));
+ Reduction const r = Reduce(&editor, merge);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(c0, r.replacement());
+}
+
+
+TEST_F(DeadCodeEliminationTest, MergeWithTwoLiveAndTwoDeadInputs) {
+ Node* const v0 = Parameter(0);
+ Node* const v1 = Parameter(1);
+ Node* const v2 = Parameter(2);
+ Node* const v3 = Parameter(3);
+ Node* const c0 =
+ graph()->NewNode(&kOp0, v0, graph()->start(), graph()->start());
+ Node* const c1 = graph()->NewNode(common()->Dead());
+ Node* const c2 = graph()->NewNode(common()->Dead());
+ Node* const c3 = graph()->NewNode(&kOp0, v3, graph()->start(), c0);
+ Node* const e0 = graph()->start();
+ Node* const e1 = graph()->NewNode(&kOp0, v1, e0, c0);
+ Node* const e2 = graph()->NewNode(&kOp0, v2, e1, c0);
+ Node* const e3 = graph()->NewNode(&kOp0, v3, graph()->start(), c3);
+ Node* const merge = graph()->NewNode(common()->Merge(4), c0, c1, c2, c3);
+ Node* const phi =
+ graph()->NewNode(common()->Phi(kMachAnyTagged, 4), v0, v1, v2, v3, merge);
+ Node* const ephi =
+ graph()->NewNode(common()->EffectPhi(4), e0, e1, e2, e3, merge);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Revisit(phi));
+ EXPECT_CALL(editor, Revisit(ephi));
+ Reduction const r = Reduce(&editor, merge);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsMerge(c0, c3));
+ EXPECT_THAT(phi, IsPhi(kMachAnyTagged, v0, v3, r.replacement()));
+ EXPECT_THAT(ephi, IsEffectPhi(e0, e3, r.replacement()));
+}
+
+
+// -----------------------------------------------------------------------------
+// Loop
+
+
+TEST_F(DeadCodeEliminationTest, LoopWithDeadFirstInput) {
+ Node* inputs[kMaxInputs + 1];
+ TRACED_FORRANGE(int, input_count, 1, kMaxInputs - 1) {
+ inputs[0] = graph()->NewNode(common()->Dead());
+ for (int i = 1; i < input_count; ++i) {
+ inputs[i] = graph()->start();
+ }
+ Reduction const r = Reduce(
+ graph()->NewNode(common()->Loop(input_count), input_count, inputs));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+}
+
+
+TEST_F(DeadCodeEliminationTest, LoopWithOnlyDeadInputs) {
+ Node* inputs[kMaxInputs + 1];
+ TRACED_FORRANGE(int, input_count, 1, kMaxInputs - 1) {
+ for (int i = 0; i < input_count; ++i) {
+ inputs[i] = graph()->NewNode(common()->Dead());
+ }
+ Reduction const r = Reduce(
+ graph()->NewNode(common()->Loop(input_count), input_count, inputs));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+}
+
+
+TEST_F(DeadCodeEliminationTest, LoopWithOneLiveAndOneDeadInput) {
+ Node* const v0 = Parameter(0);
+ Node* const v1 = Parameter(1);
+ Node* const c0 =
+ graph()->NewNode(&kOp0, v0, graph()->start(), graph()->start());
+ Node* const c1 = graph()->NewNode(common()->Dead());
+ Node* const e0 = graph()->NewNode(&kOp0, v0, graph()->start(), c0);
+ Node* const e1 = graph()->NewNode(&kOp0, v1, graph()->start(), c1);
+ Node* const loop = graph()->NewNode(common()->Loop(2), c0, c1);
+ Node* const phi =
+ graph()->NewNode(common()->Phi(kMachAnyTagged, 2), v0, v1, loop);
+ Node* const ephi = graph()->NewNode(common()->EffectPhi(2), e0, e1, loop);
+ Node* const terminate = graph()->NewNode(common()->Terminate(), ephi, loop);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Replace(phi, v0));
+ EXPECT_CALL(editor, Replace(ephi, e0));
+ EXPECT_CALL(editor, Replace(terminate, IsDead()));
+ Reduction const r = Reduce(&editor, loop);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(c0, r.replacement());
+}
+
+
+TEST_F(DeadCodeEliminationTest, LoopWithTwoLiveAndTwoDeadInputs) {
+ Node* const v0 = Parameter(0);
+ Node* const v1 = Parameter(1);
+ Node* const v2 = Parameter(2);
+ Node* const v3 = Parameter(3);
+ Node* const c0 =
+ graph()->NewNode(&kOp0, v0, graph()->start(), graph()->start());
+ Node* const c1 = graph()->NewNode(common()->Dead());
+ Node* const c2 = graph()->NewNode(common()->Dead());
+ Node* const c3 = graph()->NewNode(&kOp0, v3, graph()->start(), c0);
+ Node* const e0 = graph()->start();
+ Node* const e1 = graph()->NewNode(&kOp0, v1, e0, c0);
+ Node* const e2 = graph()->NewNode(&kOp0, v2, e1, c0);
+ Node* const e3 = graph()->NewNode(&kOp0, v3, graph()->start(), c3);
+ Node* const loop = graph()->NewNode(common()->Loop(4), c0, c1, c2, c3);
+ Node* const phi =
+ graph()->NewNode(common()->Phi(kMachAnyTagged, 4), v0, v1, v2, v3, loop);
+ Node* const ephi =
+ graph()->NewNode(common()->EffectPhi(4), e0, e1, e2, e3, loop);
+ StrictMock<MockAdvancedReducerEditor> editor;
+ EXPECT_CALL(editor, Revisit(phi));
+ EXPECT_CALL(editor, Revisit(ephi));
+ Reduction const r = Reduce(&editor, loop);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsLoop(c0, c3));
+ EXPECT_THAT(phi, IsPhi(kMachAnyTagged, v0, v3, r.replacement()));
+ EXPECT_THAT(ephi, IsEffectPhi(e0, e3, r.replacement()));
+}
+
+
+// -----------------------------------------------------------------------------
+// Phi
+
+
+TEST_F(DeadCodeEliminationTest, PhiWithDeadControlInput) {
+ Node* inputs[kMaxInputs + 1];
+ TRACED_FOREACH(MachineType, type, kMachineTypes) {
+ TRACED_FORRANGE(int, input_count, 1, kMaxInputs) {
+ for (int i = 0; i < input_count; ++i) {
+ inputs[i] = Parameter(i);
+ }
+ inputs[input_count] = graph()->NewNode(common()->Dead());
+ Reduction const r = Reduce(graph()->NewNode(
+ common()->Phi(type, input_count), input_count + 1, inputs));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+// EffectPhi
+
+
+TEST_F(DeadCodeEliminationTest, EffectPhiWithDeadControlInput) {
+ Node* inputs[kMaxInputs + 1];
+ TRACED_FORRANGE(int, input_count, 1, kMaxInputs) {
+ for (int i = 0; i < input_count; ++i) {
+ inputs[i] = graph()->start();
+ }
+ inputs[input_count] = graph()->NewNode(common()->Dead());
+ Reduction const r = Reduce(graph()->NewNode(
+ common()->EffectPhi(input_count), input_count + 1, inputs));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+// Terminate
+
+
+TEST_F(DeadCodeEliminationTest, TerminateWithDeadControlInput) {
+ Reduction const r =
+ Reduce(graph()->NewNode(common()->Terminate(), graph()->start(),
+ graph()->NewNode(common()->Dead())));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsDead());
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/graph-reducer-unittest.cc b/deps/v8/test/unittests/compiler/graph-reducer-unittest.cc
index ea981ccaf3..3ca6052af9 100644
--- a/deps/v8/test/unittests/compiler/graph-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/graph-reducer-unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
#include "src/compiler/node.h"
#include "src/compiler/operator.h"
@@ -10,9 +11,11 @@
using testing::_;
using testing::DefaultValue;
+using testing::ElementsAre;
using testing::Return;
using testing::Sequence;
using testing::StrictMock;
+using testing::UnorderedElementsAre;
namespace v8 {
namespace internal {
@@ -264,6 +267,124 @@ TEST_F(AdvancedReducerTest, Revisit) {
}
+namespace {
+
+struct ReplaceWithValueReducer final : public AdvancedReducer {
+ explicit ReplaceWithValueReducer(Editor* editor) : AdvancedReducer(editor) {}
+ Reduction Reduce(Node* node) final { return NoChange(); }
+ using AdvancedReducer::ReplaceWithValue;
+};
+
+const Operator kMockOperator(IrOpcode::kDead, Operator::kNoProperties,
+ "MockOperator", 0, 0, 0, 1, 0, 0);
+const Operator kMockOpEffect(IrOpcode::kDead, Operator::kNoProperties,
+ "MockOpEffect", 0, 1, 0, 1, 1, 0);
+const Operator kMockOpControl(IrOpcode::kDead, Operator::kNoProperties,
+ "MockOpControl", 0, 0, 1, 1, 0, 1);
+
+const IfExceptionHint kNoHint = IfExceptionHint::kLocallyCaught;
+
+} // namespace
+
+
+TEST_F(AdvancedReducerTest, ReplaceWithValue_ValueUse) {
+ CommonOperatorBuilder common(zone());
+ Node* node = graph()->NewNode(&kMockOperator);
+ Node* use_value = graph()->NewNode(common.Return(), node);
+ Node* replacement = graph()->NewNode(&kMockOperator);
+ GraphReducer graph_reducer(zone(), graph(), nullptr);
+ ReplaceWithValueReducer r(&graph_reducer);
+ r.ReplaceWithValue(node, replacement);
+ EXPECT_EQ(replacement, use_value->InputAt(0));
+ EXPECT_EQ(0, node->UseCount());
+ EXPECT_EQ(1, replacement->UseCount());
+ EXPECT_THAT(replacement->uses(), ElementsAre(use_value));
+}
+
+
+TEST_F(AdvancedReducerTest, ReplaceWithValue_EffectUse) {
+ CommonOperatorBuilder common(zone());
+ Node* start = graph()->NewNode(common.Start(1));
+ Node* node = graph()->NewNode(&kMockOpEffect, start);
+ Node* use_effect = graph()->NewNode(common.EffectPhi(1), node);
+ Node* replacement = graph()->NewNode(&kMockOperator);
+ GraphReducer graph_reducer(zone(), graph(), nullptr);
+ ReplaceWithValueReducer r(&graph_reducer);
+ r.ReplaceWithValue(node, replacement);
+ EXPECT_EQ(start, use_effect->InputAt(0));
+ EXPECT_EQ(0, node->UseCount());
+ EXPECT_EQ(2, start->UseCount());
+ EXPECT_EQ(0, replacement->UseCount());
+ EXPECT_THAT(start->uses(), UnorderedElementsAre(use_effect, node));
+}
+
+
+TEST_F(AdvancedReducerTest, ReplaceWithValue_ControlUse1) {
+ CommonOperatorBuilder common(zone());
+ Node* start = graph()->NewNode(common.Start(1));
+ Node* node = graph()->NewNode(&kMockOpControl, start);
+ Node* success = graph()->NewNode(common.IfSuccess(), node);
+ Node* use_control = graph()->NewNode(common.Merge(1), success);
+ Node* replacement = graph()->NewNode(&kMockOperator);
+ GraphReducer graph_reducer(zone(), graph(), nullptr);
+ ReplaceWithValueReducer r(&graph_reducer);
+ r.ReplaceWithValue(node, replacement);
+ EXPECT_EQ(start, use_control->InputAt(0));
+ EXPECT_EQ(0, node->UseCount());
+ EXPECT_EQ(2, start->UseCount());
+ EXPECT_EQ(0, replacement->UseCount());
+ EXPECT_THAT(start->uses(), UnorderedElementsAre(use_control, node));
+}
+
+
+TEST_F(AdvancedReducerTest, ReplaceWithValue_ControlUse2) {
+ CommonOperatorBuilder common(zone());
+ Node* start = graph()->NewNode(common.Start(1));
+ Node* effect = graph()->NewNode(&kMockOperator);
+ Node* dead = graph()->NewNode(&kMockOperator);
+ Node* node = graph()->NewNode(&kMockOpControl, start);
+ Node* success = graph()->NewNode(common.IfSuccess(), node);
+ Node* exception = graph()->NewNode(common.IfException(kNoHint), effect, node);
+ Node* use_control = graph()->NewNode(common.Merge(1), success);
+ Node* replacement = graph()->NewNode(&kMockOperator);
+ GraphReducer graph_reducer(zone(), graph(), dead);
+ ReplaceWithValueReducer r(&graph_reducer);
+ r.ReplaceWithValue(node, replacement);
+ EXPECT_EQ(start, use_control->InputAt(0));
+ EXPECT_EQ(dead, exception->InputAt(1));
+ EXPECT_EQ(0, node->UseCount());
+ EXPECT_EQ(2, start->UseCount());
+ EXPECT_EQ(1, dead->UseCount());
+ EXPECT_EQ(0, replacement->UseCount());
+ EXPECT_THAT(start->uses(), UnorderedElementsAre(use_control, node));
+ EXPECT_THAT(dead->uses(), ElementsAre(exception));
+}
+
+
+TEST_F(AdvancedReducerTest, ReplaceWithValue_ControlUse3) {
+ CommonOperatorBuilder common(zone());
+ Node* start = graph()->NewNode(common.Start(1));
+ Node* effect = graph()->NewNode(&kMockOperator);
+ Node* dead = graph()->NewNode(&kMockOperator);
+ Node* node = graph()->NewNode(&kMockOpControl, start);
+ Node* success = graph()->NewNode(common.IfSuccess(), node);
+ Node* exception = graph()->NewNode(common.IfException(kNoHint), effect, node);
+ Node* use_control = graph()->NewNode(common.Merge(1), success);
+ Node* replacement = graph()->NewNode(&kMockOperator);
+ GraphReducer graph_reducer(zone(), graph(), dead);
+ ReplaceWithValueReducer r(&graph_reducer);
+ r.ReplaceWithValue(node, replacement);
+ EXPECT_EQ(start, use_control->InputAt(0));
+ EXPECT_EQ(dead, exception->InputAt(1));
+ EXPECT_EQ(0, node->UseCount());
+ EXPECT_EQ(2, start->UseCount());
+ EXPECT_EQ(1, dead->UseCount());
+ EXPECT_EQ(0, replacement->UseCount());
+ EXPECT_THAT(start->uses(), UnorderedElementsAre(use_control, node));
+ EXPECT_THAT(dead->uses(), ElementsAre(exception));
+}
+
+
class GraphReducerTest : public TestWithZone {
public:
GraphReducerTest() : graph_(zone()) {}
@@ -280,20 +401,20 @@ class GraphReducerTest : public TestWithZone {
protected:
void ReduceNode(Node* node, Reducer* r) {
- GraphReducer reducer(graph(), zone());
+ GraphReducer reducer(zone(), graph());
reducer.AddReducer(r);
reducer.ReduceNode(node);
}
void ReduceNode(Node* node, Reducer* r1, Reducer* r2) {
- GraphReducer reducer(graph(), zone());
+ GraphReducer reducer(zone(), graph());
reducer.AddReducer(r1);
reducer.AddReducer(r2);
reducer.ReduceNode(node);
}
void ReduceNode(Node* node, Reducer* r1, Reducer* r2, Reducer* r3) {
- GraphReducer reducer(graph(), zone());
+ GraphReducer reducer(zone(), graph());
reducer.AddReducer(r1);
reducer.AddReducer(r2);
reducer.AddReducer(r3);
@@ -301,20 +422,20 @@ class GraphReducerTest : public TestWithZone {
}
void ReduceGraph(Reducer* r1) {
- GraphReducer reducer(graph(), zone());
+ GraphReducer reducer(zone(), graph());
reducer.AddReducer(r1);
reducer.ReduceGraph();
}
void ReduceGraph(Reducer* r1, Reducer* r2) {
- GraphReducer reducer(graph(), zone());
+ GraphReducer reducer(zone(), graph());
reducer.AddReducer(r1);
reducer.AddReducer(r2);
reducer.ReduceGraph();
}
void ReduceGraph(Reducer* r1, Reducer* r2, Reducer* r3) {
- GraphReducer reducer(graph(), zone());
+ GraphReducer reducer(zone(), graph());
reducer.AddReducer(r1);
reducer.AddReducer(r2);
reducer.AddReducer(r3);
@@ -401,7 +522,7 @@ TEST_F(GraphReducerTest, ReduceInPlace1) {
// Tests A* => B* with in-place updates.
InPlaceABReducer r;
for (int i = 0; i < 3; i++) {
- int before = graph()->NodeCount();
+ size_t before = graph()->NodeCount();
ReduceGraph(&r);
EXPECT_EQ(before, graph()->NodeCount());
EXPECT_EQ(&kOpB0, n1->op());
@@ -421,7 +542,7 @@ TEST_F(GraphReducerTest, ReduceInPlace2) {
// Tests A* => B* with in-place updates.
InPlaceABReducer r;
for (int i = 0; i < 3; i++) {
- int before = graph()->NodeCount();
+ size_t before = graph()->NodeCount();
ReduceGraph(&r);
EXPECT_EQ(before, graph()->NodeCount());
EXPECT_EQ(&kOpB0, n1->op());
@@ -446,7 +567,7 @@ TEST_F(GraphReducerTest, ReduceNew1) {
NewABReducer r(graph());
// Tests A* => B* while creating new nodes.
for (int i = 0; i < 3; i++) {
- int before = graph()->NodeCount();
+ size_t before = graph()->NodeCount();
ReduceGraph(&r);
if (i == 0) {
EXPECT_NE(before, graph()->NodeCount());
@@ -473,12 +594,12 @@ TEST_F(GraphReducerTest, ReduceNew1) {
TEST_F(GraphReducerTest, Wrapping1) {
Node* end = graph()->NewNode(&kOpA0);
graph()->SetEnd(end);
- EXPECT_EQ(1, graph()->NodeCount());
+ EXPECT_EQ(1U, graph()->NodeCount());
A0Wrapper r(graph());
ReduceGraph(&r);
- EXPECT_EQ(2, graph()->NodeCount());
+ EXPECT_EQ(2U, graph()->NodeCount());
Node* nend = graph()->end();
EXPECT_NE(end, nend);
@@ -491,12 +612,12 @@ TEST_F(GraphReducerTest, Wrapping1) {
TEST_F(GraphReducerTest, Wrapping2) {
Node* end = graph()->NewNode(&kOpB0);
graph()->SetEnd(end);
- EXPECT_EQ(1, graph()->NodeCount());
+ EXPECT_EQ(1U, graph()->NodeCount());
B0Wrapper r(graph());
ReduceGraph(&r);
- EXPECT_EQ(3, graph()->NodeCount());
+ EXPECT_EQ(3U, graph()->NodeCount());
Node* nend = graph()->end();
EXPECT_NE(end, nend);
@@ -520,7 +641,7 @@ TEST_F(GraphReducerTest, Forwarding1) {
// Tests A1(x) => x
for (int i = 0; i < 3; i++) {
- int before = graph()->NodeCount();
+ size_t before = graph()->NodeCount();
ReduceGraph(&r);
EXPECT_EQ(before, graph()->NodeCount());
EXPECT_EQ(&kOpA0, n1->op());
@@ -540,7 +661,7 @@ TEST_F(GraphReducerTest, Forwarding2) {
// Tests reducing A2(A1(x), A1(y)) => A2(x, y).
for (int i = 0; i < 3; i++) {
- int before = graph()->NodeCount();
+ size_t before = graph()->NodeCount();
ReduceGraph(&r);
EXPECT_EQ(before, graph()->NodeCount());
EXPECT_EQ(&kOpA0, n1->op());
@@ -565,8 +686,8 @@ TEST_F(GraphReducerTest, Forwarding3) {
A1Forwarder r;
- for (int i = 0; i < 3; i++) {
- int before = graph()->NodeCount();
+ for (size_t i = 0; i < 3; i++) {
+ size_t before = graph()->NodeCount();
ReduceGraph(&r);
EXPECT_EQ(before, graph()->NodeCount());
EXPECT_EQ(&kOpA0, n1->op());
@@ -587,8 +708,8 @@ TEST_F(GraphReducerTest, ReduceForward1) {
B1Forwarder f;
// Tests first reducing A => B, then B1(x) => x.
- for (int i = 0; i < 3; i++) {
- int before = graph()->NodeCount();
+ for (size_t i = 0; i < 3; i++) {
+ size_t before = graph()->NodeCount();
ReduceGraph(&r, &f);
EXPECT_EQ(before, graph()->NodeCount());
EXPECT_EQ(&kOpB0, n1->op());
@@ -620,7 +741,7 @@ TEST_F(GraphReducerTest, Sorter1) {
graph()->SetEnd(end);
- int before = graph()->NodeCount();
+ size_t before = graph()->NodeCount();
ReduceGraph(&r);
EXPECT_EQ(before, graph()->NodeCount());
EXPECT_EQ(&kOpA0, n1->op());
@@ -715,8 +836,8 @@ TEST_F(GraphReducerTest, Order) {
InPlaceBCReducer bcr;
// Tests A* => C* with in-place updates.
- for (int j = 0; j < 3; j++) {
- int before = graph()->NodeCount();
+ for (size_t j = 0; j < 3; j++) {
+ size_t before = graph()->NodeCount();
if (i == 0) {
ReduceGraph(&abr, &bcr);
} else {
diff --git a/deps/v8/test/unittests/compiler/graph-reducer-unittest.h b/deps/v8/test/unittests/compiler/graph-reducer-unittest.h
index 4cde964709..2b0651da13 100644
--- a/deps/v8/test/unittests/compiler/graph-reducer-unittest.h
+++ b/deps/v8/test/unittests/compiler/graph-reducer-unittest.h
@@ -15,6 +15,7 @@ namespace compiler {
struct MockAdvancedReducerEditor : public AdvancedReducer::Editor {
MOCK_METHOD1(Revisit, void(Node*));
MOCK_METHOD2(Replace, void(Node*, Node*));
+ MOCK_METHOD4(ReplaceWithValue, void(Node*, Node*, Node*, Node*));
};
} // namespace compiler
diff --git a/deps/v8/test/unittests/compiler/graph-trimmer-unittest.cc b/deps/v8/test/unittests/compiler/graph-trimmer-unittest.cc
new file mode 100644
index 0000000000..36892e6ee8
--- /dev/null
+++ b/deps/v8/test/unittests/compiler/graph-trimmer-unittest.cc
@@ -0,0 +1,85 @@
+// Copyright 2015 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/graph-trimmer.h"
+#include "test/unittests/compiler/graph-unittest.h"
+#include "testing/gmock-support.h"
+
+using testing::ElementsAre;
+using testing::UnorderedElementsAre;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class GraphTrimmerTest : public GraphTest {
+ public:
+ GraphTrimmerTest() : GraphTest(1) {}
+
+ protected:
+ void TrimGraph(Node* root) {
+ Node* const roots[1] = {root};
+ GraphTrimmer trimmer(zone(), graph());
+ trimmer.TrimGraph(&roots[0], &roots[arraysize(roots)]);
+ }
+ void TrimGraph() {
+ GraphTrimmer trimmer(zone(), graph());
+ trimmer.TrimGraph();
+ }
+};
+
+
+namespace {
+
+const Operator kDead0(IrOpcode::kDead, Operator::kNoProperties, "Dead0", 0, 0,
+ 1, 0, 0, 0);
+const Operator kLive0(IrOpcode::kDead, Operator::kNoProperties, "Live0", 0, 0,
+ 1, 0, 0, 1);
+
+} // namespace
+
+
+TEST_F(GraphTrimmerTest, Empty) {
+ Node* const start = graph()->NewNode(common()->Start(0));
+ Node* const end = graph()->NewNode(common()->End(1), start);
+ graph()->SetStart(start);
+ graph()->SetEnd(end);
+ TrimGraph();
+ EXPECT_EQ(end, graph()->end());
+ EXPECT_EQ(start, graph()->start());
+ EXPECT_EQ(start, end->InputAt(0));
+}
+
+
+TEST_F(GraphTrimmerTest, DeadUseOfStart) {
+ Node* const dead0 = graph()->NewNode(&kDead0, graph()->start());
+ graph()->SetEnd(graph()->NewNode(common()->End(1), graph()->start()));
+ TrimGraph();
+ EXPECT_THAT(dead0->inputs(), ElementsAre(nullptr));
+ EXPECT_THAT(graph()->start()->uses(), ElementsAre(graph()->end()));
+}
+
+
+TEST_F(GraphTrimmerTest, DeadAndLiveUsesOfStart) {
+ Node* const dead0 = graph()->NewNode(&kDead0, graph()->start());
+ Node* const live0 = graph()->NewNode(&kLive0, graph()->start());
+ graph()->SetEnd(graph()->NewNode(common()->End(1), live0));
+ TrimGraph();
+ EXPECT_THAT(dead0->inputs(), ElementsAre(nullptr));
+ EXPECT_THAT(graph()->start()->uses(), ElementsAre(live0));
+ EXPECT_THAT(live0->uses(), ElementsAre(graph()->end()));
+}
+
+
+TEST_F(GraphTrimmerTest, Roots) {
+ Node* const live0 = graph()->NewNode(&kLive0, graph()->start());
+ Node* const live1 = graph()->NewNode(&kLive0, graph()->start());
+ graph()->SetEnd(graph()->NewNode(common()->End(1), live0));
+ TrimGraph(live1);
+ EXPECT_THAT(graph()->start()->uses(), UnorderedElementsAre(live0, live1));
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/graph-unittest.cc b/deps/v8/test/unittests/compiler/graph-unittest.cc
index 9da3950e54..6b8546b95a 100644
--- a/deps/v8/test/unittests/compiler/graph-unittest.cc
+++ b/deps/v8/test/unittests/compiler/graph-unittest.cc
@@ -13,7 +13,7 @@ namespace compiler {
GraphTest::GraphTest(int num_parameters) : common_(zone()), graph_(zone()) {
graph()->SetStart(graph()->NewNode(common()->Start(num_parameters)));
- graph()->SetEnd(graph()->NewNode(common()->End(), graph()->start()));
+ graph()->SetEnd(graph()->NewNode(common()->End(1), graph()->start()));
}
@@ -81,6 +81,16 @@ Node* GraphTest::UndefinedConstant() {
}
+Node* GraphTest::EmptyFrameState() {
+ Node* state_values = graph()->NewNode(common()->StateValues(0));
+ return graph()->NewNode(
+ common()->FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(),
+ nullptr),
+ state_values, state_values, state_values, NumberConstant(0),
+ UndefinedConstant(), graph()->start());
+}
+
+
Matcher<Node*> GraphTest::IsFalseConstant() {
return IsHeapConstant(
Unique<HeapObject>::CreateImmovable(factory()->false_value()));
@@ -100,8 +110,7 @@ Matcher<Node*> GraphTest::IsUndefinedConstant() {
TypedGraphTest::TypedGraphTest(int num_parameters)
- : GraphTest(num_parameters),
- typer_(isolate(), graph(), MaybeHandle<Context>()) {}
+ : GraphTest(num_parameters), typer_(isolate(), graph()) {}
TypedGraphTest::~TypedGraphTest() {}
@@ -126,8 +135,8 @@ TEST_F(GraphTest, NewNode) {
Node* n0 = graph()->NewNode(&kDummyOperator);
Node* n1 = graph()->NewNode(&kDummyOperator);
EXPECT_NE(n0, n1);
- EXPECT_LT(0, n0->id());
- EXPECT_LT(0, n1->id());
+ EXPECT_LT(0u, n0->id());
+ EXPECT_LT(0u, n1->id());
EXPECT_NE(n0->id(), n1->id());
EXPECT_EQ(&kDummyOperator, n0->op());
EXPECT_EQ(&kDummyOperator, n1->op());
diff --git a/deps/v8/test/unittests/compiler/graph-unittest.h b/deps/v8/test/unittests/compiler/graph-unittest.h
index c905f30c6a..2318fa61f8 100644
--- a/deps/v8/test/unittests/compiler/graph-unittest.h
+++ b/deps/v8/test/unittests/compiler/graph-unittest.h
@@ -50,6 +50,8 @@ class GraphTest : public TestWithContext, public TestWithIsolateAndZone {
Node* TrueConstant();
Node* UndefinedConstant();
+ Node* EmptyFrameState();
+
Matcher<Node*> IsFalseConstant();
Matcher<Node*> IsTrueConstant();
Matcher<Node*> IsUndefinedConstant();
diff --git a/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc b/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc
index dfdb4c2b1f..acab91b009 100644
--- a/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc
+++ b/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc
@@ -148,6 +148,15 @@ bool InstructionSelectorTest::Stream::IsUsedAtStart(
}
+const FrameStateFunctionInfo*
+InstructionSelectorTest::StreamBuilder::GetFrameStateFunctionInfo(
+ int parameter_count, int local_count) {
+ return common()->CreateFrameStateFunctionInfo(
+ FrameStateType::kJavaScriptFunction, parameter_count, local_count,
+ Handle<SharedFunctionInfo>());
+}
+
+
// -----------------------------------------------------------------------------
// Return.
@@ -198,7 +207,8 @@ TARGET_TEST_F(InstructionSelectorTest, ReturnZero) {
TARGET_TEST_F(InstructionSelectorTest, TruncateFloat64ToInt32WithParameter) {
StreamBuilder m(this, kMachInt32, kMachFloat64);
- m.Return(m.TruncateFloat64ToInt32(m.Parameter(0)));
+ m.Return(
+ m.TruncateFloat64ToInt32(TruncationMode::kJavaScript, m.Parameter(0)));
Stream s = m.Build(kAllInstructions);
ASSERT_EQ(4U, s.size());
EXPECT_EQ(kArchNop, s[0]->arch_opcode());
@@ -363,9 +373,10 @@ TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) {
Node* context_dummy = m.Int32Constant(0);
Node* state_node = m.NewNode(
- m.common()->FrameState(JS_FRAME, bailout_id,
- OutputFrameStateCombine::Push()),
- parameters, locals, stack, context_dummy, m.UndefinedConstant());
+ m.common()->FrameState(bailout_id, OutputFrameStateCombine::Push(),
+ m.GetFrameStateFunctionInfo(1, 0)),
+ parameters, locals, stack, context_dummy, function_node,
+ m.UndefinedConstant());
Node* call = m.CallJS0(function_node, receiver, context, state_node);
m.Return(call);
@@ -411,9 +422,10 @@ TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) {
Node* context_sentinel = m.Int32Constant(0);
Node* frame_state_before = m.NewNode(
- m.common()->FrameState(JS_FRAME, bailout_id_before,
- OutputFrameStateCombine::Push()),
- parameters, locals, stack, context_sentinel, m.UndefinedConstant());
+ m.common()->FrameState(bailout_id_before, OutputFrameStateCombine::Push(),
+ m.GetFrameStateFunctionInfo(1, 1)),
+ parameters, locals, stack, context_sentinel, function_node,
+ m.UndefinedConstant());
// Build the call.
Node* call = m.CallFunctionStub0(function_node, receiver, context,
@@ -437,7 +449,7 @@ TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) {
size_t num_operands =
1 + // Code object.
1 +
- 4 + // Frame state deopt id + one input for each value in frame state.
+ 5 + // Frame state deopt id + one input for each value in frame state.
1 + // Function.
1; // Context.
ASSERT_EQ(num_operands, call_instr->InputCount());
@@ -455,21 +467,23 @@ TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) {
EXPECT_EQ(1u, desc_before->parameters_count());
EXPECT_EQ(1u, desc_before->locals_count());
EXPECT_EQ(1u, desc_before->stack_count());
- EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(2)));
- EXPECT_EQ(0, s.ToInt32(call_instr->InputAt(3))); // This should be a context.
+ EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(3)));
+ EXPECT_EQ(0, s.ToInt32(call_instr->InputAt(4))); // This should be a context.
// We inserted 0 here.
- EXPECT_EQ(0.5, s.ToFloat64(call_instr->InputAt(4)));
- EXPECT_TRUE(s.ToHeapObject(call_instr->InputAt(5))->IsUndefined());
- EXPECT_EQ(kMachInt32, desc_before->GetType(0));
- EXPECT_EQ(kMachAnyTagged, desc_before->GetType(1)); // context is always
+ EXPECT_EQ(0.5, s.ToFloat64(call_instr->InputAt(5)));
+ EXPECT_TRUE(s.ToHeapObject(call_instr->InputAt(6))->IsUndefined());
+ EXPECT_EQ(kMachAnyTagged, desc_before->GetType(0)); // function is always
// tagged/any.
- EXPECT_EQ(kMachFloat64, desc_before->GetType(2));
- EXPECT_EQ(kMachAnyTagged, desc_before->GetType(3));
+ EXPECT_EQ(kMachInt32, desc_before->GetType(1));
+ EXPECT_EQ(kMachAnyTagged, desc_before->GetType(2)); // context is always
+ // tagged/any.
+ EXPECT_EQ(kMachFloat64, desc_before->GetType(3));
+ EXPECT_EQ(kMachAnyTagged, desc_before->GetType(4));
// Function.
- EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(6)));
+ EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(7)));
// Context.
- EXPECT_EQ(s.ToVreg(context), s.ToVreg(call_instr->InputAt(7)));
+ EXPECT_EQ(s.ToVreg(context), s.ToVreg(call_instr->InputAt(8)));
EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
@@ -501,10 +515,11 @@ TARGET_TEST_F(InstructionSelectorTest,
m.NewNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(64));
Node* stack =
m.NewNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(65));
- Node* frame_state_parent =
- m.NewNode(m.common()->FrameState(JS_FRAME, bailout_id_parent,
- OutputFrameStateCombine::Ignore()),
- parameters, locals, stack, context, m.UndefinedConstant());
+ Node* frame_state_parent = m.NewNode(
+ m.common()->FrameState(bailout_id_parent,
+ OutputFrameStateCombine::Ignore(),
+ m.GetFrameStateFunctionInfo(1, 1)),
+ parameters, locals, stack, context, function_node, m.UndefinedConstant());
Node* context2 = m.Int32Constant(46);
Node* parameters2 =
@@ -513,10 +528,11 @@ TARGET_TEST_F(InstructionSelectorTest,
m.Float64Constant(0.25));
Node* stack2 = m.NewNode(m.common()->TypedStateValues(&int32x2_type),
m.Int32Constant(44), m.Int32Constant(45));
- Node* frame_state_before =
- m.NewNode(m.common()->FrameState(JS_FRAME, bailout_id_before,
- OutputFrameStateCombine::Push()),
- parameters2, locals2, stack2, context2, frame_state_parent);
+ Node* frame_state_before = m.NewNode(
+ m.common()->FrameState(bailout_id_before, OutputFrameStateCombine::Push(),
+ m.GetFrameStateFunctionInfo(1, 1)),
+ parameters2, locals2, stack2, context2, function_node,
+ frame_state_parent);
// Build the call.
Node* call = m.CallFunctionStub0(function_node, receiver, context2,
@@ -540,8 +556,8 @@ TARGET_TEST_F(InstructionSelectorTest,
size_t num_operands =
1 + // Code object.
1 + // Frame state deopt id
- 5 + // One input for each value in frame state + context.
- 4 + // One input for each value in the parent frame state + context.
+ 6 + // One input for each value in frame state + context.
+ 5 + // One input for each value in the parent frame state + context.
1 + // Function.
1; // Context.
EXPECT_EQ(num_operands, call_instr->InputCount());
@@ -558,34 +574,36 @@ TARGET_TEST_F(InstructionSelectorTest,
EXPECT_EQ(1u, desc_before_outer->locals_count());
EXPECT_EQ(1u, desc_before_outer->stack_count());
// Values from parent environment.
- EXPECT_EQ(63, s.ToInt32(call_instr->InputAt(2)));
- EXPECT_EQ(kMachInt32, desc_before_outer->GetType(0));
+ EXPECT_EQ(kMachAnyTagged, desc_before->GetType(0));
+ EXPECT_EQ(63, s.ToInt32(call_instr->InputAt(3)));
+ EXPECT_EQ(kMachInt32, desc_before_outer->GetType(1));
// Context:
- EXPECT_EQ(66, s.ToInt32(call_instr->InputAt(3)));
- EXPECT_EQ(kMachAnyTagged, desc_before_outer->GetType(1));
- EXPECT_EQ(64, s.ToInt32(call_instr->InputAt(4)));
- EXPECT_EQ(kMachInt32, desc_before_outer->GetType(2));
- EXPECT_EQ(65, s.ToInt32(call_instr->InputAt(5)));
+ EXPECT_EQ(66, s.ToInt32(call_instr->InputAt(4)));
+ EXPECT_EQ(kMachAnyTagged, desc_before_outer->GetType(2));
+ EXPECT_EQ(64, s.ToInt32(call_instr->InputAt(5)));
EXPECT_EQ(kMachInt32, desc_before_outer->GetType(3));
+ EXPECT_EQ(65, s.ToInt32(call_instr->InputAt(6)));
+ EXPECT_EQ(kMachInt32, desc_before_outer->GetType(4));
// Values from the nested frame.
EXPECT_EQ(1u, desc_before->parameters_count());
EXPECT_EQ(1u, desc_before->locals_count());
EXPECT_EQ(2u, desc_before->stack_count());
- EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(6)));
- EXPECT_EQ(kMachInt32, desc_before->GetType(0));
- EXPECT_EQ(46, s.ToInt32(call_instr->InputAt(7)));
- EXPECT_EQ(kMachAnyTagged, desc_before->GetType(1));
- EXPECT_EQ(0.25, s.ToFloat64(call_instr->InputAt(8)));
- EXPECT_EQ(kMachFloat64, desc_before->GetType(2));
- EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(9)));
- EXPECT_EQ(kMachInt32, desc_before->GetType(3));
- EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(10)));
+ EXPECT_EQ(kMachAnyTagged, desc_before->GetType(0));
+ EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(8)));
+ EXPECT_EQ(kMachInt32, desc_before->GetType(1));
+ EXPECT_EQ(46, s.ToInt32(call_instr->InputAt(9)));
+ EXPECT_EQ(kMachAnyTagged, desc_before->GetType(2));
+ EXPECT_EQ(0.25, s.ToFloat64(call_instr->InputAt(10)));
+ EXPECT_EQ(kMachFloat64, desc_before->GetType(3));
+ EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(11)));
EXPECT_EQ(kMachInt32, desc_before->GetType(4));
+ EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(12)));
+ EXPECT_EQ(kMachInt32, desc_before->GetType(5));
// Function.
- EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(11)));
+ EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(13)));
// Context.
- EXPECT_EQ(s.ToVreg(context2), s.ToVreg(call_instr->InputAt(12)));
+ EXPECT_EQ(s.ToVreg(context2), s.ToVreg(call_instr->InputAt(14)));
// Continuation.
EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
diff --git a/deps/v8/test/unittests/compiler/instruction-selector-unittest.h b/deps/v8/test/unittests/compiler/instruction-selector-unittest.h
index a23d531a3a..15d3b2005f 100644
--- a/deps/v8/test/unittests/compiler/instruction-selector-unittest.h
+++ b/deps/v8/test/unittests/compiler/instruction-selector-unittest.h
@@ -37,22 +37,25 @@ class InstructionSelectorTest : public TestWithContext,
class StreamBuilder final : public RawMachineAssembler {
public:
StreamBuilder(InstructionSelectorTest* test, MachineType return_type)
- : RawMachineAssembler(test->isolate(),
- new (test->zone()) Graph(test->zone()),
- MakeMachineSignature(test->zone(), return_type)),
+ : RawMachineAssembler(
+ test->isolate(), new (test->zone()) Graph(test->zone()),
+ MakeMachineSignature(test->zone(), return_type), kMachPtr,
+ MachineOperatorBuilder::kAllOptionalOps),
test_(test) {}
StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
MachineType parameter0_type)
: RawMachineAssembler(
test->isolate(), new (test->zone()) Graph(test->zone()),
- MakeMachineSignature(test->zone(), return_type, parameter0_type)),
+ MakeMachineSignature(test->zone(), return_type, parameter0_type),
+ kMachPtr, MachineOperatorBuilder::kAllOptionalOps),
test_(test) {}
StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
MachineType parameter0_type, MachineType parameter1_type)
: RawMachineAssembler(
test->isolate(), new (test->zone()) Graph(test->zone()),
MakeMachineSignature(test->zone(), return_type, parameter0_type,
- parameter1_type)),
+ parameter1_type),
+ kMachPtr, MachineOperatorBuilder::kAllOptionalOps),
test_(test) {}
StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
MachineType parameter0_type, MachineType parameter1_type,
@@ -60,7 +63,8 @@ class InstructionSelectorTest : public TestWithContext,
: RawMachineAssembler(
test->isolate(), new (test->zone()) Graph(test->zone()),
MakeMachineSignature(test->zone(), return_type, parameter0_type,
- parameter1_type, parameter2_type)),
+ parameter1_type, parameter2_type),
+ kMachPtr, MachineOperatorBuilder::kAllOptionalOps),
test_(test) {}
Stream Build(CpuFeature feature) {
@@ -77,6 +81,9 @@ class InstructionSelectorTest : public TestWithContext,
InstructionSelector::SourcePositionMode source_position_mode =
InstructionSelector::kAllSourcePositions);
+ const FrameStateFunctionInfo* GetFrameStateFunctionInfo(int parameter_count,
+ int local_count);
+
private:
MachineSignature* MakeMachineSignature(Zone* zone,
MachineType return_type) {
diff --git a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc
index f659b07887..1ff441f746 100644
--- a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc
+++ b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc
@@ -429,8 +429,8 @@ InstructionBlock* InstructionSequenceTest::NewBlock() {
}
}
// Construct instruction block.
- auto instruction_block =
- new (zone()) InstructionBlock(zone(), rpo, loop_header, loop_end, false);
+ auto instruction_block = new (zone())
+ InstructionBlock(zone(), rpo, loop_header, loop_end, false, false);
instruction_blocks_.push_back(instruction_block);
current_block_ = instruction_block;
sequence()->StartBlock(rpo);
diff --git a/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc b/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc
index 090f610066..b452ba56c5 100644
--- a/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc
@@ -26,7 +26,9 @@ class JSBuiltinReducerTest : public TypedGraphTest {
MachineOperatorBuilder::Flag::kNoFlags) {
MachineOperatorBuilder machine(zone(), kMachPtr, flags);
JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
- JSBuiltinReducer reducer(&jsgraph);
+ // TODO(titzer): mock the GraphReducer here for better unit testing.
+ GraphReducer graph_reducer(zone(), graph());
+ JSBuiltinReducer reducer(&graph_reducer, &jsgraph);
return reducer.Reduce(node);
}
@@ -77,10 +79,14 @@ Type* const kNumberTypes[] = {
TEST_F(JSBuiltinReducerTest, MathMax0) {
Node* function = MathFunction("max");
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
Node* call = graph()->NewNode(
javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, language_mode),
- function, UndefinedConstant());
+ function, UndefinedConstant(), frame_state, frame_state, effect,
+ control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
@@ -92,12 +98,16 @@ TEST_F(JSBuiltinReducerTest, MathMax0) {
TEST_F(JSBuiltinReducerTest, MathMax1) {
Node* function = MathFunction("max");
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
TRACED_FOREACH(Type*, t0, kNumberTypes) {
Node* p0 = Parameter(t0, 0);
Node* call = graph()->NewNode(
javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS, language_mode),
- function, UndefinedConstant(), p0);
+ function, UndefinedConstant(), p0, frame_state, frame_state, effect,
+ control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
@@ -110,6 +120,9 @@ TEST_F(JSBuiltinReducerTest, MathMax1) {
TEST_F(JSBuiltinReducerTest, MathMax2) {
Node* function = MathFunction("max");
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
TRACED_FOREACH(Type*, t0, kIntegral32Types) {
TRACED_FOREACH(Type*, t1, kIntegral32Types) {
@@ -118,7 +131,8 @@ TEST_F(JSBuiltinReducerTest, MathMax2) {
Node* call =
graph()->NewNode(javascript()->CallFunction(
4, NO_CALL_FUNCTION_FLAGS, language_mode),
- function, UndefinedConstant(), p0, p1);
+ function, UndefinedConstant(), p0, p1, frame_state,
+ frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
@@ -137,6 +151,9 @@ TEST_F(JSBuiltinReducerTest, MathMax2) {
TEST_F(JSBuiltinReducerTest, MathImul) {
Node* function = MathFunction("imul");
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
TRACED_FOREACH(Type*, t0, kIntegral32Types) {
TRACED_FOREACH(Type*, t1, kIntegral32Types) {
@@ -145,7 +162,8 @@ TEST_F(JSBuiltinReducerTest, MathImul) {
Node* call =
graph()->NewNode(javascript()->CallFunction(
4, NO_CALL_FUNCTION_FLAGS, language_mode),
- function, UndefinedConstant(), p0, p1);
+ function, UndefinedConstant(), p0, p1, frame_state,
+ frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
@@ -163,12 +181,16 @@ TEST_F(JSBuiltinReducerTest, MathImul) {
TEST_F(JSBuiltinReducerTest, MathFround) {
Node* function = MathFunction("fround");
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
TRACED_FOREACH(Type*, t0, kNumberTypes) {
Node* p0 = Parameter(t0, 0);
Node* call = graph()->NewNode(
javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS, language_mode),
- function, UndefinedConstant(), p0);
+ function, UndefinedConstant(), p0, frame_state, frame_state, effect,
+ control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
diff --git a/deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc b/deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc
index bc343060ca..92be4e43e0 100644
--- a/deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc
@@ -33,7 +33,10 @@ class JSIntrinsicLoweringTest : public GraphTest {
MachineOperatorBuilder::kNoFlags) {
MachineOperatorBuilder machine(zone(), kMachPtr, flags);
JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
- JSIntrinsicLowering reducer(&jsgraph);
+ // TODO(titzer): mock the GraphReducer here for better unit testing.
+ GraphReducer graph_reducer(zone(), graph());
+ JSIntrinsicLowering reducer(&graph_reducer, &jsgraph,
+ JSIntrinsicLowering::kDeoptimizationEnabled);
return reducer.Reduce(node);
}
@@ -171,6 +174,68 @@ TEST_F(JSIntrinsicLoweringTest, InlineIsArray) {
// -----------------------------------------------------------------------------
+// %_IsDate
+
+
+TEST_F(JSIntrinsicLoweringTest, InlineIsDate) {
+ Node* const input = Parameter(0);
+ Node* const context = Parameter(1);
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Reduction const r = Reduce(
+ graph()->NewNode(javascript()->CallRuntime(Runtime::kInlineIsDate, 1),
+ input, context, effect, control));
+ ASSERT_TRUE(r.Changed());
+
+ Node* phi = r.replacement();
+ Capture<Node*> branch, if_false;
+ EXPECT_THAT(
+ phi,
+ IsPhi(
+ static_cast<MachineType>(kTypeBool | kRepTagged), IsFalseConstant(),
+ IsWord32Equal(IsLoadField(AccessBuilder::ForMapInstanceType(),
+ IsLoadField(AccessBuilder::ForMap(), input,
+ effect, CaptureEq(&if_false)),
+ effect, _),
+ IsInt32Constant(JS_DATE_TYPE)),
+ IsMerge(IsIfTrue(AllOf(CaptureEq(&branch),
+ IsBranch(IsObjectIsSmi(input), control))),
+ AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
+}
+
+
+// -----------------------------------------------------------------------------
+// %_IsTypedArray
+
+
+TEST_F(JSIntrinsicLoweringTest, InlineIsTypedArray) {
+ Node* const input = Parameter(0);
+ Node* const context = Parameter(1);
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Reduction const r = Reduce(graph()->NewNode(
+ javascript()->CallRuntime(Runtime::kInlineIsTypedArray, 1), input,
+ context, effect, control));
+ ASSERT_TRUE(r.Changed());
+
+ Node* phi = r.replacement();
+ Capture<Node*> branch, if_false;
+ EXPECT_THAT(
+ phi,
+ IsPhi(
+ static_cast<MachineType>(kTypeBool | kRepTagged), IsFalseConstant(),
+ IsWord32Equal(IsLoadField(AccessBuilder::ForMapInstanceType(),
+ IsLoadField(AccessBuilder::ForMap(), input,
+ effect, CaptureEq(&if_false)),
+ effect, _),
+ IsInt32Constant(JS_TYPED_ARRAY_TYPE)),
+ IsMerge(IsIfTrue(AllOf(CaptureEq(&branch),
+ IsBranch(IsObjectIsSmi(input), control))),
+ AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
+}
+
+
+// -----------------------------------------------------------------------------
// %_IsFunction
@@ -264,7 +329,7 @@ TEST_F(JSIntrinsicLoweringTest, Likely) {
Node* const to_boolean =
graph()->NewNode(javascript()->ToBoolean(), likely, context);
Diamond d(graph(), common(), to_boolean);
- graph()->SetEnd(graph()->NewNode(common()->End(), d.merge));
+ graph()->SetEnd(graph()->NewNode(common()->End(1), d.merge));
ASSERT_EQ(BranchHint::kNone, BranchHintOf(d.branch->op()));
Reduction const r = Reduce(likely);
@@ -359,7 +424,7 @@ TEST_F(JSIntrinsicLoweringTest, Unlikely) {
Node* const to_boolean =
graph()->NewNode(javascript()->ToBoolean(), unlikely, context);
Diamond d(graph(), common(), to_boolean);
- graph()->SetEnd(graph()->NewNode(common()->End(), d.merge));
+ graph()->SetEnd(graph()->NewNode(common()->End(1), d.merge));
ASSERT_EQ(BranchHint::kNone, BranchHintOf(d.branch->op()));
Reduction const r = Reduce(unlikely);
diff --git a/deps/v8/test/unittests/compiler/js-operator-unittest.cc b/deps/v8/test/unittests/compiler/js-operator-unittest.cc
index a8a2d8c38a..0f33ddea8d 100644
--- a/deps/v8/test/unittests/compiler/js-operator-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-operator-unittest.cc
@@ -186,10 +186,10 @@ const SharedOperatorWithLanguageMode kSharedOperatorsWithLanguageMode[] = {
control_input_count, value_output_count, effect_output_count, \
control_output_count \
}
- SHARED(LessThan, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
- SHARED(GreaterThan, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
- SHARED(LessThanOrEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
- SHARED(GreaterThanOrEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
+ SHARED(LessThan, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
+ SHARED(GreaterThan, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
+ SHARED(LessThanOrEqual, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
+ SHARED(GreaterThanOrEqual, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(BitwiseOr, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(BitwiseXor, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(BitwiseAnd, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
@@ -201,7 +201,6 @@ const SharedOperatorWithLanguageMode kSharedOperatorsWithLanguageMode[] = {
SHARED(Multiply, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(Divide, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(Modulus, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
- SHARED(StoreProperty, Operator::kNoProperties, 3, 2, 1, 1, 0, 1, 2),
#undef SHARED
};
diff --git a/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc b/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc
index 08fe68a8ba..d52242ec7d 100644
--- a/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc
@@ -34,15 +34,18 @@ class JSTypeFeedbackTest : public TypedGraphTest {
~JSTypeFeedbackTest() override { dependencies_.Rollback(); }
protected:
- Reduction Reduce(Node* node) {
+ Reduction Reduce(Node* node,
+ JSTypeFeedbackSpecializer::DeoptimizationMode mode) {
Handle<GlobalObject> global_object(
isolate()->native_context()->global_object(), isolate());
MachineOperatorBuilder machine(zone());
JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
JSTypeFeedbackTable table(zone());
- JSTypeFeedbackSpecializer reducer(&jsgraph, &table, nullptr, global_object,
- &dependencies_);
+ // TODO(titzer): mock the GraphReducer here for better unit testing.
+ GraphReducer graph_reducer(zone(), graph());
+ JSTypeFeedbackSpecializer reducer(&graph_reducer, &jsgraph, &table, nullptr,
+ global_object, mode, &dependencies_);
return reducer.Reduce(node);
}
@@ -71,19 +74,23 @@ class JSTypeFeedbackTest : public TypedGraphTest {
result.Assert();
}
- Node* ReturnLoadNamedFromGlobal(const char* string, Node* effect,
- Node* control) {
- VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(),
- FeedbackVectorICSlot::Invalid());
- Node* global = Parameter(Type::GlobalObject());
+ Node* ReturnLoadNamedFromGlobal(
+ const char* string, Node* effect, Node* control,
+ JSTypeFeedbackSpecializer::DeoptimizationMode mode) {
+ VectorSlotPair feedback;
+ Node* global = UndefinedConstant();
+ Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Unique<Name> name = Unique<Name>::CreateUninitialized(
- isolate()->factory()->NewStringFromAsciiChecked(string));
- Node* load = graph()->NewNode(javascript()->LoadNamed(name, feedback),
- global, context);
- if (FLAG_turbo_deoptimization) {
- load->AppendInput(zone(), EmptyFrameState());
+ isolate()->factory()->InternalizeUtf8String(string));
+ const Operator* op = javascript()->LoadGlobal(name, feedback);
+ Node* load = graph()->NewNode(op, global, vector, context);
+ if (mode == JSTypeFeedbackSpecializer::kDeoptimizationEnabled) {
+ for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op);
+ i++) {
+ load->AppendInput(zone(), EmptyFrameState());
+ }
}
load->AppendInput(zone(), effect);
load->AppendInput(zone(), control);
@@ -98,180 +105,240 @@ class JSTypeFeedbackTest : public TypedGraphTest {
CompilationDependencies dependencies_;
};
-#define WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION \
- for (int i = FLAG_turbo_deoptimization = 0; i < 2; \
- FLAG_turbo_deoptimization = ++i)
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmi) {
+ const int kValue = 111;
+ const char* kName = "banana";
+ SetGlobalProperty(kName, kValue);
-TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConst_smi) {
- const int const_value = 111;
- const char* property_name = "banana";
- SetGlobalProperty(property_name, const_value);
+ Node* ret = ReturnLoadNamedFromGlobal(
+ kName, graph()->start(), graph()->start(),
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
- WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION {
- Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(),
- graph()->start());
- graph()->SetEnd(graph()->NewNode(common()->End(), ret));
+ Reduction r = Reduce(ret->InputAt(0),
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
+ EXPECT_FALSE(r.Changed());
+ EXPECT_TRUE(dependencies()->IsEmpty());
+}
- Reduction r = Reduce(ret->InputAt(0));
- if (FLAG_turbo_deoptimization) {
- // Check LoadNamed(global) => HeapConstant[const_value]
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsNumberConstant(const_value));
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmiWithDeoptimization) {
+ const int kValue = 111;
+ const char* kName = "banana";
+ SetGlobalProperty(kName, kValue);
- EXPECT_THAT(ret, IsReturn(IsNumberConstant(const_value), graph()->start(),
- graph()->start()));
- EXPECT_THAT(graph()->end(), IsEnd(ret));
+ Node* ret = ReturnLoadNamedFromGlobal(
+ kName, graph()->start(), graph()->start(),
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
- EXPECT_FALSE(dependencies()->IsEmpty());
- dependencies()->Rollback();
- } else {
- ASSERT_FALSE(r.Changed());
- EXPECT_TRUE(dependencies()->IsEmpty());
- }
- }
+ Reduction r = Reduce(ret->InputAt(0),
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
+
+ // Check LoadNamed(global) => HeapConstant[kValue]
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberConstant(kValue));
+
+ EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(),
+ graph()->start()));
+ EXPECT_THAT(graph()->end(), IsEnd(ret));
+
+ EXPECT_FALSE(dependencies()->IsEmpty());
+ dependencies()->Rollback();
}
-TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConst_derble) {
- const double const_value = -11.25;
- const char* property_name = "kiwi";
- SetGlobalProperty(property_name, const_value);
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumber) {
+ const double kValue = -11.25;
+ const char* kName = "kiwi";
+ SetGlobalProperty(kName, kValue);
- WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION {
- Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(),
- graph()->start());
- graph()->SetEnd(graph()->NewNode(common()->End(), ret));
+ Node* ret = ReturnLoadNamedFromGlobal(
+ kName, graph()->start(), graph()->start(),
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
- Reduction r = Reduce(ret->InputAt(0));
+ Reduction r = Reduce(ret->InputAt(0),
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
- if (FLAG_turbo_deoptimization) {
- // Check LoadNamed(global) => HeapConstant[const_value]
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsNumberConstant(const_value));
+ EXPECT_FALSE(r.Changed());
+ EXPECT_TRUE(dependencies()->IsEmpty());
+}
- EXPECT_THAT(ret, IsReturn(IsNumberConstant(const_value), graph()->start(),
- graph()->start()));
- EXPECT_THAT(graph()->end(), IsEnd(ret));
- EXPECT_FALSE(dependencies()->IsEmpty());
- } else {
- ASSERT_FALSE(r.Changed());
- EXPECT_TRUE(dependencies()->IsEmpty());
- }
- }
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumberWithDeoptimization) {
+ const double kValue = -11.25;
+ const char* kName = "kiwi";
+ SetGlobalProperty(kName, kValue);
+
+ Node* ret = ReturnLoadNamedFromGlobal(
+ kName, graph()->start(), graph()->start(),
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
+
+ Reduction r = Reduce(ret->InputAt(0),
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
+
+ // Check LoadNamed(global) => HeapConstant[kValue]
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberConstant(kValue));
+
+ EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(),
+ graph()->start()));
+ EXPECT_THAT(graph()->end(), IsEnd(ret));
+
+ EXPECT_FALSE(dependencies()->IsEmpty());
}
-TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConst_string) {
- Unique<HeapObject> const_value = Unique<HeapObject>::CreateImmovable(
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstString) {
+ Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable(
isolate()->factory()->undefined_string());
- const char* property_name = "mango";
- SetGlobalProperty(property_name, const_value.handle());
-
- WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION {
- Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(),
- graph()->start());
- graph()->SetEnd(graph()->NewNode(common()->End(), ret));
-
- Reduction r = Reduce(ret->InputAt(0));
-
- if (FLAG_turbo_deoptimization) {
- // Check LoadNamed(global) => HeapConstant[const_value]
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsHeapConstant(const_value));
-
- EXPECT_THAT(ret, IsReturn(IsHeapConstant(const_value), graph()->start(),
- graph()->start()));
- EXPECT_THAT(graph()->end(), IsEnd(ret));
-
- EXPECT_FALSE(dependencies()->IsEmpty());
- dependencies()->Rollback();
- } else {
- ASSERT_FALSE(r.Changed());
- EXPECT_TRUE(dependencies()->IsEmpty());
- }
- }
+ const char* kName = "mango";
+ SetGlobalProperty(kName, kValue.handle());
+
+ Node* ret = ReturnLoadNamedFromGlobal(
+ kName, graph()->start(), graph()->start(),
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
+
+ Reduction r = Reduce(ret->InputAt(0),
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
+ ASSERT_FALSE(r.Changed());
+ EXPECT_TRUE(dependencies()->IsEmpty());
}
-TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCell_smi) {
- const char* property_name = "melon";
- SetGlobalProperty(property_name, 123);
- SetGlobalProperty(property_name, 124);
-
- WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION {
- Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(),
- graph()->start());
- graph()->SetEnd(graph()->NewNode(common()->End(), ret));
-
- Reduction r = Reduce(ret->InputAt(0));
-
- if (FLAG_turbo_deoptimization) {
- // Check LoadNamed(global) => LoadField[PropertyCell::value](cell)
- ASSERT_TRUE(r.Changed());
- FieldAccess access = AccessBuilder::ForPropertyCellValue();
- Capture<Node*> cell_capture;
- Matcher<Node*> load_field_match = IsLoadField(
- access, CaptureEq(&cell_capture), graph()->start(), graph()->start());
- EXPECT_THAT(r.replacement(), load_field_match);
-
- HeapObjectMatcher<PropertyCell> cell(cell_capture.value());
- EXPECT_TRUE(cell.HasValue());
- EXPECT_TRUE(cell.Value().handle()->IsPropertyCell());
-
- EXPECT_THAT(
- ret, IsReturn(load_field_match, load_field_match, graph()->start()));
- EXPECT_THAT(graph()->end(), IsEnd(ret));
-
- EXPECT_FALSE(dependencies()->IsEmpty());
- dependencies()->Rollback();
- } else {
- ASSERT_FALSE(r.Changed());
- EXPECT_TRUE(dependencies()->IsEmpty());
- }
- }
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstStringWithDeoptimization) {
+ Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable(
+ isolate()->factory()->undefined_string());
+ const char* kName = "mango";
+ SetGlobalProperty(kName, kValue.handle());
+
+ Node* ret = ReturnLoadNamedFromGlobal(
+ kName, graph()->start(), graph()->start(),
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
+
+ Reduction r = Reduce(ret->InputAt(0),
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
+
+ // Check LoadNamed(global) => HeapConstant[kValue]
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsHeapConstant(kValue));
+
+ EXPECT_THAT(ret, IsReturn(IsHeapConstant(kValue), graph()->start(),
+ graph()->start()));
+ EXPECT_THAT(graph()->end(), IsEnd(ret));
+
+ EXPECT_FALSE(dependencies()->IsEmpty());
+ dependencies()->Rollback();
}
-TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCell_string) {
- const char* property_name = "pineapple";
- SetGlobalProperty(property_name, isolate()->factory()->undefined_string());
- SetGlobalProperty(property_name, isolate()->factory()->undefined_value());
-
- WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION {
- Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(),
- graph()->start());
- graph()->SetEnd(graph()->NewNode(common()->End(), ret));
-
- Reduction r = Reduce(ret->InputAt(0));
-
- if (FLAG_turbo_deoptimization) {
- // Check LoadNamed(global) => LoadField[PropertyCell::value](cell)
- ASSERT_TRUE(r.Changed());
- FieldAccess access = AccessBuilder::ForPropertyCellValue();
- Capture<Node*> cell_capture;
- Matcher<Node*> load_field_match = IsLoadField(
- access, CaptureEq(&cell_capture), graph()->start(), graph()->start());
- EXPECT_THAT(r.replacement(), load_field_match);
-
- HeapObjectMatcher<PropertyCell> cell(cell_capture.value());
- EXPECT_TRUE(cell.HasValue());
- EXPECT_TRUE(cell.Value().handle()->IsPropertyCell());
-
- EXPECT_THAT(
- ret, IsReturn(load_field_match, load_field_match, graph()->start()));
- EXPECT_THAT(graph()->end(), IsEnd(ret));
-
- EXPECT_FALSE(dependencies()->IsEmpty());
- dependencies()->Rollback();
- } else {
- ASSERT_FALSE(r.Changed());
- EXPECT_TRUE(dependencies()->IsEmpty());
- }
- }
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmi) {
+ const char* kName = "melon";
+ SetGlobalProperty(kName, 123);
+ SetGlobalProperty(kName, 124);
+
+ Node* ret = ReturnLoadNamedFromGlobal(
+ kName, graph()->start(), graph()->start(),
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
+
+ Reduction r = Reduce(ret->InputAt(0),
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
+ ASSERT_FALSE(r.Changed());
+ EXPECT_TRUE(dependencies()->IsEmpty());
}
+
+
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmiWithDeoptimization) {
+ const char* kName = "melon";
+ SetGlobalProperty(kName, 123);
+ SetGlobalProperty(kName, 124);
+
+ Node* ret = ReturnLoadNamedFromGlobal(
+ kName, graph()->start(), graph()->start(),
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
+
+ Reduction r = Reduce(ret->InputAt(0),
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
+
+ // Check LoadNamed(global) => LoadField[PropertyCell::value](cell)
+ ASSERT_TRUE(r.Changed());
+ FieldAccess access = AccessBuilder::ForPropertyCellValue();
+ Capture<Node*> cell_capture;
+ Matcher<Node*> load_field_match = IsLoadField(
+ access, CaptureEq(&cell_capture), graph()->start(), graph()->start());
+ EXPECT_THAT(r.replacement(), load_field_match);
+
+ HeapObjectMatcher cell(cell_capture.value());
+ EXPECT_TRUE(cell.HasValue());
+ EXPECT_TRUE(cell.Value().handle()->IsPropertyCell());
+
+ EXPECT_THAT(ret,
+ IsReturn(load_field_match, load_field_match, graph()->start()));
+ EXPECT_THAT(graph()->end(), IsEnd(ret));
+
+ EXPECT_FALSE(dependencies()->IsEmpty());
+ dependencies()->Rollback();
}
+
+
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellString) {
+ const char* kName = "pineapple";
+ SetGlobalProperty(kName, isolate()->factory()->undefined_string());
+ SetGlobalProperty(kName, isolate()->factory()->undefined_value());
+
+ Node* ret = ReturnLoadNamedFromGlobal(
+ kName, graph()->start(), graph()->start(),
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
+
+ Reduction r = Reduce(ret->InputAt(0),
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
+ ASSERT_FALSE(r.Changed());
+ EXPECT_TRUE(dependencies()->IsEmpty());
}
+
+
+TEST_F(JSTypeFeedbackTest,
+ JSLoadNamedGlobalPropertyCellStringWithDeoptimization) {
+ const char* kName = "pineapple";
+ SetGlobalProperty(kName, isolate()->factory()->undefined_string());
+ SetGlobalProperty(kName, isolate()->factory()->undefined_value());
+
+ Node* ret = ReturnLoadNamedFromGlobal(
+ kName, graph()->start(), graph()->start(),
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
+
+ Reduction r = Reduce(ret->InputAt(0),
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
+
+ // Check LoadNamed(global) => LoadField[PropertyCell::value](cell)
+ ASSERT_TRUE(r.Changed());
+ FieldAccess access = AccessBuilder::ForPropertyCellValue();
+ Capture<Node*> cell_capture;
+ Matcher<Node*> load_field_match = IsLoadField(
+ access, CaptureEq(&cell_capture), graph()->start(), graph()->start());
+ EXPECT_THAT(r.replacement(), load_field_match);
+
+ HeapObjectMatcher cell(cell_capture.value());
+ EXPECT_TRUE(cell.HasValue());
+ EXPECT_TRUE(cell.Value().handle()->IsPropertyCell());
+
+ EXPECT_THAT(ret,
+ IsReturn(load_field_match, load_field_match, graph()->start()));
+ EXPECT_THAT(graph()->end(), IsEnd(ret));
+
+ EXPECT_FALSE(dependencies()->IsEmpty());
+ dependencies()->Rollback();
}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc
index 9e7b1eecbd..a12d79f02b 100644
--- a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc
@@ -80,16 +80,12 @@ class JSTypedLoweringTest : public TypedGraphTest {
Reduction Reduce(Node* node) {
MachineOperatorBuilder machine(zone());
JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
- JSTypedLowering reducer(&jsgraph, zone());
+ // TODO(titzer): mock the GraphReducer here for better unit testing.
+ GraphReducer graph_reducer(zone(), graph());
+ JSTypedLowering reducer(&graph_reducer, &jsgraph, zone());
return reducer.Reduce(node);
}
- Node* EmptyFrameState() {
- MachineOperatorBuilder machine(zone());
- JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
- return jsgraph.EmptyFrameState();
- }
-
Handle<JSArrayBuffer> NewArrayBuffer(void* bytes, size_t byte_length) {
Handle<JSArrayBuffer> buffer = factory()->NewJSArrayBuffer();
Runtime::SetupArrayBuffer(isolate(), buffer, true, bytes, byte_length);
@@ -434,18 +430,27 @@ TEST_F(JSTypedLoweringTest, JSToNumberWithPlainPrimitive) {
TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) {
Node* const the_hole = HeapConstant(factory()->the_hole_value());
Node* const context = UndefinedConstant();
- Node* const effect = graph()->start();
- Node* const control = graph()->start();
TRACED_FOREACH(Type*, type, kJSTypes) {
Node* const lhs = Parameter(type);
- Reduction r = Reduce(graph()->NewNode(javascript()->StrictEqual(), lhs,
- the_hole, context, effect, control));
+ Reduction r = Reduce(
+ graph()->NewNode(javascript()->StrictEqual(), lhs, the_hole, context));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFalseConstant());
}
}
+TEST_F(JSTypedLoweringTest, JSStrictEqualWithUnique) {
+ Node* const lhs = Parameter(Type::Unique(), 0);
+ Node* const rhs = Parameter(Type::Unique(), 1);
+ Node* const context = Parameter(Type::Any(), 2);
+ Reduction r =
+ Reduce(graph()->NewNode(javascript()->StrictEqual(), lhs, rhs, context));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsReferenceEqual(Type::Unique(), lhs, rhs));
+}
+
+
// -----------------------------------------------------------------------------
// JSShiftLeft
@@ -457,13 +462,12 @@ TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndConstant) {
Node* const control = graph()->start();
TRACED_FORRANGE(double, rhs, 0, 31) {
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
- Reduction r =
- Reduce(graph()->NewNode(javascript()->ShiftLeft(language_mode), lhs,
- NumberConstant(rhs), context, effect,
- control));
+ Reduction r = Reduce(graph()->NewNode(
+ javascript()->ShiftLeft(language_mode), lhs, NumberConstant(rhs),
+ context, EmptyFrameState(), EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
- IsWord32Shl(lhs, IsNumberConstant(BitEq(rhs))));
+ IsNumberShiftLeft(lhs, IsNumberConstant(BitEq(rhs))));
}
}
}
@@ -476,12 +480,11 @@ TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndUnsigned32) {
Node* const effect = graph()->start();
Node* const control = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
- Reduction r =
- Reduce(graph()->NewNode(javascript()->ShiftLeft(language_mode), lhs,
- rhs, context, effect, control));
+ Reduction r = Reduce(graph()->NewNode(
+ javascript()->ShiftLeft(language_mode), lhs, rhs, context,
+ EmptyFrameState(), EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(),
- IsWord32Shl(lhs, IsWord32And(rhs, IsInt32Constant(0x1f))));
+ EXPECT_THAT(r.replacement(), IsNumberShiftLeft(lhs, rhs));
}
}
@@ -497,13 +500,12 @@ TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndConstant) {
Node* const control = graph()->start();
TRACED_FORRANGE(double, rhs, 0, 31) {
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
- Reduction r =
- Reduce(graph()->NewNode(javascript()-> ShiftRight(language_mode), lhs,
- NumberConstant(rhs), context, effect,
- control));
+ Reduction r = Reduce(graph()->NewNode(
+ javascript()->ShiftRight(language_mode), lhs, NumberConstant(rhs),
+ context, EmptyFrameState(), EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
- IsWord32Sar(lhs, IsNumberConstant(BitEq(rhs))));
+ IsNumberShiftRight(lhs, IsNumberConstant(BitEq(rhs))));
}
}
}
@@ -516,12 +518,11 @@ TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndUnsigned32) {
Node* const effect = graph()->start();
Node* const control = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
- Reduction r = Reduce(graph()->NewNode(javascript()->
- ShiftRight(language_mode), lhs, rhs,
- context, effect, control));
+ Reduction r = Reduce(graph()->NewNode(
+ javascript()->ShiftRight(language_mode), lhs, rhs, context,
+ EmptyFrameState(), EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(),
- IsWord32Sar(lhs, IsWord32And(rhs, IsInt32Constant(0x1f))));
+ EXPECT_THAT(r.replacement(), IsNumberShiftRight(lhs, rhs));
}
}
@@ -538,14 +539,13 @@ TEST_F(JSTypedLoweringTest,
Node* const control = graph()->start();
TRACED_FORRANGE(double, rhs, 0, 31) {
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
- Reduction r =
- Reduce(graph()->NewNode(javascript()->
- ShiftRightLogical(language_mode), lhs,
- NumberConstant(rhs), context, effect,
- control));
+ Reduction r = Reduce(
+ graph()->NewNode(javascript()->ShiftRightLogical(language_mode), lhs,
+ NumberConstant(rhs), context, EmptyFrameState(),
+ EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
- IsWord32Shr(lhs, IsNumberConstant(BitEq(rhs))));
+ IsNumberShiftRightLogical(lhs, IsNumberConstant(BitEq(rhs))));
}
}
}
@@ -559,12 +559,11 @@ TEST_F(JSTypedLoweringTest,
Node* const effect = graph()->start();
Node* const control = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
- Reduction r = Reduce(graph()->NewNode(javascript()->
- ShiftRightLogical(language_mode), lhs,
- rhs, context, effect, control));
+ Reduction r = Reduce(graph()->NewNode(
+ javascript()->ShiftRightLogical(language_mode), lhs, rhs, context,
+ EmptyFrameState(), EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(),
- IsWord32Shr(lhs, IsWord32And(rhs, IsInt32Constant(0x1f))));
+ EXPECT_THAT(r.replacement(), IsNumberShiftRightLogical(lhs, rhs));
}
}
@@ -646,36 +645,39 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
double backing_store[kLength];
Handle<JSArrayBuffer> buffer =
NewArrayBuffer(backing_store, sizeof(backing_store));
- VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(),
- FeedbackVectorICSlot::Invalid());
+ VectorSlotPair feedback;
TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
- Handle<JSTypedArray> array =
- factory()->NewJSTypedArray(type, buffer, 0, kLength);
- int const element_size = static_cast<int>(array->element_size());
-
- Node* key = Parameter(
- Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
- Node* base = HeapConstant(array);
- Node* context = UndefinedConstant();
- Node* effect = graph()->start();
- Node* control = graph()->start();
- Reduction r =
- Reduce(graph()->NewNode(javascript()->LoadProperty(feedback), base, key,
- context, EmptyFrameState(), effect, control));
+ TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
+ Handle<JSTypedArray> array =
+ factory()->NewJSTypedArray(type, buffer, 0, kLength);
+ int const element_size = static_cast<int>(array->element_size());
+
+ Node* key = Parameter(
+ Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
+ Node* base = HeapConstant(array);
+ Node* vector = UndefinedConstant();
+ Node* context = UndefinedConstant();
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Reduction r = Reduce(
+ graph()->NewNode(javascript()->LoadProperty(feedback, language_mode),
+ base, key, vector, context, EmptyFrameState(),
+ EmptyFrameState(), effect, control));
- Matcher<Node*> offset_matcher =
- element_size == 1
- ? key
- : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
+ Matcher<Node*> offset_matcher =
+ element_size == 1
+ ? key
+ : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(
- r.replacement(),
- IsLoadBuffer(BufferAccess(type),
- IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
- offset_matcher,
- IsNumberConstant(array->byte_length()->Number()), effect,
- control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(
+ r.replacement(),
+ IsLoadBuffer(BufferAccess(type),
+ IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
+ offset_matcher,
+ IsNumberConstant(array->byte_length()->Number()), effect,
+ control));
+ }
}
}
@@ -685,31 +687,34 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArrayWithSafeKey) {
double backing_store[kLength];
Handle<JSArrayBuffer> buffer =
NewArrayBuffer(backing_store, sizeof(backing_store));
- VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(),
- FeedbackVectorICSlot::Invalid());
+ VectorSlotPair feedback;
TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
- Handle<JSTypedArray> array =
- factory()->NewJSTypedArray(type, buffer, 0, kLength);
- ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
-
- int min = random_number_generator()->NextInt(static_cast<int>(kLength));
- int max = random_number_generator()->NextInt(static_cast<int>(kLength));
- if (min > max) std::swap(min, max);
- Node* key = Parameter(Type::Range(min, max, zone()));
- Node* base = HeapConstant(array);
- Node* context = UndefinedConstant();
- Node* effect = graph()->start();
- Node* control = graph()->start();
- Reduction r =
- Reduce(graph()->NewNode(javascript()->LoadProperty(feedback), base, key,
- context, EmptyFrameState(), effect, control));
+ TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
+ Handle<JSTypedArray> array =
+ factory()->NewJSTypedArray(type, buffer, 0, kLength);
+ ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(
- r.replacement(),
- IsLoadElement(access,
- IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
- key, effect, control));
+ int min = random_number_generator()->NextInt(static_cast<int>(kLength));
+ int max = random_number_generator()->NextInt(static_cast<int>(kLength));
+ if (min > max) std::swap(min, max);
+ Node* key = Parameter(Type::Range(min, max, zone()));
+ Node* base = HeapConstant(array);
+ Node* vector = UndefinedConstant();
+ Node* context = UndefinedConstant();
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Reduction r = Reduce(
+ graph()->NewNode(javascript()->LoadProperty(feedback, language_mode),
+ base, key, vector, context, EmptyFrameState(),
+ EmptyFrameState(), effect, control));
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(
+ r.replacement(),
+ IsLoadElement(access,
+ IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
+ key, effect, control));
+ }
}
}
@@ -734,11 +739,13 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) {
Node* base = HeapConstant(array);
Node* value =
Parameter(AccessBuilder::ForTypedArrayElement(type, true).type);
+ Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
- Node* node = graph()->NewNode(javascript()->StoreProperty(language_mode),
- base, key, value, context);
+ VectorSlotPair feedback;
+ const Operator* op = javascript()->StoreProperty(language_mode, feedback);
+ Node* node = graph()->NewNode(op, base, key, value, vector, context);
for (int i = 0;
i < OperatorProperties::GetFrameStateInputCount(node->op()); i++) {
node->AppendInput(zone(), EmptyFrameState());
@@ -780,11 +787,13 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
Node* base = HeapConstant(array);
Node* value = Parameter(Type::Any());
+ Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
- Node* node = graph()->NewNode(javascript()->StoreProperty(language_mode),
- base, key, value, context);
+ VectorSlotPair feedback;
+ const Operator* op = javascript()->StoreProperty(language_mode, feedback);
+ Node* node = graph()->NewNode(op, base, key, value, vector, context);
for (int i = 0;
i < OperatorProperties::GetFrameStateInputCount(node->op()); i++) {
node->AppendInput(zone(), EmptyFrameState());
@@ -839,11 +848,13 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) {
Node* key = Parameter(Type::Range(min, max, zone()));
Node* base = HeapConstant(array);
Node* value = Parameter(access.type);
+ Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
- Node* node = graph()->NewNode(javascript()->StoreProperty(language_mode),
- base, key, value, context);
+ VectorSlotPair feedback;
+ const Operator* op = javascript()->StoreProperty(language_mode, feedback);
+ Node* node = graph()->NewNode(op, base, key, value, vector, context);
for (int i = 0;
i < OperatorProperties::GetFrameStateInputCount(node->op()); i++) {
node->AppendInput(zone(), EmptyFrameState());
@@ -876,18 +887,18 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) {
IsNumberConstant(IsNaN()) // --
};
- VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(),
- FeedbackVectorICSlot::Invalid());
- Node* global = Parameter(Type::GlobalObject());
+ VectorSlotPair feedback;
+ Node* global = UndefinedConstant();
+ Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
for (size_t i = 0; i < arraysize(names); i++) {
Unique<Name> name = Unique<Name>::CreateImmovable(names[i]);
- Reduction r =
- Reduce(graph()->NewNode(javascript()->LoadNamed(name, feedback), global,
- context, EmptyFrameState(), effect, control));
+ Reduction r = Reduce(graph()->NewNode(
+ javascript()->LoadGlobal(name, feedback), global, vector, context,
+ EmptyFrameState(), EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), matches[i]);
@@ -896,9 +907,106 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) {
// -----------------------------------------------------------------------------
-// JSCreateClosure
+// JSLoadDynamicGlobal
+
+
+TEST_F(JSTypedLoweringTest, JSLoadDynamicGlobal) {
+ Node* const context = Parameter(Type::Any());
+ Node* const vector = UndefinedConstant();
+ Node* const frame_state = EmptyFrameState();
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Handle<String> name = factory()->object_string();
+ VectorSlotPair feedback;
+ for (int i = 0; i < DynamicGlobalAccess::kMaxCheckDepth; ++i) {
+ uint32_t bitset = 1 << i; // Only single check.
+ Reduction r = Reduce(graph()->NewNode(
+ javascript()->LoadDynamicGlobal(name, bitset, feedback, NOT_CONTEXTUAL),
+ vector, context, context, frame_state, frame_state, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(
+ r.replacement(),
+ IsPhi(kMachAnyTagged, _, _,
+ IsMerge(
+ IsIfTrue(IsBranch(
+ IsReferenceEqual(
+ Type::Tagged(),
+ IsLoadContext(
+ ContextAccess(i, Context::EXTENSION_INDEX, false),
+ context),
+ IsNumberConstant(BitEq(0.0))),
+ control)),
+ _)));
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+// JSLoadDynamicContext
+
+
+TEST_F(JSTypedLoweringTest, JSLoadDynamicContext) {
+ Node* const context = Parameter(Type::Any());
+ Node* const frame_state = EmptyFrameState();
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Handle<String> name = factory()->object_string();
+ for (int i = 0; i < DynamicContextAccess::kMaxCheckDepth; ++i) {
+ uint32_t bitset = 1 << i; // Only single check.
+ Reduction r = Reduce(
+ graph()->NewNode(javascript()->LoadDynamicContext(name, bitset, 23, 42),
+ context, context, frame_state, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(
+ r.replacement(),
+ IsPhi(kMachAnyTagged,
+ IsLoadContext(ContextAccess(23, 42, false), context), _,
+ IsMerge(
+ IsIfTrue(IsBranch(
+ IsReferenceEqual(
+ Type::Tagged(),
+ IsLoadContext(
+ ContextAccess(i, Context::EXTENSION_INDEX, false),
+ context),
+ IsNumberConstant(BitEq(0.0))),
+ control)),
+ _)));
+ }
+}
#if V8_TURBOFAN_TARGET
+
+// -----------------------------------------------------------------------------
+// JSAdd
+
+
+TEST_F(JSTypedLoweringTest, JSAddWithString) {
+ TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
+ Node* lhs = Parameter(Type::String(), 0);
+ Node* rhs = Parameter(Type::String(), 1);
+ Node* context = Parameter(Type::Any(), 2);
+ Node* frame_state0 = EmptyFrameState();
+ Node* frame_state1 = EmptyFrameState();
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Reduction r = Reduce(graph()->NewNode(javascript()->Add(language_mode), lhs,
+ rhs, context, frame_state0,
+ frame_state1, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(
+ r.replacement(),
+ IsCall(_, IsHeapConstant(Unique<HeapObject>::CreateImmovable(
+ CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE,
+ NOT_TENURED).code())),
+ lhs, rhs, context, frame_state0, effect, control));
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+// JSCreateClosure
+
+
TEST_F(JSTypedLoweringTest, JSCreateClosure) {
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
@@ -965,7 +1073,8 @@ TEST_F(JSTypedLoweringTest, JSCreateLiteralObject) {
CodeFactory::FastCloneShallowObject(isolate(), 6).code())),
input0, input1, input2, _, context, frame_state, effect, control));
}
-#endif
+
+#endif // V8_TURBOFAN_TARGET
// -----------------------------------------------------------------------------
diff --git a/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc b/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc
index d5a95ccd1d..1e142550d5 100644
--- a/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc
@@ -57,8 +57,13 @@ class LivenessAnalysisTest : public GraphTest {
Node* locals =
graph()->NewNode(locals_op, locals_count_, &local_inputs.front());
+ const FrameStateFunctionInfo* state_info =
+ common()->CreateFrameStateFunctionInfo(
+ FrameStateType::kJavaScriptFunction, 0, locals_count_,
+ Handle<SharedFunctionInfo>());
+
const Operator* op = common()->FrameState(
- JS_FRAME, BailoutId(ast_num), OutputFrameStateCombine::Ignore());
+ BailoutId(ast_num), OutputFrameStateCombine::Ignore(), state_info);
Node* result = graph()->NewNode(op, empty_values_, locals, empty_values_,
jsgraph()->UndefinedConstant(),
jsgraph()->UndefinedConstant());
@@ -93,8 +98,7 @@ class LivenessAnalysisTest : public GraphTest {
}
DCHECK(frame_state->opcode() == IrOpcode::kFrameState);
- FrameStateCallInfo state_info =
- OpParameter<FrameStateCallInfo>(frame_state);
+ FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
int ast_num = state_info.bailout_id().ToInt();
int first_const = intconst_from_bailout_id(ast_num, locals_count_);
diff --git a/deps/v8/test/unittests/compiler/load-elimination-unittest.cc b/deps/v8/test/unittests/compiler/load-elimination-unittest.cc
index 52c3143e2a..3ad11cf43f 100644
--- a/deps/v8/test/unittests/compiler/load-elimination-unittest.cc
+++ b/deps/v8/test/unittests/compiler/load-elimination-unittest.cc
@@ -19,7 +19,9 @@ class LoadEliminationTest : public GraphTest {
protected:
Reduction Reduce(Node* node) {
- LoadElimination reducer;
+ // TODO(titzer): mock the GraphReducer here for better unit testing.
+ GraphReducer graph_reducer(zone(), graph());
+ LoadElimination reducer(&graph_reducer);
return reducer.Reduce(node);
}
diff --git a/deps/v8/test/unittests/compiler/loop-peeling-unittest.cc b/deps/v8/test/unittests/compiler/loop-peeling-unittest.cc
index d3eff716a7..c725a27cc0 100644
--- a/deps/v8/test/unittests/compiler/loop-peeling-unittest.cc
+++ b/deps/v8/test/unittests/compiler/loop-peeling-unittest.cc
@@ -478,7 +478,8 @@ TEST_F(LoopPeelingTest, TwoExitLoopWithCall_nope) {
Node* call = graph()->NewNode(&kMockCall, b1.if_true);
Node* if_success = graph()->NewNode(common()->IfSuccess(), call);
- Node* if_exception = graph()->NewNode(common()->IfException(), call);
+ Node* if_exception = graph()->NewNode(
+ common()->IfException(IfExceptionHint::kLocallyUncaught), call);
loop->ReplaceInput(1, if_success);
Node* merge = graph()->NewNode(common()->Merge(2), b1.if_false, if_exception);
diff --git a/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc b/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc
index 9836be4fb2..ce11fdef81 100644
--- a/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc
@@ -234,6 +234,10 @@ const uint32_t kUint32Values[] = {
0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff};
+const TruncationMode kTruncationModes[] = {TruncationMode::kJavaScript,
+ TruncationMode::kRoundToZero};
+
+
struct ComparisonBinaryOperator {
const Operator* (MachineOperatorBuilder::*constructor)();
const char* constructor_name;
@@ -258,53 +262,6 @@ const ComparisonBinaryOperator kComparisonBinaryOperators[] = {
// -----------------------------------------------------------------------------
-// Unary operators
-
-
-namespace {
-
-struct UnaryOperator {
- const Operator* (MachineOperatorBuilder::*constructor)();
- const char* constructor_name;
-};
-
-
-std::ostream& operator<<(std::ostream& os, const UnaryOperator& unop) {
- return os << unop.constructor_name;
-}
-
-
-static const UnaryOperator kUnaryOperators[] = {
- {&MachineOperatorBuilder::ChangeInt32ToFloat64, "ChangeInt32ToFloat64"},
- {&MachineOperatorBuilder::ChangeUint32ToFloat64, "ChangeUint32ToFloat64"},
- {&MachineOperatorBuilder::ChangeFloat64ToInt32, "ChangeFloat64ToInt32"},
- {&MachineOperatorBuilder::ChangeFloat64ToUint32, "ChangeFloat64ToUint32"},
- {&MachineOperatorBuilder::ChangeInt32ToInt64, "ChangeInt32ToInt64"},
- {&MachineOperatorBuilder::ChangeUint32ToUint64, "ChangeUint32ToUint64"},
- {&MachineOperatorBuilder::TruncateFloat64ToInt32, "TruncateFloat64ToInt32"},
- {&MachineOperatorBuilder::TruncateInt64ToInt32, "TruncateInt64ToInt32"}};
-
-} // namespace
-
-
-typedef MachineOperatorReducerTestWithParam<UnaryOperator>
- MachineUnaryOperatorReducerTest;
-
-
-TEST_P(MachineUnaryOperatorReducerTest, Parameter) {
- const UnaryOperator unop = GetParam();
- Reduction reduction =
- Reduce(graph()->NewNode((machine()->*unop.constructor)(), Parameter(0)));
- EXPECT_FALSE(reduction.Changed());
-}
-
-
-INSTANTIATE_TEST_CASE_P(MachineOperatorReducerTest,
- MachineUnaryOperatorReducerTest,
- ::testing::ValuesIn(kUnaryOperators));
-
-
-// -----------------------------------------------------------------------------
// ChangeFloat64ToFloat32
@@ -459,19 +416,22 @@ TEST_F(MachineOperatorReducerTest, TruncateFloat64ToFloat32WithConstant) {
TEST_F(MachineOperatorReducerTest,
TruncateFloat64ToInt32WithChangeInt32ToFloat64) {
- Node* value = Parameter(0);
- Reduction reduction = Reduce(graph()->NewNode(
- machine()->TruncateFloat64ToInt32(),
- graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
- ASSERT_TRUE(reduction.Changed());
- EXPECT_EQ(value, reduction.replacement());
+ TRACED_FOREACH(TruncationMode, mode, kTruncationModes) {
+ Node* value = Parameter(0);
+ Reduction reduction = Reduce(graph()->NewNode(
+ machine()->TruncateFloat64ToInt32(mode),
+ graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
+ ASSERT_TRUE(reduction.Changed());
+ EXPECT_EQ(value, reduction.replacement());
+ }
}
TEST_F(MachineOperatorReducerTest, TruncateFloat64ToInt32WithConstant) {
TRACED_FOREACH(double, x, kFloat64Values) {
Reduction reduction = Reduce(graph()->NewNode(
- machine()->TruncateFloat64ToInt32(), Float64Constant(x)));
+ machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript),
+ Float64Constant(x)));
ASSERT_TRUE(reduction.Changed());
EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(x)));
}
@@ -482,13 +442,15 @@ TEST_F(MachineOperatorReducerTest, TruncateFloat64ToInt32WithPhi) {
Node* const p0 = Parameter(0);
Node* const p1 = Parameter(1);
Node* const merge = graph()->start();
- Reduction reduction = Reduce(graph()->NewNode(
- machine()->TruncateFloat64ToInt32(),
- graph()->NewNode(common()->Phi(kMachFloat64, 2), p0, p1, merge)));
- ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(),
- IsPhi(kMachInt32, IsTruncateFloat64ToInt32(p0),
- IsTruncateFloat64ToInt32(p1), merge));
+ TRACED_FOREACH(TruncationMode, mode, kTruncationModes) {
+ Reduction reduction = Reduce(graph()->NewNode(
+ machine()->TruncateFloat64ToInt32(mode),
+ graph()->NewNode(common()->Phi(kMachFloat64, 2), p0, p1, merge)));
+ ASSERT_TRUE(reduction.Changed());
+ EXPECT_THAT(reduction.replacement(),
+ IsPhi(kMachInt32, IsTruncateFloat64ToInt32(p0),
+ IsTruncateFloat64ToInt32(p1), merge));
+ }
}
diff --git a/deps/v8/test/unittests/compiler/machine-operator-unittest.cc b/deps/v8/test/unittests/compiler/machine-operator-unittest.cc
index 31f55793c3..fca53e2bd8 100644
--- a/deps/v8/test/unittests/compiler/machine-operator-unittest.cc
+++ b/deps/v8/test/unittests/compiler/machine-operator-unittest.cc
@@ -149,130 +149,199 @@ INSTANTIATE_TEST_CASE_P(
::testing::Combine(::testing::ValuesIn(kMachineTypes),
::testing::Values(kNoWriteBarrier,
kFullWriteBarrier))));
-
+#endif
// -----------------------------------------------------------------------------
// Pure operators.
-
namespace {
struct PureOperator {
const Operator* (MachineOperatorBuilder::*constructor)();
- IrOpcode::Value opcode;
+ char const* const constructor_name;
int value_input_count;
int control_input_count;
int value_output_count;
};
-std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
- return os << IrOpcode::Mnemonic(pop.opcode);
+std::ostream& operator<<(std::ostream& os, PureOperator const& pop) {
+ return os << pop.constructor_name;
}
-
const PureOperator kPureOperators[] = {
#define PURE(Name, value_input_count, control_input_count, value_output_count) \
{ \
- &MachineOperatorBuilder::Name, IrOpcode::k##Name, value_input_count, \
+ &MachineOperatorBuilder::Name, #Name, value_input_count, \
control_input_count, value_output_count \
}
- PURE(Word32And, 2, 0, 1), PURE(Word32Or, 2, 0, 1), PURE(Word32Xor, 2, 0, 1),
- PURE(Word32Shl, 2, 0, 1), PURE(Word32Shr, 2, 0, 1),
- PURE(Word32Sar, 2, 0, 1), PURE(Word32Ror, 2, 0, 1),
- PURE(Word32Equal, 2, 0, 1), PURE(Word32Clz, 1, 0, 1),
- PURE(Word64And, 2, 0, 1), PURE(Word64Or, 2, 0, 1), PURE(Word64Xor, 2, 0, 1),
- PURE(Word64Shl, 2, 0, 1), PURE(Word64Shr, 2, 0, 1),
- PURE(Word64Sar, 2, 0, 1), PURE(Word64Ror, 2, 0, 1),
- PURE(Word64Equal, 2, 0, 1), PURE(Int32Add, 2, 0, 1),
- PURE(Int32AddWithOverflow, 2, 0, 2), PURE(Int32Sub, 2, 0, 1),
- PURE(Int32SubWithOverflow, 2, 0, 2), PURE(Int32Mul, 2, 0, 1),
- PURE(Int32MulHigh, 2, 0, 1), PURE(Int32Div, 2, 1, 1),
- PURE(Uint32Div, 2, 1, 1), PURE(Int32Mod, 2, 1, 1), PURE(Uint32Mod, 2, 1, 1),
- PURE(Int32LessThan, 2, 0, 1), PURE(Int32LessThanOrEqual, 2, 0, 1),
- PURE(Uint32LessThan, 2, 0, 1), PURE(Uint32LessThanOrEqual, 2, 0, 1),
- PURE(Int64Add, 2, 0, 1), PURE(Int64Sub, 2, 0, 1), PURE(Int64Mul, 2, 0, 1),
- PURE(Int64Div, 2, 0, 1), PURE(Uint64Div, 2, 0, 1), PURE(Int64Mod, 2, 0, 1),
- PURE(Uint64Mod, 2, 0, 1), PURE(Int64LessThan, 2, 0, 1),
- PURE(Int64LessThanOrEqual, 2, 0, 1), PURE(Uint64LessThan, 2, 0, 1),
- PURE(ChangeFloat32ToFloat64, 1, 0, 1), PURE(ChangeFloat64ToInt32, 1, 0, 1),
- PURE(ChangeFloat64ToUint32, 1, 0, 1), PURE(ChangeInt32ToInt64, 1, 0, 1),
- PURE(ChangeUint32ToFloat64, 1, 0, 1), PURE(ChangeUint32ToUint64, 1, 0, 1),
- PURE(TruncateFloat64ToFloat32, 1, 0, 1),
- PURE(TruncateFloat64ToInt32, 1, 0, 1), PURE(TruncateInt64ToInt32, 1, 0, 1),
- PURE(Float32Add, 2, 0, 1), PURE(Float32Sub, 2, 0, 1),
- PURE(Float32Mul, 2, 0, 1), PURE(Float32Div, 2, 0, 1),
- PURE(Float32Abs, 1, 0, 1), PURE(Float32Sqrt, 1, 0, 1),
- PURE(Float32Equal, 2, 0, 1), PURE(Float32LessThan, 2, 0, 1),
- PURE(Float32LessThanOrEqual, 2, 0, 1), PURE(Float32Max, 2, 0, 1),
- PURE(Float32Min, 2, 0, 1), PURE(Float64Add, 2, 0, 1),
- PURE(Float64Sub, 2, 0, 1), PURE(Float64Mul, 2, 0, 1),
- PURE(Float64Div, 2, 0, 1), PURE(Float64Mod, 2, 0, 1),
- PURE(Float64Abs, 1, 0, 1), PURE(Float64Sqrt, 1, 0, 1),
- PURE(Float64Equal, 2, 0, 1), PURE(Float64LessThan, 2, 0, 1),
- PURE(Float64LessThanOrEqual, 2, 0, 1), PURE(Float64Max, 2, 0, 1),
- PURE(Float64Min, 2, 0, 1), PURE(LoadStackPointer, 0, 0, 1),
- PURE(Float64RoundDown, 1, 0, 1), PURE(Float64RoundTruncate, 1, 0, 1),
- PURE(Float64RoundTiesAway, 1, 0, 1), PURE(Float64ExtractLowWord32, 1, 0, 1),
- PURE(Float64ExtractHighWord32, 1, 0, 1),
- PURE(Float64InsertLowWord32, 2, 0, 1),
- PURE(Float64InsertHighWord32, 2, 0, 1)
+ PURE(Word32And, 2, 0, 1), // --
+ PURE(Word32Or, 2, 0, 1), // --
+ PURE(Word32Xor, 2, 0, 1), // --
+ PURE(Word32Shl, 2, 0, 1), // --
+ PURE(Word32Shr, 2, 0, 1), // --
+ PURE(Word32Sar, 2, 0, 1), // --
+ PURE(Word32Ror, 2, 0, 1), // --
+ PURE(Word32Equal, 2, 0, 1), // --
+ PURE(Word32Clz, 1, 0, 1), // --
+ PURE(Word64And, 2, 0, 1), // --
+ PURE(Word64Or, 2, 0, 1), // --
+ PURE(Word64Xor, 2, 0, 1), // --
+ PURE(Word64Shl, 2, 0, 1), // --
+ PURE(Word64Shr, 2, 0, 1), // --
+ PURE(Word64Sar, 2, 0, 1), // --
+ PURE(Word64Ror, 2, 0, 1), // --
+ PURE(Word64Equal, 2, 0, 1), // --
+ PURE(Int32Add, 2, 0, 1), // --
+ PURE(Int32AddWithOverflow, 2, 0, 2), // --
+ PURE(Int32Sub, 2, 0, 1), // --
+ PURE(Int32SubWithOverflow, 2, 0, 2), // --
+ PURE(Int32Mul, 2, 0, 1), // --
+ PURE(Int32MulHigh, 2, 0, 1), // --
+ PURE(Int32Div, 2, 1, 1), // --
+ PURE(Uint32Div, 2, 1, 1), // --
+ PURE(Int32Mod, 2, 1, 1), // --
+ PURE(Uint32Mod, 2, 1, 1), // --
+ PURE(Int32LessThan, 2, 0, 1), // --
+ PURE(Int32LessThanOrEqual, 2, 0, 1), // --
+ PURE(Uint32LessThan, 2, 0, 1), // --
+ PURE(Uint32LessThanOrEqual, 2, 0, 1), // --
+ PURE(Int64Add, 2, 0, 1), // --
+ PURE(Int64Sub, 2, 0, 1), // --
+ PURE(Int64Mul, 2, 0, 1), // --
+ PURE(Int64Div, 2, 1, 1), // --
+ PURE(Uint64Div, 2, 1, 1), // --
+ PURE(Int64Mod, 2, 1, 1), // --
+ PURE(Uint64Mod, 2, 1, 1), // --
+ PURE(Int64LessThan, 2, 0, 1), // --
+ PURE(Int64LessThanOrEqual, 2, 0, 1), // --
+ PURE(Uint64LessThan, 2, 0, 1), // --
+ PURE(Uint64LessThanOrEqual, 2, 0, 1), // --
+ PURE(ChangeFloat32ToFloat64, 1, 0, 1), // --
+ PURE(ChangeFloat64ToInt32, 1, 0, 1), // --
+ PURE(ChangeFloat64ToUint32, 1, 0, 1), // --
+ PURE(ChangeInt32ToInt64, 1, 0, 1), // --
+ PURE(ChangeUint32ToFloat64, 1, 0, 1), // --
+ PURE(ChangeUint32ToUint64, 1, 0, 1), // --
+ PURE(TruncateFloat64ToFloat32, 1, 0, 1), // --
+ PURE(TruncateInt64ToInt32, 1, 0, 1), // --
+ PURE(Float32Abs, 1, 0, 1), // --
+ PURE(Float32Add, 2, 0, 1), // --
+ PURE(Float32Sub, 2, 0, 1), // --
+ PURE(Float32Mul, 2, 0, 1), // --
+ PURE(Float32Div, 2, 0, 1), // --
+ PURE(Float32Sqrt, 1, 0, 1), // --
+ PURE(Float32Equal, 2, 0, 1), // --
+ PURE(Float32LessThan, 2, 0, 1), // --
+ PURE(Float32LessThanOrEqual, 2, 0, 1), // --
+ PURE(Float64Abs, 1, 0, 1), // --
+ PURE(Float64Add, 2, 0, 1), // --
+ PURE(Float64Sub, 2, 0, 1), // --
+ PURE(Float64Mul, 2, 0, 1), // --
+ PURE(Float64Div, 2, 0, 1), // --
+ PURE(Float64Mod, 2, 0, 1), // --
+ PURE(Float64Sqrt, 1, 0, 1), // --
+ PURE(Float64Equal, 2, 0, 1), // --
+ PURE(Float64LessThan, 2, 0, 1), // --
+ PURE(Float64LessThanOrEqual, 2, 0, 1), // --
+ PURE(LoadStackPointer, 0, 0, 1), // --
+ PURE(Float64ExtractLowWord32, 1, 0, 1), // --
+ PURE(Float64ExtractHighWord32, 1, 0, 1), // --
+ PURE(Float64InsertLowWord32, 2, 0, 1), // --
+ PURE(Float64InsertHighWord32, 2, 0, 1), // --
#undef PURE
};
-
-typedef MachineOperatorTestWithParam<PureOperator> MachinePureOperatorTest;
-
} // namespace
+class MachinePureOperatorTest : public TestWithZone {
+ protected:
+ MachineType word_type() { return kMachPtr; }
+};
-TEST_P(MachinePureOperatorTest, InstancesAreGloballyShared) {
- const PureOperator& pop = GetParam();
- MachineOperatorBuilder machine1(zone(), type());
- MachineOperatorBuilder machine2(zone(), type());
- EXPECT_EQ((machine1.*pop.constructor)(), (machine2.*pop.constructor)());
+
+TEST_F(MachinePureOperatorTest, PureOperators) {
+ TRACED_FOREACH(MachineType, machine_rep1, kMachineReps) {
+ MachineOperatorBuilder machine1(zone(), machine_rep1);
+ TRACED_FOREACH(MachineType, machine_rep2, kMachineReps) {
+ MachineOperatorBuilder machine2(zone(), machine_rep2);
+ TRACED_FOREACH(PureOperator, pop, kPureOperators) {
+ const Operator* op1 = (machine1.*pop.constructor)();
+ const Operator* op2 = (machine2.*pop.constructor)();
+ EXPECT_EQ(op1, op2);
+ EXPECT_EQ(pop.value_input_count, op1->ValueInputCount());
+ EXPECT_EQ(pop.control_input_count, op1->ControlInputCount());
+ EXPECT_EQ(pop.value_output_count, op1->ValueOutputCount());
+ }
+ }
+ }
}
-TEST_P(MachinePureOperatorTest, NumberOfInputsAndOutputs) {
- MachineOperatorBuilder machine(zone(), type());
- const PureOperator& pop = GetParam();
- const Operator* op = (machine.*pop.constructor)();
+// Optional operators.
- EXPECT_EQ(pop.value_input_count, op->ValueInputCount());
- EXPECT_EQ(0, op->EffectInputCount());
- EXPECT_EQ(pop.control_input_count, op->ControlInputCount());
- EXPECT_EQ(pop.value_input_count + pop.control_input_count,
- OperatorProperties::GetTotalInputCount(op));
+namespace {
- EXPECT_EQ(pop.value_output_count, op->ValueOutputCount());
- EXPECT_EQ(0, op->EffectOutputCount());
- EXPECT_EQ(0, op->ControlOutputCount());
-}
+struct OptionalOperatorEntry {
+ const OptionalOperator (MachineOperatorBuilder::*constructor)();
+ MachineOperatorBuilder::Flag enabling_flag;
+ char const* const constructor_name;
+ int value_input_count;
+ int control_input_count;
+ int value_output_count;
+};
-TEST_P(MachinePureOperatorTest, MarkedAsPure) {
- MachineOperatorBuilder machine(zone(), type());
- const PureOperator& pop = GetParam();
- const Operator* op = (machine.*pop.constructor)();
- EXPECT_TRUE(op->HasProperty(Operator::kPure));
+std::ostream& operator<<(std::ostream& os, OptionalOperatorEntry const& pop) {
+ return os << pop.constructor_name;
}
+const OptionalOperatorEntry kOptionalOperators[] = {
+#define OPTIONAL_ENTRY(Name, value_input_count, control_input_count, \
+ value_output_count) \
+ { \
+ &MachineOperatorBuilder::Name, MachineOperatorBuilder::k##Name, #Name, \
+ value_input_count, control_input_count, value_output_count \
+ }
+ OPTIONAL_ENTRY(Float32Max, 2, 0, 1), // --
+ OPTIONAL_ENTRY(Float32Min, 2, 0, 1), // --
+ OPTIONAL_ENTRY(Float64Max, 2, 0, 1), // --
+ OPTIONAL_ENTRY(Float64Min, 2, 0, 1), // --
+ OPTIONAL_ENTRY(Float64RoundDown, 1, 0, 1), // --
+ OPTIONAL_ENTRY(Float64RoundTruncate, 1, 0, 1), // --
+ OPTIONAL_ENTRY(Float64RoundTiesAway, 1, 0, 1), // --
+#undef OPTIONAL_ENTRY
+};
+} // namespace
-TEST_P(MachinePureOperatorTest, OpcodeIsCorrect) {
- MachineOperatorBuilder machine(zone(), type());
- const PureOperator& pop = GetParam();
- const Operator* op = (machine.*pop.constructor)();
- EXPECT_EQ(pop.opcode, op->opcode());
-}
+class MachineOptionalOperatorTest : public TestWithZone {
+ protected:
+ MachineType word_type() { return kMachPtr; }
+};
-INSTANTIATE_TEST_CASE_P(
- MachineOperatorTest, MachinePureOperatorTest,
- ::testing::Combine(::testing::ValuesIn(kMachineReps),
- ::testing::ValuesIn(kPureOperators)));
-#endif // GTEST_HAS_COMBINE
+TEST_F(MachineOptionalOperatorTest, OptionalOperators) {
+ TRACED_FOREACH(OptionalOperatorEntry, pop, kOptionalOperators) {
+ TRACED_FOREACH(MachineType, machine_rep1, kMachineReps) {
+ MachineOperatorBuilder machine1(zone(), machine_rep1, pop.enabling_flag);
+ TRACED_FOREACH(MachineType, machine_rep2, kMachineReps) {
+ MachineOperatorBuilder machine2(zone(), machine_rep2,
+ pop.enabling_flag);
+ const Operator* op1 = (machine1.*pop.constructor)().op();
+ const Operator* op2 = (machine2.*pop.constructor)().op();
+ EXPECT_EQ(op1, op2);
+ EXPECT_EQ(pop.value_input_count, op1->ValueInputCount());
+ EXPECT_EQ(pop.control_input_count, op1->ControlInputCount());
+ EXPECT_EQ(pop.value_output_count, op1->ValueOutputCount());
+
+ MachineOperatorBuilder machine3(zone(), word_type());
+ EXPECT_TRUE((machine1.*pop.constructor)().IsSupported());
+ EXPECT_FALSE((machine3.*pop.constructor)().IsSupported());
+ }
+ }
+ }
+}
// -----------------------------------------------------------------------------
diff --git a/deps/v8/test/unittests/compiler/node-properties-unittest.cc b/deps/v8/test/unittests/compiler/node-properties-unittest.cc
index 2bec4faf4d..463948d43f 100644
--- a/deps/v8/test/unittests/compiler/node-properties-unittest.cc
+++ b/deps/v8/test/unittests/compiler/node-properties-unittest.cc
@@ -10,78 +10,72 @@
using testing::AnyOf;
using testing::ElementsAre;
using testing::IsNull;
-using testing::UnorderedElementsAre;
namespace v8 {
namespace internal {
namespace compiler {
-typedef TestWithZone NodePropertiesTest;
-
+class NodePropertiesTest : public TestWithZone {
+ public:
+ Node* NewMockNode(const Operator* op) {
+ return Node::New(zone(), 0, op, 0, nullptr, false);
+ }
+ Node* NewMockNode(const Operator* op, Node* n1) {
+ Node* nodes[] = {n1};
+ return Node::New(zone(), 0, op, arraysize(nodes), nodes, false);
+ }
+ Node* NewMockNode(const Operator* op, Node* n1, Node* n2) {
+ Node* nodes[] = {n1, n2};
+ return Node::New(zone(), 0, op, arraysize(nodes), nodes, false);
+ }
+};
namespace {
const Operator kMockOperator(IrOpcode::kDead, Operator::kNoProperties,
- "MockOperator", 0, 0, 0, 1, 0, 0);
-const Operator kMockOpEffect(IrOpcode::kDead, Operator::kNoProperties,
- "MockOpEffect", 0, 1, 0, 1, 1, 0);
-const Operator kMockOpControl(IrOpcode::kDead, Operator::kNoProperties,
- "MockOpControl", 0, 0, 1, 1, 0, 1);
+ "MockOperator", 0, 0, 0, 1, 1, 2);
const Operator kMockCallOperator(IrOpcode::kCall, Operator::kNoProperties,
"MockCallOperator", 0, 0, 0, 0, 0, 2);
-} // namespace
-
-
-TEST_F(NodePropertiesTest, ReplaceWithValue_ValueUse) {
- CommonOperatorBuilder common(zone());
- Node* node = Node::New(zone(), 0, &kMockOperator, 0, nullptr, false);
- Node* use_value = Node::New(zone(), 0, common.Return(), 1, &node, false);
- Node* replacement = Node::New(zone(), 0, &kMockOperator, 0, nullptr, false);
- NodeProperties::ReplaceWithValue(node, replacement);
- EXPECT_EQ(replacement, use_value->InputAt(0));
- EXPECT_EQ(0, node->UseCount());
- EXPECT_EQ(1, replacement->UseCount());
- EXPECT_THAT(replacement->uses(), ElementsAre(use_value));
-}
-
+const IfExceptionHint kNoHint = IfExceptionHint::kLocallyCaught;
-TEST_F(NodePropertiesTest, ReplaceWithValue_EffectUse) {
- CommonOperatorBuilder common(zone());
- Node* start = Node::New(zone(), 0, common.Start(1), 0, nullptr, false);
- Node* node = Node::New(zone(), 0, &kMockOpEffect, 1, &start, false);
- Node* use_effect = Node::New(zone(), 0, common.EffectPhi(1), 1, &node, false);
- Node* replacement = Node::New(zone(), 0, &kMockOperator, 0, nullptr, false);
- NodeProperties::ReplaceWithValue(node, replacement);
- EXPECT_EQ(start, use_effect->InputAt(0));
- EXPECT_EQ(0, node->UseCount());
- EXPECT_EQ(2, start->UseCount());
- EXPECT_EQ(0, replacement->UseCount());
- EXPECT_THAT(start->uses(), UnorderedElementsAre(use_effect, node));
-}
+} // namespace
-TEST_F(NodePropertiesTest, ReplaceWithValue_ControlUse) {
+TEST_F(NodePropertiesTest, ReplaceUses) {
CommonOperatorBuilder common(zone());
- Node* start = Node::New(zone(), 0, common.Start(1), 0, nullptr, false);
- Node* node = Node::New(zone(), 0, &kMockOpControl, 1, &start, false);
- Node* success = Node::New(zone(), 0, common.IfSuccess(), 1, &node, false);
- Node* use_control = Node::New(zone(), 0, common.Merge(1), 1, &success, false);
- Node* replacement = Node::New(zone(), 0, &kMockOperator, 0, nullptr, false);
- NodeProperties::ReplaceWithValue(node, replacement);
- EXPECT_EQ(start, use_control->InputAt(0));
+ Node* node = NewMockNode(&kMockOperator);
+ Node* effect = NewMockNode(&kMockOperator);
+ Node* use_value = NewMockNode(common.Return(), node);
+ Node* use_effect = NewMockNode(common.EffectPhi(1), node);
+ Node* use_success = NewMockNode(common.IfSuccess(), node);
+ Node* use_exception = NewMockNode(common.IfException(kNoHint), effect, node);
+ Node* r_value = NewMockNode(&kMockOperator);
+ Node* r_effect = NewMockNode(&kMockOperator);
+ Node* r_success = NewMockNode(&kMockOperator);
+ Node* r_exception = NewMockNode(&kMockOperator);
+ NodeProperties::ReplaceUses(node, r_value, r_effect, r_success, r_exception);
+ EXPECT_EQ(r_value, use_value->InputAt(0));
+ EXPECT_EQ(r_effect, use_effect->InputAt(0));
+ EXPECT_EQ(r_success, use_success->InputAt(0));
+ EXPECT_EQ(r_exception, use_exception->InputAt(1));
EXPECT_EQ(0, node->UseCount());
- EXPECT_EQ(2, start->UseCount());
- EXPECT_EQ(0, replacement->UseCount());
- EXPECT_THAT(start->uses(), UnorderedElementsAre(use_control, node));
+ EXPECT_EQ(1, r_value->UseCount());
+ EXPECT_EQ(1, r_effect->UseCount());
+ EXPECT_EQ(1, r_success->UseCount());
+ EXPECT_EQ(1, r_exception->UseCount());
+ EXPECT_THAT(r_value->uses(), ElementsAre(use_value));
+ EXPECT_THAT(r_effect->uses(), ElementsAre(use_effect));
+ EXPECT_THAT(r_success->uses(), ElementsAre(use_success));
+ EXPECT_THAT(r_exception->uses(), ElementsAre(use_exception));
}
TEST_F(NodePropertiesTest, FindProjection) {
CommonOperatorBuilder common(zone());
- Node* start = Node::New(zone(), 0, common.Start(1), 0, nullptr, false);
- Node* proj0 = Node::New(zone(), 1, common.Projection(0), 1, &start, false);
- Node* proj1 = Node::New(zone(), 2, common.Projection(1), 1, &start, false);
+ Node* start = NewMockNode(common.Start(1));
+ Node* proj0 = NewMockNode(common.Projection(0), start);
+ Node* proj1 = NewMockNode(common.Projection(1), start);
EXPECT_EQ(proj0, NodeProperties::FindProjection(start, 0));
EXPECT_EQ(proj1, NodeProperties::FindProjection(start, 1));
EXPECT_THAT(NodeProperties::FindProjection(start, 2), IsNull());
@@ -92,9 +86,9 @@ TEST_F(NodePropertiesTest, FindProjection) {
TEST_F(NodePropertiesTest, CollectControlProjections_Branch) {
Node* result[2];
CommonOperatorBuilder common(zone());
- Node* branch = Node::New(zone(), 1, common.Branch(), 0, nullptr, false);
- Node* if_false = Node::New(zone(), 2, common.IfFalse(), 1, &branch, false);
- Node* if_true = Node::New(zone(), 3, common.IfTrue(), 1, &branch, false);
+ Node* branch = NewMockNode(common.Branch());
+ Node* if_false = NewMockNode(common.IfFalse(), branch);
+ Node* if_true = NewMockNode(common.IfTrue(), branch);
NodeProperties::CollectControlProjections(branch, result, arraysize(result));
EXPECT_EQ(if_true, result[0]);
EXPECT_EQ(if_false, result[1]);
@@ -104,9 +98,9 @@ TEST_F(NodePropertiesTest, CollectControlProjections_Branch) {
TEST_F(NodePropertiesTest, CollectControlProjections_Call) {
Node* result[2];
CommonOperatorBuilder common(zone());
- Node* call = Node::New(zone(), 1, &kMockCallOperator, 0, nullptr, false);
- Node* if_ex = Node::New(zone(), 2, common.IfException(), 1, &call, false);
- Node* if_ok = Node::New(zone(), 3, common.IfSuccess(), 1, &call, false);
+ Node* call = NewMockNode(&kMockCallOperator);
+ Node* if_ex = NewMockNode(common.IfException(kNoHint), call, call);
+ Node* if_ok = NewMockNode(common.IfSuccess(), call);
NodeProperties::CollectControlProjections(call, result, arraysize(result));
EXPECT_EQ(if_ok, result[0]);
EXPECT_EQ(if_ex, result[1]);
@@ -116,10 +110,10 @@ TEST_F(NodePropertiesTest, CollectControlProjections_Call) {
TEST_F(NodePropertiesTest, CollectControlProjections_Switch) {
Node* result[3];
CommonOperatorBuilder common(zone());
- Node* sw = Node::New(zone(), 1, common.Switch(3), 0, nullptr, false);
- Node* if_default = Node::New(zone(), 2, common.IfDefault(), 1, &sw, false);
- Node* if_value1 = Node::New(zone(), 3, common.IfValue(1), 1, &sw, false);
- Node* if_value2 = Node::New(zone(), 4, common.IfValue(2), 1, &sw, false);
+ Node* sw = NewMockNode(common.Switch(3));
+ Node* if_default = NewMockNode(common.IfDefault(), sw);
+ Node* if_value1 = NewMockNode(common.IfValue(1), sw);
+ Node* if_value2 = NewMockNode(common.IfValue(2), sw);
NodeProperties::CollectControlProjections(sw, result, arraysize(result));
EXPECT_THAT(result[0], AnyOf(if_value1, if_value2));
EXPECT_THAT(result[1], AnyOf(if_value1, if_value2));
diff --git a/deps/v8/test/unittests/compiler/node-test-utils.cc b/deps/v8/test/unittests/compiler/node-test-utils.cc
index e6201ec67f..520ce0159e 100644
--- a/deps/v8/test/unittests/compiler/node-test-utils.cc
+++ b/deps/v8/test/unittests/compiler/node-test-utils.cc
@@ -7,6 +7,7 @@
#include <vector>
#include "src/assembler.h"
+#include "src/compiler/js-operator.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/simplified-operator.h"
#include "src/unique.h"
@@ -748,6 +749,32 @@ class IsTailCallMatcher final : public NodeMatcher {
};
+class IsReferenceEqualMatcher final : public NodeMatcher {
+ public:
+ IsReferenceEqualMatcher(const Matcher<Type*>& type_matcher,
+ const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher)
+ : NodeMatcher(IrOpcode::kReferenceEqual),
+ type_matcher_(type_matcher),
+ lhs_matcher_(lhs_matcher),
+ rhs_matcher_(rhs_matcher) {}
+
+ bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
+ return (NodeMatcher::MatchAndExplain(node, listener) &&
+ // TODO(bmeurer): The type parameter is currently ignored.
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
+ lhs_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
+ rhs_matcher_, listener));
+ }
+
+ private:
+ const Matcher<Type*> type_matcher_;
+ const Matcher<Node*> lhs_matcher_;
+ const Matcher<Node*> rhs_matcher_;
+};
+
+
class IsAllocateMatcher final : public NodeMatcher {
public:
IsAllocateMatcher(const Matcher<Node*>& size_matcher,
@@ -1160,24 +1187,32 @@ class IsLoadMatcher final : public NodeMatcher {
};
-class IsToNumberMatcher final : public NodeMatcher {
+class IsStoreMatcher final : public NodeMatcher {
public:
- IsToNumberMatcher(const Matcher<Node*>& base_matcher,
- const Matcher<Node*>& context_matcher,
- const Matcher<Node*>& effect_matcher,
- const Matcher<Node*>& control_matcher)
- : NodeMatcher(IrOpcode::kJSToNumber),
+ IsStoreMatcher(const Matcher<StoreRepresentation>& rep_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),
+ rep_matcher_(rep_matcher),
base_matcher_(base_matcher),
- context_matcher_(context_matcher),
+ index_matcher_(index_matcher),
+ value_matcher_(value_matcher),
effect_matcher_(effect_matcher),
control_matcher_(control_matcher) {}
void DescribeTo(std::ostream* os) const final {
NodeMatcher::DescribeTo(os);
- *os << " whose base (";
+ *os << " whose rep (";
+ rep_matcher_.DescribeTo(os);
+ *os << "), base (";
base_matcher_.DescribeTo(os);
- *os << "), context (";
- context_matcher_.DescribeTo(os);
+ *os << "), index (";
+ index_matcher_.DescribeTo(os);
+ *os << "), value (";
+ value_matcher_.DescribeTo(os);
*os << "), effect (";
effect_matcher_.DescribeTo(os);
*os << ") and control (";
@@ -1187,10 +1222,14 @@ class IsToNumberMatcher final : public NodeMatcher {
bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(OpParameter<StoreRepresentation>(node), "rep",
+ rep_matcher_, listener) &&
PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
base_matcher_, listener) &&
- PrintMatchAndExplain(NodeProperties::GetContextInput(node),
- "context", context_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),
@@ -1198,39 +1237,33 @@ class IsToNumberMatcher final : public NodeMatcher {
}
private:
+ const Matcher<StoreRepresentation> rep_matcher_;
const Matcher<Node*> base_matcher_;
- const Matcher<Node*> context_matcher_;
+ const Matcher<Node*> index_matcher_;
+ const Matcher<Node*> value_matcher_;
const Matcher<Node*> effect_matcher_;
const Matcher<Node*> control_matcher_;
};
-class IsStoreMatcher final : public NodeMatcher {
+class IsToNumberMatcher final : public NodeMatcher {
public:
- IsStoreMatcher(const Matcher<StoreRepresentation>& rep_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),
- rep_matcher_(rep_matcher),
+ IsToNumberMatcher(const Matcher<Node*>& base_matcher,
+ const Matcher<Node*>& context_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher)
+ : NodeMatcher(IrOpcode::kJSToNumber),
base_matcher_(base_matcher),
- index_matcher_(index_matcher),
- value_matcher_(value_matcher),
+ context_matcher_(context_matcher),
effect_matcher_(effect_matcher),
control_matcher_(control_matcher) {}
void DescribeTo(std::ostream* os) const final {
NodeMatcher::DescribeTo(os);
- *os << " whose rep (";
- rep_matcher_.DescribeTo(os);
- *os << "), base (";
+ *os << " whose base (";
base_matcher_.DescribeTo(os);
- *os << "), index (";
- index_matcher_.DescribeTo(os);
- *os << "), value (";
- value_matcher_.DescribeTo(os);
+ *os << "), context (";
+ context_matcher_.DescribeTo(os);
*os << "), effect (";
effect_matcher_.DescribeTo(os);
*os << ") and control (";
@@ -1240,14 +1273,10 @@ class IsStoreMatcher final : public NodeMatcher {
bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
return (NodeMatcher::MatchAndExplain(node, listener) &&
- PrintMatchAndExplain(OpParameter<StoreRepresentation>(node), "rep",
- rep_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::GetContextInput(node),
+ "context", context_matcher_, listener) &&
PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
effect_matcher_, listener) &&
PrintMatchAndExplain(NodeProperties::GetControlInput(node),
@@ -1255,15 +1284,44 @@ class IsStoreMatcher final : public NodeMatcher {
}
private:
- const Matcher<StoreRepresentation> rep_matcher_;
const Matcher<Node*> base_matcher_;
- const Matcher<Node*> index_matcher_;
- const Matcher<Node*> value_matcher_;
+ const Matcher<Node*> context_matcher_;
const Matcher<Node*> effect_matcher_;
const Matcher<Node*> control_matcher_;
};
+class IsLoadContextMatcher final : public NodeMatcher {
+ public:
+ IsLoadContextMatcher(const Matcher<ContextAccess>& access_matcher,
+ const Matcher<Node*>& context_matcher)
+ : NodeMatcher(IrOpcode::kJSLoadContext),
+ access_matcher_(access_matcher),
+ context_matcher_(context_matcher) {}
+
+ void DescribeTo(std::ostream* os) const final {
+ NodeMatcher::DescribeTo(os);
+ *os << " whose access (";
+ access_matcher_.DescribeTo(os);
+ *os << ") and context (";
+ context_matcher_.DescribeTo(os);
+ *os << ")";
+ }
+
+ bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
+ return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(OpParameter<ContextAccess>(node), "access",
+ access_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetContextInput(node),
+ "context", context_matcher_, listener));
+ }
+
+ private:
+ const Matcher<ContextAccess> access_matcher_;
+ const Matcher<Node*> context_matcher_;
+};
+
+
class IsBinopMatcher final : public NodeMatcher {
public:
IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher,
@@ -1320,8 +1378,28 @@ class IsUnopMatcher final : public NodeMatcher {
} // namespace
-Matcher<Node*> IsEnd(const Matcher<Node*>& control_matcher) {
- return MakeMatcher(new IsControl1Matcher(IrOpcode::kEnd, control_matcher));
+Matcher<Node*> IsDead() {
+ return MakeMatcher(new NodeMatcher(IrOpcode::kDead));
+}
+
+
+Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher) {
+ return MakeMatcher(new IsControl1Matcher(IrOpcode::kEnd, control0_matcher));
+}
+
+
+Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher,
+ const Matcher<Node*>& control1_matcher) {
+ return MakeMatcher(new IsControl2Matcher(IrOpcode::kEnd, control0_matcher,
+ control1_matcher));
+}
+
+
+Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher,
+ const Matcher<Node*>& control1_matcher,
+ const Matcher<Node*>& control2_matcher) {
+ return MakeMatcher(new IsControl3Matcher(IrOpcode::kEnd, control0_matcher,
+ control1_matcher, control2_matcher));
}
@@ -1600,6 +1678,14 @@ Matcher<Node*> IsTailCall(
}
+Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher,
+ const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher) {
+ return MakeMatcher(
+ new IsReferenceEqualMatcher(type_matcher, lhs_matcher, rhs_matcher));
+}
+
+
Matcher<Node*> IsAllocate(const Matcher<Node*>& size_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher) {
@@ -1686,15 +1772,6 @@ Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher,
}
-Matcher<Node*> IsToNumber(const Matcher<Node*>& base_matcher,
- const Matcher<Node*>& context_matcher,
- const Matcher<Node*>& effect_matcher,
- const Matcher<Node*>& control_matcher) {
- return MakeMatcher(new IsToNumberMatcher(base_matcher, context_matcher,
- effect_matcher, control_matcher));
-}
-
-
Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher,
const Matcher<Node*>& base_matcher,
const Matcher<Node*>& index_matcher,
@@ -1707,6 +1784,21 @@ Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher,
}
+Matcher<Node*> IsToNumber(const Matcher<Node*>& base_matcher,
+ const Matcher<Node*>& context_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher) {
+ return MakeMatcher(new IsToNumberMatcher(base_matcher, context_matcher,
+ effect_matcher, control_matcher));
+}
+
+
+Matcher<Node*> IsLoadContext(const Matcher<ContextAccess>& access_matcher,
+ const Matcher<Node*>& context_matcher) {
+ return MakeMatcher(new IsLoadContextMatcher(access_matcher, context_matcher));
+}
+
+
#define IS_BINOP_MATCHER(Name) \
Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher, \
const Matcher<Node*>& rhs_matcher) { \
@@ -1717,6 +1809,9 @@ IS_BINOP_MATCHER(NumberEqual)
IS_BINOP_MATCHER(NumberLessThan)
IS_BINOP_MATCHER(NumberSubtract)
IS_BINOP_MATCHER(NumberMultiply)
+IS_BINOP_MATCHER(NumberShiftLeft)
+IS_BINOP_MATCHER(NumberShiftRight)
+IS_BINOP_MATCHER(NumberShiftRightLogical)
IS_BINOP_MATCHER(Word32And)
IS_BINOP_MATCHER(Word32Sar)
IS_BINOP_MATCHER(Word32Shl)
diff --git a/deps/v8/test/unittests/compiler/node-test-utils.h b/deps/v8/test/unittests/compiler/node-test-utils.h
index 9c4646b2f0..a64d9f009a 100644
--- a/deps/v8/test/unittests/compiler/node-test-utils.h
+++ b/deps/v8/test/unittests/compiler/node-test-utils.h
@@ -17,12 +17,17 @@ class ExternalReference;
class HeapObject;
template <class T>
class Unique;
+template <class>
+class TypeImpl;
+struct ZoneTypeConfig;
+typedef TypeImpl<ZoneTypeConfig> Type;
namespace compiler {
// Forward declarations.
class BufferAccess;
class CallDescriptor;
+class ContextAccess;
struct ElementAccess;
struct FieldAccess;
class Node;
@@ -31,7 +36,13 @@ class Node;
using ::testing::Matcher;
-Matcher<Node*> IsEnd(const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsDead();
+Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher);
+Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher,
+ const Matcher<Node*>& control1_matcher);
+Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher,
+ const Matcher<Node*>& control1_matcher,
+ const Matcher<Node*>& control2_matcher);
Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
const Matcher<Node*>& control_matcher);
Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
@@ -125,6 +136,9 @@ Matcher<Node*> IsTailCall(
const Matcher<Node*>& control_matcher);
Matcher<Node*> IsBooleanNot(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher,
+ const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsNumberEqual(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsNumberLessThan(const Matcher<Node*>& lhs_matcher,
@@ -133,6 +147,12 @@ Matcher<Node*> IsNumberSubtract(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsNumberMultiply(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsNumberShiftLeft(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsNumberShiftRight(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsNumberShiftRightLogical(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsAllocate(const Matcher<Node*>& size_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
@@ -255,6 +275,8 @@ Matcher<Node*> IsToNumber(const Matcher<Node*>& base_matcher,
const Matcher<Node*>& context_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsLoadContext(const Matcher<ContextAccess>& access_matcher,
+ const Matcher<Node*>& context_matcher);
Matcher<Node*> IsNumberToInt32(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsNumberToUint32(const Matcher<Node*>& input_matcher);
diff --git a/deps/v8/test/unittests/compiler/node-unittest.cc b/deps/v8/test/unittests/compiler/node-unittest.cc
index 6b61bd5c1c..5341f69716 100644
--- a/deps/v8/test/unittests/compiler/node-unittest.cc
+++ b/deps/v8/test/unittests/compiler/node-unittest.cc
@@ -32,7 +32,7 @@ const Operator kOp2(kOpcode2, Operator::kNoProperties, "Op2", 2, 0, 0, 1, 0, 0);
TEST_F(NodeTest, New) {
Node* const node = Node::New(zone(), 1, &kOp0, 0, nullptr, false);
- EXPECT_EQ(1, node->id());
+ EXPECT_EQ(1U, node->id());
EXPECT_EQ(0, node->UseCount());
EXPECT_TRUE(node->uses().empty());
EXPECT_EQ(0, node->InputCount());
@@ -166,6 +166,96 @@ TEST_F(NodeTest, AppendInput) {
EXPECT_THAT(node->inputs(), ElementsAre(n0, n1, n0, n0, n1));
}
+
+TEST_F(NodeTest, TrimThenAppend) {
+ Node* n0 = Node::New(zone(), 0, &kOp0, 0, nullptr, false);
+ Node* n1 = Node::New(zone(), 1, &kOp0, 0, nullptr, false);
+ Node* n2 = Node::New(zone(), 2, &kOp0, 0, nullptr, false);
+ Node* n3 = Node::New(zone(), 3, &kOp0, 0, nullptr, false);
+ Node* n4 = Node::New(zone(), 4, &kOp0, 0, nullptr, false);
+ Node* n5 = Node::New(zone(), 5, &kOp0, 0, nullptr, false);
+ Node* n6 = Node::New(zone(), 6, &kOp0, 0, nullptr, false);
+ Node* n7 = Node::New(zone(), 7, &kOp0, 0, nullptr, false);
+ Node* n8 = Node::New(zone(), 8, &kOp0, 0, nullptr, false);
+ Node* n9 = Node::New(zone(), 9, &kOp0, 0, nullptr, false);
+ Node* node = Node::New(zone(), 12345, &kOp0, 0, nullptr, true);
+
+ EXPECT_TRUE(node->inputs().empty());
+
+ node->AppendInput(zone(), n0);
+ EXPECT_FALSE(node->inputs().empty());
+ EXPECT_THAT(node->inputs(), ElementsAre(n0));
+
+ node->TrimInputCount(0);
+ EXPECT_TRUE(node->inputs().empty());
+
+ node->AppendInput(zone(), n1);
+ EXPECT_FALSE(node->inputs().empty());
+ EXPECT_THAT(node->inputs(), ElementsAre(n1));
+
+ node->AppendInput(zone(), n2);
+ EXPECT_FALSE(node->inputs().empty());
+ EXPECT_THAT(node->inputs(), ElementsAre(n1, n2));
+
+ node->TrimInputCount(1);
+ EXPECT_FALSE(node->inputs().empty());
+ EXPECT_THAT(node->inputs(), ElementsAre(n1));
+
+ node->AppendInput(zone(), n3);
+ EXPECT_FALSE(node->inputs().empty());
+ EXPECT_THAT(node->inputs(), ElementsAre(n1, n3));
+
+ node->AppendInput(zone(), n4);
+ EXPECT_FALSE(node->inputs().empty());
+ EXPECT_THAT(node->inputs(), ElementsAre(n1, n3, n4));
+
+ node->AppendInput(zone(), n5);
+ EXPECT_FALSE(node->inputs().empty());
+ EXPECT_THAT(node->inputs(), ElementsAre(n1, n3, n4, n5));
+
+ node->AppendInput(zone(), n6);
+ EXPECT_FALSE(node->inputs().empty());
+ EXPECT_THAT(node->inputs(), ElementsAre(n1, n3, n4, n5, n6));
+
+ node->AppendInput(zone(), n7);
+ EXPECT_FALSE(node->inputs().empty());
+ EXPECT_THAT(node->inputs(), ElementsAre(n1, n3, n4, n5, n6, n7));
+
+ node->TrimInputCount(4);
+ EXPECT_THAT(node->inputs(), ElementsAre(n1, n3, n4, n5));
+
+ node->AppendInput(zone(), n8);
+ EXPECT_FALSE(node->inputs().empty());
+ EXPECT_THAT(node->inputs(), ElementsAre(n1, n3, n4, n5, n8));
+
+ node->AppendInput(zone(), n9);
+ EXPECT_FALSE(node->inputs().empty());
+ EXPECT_THAT(node->inputs(), ElementsAre(n1, n3, n4, n5, n8, n9));
+}
+
+
+TEST_F(NodeTest, BigNodes) {
+ static const int kMaxSize = 512;
+ Node* inputs[kMaxSize];
+
+ Node* n0 = Node::New(zone(), 0, &kOp0, 0, nullptr, false);
+ Node* n1 = Node::New(zone(), 1, &kOp1, 1, &n0, false);
+
+ for (int i = 0; i < kMaxSize; i++) {
+ inputs[i] = i & 1 ? n0 : n1;
+ }
+
+ for (int size = 13; size <= kMaxSize; size += 9) {
+ Node* node = Node::New(zone(), 12345, &kOp0, size, inputs, false);
+ EXPECT_EQ(size, node->InputCount());
+
+ for (int i = 0; i < size; i++) {
+ EXPECT_EQ(inputs[i], node->InputAt(i));
+ }
+ }
+}
+
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/scheduler-unittest.cc b/deps/v8/test/unittests/compiler/scheduler-unittest.cc
index 4de15492b2..45c636b27a 100644
--- a/deps/v8/test/unittests/compiler/scheduler-unittest.cc
+++ b/deps/v8/test/unittests/compiler/scheduler-unittest.cc
@@ -631,7 +631,7 @@ TEST_F(SchedulerRPOTest, LoopMultibackedge) {
TEST_F(SchedulerTest, BuildScheduleEmpty) {
graph()->SetStart(graph()->NewNode(common()->Start(0)));
- graph()->SetEnd(graph()->NewNode(common()->End(), graph()->start()));
+ graph()->SetEnd(graph()->NewNode(common()->End(1), graph()->start()));
USE(Scheduler::ComputeSchedule(zone(), graph(), Scheduler::kNoFlags));
}
@@ -643,22 +643,23 @@ TEST_F(SchedulerTest, BuildScheduleOneParameter) {
Node* ret = graph()->NewNode(common()->Return(), p1, graph()->start(),
graph()->start());
- graph()->SetEnd(graph()->NewNode(common()->End(), ret));
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
USE(Scheduler::ComputeSchedule(zone(), graph(), Scheduler::kNoFlags));
}
TEST_F(SchedulerTest, BuildScheduleIfSplit) {
- graph()->SetStart(graph()->NewNode(common()->Start(3)));
+ graph()->SetStart(graph()->NewNode(common()->Start(5)));
Node* p1 = graph()->NewNode(common()->Parameter(0), graph()->start());
Node* p2 = graph()->NewNode(common()->Parameter(1), graph()->start());
Node* p3 = graph()->NewNode(common()->Parameter(2), graph()->start());
Node* p4 = graph()->NewNode(common()->Parameter(3), graph()->start());
Node* p5 = graph()->NewNode(common()->Parameter(4), graph()->start());
- Node* cmp = graph()->NewNode(js()->LessThanOrEqual(LanguageMode::SLOPPY), p1,
- p2, p3, graph()->start(), graph()->start());
+ Node* cmp =
+ graph()->NewNode(js()->LessThanOrEqual(LanguageMode::SLOPPY), p1, p2, p3,
+ p4, p5, graph()->start(), graph()->start());
Node* branch = graph()->NewNode(common()->Branch(), cmp, graph()->start());
Node* true_branch = graph()->NewNode(common()->IfTrue(), branch);
Node* false_branch = graph()->NewNode(common()->IfFalse(), branch);
@@ -667,1341 +668,12 @@ TEST_F(SchedulerTest, BuildScheduleIfSplit) {
graph()->NewNode(common()->Return(), p4, graph()->start(), true_branch);
Node* ret2 =
graph()->NewNode(common()->Return(), p5, graph()->start(), false_branch);
- Node* merge = graph()->NewNode(common()->Merge(2), ret1, ret2);
- graph()->SetEnd(graph()->NewNode(common()->End(), merge));
+ graph()->SetEnd(graph()->NewNode(common()->End(2), ret1, ret2));
ComputeAndVerifySchedule(13);
}
-TEST_F(SchedulerTest, BuildScheduleIfSplitWithEffects) {
- const Operator* op;
- Unique<HeapObject> unique_constant =
- Unique<HeapObject>::CreateImmovable(factory()->undefined_value());
-
- // 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;
- // }
- // }
- Node* nil = graph()->NewNode(common()->Dead());
- op = common()->End();
- Node* n39 = graph()->NewNode(op, nil);
- USE(n39);
- op = common()->Merge(2);
- Node* n37 = graph()->NewNode(op, nil, nil);
- USE(n37);
- op = common()->Return();
- Node* n29 = graph()->NewNode(op, nil, nil, nil);
- USE(n29);
- op = common()->Return();
- Node* n36 = graph()->NewNode(op, nil, nil, nil);
- USE(n36);
- op = js()->Add(LanguageMode::SLOPPY);
- Node* n27 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n27);
- op = common()->IfSuccess();
- Node* n28 = graph()->NewNode(op, nil);
- USE(n28);
- op = js()->Subtract(LanguageMode::SLOPPY);
- Node* n34 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n34);
- op = common()->IfSuccess();
- Node* n35 = graph()->NewNode(op, nil);
- USE(n35);
- op = js()->Subtract(LanguageMode::SLOPPY);
- Node* n25 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n25);
- op = common()->Parameter(4);
- Node* n5 = graph()->NewNode(op, nil);
- USE(n5);
- op = common()->Parameter(5);
- Node* n7 = graph()->NewNode(op, nil);
- USE(n7);
- op = common()->FrameState(JS_FRAME, BailoutId(-1),
- OutputFrameStateCombine::Ignore());
- Node* n13 = graph()->NewNode(op, nil, nil, nil, nil, nil);
- USE(n13);
- op = common()->IfSuccess();
- Node* n26 = graph()->NewNode(op, nil);
- USE(n26);
- op = js()->Multiply(LanguageMode::SLOPPY);
- Node* n32 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n32);
- op = common()->Parameter(1);
- Node* n2 = graph()->NewNode(op, nil);
- USE(n2);
- op = common()->IfSuccess();
- Node* n33 = graph()->NewNode(op, nil);
- USE(n33);
- op = js()->Subtract(LanguageMode::SLOPPY);
- Node* n23 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n23);
- op = common()->IfSuccess();
- Node* n24 = graph()->NewNode(op, nil);
- USE(n24);
- op = common()->Start(4);
- Node* n0 = graph()->NewNode(op);
- USE(n0);
- op = common()->StateValues(0);
- Node* n11 = graph()->NewNode(op);
- USE(n11);
- op = common()->NumberConstant(0);
- Node* n12 = graph()->NewNode(op);
- USE(n12);
- op = common()->HeapConstant(unique_constant);
- Node* n6 = graph()->NewNode(op);
- USE(n6);
- op = common()->Parameter(3);
- Node* n4 = graph()->NewNode(op, nil);
- USE(n4);
- op = js()->LessThan(LanguageMode::SLOPPY);
- Node* n15 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil);
- USE(n15);
- op = common()->IfFalse();
- Node* n31 = graph()->NewNode(op, nil);
- USE(n31);
- op = js()->Add(LanguageMode::SLOPPY);
- Node* n19 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n19);
- op = js()->Multiply(LanguageMode::SLOPPY);
- Node* n21 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n21);
- op = common()->IfSuccess();
- Node* n22 = graph()->NewNode(op, nil);
- USE(n22);
- op = common()->Parameter(2);
- Node* n3 = graph()->NewNode(op, nil);
- USE(n3);
- op = js()->StackCheck();
- Node* n9 = graph()->NewNode(op, nil, nil, nil, nil);
- USE(n9);
- op = common()->IfSuccess();
- Node* n10 = graph()->NewNode(op, nil);
- USE(n10);
- op = common()->Branch();
- Node* n17 = graph()->NewNode(op, nil, nil);
- USE(n17);
- op = common()->IfTrue();
- Node* n18 = graph()->NewNode(op, nil);
- USE(n18);
- op = common()->IfSuccess();
- Node* n20 = graph()->NewNode(op, nil);
- USE(n20);
- op = common()->IfSuccess();
- Node* n16 = graph()->NewNode(op, nil);
- USE(n16);
- n39->ReplaceInput(0, n37);
- n37->ReplaceInput(0, n29);
- n37->ReplaceInput(1, n36);
- n29->ReplaceInput(0, n27);
- n29->ReplaceInput(1, n27);
- n29->ReplaceInput(2, n28);
- n36->ReplaceInput(0, n34);
- n36->ReplaceInput(1, n34);
- n36->ReplaceInput(2, n35);
- n27->ReplaceInput(0, n25);
- n27->ReplaceInput(1, n5);
- n27->ReplaceInput(2, n7);
- n27->ReplaceInput(3, n13);
- n27->ReplaceInput(4, n13);
- n27->ReplaceInput(5, n25);
- n27->ReplaceInput(6, n26);
- n28->ReplaceInput(0, n27);
- n34->ReplaceInput(0, n32);
- n34->ReplaceInput(1, n2);
- n34->ReplaceInput(2, n7);
- n34->ReplaceInput(3, n13);
- n34->ReplaceInput(4, n13);
- n34->ReplaceInput(5, n32);
- n34->ReplaceInput(6, n33);
- n35->ReplaceInput(0, n34);
- n25->ReplaceInput(0, n23);
- n25->ReplaceInput(1, n2);
- n25->ReplaceInput(2, n7);
- n25->ReplaceInput(3, n13);
- n25->ReplaceInput(4, n13);
- n25->ReplaceInput(5, n23);
- n25->ReplaceInput(6, n24);
- n5->ReplaceInput(0, n0);
- n7->ReplaceInput(0, n0);
- n13->ReplaceInput(0, n11);
- n13->ReplaceInput(1, n11);
- n13->ReplaceInput(2, n11);
- n13->ReplaceInput(3, n12);
- n13->ReplaceInput(4, n6);
- n26->ReplaceInput(0, n25);
- n32->ReplaceInput(0, n4);
- n32->ReplaceInput(1, n4);
- n32->ReplaceInput(2, n7);
- n32->ReplaceInput(3, n13);
- n32->ReplaceInput(4, n13);
- n32->ReplaceInput(5, n15);
- n32->ReplaceInput(6, n31);
- n2->ReplaceInput(0, n0);
- n33->ReplaceInput(0, n32);
- n23->ReplaceInput(0, n19);
- n23->ReplaceInput(1, n21);
- n23->ReplaceInput(2, n7);
- n23->ReplaceInput(3, n13);
- n23->ReplaceInput(4, n13);
- n23->ReplaceInput(5, n21);
- n23->ReplaceInput(6, n22);
- n24->ReplaceInput(0, n23);
- n4->ReplaceInput(0, n0);
- n15->ReplaceInput(0, n2);
- n15->ReplaceInput(1, n3);
- n15->ReplaceInput(2, n7);
- n15->ReplaceInput(3, n13);
- n15->ReplaceInput(4, n9);
- n15->ReplaceInput(5, n10);
- n31->ReplaceInput(0, n17);
- n19->ReplaceInput(0, n2);
- n19->ReplaceInput(1, n3);
- n19->ReplaceInput(2, n7);
- n19->ReplaceInput(3, n13);
- n19->ReplaceInput(4, n13);
- n19->ReplaceInput(5, n15);
- n19->ReplaceInput(6, n18);
- n21->ReplaceInput(0, n4);
- n21->ReplaceInput(1, n4);
- n21->ReplaceInput(2, n7);
- n21->ReplaceInput(3, n13);
- n21->ReplaceInput(4, n13);
- n21->ReplaceInput(5, n19);
- n21->ReplaceInput(6, n20);
- n22->ReplaceInput(0, n21);
- n3->ReplaceInput(0, n0);
- n9->ReplaceInput(0, n7);
- n9->ReplaceInput(1, n13);
- n9->ReplaceInput(2, n0);
- n9->ReplaceInput(3, n0);
- n10->ReplaceInput(0, n9);
- n17->ReplaceInput(0, n15);
- n17->ReplaceInput(1, n16);
- n18->ReplaceInput(0, n17);
- n20->ReplaceInput(0, n19);
- n16->ReplaceInput(0, n15);
-
- graph()->SetStart(n0);
- graph()->SetEnd(n39);
-
- ComputeAndVerifySchedule(34);
-}
-
-
-TEST_F(SchedulerTest, BuildScheduleSimpleLoop) {
- const Operator* op;
- Unique<HeapObject> unique_constant =
- Unique<HeapObject>::CreateImmovable(factory()->undefined_value());
-
- // Manually transcripted code for:
- // function turbo_fan_test(a, b) {
- // while (a < b) {
- // a++;
- // }
- // return a;
- // }
- Node* nil = graph()->NewNode(common()->Dead());
- op = common()->End();
- Node* n34 = graph()->NewNode(op, nil);
- USE(n34);
- op = common()->Return();
- Node* n32 = graph()->NewNode(op, nil, nil, nil);
- USE(n32);
- op = common()->Phi(kMachAnyTagged, 2);
- Node* n13 = graph()->NewNode(op, nil, nil, nil);
- USE(n13);
- op = js()->LessThan(LanguageMode::SLOPPY);
- Node* n16 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil);
- USE(n16);
- op = common()->IfFalse();
- Node* n22 = graph()->NewNode(op, nil);
- USE(n22);
- op = common()->Parameter(1);
- Node* n2 = graph()->NewNode(op, nil);
- USE(n2);
- op = js()->Add(LanguageMode::SLOPPY);
- Node* n29 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n29);
- op = common()->Loop(2);
- Node* n12 = graph()->NewNode(op, nil, nil);
- USE(n12);
- op = common()->Parameter(2);
- Node* n3 = graph()->NewNode(op, nil);
- USE(n3);
- op = common()->Parameter(3);
- Node* n5 = graph()->NewNode(op, nil);
- USE(n5);
- op = common()->FrameState(JS_FRAME, BailoutId(-1),
- OutputFrameStateCombine::Ignore());
- Node* n11 = graph()->NewNode(op, nil, nil, nil, nil, nil);
- USE(n11);
- op = common()->EffectPhi(2);
- Node* n14 = graph()->NewNode(op, nil, nil, nil);
- USE(n14);
- op = common()->Branch();
- Node* n19 = graph()->NewNode(op, nil, nil);
- USE(n19);
- op = common()->Start(2);
- Node* n0 = graph()->NewNode(op);
- USE(n0);
- op = js()->ToNumber();
- Node* n26 = graph()->NewNode(op, nil, nil, nil, nil, nil);
- USE(n26);
- op = common()->NumberConstant(1);
- Node* n28 = graph()->NewNode(op);
- USE(n28);
- op = common()->IfSuccess();
- Node* n27 = graph()->NewNode(op, nil);
- USE(n27);
- op = common()->IfSuccess();
- Node* n8 = graph()->NewNode(op, nil);
- USE(n8);
- op = common()->IfSuccess();
- Node* n30 = graph()->NewNode(op, nil);
- USE(n30);
- op = common()->StateValues(0);
- Node* n9 = graph()->NewNode(op);
- USE(n9);
- op = common()->NumberConstant(0);
- Node* n10 = graph()->NewNode(op);
- USE(n10);
- op = common()->HeapConstant(unique_constant);
- Node* n4 = graph()->NewNode(op);
- USE(n4);
- op = js()->StackCheck();
- Node* n7 = graph()->NewNode(op, nil, nil, nil, nil);
- USE(n7);
- op = js()->ToBoolean();
- Node* n18 = graph()->NewNode(op, nil, nil);
- USE(n18);
- op = common()->IfSuccess();
- Node* n17 = graph()->NewNode(op, nil);
- USE(n17);
- op = js()->StackCheck();
- Node* n24 = graph()->NewNode(op, nil, nil, nil, nil);
- USE(n24);
- op = common()->IfSuccess();
- Node* n25 = graph()->NewNode(op, nil);
- USE(n25);
- op = common()->IfTrue();
- Node* n20 = graph()->NewNode(op, nil);
- USE(n20);
- n34->ReplaceInput(0, n32);
- n32->ReplaceInput(0, n13);
- n32->ReplaceInput(1, n16);
- n32->ReplaceInput(2, n22);
- n13->ReplaceInput(0, n2);
- n13->ReplaceInput(1, n29);
- n13->ReplaceInput(2, n12);
- n16->ReplaceInput(0, n13);
- n16->ReplaceInput(1, n3);
- n16->ReplaceInput(2, n5);
- n16->ReplaceInput(3, n11);
- n16->ReplaceInput(4, n14);
- n16->ReplaceInput(5, n12);
- n22->ReplaceInput(0, n19);
- n2->ReplaceInput(0, n0);
- n29->ReplaceInput(0, n26);
- n29->ReplaceInput(1, n28);
- n29->ReplaceInput(2, n5);
- n29->ReplaceInput(3, n11);
- n29->ReplaceInput(4, n11);
- n29->ReplaceInput(5, n26);
- n29->ReplaceInput(6, n27);
- n12->ReplaceInput(0, n8);
- n12->ReplaceInput(1, n30);
- n3->ReplaceInput(0, n0);
- n5->ReplaceInput(0, n0);
- n11->ReplaceInput(0, n9);
- n11->ReplaceInput(1, n9);
- n11->ReplaceInput(2, n9);
- n11->ReplaceInput(3, n10);
- n11->ReplaceInput(4, n4);
- n14->ReplaceInput(0, n7);
- n14->ReplaceInput(1, n29);
- n14->ReplaceInput(2, n12);
- n19->ReplaceInput(0, n18);
- n19->ReplaceInput(1, n17);
- n26->ReplaceInput(0, n13);
- n26->ReplaceInput(1, n5);
- n26->ReplaceInput(2, n11);
- n26->ReplaceInput(3, n24);
- n26->ReplaceInput(4, n25);
- n27->ReplaceInput(0, n26);
- n8->ReplaceInput(0, n7);
- n30->ReplaceInput(0, n29);
- n7->ReplaceInput(0, n5);
- n7->ReplaceInput(1, n11);
- n7->ReplaceInput(2, n0);
- n7->ReplaceInput(3, n0);
- n18->ReplaceInput(0, n16);
- n18->ReplaceInput(1, n5);
- n17->ReplaceInput(0, n16);
- n24->ReplaceInput(0, n5);
- n24->ReplaceInput(1, n11);
- n24->ReplaceInput(2, n16);
- n24->ReplaceInput(3, n20);
- n25->ReplaceInput(0, n24);
- n20->ReplaceInput(0, n19);
-
- graph()->SetStart(n0);
- graph()->SetEnd(n34);
-
- ComputeAndVerifySchedule(30);
-}
-
-
-TEST_F(SchedulerTest, BuildScheduleComplexLoops) {
- const Operator* op;
- Unique<HeapObject> unique_constant =
- Unique<HeapObject>::CreateImmovable(factory()->undefined_value());
-
- // 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;
- // }
- Node* nil = graph()->NewNode(common()->Dead());
- op = common()->End();
- Node* n71 = graph()->NewNode(op, nil);
- USE(n71);
- op = common()->Return();
- Node* n69 = graph()->NewNode(op, nil, nil, nil);
- USE(n69);
- op = common()->Phi(kMachAnyTagged, 2);
- Node* n53 = graph()->NewNode(op, nil, nil, nil);
- USE(n53);
- op = js()->LessThan(LanguageMode::SLOPPY);
- Node* n55 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil);
- USE(n55);
- op = common()->IfFalse();
- Node* n61 = graph()->NewNode(op, nil);
- USE(n61);
- op = common()->Phi(kMachAnyTagged, 2);
- Node* n14 = graph()->NewNode(op, nil, nil, nil);
- USE(n14);
- op = js()->Add(LanguageMode::SLOPPY);
- Node* n66 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n66);
- op = common()->Loop(2);
- Node* n52 = graph()->NewNode(op, nil, nil);
- USE(n52);
- op = common()->Parameter(2);
- Node* n3 = graph()->NewNode(op, nil);
- USE(n3);
- op = common()->Parameter(4);
- Node* n6 = graph()->NewNode(op, nil);
- USE(n6);
- op = common()->FrameState(JS_FRAME, BailoutId(-1),
- OutputFrameStateCombine::Ignore());
- Node* n12 = graph()->NewNode(op, nil, nil, nil, nil, nil);
- USE(n12);
- op = common()->EffectPhi(2);
- Node* n54 = graph()->NewNode(op, nil, nil, nil);
- USE(n54);
- op = common()->Branch();
- Node* n58 = graph()->NewNode(op, nil, nil);
- USE(n58);
- op = common()->Parameter(1);
- Node* n2 = graph()->NewNode(op, nil);
- USE(n2);
- op = js()->Add(LanguageMode::SLOPPY);
- Node* n31 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n31);
- op = common()->Loop(2);
- Node* n13 = graph()->NewNode(op, nil, nil);
- USE(n13);
- op = common()->NumberConstant(2);
- Node* n65 = graph()->NewNode(op);
- USE(n65);
- op = js()->StackCheck();
- Node* n63 = graph()->NewNode(op, nil, nil, nil, nil);
- USE(n63);
- op = common()->IfSuccess();
- Node* n64 = graph()->NewNode(op, nil);
- USE(n64);
- op = common()->IfFalse();
- Node* n24 = graph()->NewNode(op, nil);
- USE(n24);
- op = common()->IfSuccess();
- Node* n67 = graph()->NewNode(op, nil);
- USE(n67);
- op = common()->Start(3);
- Node* n0 = graph()->NewNode(op);
- USE(n0);
- op = common()->StateValues(0);
- Node* n10 = graph()->NewNode(op);
- USE(n10);
- op = common()->NumberConstant(0);
- Node* n11 = graph()->NewNode(op);
- USE(n11);
- op = common()->HeapConstant(unique_constant);
- Node* n5 = graph()->NewNode(op);
- USE(n5);
- op = js()->LessThan(LanguageMode::SLOPPY);
- Node* n18 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil);
- USE(n18);
- op = js()->ToBoolean();
- Node* n57 = graph()->NewNode(op, nil, nil);
- USE(n57);
- op = common()->IfSuccess();
- Node* n56 = graph()->NewNode(op, nil);
- USE(n56);
- op = js()->ToNumber();
- Node* n28 = graph()->NewNode(op, nil, nil, nil, nil, nil);
- USE(n28);
- op = common()->NumberConstant(1);
- Node* n30 = graph()->NewNode(op);
- USE(n30);
- op = common()->IfSuccess();
- Node* n29 = graph()->NewNode(op, nil);
- USE(n29);
- op = common()->IfSuccess();
- Node* n9 = graph()->NewNode(op, nil);
- USE(n9);
- op = common()->IfFalse();
- Node* n42 = graph()->NewNode(op, nil);
- USE(n42);
- op = common()->IfTrue();
- Node* n59 = graph()->NewNode(op, nil);
- USE(n59);
- op = common()->Branch();
- Node* n21 = graph()->NewNode(op, nil, nil);
- USE(n21);
- op = common()->EffectPhi(2);
- Node* n16 = graph()->NewNode(op, nil, nil, nil);
- USE(n16);
- op = js()->StackCheck();
- Node* n26 = graph()->NewNode(op, nil, nil, nil, nil);
- USE(n26);
- op = common()->IfSuccess();
- Node* n27 = graph()->NewNode(op, nil);
- USE(n27);
- op = js()->StackCheck();
- Node* n8 = graph()->NewNode(op, nil, nil, nil, nil);
- USE(n8);
- op = common()->Branch();
- Node* n39 = graph()->NewNode(op, nil, nil);
- USE(n39);
- op = js()->ToBoolean();
- Node* n20 = graph()->NewNode(op, nil, nil);
- USE(n20);
- op = common()->IfSuccess();
- Node* n19 = graph()->NewNode(op, nil);
- USE(n19);
- op = js()->LessThan(LanguageMode::SLOPPY);
- Node* n36 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil);
- USE(n36);
- op = common()->IfTrue();
- Node* n22 = graph()->NewNode(op, nil);
- USE(n22);
- op = js()->ToBoolean();
- Node* n38 = graph()->NewNode(op, nil, nil);
- USE(n38);
- op = common()->IfSuccess();
- Node* n37 = graph()->NewNode(op, nil);
- USE(n37);
- op = common()->Phi(kMachAnyTagged, 2);
- Node* n34 = graph()->NewNode(op, nil, nil, nil);
- USE(n34);
- op = common()->EffectPhi(2);
- Node* n35 = graph()->NewNode(op, nil, nil, nil);
- USE(n35);
- op = common()->Loop(2);
- Node* n33 = graph()->NewNode(op, nil, nil);
- USE(n33);
- op = common()->Phi(kMachAnyTagged, 2);
- Node* n15 = graph()->NewNode(op, nil, nil, nil);
- USE(n15);
- op = js()->Add(LanguageMode::SLOPPY);
- Node* n48 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n48);
- op = common()->IfSuccess();
- Node* n32 = graph()->NewNode(op, nil);
- USE(n32);
- op = common()->IfSuccess();
- Node* n49 = graph()->NewNode(op, nil);
- USE(n49);
- op = common()->Parameter(3);
- Node* n4 = graph()->NewNode(op, nil);
- USE(n4);
- op = js()->ToNumber();
- Node* n46 = graph()->NewNode(op, nil, nil, nil, nil, nil);
- USE(n46);
- op = common()->IfSuccess();
- Node* n47 = graph()->NewNode(op, nil);
- USE(n47);
- op = js()->StackCheck();
- Node* n44 = graph()->NewNode(op, nil, nil, nil, nil);
- USE(n44);
- op = common()->IfSuccess();
- Node* n45 = graph()->NewNode(op, nil);
- USE(n45);
- op = common()->IfTrue();
- Node* n40 = graph()->NewNode(op, nil);
- USE(n40);
- n71->ReplaceInput(0, n69);
- n69->ReplaceInput(0, n53);
- n69->ReplaceInput(1, n55);
- n69->ReplaceInput(2, n61);
- n53->ReplaceInput(0, n14);
- n53->ReplaceInput(1, n66);
- n53->ReplaceInput(2, n52);
- n55->ReplaceInput(0, n53);
- n55->ReplaceInput(1, n3);
- n55->ReplaceInput(2, n6);
- n55->ReplaceInput(3, n12);
- n55->ReplaceInput(4, n54);
- n55->ReplaceInput(5, n52);
- n61->ReplaceInput(0, n58);
- n14->ReplaceInput(0, n2);
- n14->ReplaceInput(1, n31);
- n14->ReplaceInput(2, n13);
- n66->ReplaceInput(0, n53);
- n66->ReplaceInput(1, n65);
- n66->ReplaceInput(2, n6);
- n66->ReplaceInput(3, n12);
- n66->ReplaceInput(4, n12);
- n66->ReplaceInput(5, n63);
- n66->ReplaceInput(6, n64);
- n52->ReplaceInput(0, n24);
- n52->ReplaceInput(1, n67);
- n3->ReplaceInput(0, n0);
- n6->ReplaceInput(0, n0);
- n12->ReplaceInput(0, n10);
- n12->ReplaceInput(1, n10);
- n12->ReplaceInput(2, n10);
- n12->ReplaceInput(3, n11);
- n12->ReplaceInput(4, n5);
- n54->ReplaceInput(0, n18);
- n54->ReplaceInput(1, n66);
- n54->ReplaceInput(2, n52);
- n58->ReplaceInput(0, n57);
- n58->ReplaceInput(1, n56);
- n2->ReplaceInput(0, n0);
- n31->ReplaceInput(0, n28);
- n31->ReplaceInput(1, n30);
- n31->ReplaceInput(2, n6);
- n31->ReplaceInput(3, n12);
- n31->ReplaceInput(4, n12);
- n31->ReplaceInput(5, n28);
- n31->ReplaceInput(6, n29);
- n13->ReplaceInput(0, n9);
- n13->ReplaceInput(1, n42);
- n63->ReplaceInput(0, n6);
- n63->ReplaceInput(1, n12);
- n63->ReplaceInput(2, n55);
- n63->ReplaceInput(3, n59);
- n64->ReplaceInput(0, n63);
- n24->ReplaceInput(0, n21);
- n67->ReplaceInput(0, n66);
- n18->ReplaceInput(0, n14);
- n18->ReplaceInput(1, n3);
- n18->ReplaceInput(2, n6);
- n18->ReplaceInput(3, n12);
- n18->ReplaceInput(4, n16);
- n18->ReplaceInput(5, n13);
- n57->ReplaceInput(0, n55);
- n57->ReplaceInput(1, n6);
- n56->ReplaceInput(0, n55);
- n28->ReplaceInput(0, n14);
- n28->ReplaceInput(1, n6);
- n28->ReplaceInput(2, n12);
- n28->ReplaceInput(3, n26);
- n28->ReplaceInput(4, n27);
- n29->ReplaceInput(0, n28);
- n9->ReplaceInput(0, n8);
- n42->ReplaceInput(0, n39);
- n59->ReplaceInput(0, n58);
- n21->ReplaceInput(0, n20);
- n21->ReplaceInput(1, n19);
- n16->ReplaceInput(0, n8);
- n16->ReplaceInput(1, n36);
- n16->ReplaceInput(2, n13);
- n26->ReplaceInput(0, n6);
- n26->ReplaceInput(1, n12);
- n26->ReplaceInput(2, n18);
- n26->ReplaceInput(3, n22);
- n27->ReplaceInput(0, n26);
- n8->ReplaceInput(0, n6);
- n8->ReplaceInput(1, n12);
- n8->ReplaceInput(2, n0);
- n8->ReplaceInput(3, n0);
- n39->ReplaceInput(0, n38);
- n39->ReplaceInput(1, n37);
- n20->ReplaceInput(0, n18);
- n20->ReplaceInput(1, n6);
- n19->ReplaceInput(0, n18);
- n36->ReplaceInput(0, n34);
- n36->ReplaceInput(1, n3);
- n36->ReplaceInput(2, n6);
- n36->ReplaceInput(3, n12);
- n36->ReplaceInput(4, n35);
- n36->ReplaceInput(5, n33);
- n22->ReplaceInput(0, n21);
- n38->ReplaceInput(0, n36);
- n38->ReplaceInput(1, n6);
- n37->ReplaceInput(0, n36);
- n34->ReplaceInput(0, n15);
- n34->ReplaceInput(1, n48);
- n34->ReplaceInput(2, n33);
- n35->ReplaceInput(0, n31);
- n35->ReplaceInput(1, n48);
- n35->ReplaceInput(2, n33);
- n33->ReplaceInput(0, n32);
- n33->ReplaceInput(1, n49);
- n15->ReplaceInput(0, n4);
- n15->ReplaceInput(1, n34);
- n15->ReplaceInput(2, n13);
- n48->ReplaceInput(0, n46);
- n48->ReplaceInput(1, n30);
- n48->ReplaceInput(2, n6);
- n48->ReplaceInput(3, n12);
- n48->ReplaceInput(4, n12);
- n48->ReplaceInput(5, n46);
- n48->ReplaceInput(6, n47);
- n32->ReplaceInput(0, n31);
- n49->ReplaceInput(0, n48);
- n4->ReplaceInput(0, n0);
- n46->ReplaceInput(0, n34);
- n46->ReplaceInput(1, n6);
- n46->ReplaceInput(2, n12);
- n46->ReplaceInput(3, n44);
- n46->ReplaceInput(4, n45);
- n47->ReplaceInput(0, n46);
- n44->ReplaceInput(0, n6);
- n44->ReplaceInput(1, n12);
- n44->ReplaceInput(2, n36);
- n44->ReplaceInput(3, n40);
- n45->ReplaceInput(0, n44);
- n40->ReplaceInput(0, n39);
-
- graph()->SetStart(n0);
- graph()->SetEnd(n71);
-
- ComputeAndVerifySchedule(65);
-}
-
-
-TEST_F(SchedulerTest, BuildScheduleBreakAndContinue) {
- const Operator* op;
- Unique<HeapObject> unique_constant =
- Unique<HeapObject>::CreateImmovable(factory()->undefined_value());
-
- // 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;
- // }
- Node* nil = graph()->NewNode(common()->Dead());
- op = common()->End();
- Node* n86 = graph()->NewNode(op, nil);
- USE(n86);
- op = common()->Return();
- Node* n84 = graph()->NewNode(op, nil, nil, nil);
- USE(n84);
- op = js()->Add(LanguageMode::SLOPPY);
- Node* n82 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n82);
- op = common()->IfSuccess();
- Node* n83 = graph()->NewNode(op, nil);
- USE(n83);
- op = common()->Phi(kMachAnyTagged, 2);
- Node* n15 = graph()->NewNode(op, nil, nil, nil);
- USE(n15);
- op = common()->Phi(kMachAnyTagged, 2);
- Node* n17 = graph()->NewNode(op, nil, nil, nil);
- USE(n17);
- op = common()->Parameter(4);
- Node* n6 = graph()->NewNode(op, nil);
- USE(n6);
- op = common()->FrameState(JS_FRAME, BailoutId(-1),
- OutputFrameStateCombine::Ignore());
- Node* n12 = graph()->NewNode(op, nil, nil, nil, nil, nil);
- USE(n12);
- op = js()->LessThan(LanguageMode::SLOPPY);
- Node* n19 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil);
- USE(n19);
- op = common()->IfFalse();
- Node* n25 = graph()->NewNode(op, nil);
- USE(n25);
- op = common()->Parameter(1);
- Node* n2 = graph()->NewNode(op, nil);
- USE(n2);
- op = common()->Phi(kMachAnyTagged, 2);
- Node* n35 = graph()->NewNode(op, nil, nil, nil);
- USE(n35);
- op = common()->Loop(2);
- Node* n14 = graph()->NewNode(op, nil, nil);
- USE(n14);
- op = common()->NumberConstant(0);
- Node* n11 = graph()->NewNode(op);
- USE(n11);
- op = common()->Phi(kMachAnyTagged, 2);
- Node* n81 = graph()->NewNode(op, nil, nil, nil);
- USE(n81);
- op = common()->Start(3);
- Node* n0 = graph()->NewNode(op);
- USE(n0);
- op = common()->StateValues(0);
- Node* n10 = graph()->NewNode(op);
- USE(n10);
- op = common()->HeapConstant(unique_constant);
- Node* n5 = graph()->NewNode(op);
- USE(n5);
- op = common()->Parameter(2);
- Node* n3 = graph()->NewNode(op, nil);
- USE(n3);
- op = common()->EffectPhi(2);
- Node* n18 = graph()->NewNode(op, nil, nil, nil);
- USE(n18);
- op = common()->Branch();
- Node* n22 = graph()->NewNode(op, nil, nil);
- USE(n22);
- op = js()->Add(LanguageMode::SLOPPY);
- Node* n32 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n32);
- op = js()->Add(LanguageMode::SLOPPY);
- Node* n64 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n64);
- op = common()->Loop(2);
- Node* n34 = graph()->NewNode(op, nil, nil);
- USE(n34);
- op = common()->IfSuccess();
- Node* n9 = graph()->NewNode(op, nil);
- USE(n9);
- op = common()->Merge(2);
- Node* n72 = graph()->NewNode(op, nil, nil);
- USE(n72);
- op = js()->Add(LanguageMode::SLOPPY);
- Node* n78 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n78);
- op = js()->StackCheck();
- Node* n8 = graph()->NewNode(op, nil, nil, nil, nil);
- USE(n8);
- op = common()->EffectPhi(2);
- Node* n80 = graph()->NewNode(op, nil, nil, nil);
- USE(n80);
- op = js()->ToBoolean();
- Node* n21 = graph()->NewNode(op, nil, nil);
- USE(n21);
- op = common()->IfSuccess();
- Node* n20 = graph()->NewNode(op, nil);
- USE(n20);
- op = js()->ToNumber();
- Node* n29 = graph()->NewNode(op, nil, nil, nil, nil, nil);
- USE(n29);
- op = common()->NumberConstant(1);
- Node* n31 = graph()->NewNode(op);
- USE(n31);
- op = common()->IfSuccess();
- Node* n30 = graph()->NewNode(op, nil);
- USE(n30);
- op = js()->ToNumber();
- Node* n62 = graph()->NewNode(op, nil, nil, nil, nil, nil);
- USE(n62);
- op = common()->IfSuccess();
- Node* n63 = graph()->NewNode(op, nil);
- USE(n63);
- op = common()->IfSuccess();
- Node* n33 = graph()->NewNode(op, nil);
- USE(n33);
- op = common()->IfSuccess();
- Node* n65 = graph()->NewNode(op, nil);
- USE(n65);
- op = common()->IfTrue();
- Node* n71 = graph()->NewNode(op, nil);
- USE(n71);
- op = common()->IfSuccess();
- Node* n79 = graph()->NewNode(op, nil);
- USE(n79);
- op = js()->ToNumber();
- Node* n76 = graph()->NewNode(op, nil, nil, nil, nil, nil);
- USE(n76);
- op = common()->IfSuccess();
- Node* n77 = graph()->NewNode(op, nil);
- USE(n77);
- op = js()->Equal();
- Node* n67 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil);
- USE(n67);
- op = js()->StackCheck();
- Node* n27 = graph()->NewNode(op, nil, nil, nil, nil);
- USE(n27);
- op = common()->IfSuccess();
- Node* n28 = graph()->NewNode(op, nil);
- USE(n28);
- op = js()->Equal();
- Node* n52 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil);
- USE(n52);
- op = common()->IfFalse();
- Node* n60 = graph()->NewNode(op, nil);
- USE(n60);
- op = common()->Branch();
- Node* n70 = graph()->NewNode(op, nil, nil);
- USE(n70);
- op = common()->IfFalse();
- Node* n74 = graph()->NewNode(op, nil);
- USE(n74);
- op = common()->EffectPhi(2);
- Node* n57 = graph()->NewNode(op, nil, nil, nil);
- USE(n57);
- op = common()->Merge(2);
- Node* n45 = graph()->NewNode(op, nil, nil);
- USE(n45);
- op = common()->IfTrue();
- Node* n23 = graph()->NewNode(op, nil);
- USE(n23);
- op = js()->Add(LanguageMode::SLOPPY);
- Node* n50 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n50);
- op = common()->IfSuccess();
- Node* n51 = graph()->NewNode(op, nil);
- USE(n51);
- op = common()->Branch();
- Node* n55 = graph()->NewNode(op, nil, nil);
- USE(n55);
- op = js()->ToBoolean();
- Node* n69 = graph()->NewNode(op, nil, nil);
- USE(n69);
- op = common()->IfSuccess();
- Node* n68 = graph()->NewNode(op, nil);
- USE(n68);
- op = js()->LessThan(LanguageMode::SLOPPY);
- Node* n38 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil);
- USE(n38);
- op = common()->IfFalse();
- Node* n44 = graph()->NewNode(op, nil);
- USE(n44);
- op = common()->IfTrue();
- Node* n56 = graph()->NewNode(op, nil);
- USE(n56);
- op = js()->ToNumber();
- Node* n48 = graph()->NewNode(op, nil, nil, nil, nil, nil);
- USE(n48);
- op = common()->IfSuccess();
- Node* n49 = graph()->NewNode(op, nil);
- USE(n49);
- op = js()->ToBoolean();
- Node* n54 = graph()->NewNode(op, nil, nil);
- USE(n54);
- op = common()->IfSuccess();
- Node* n53 = graph()->NewNode(op, nil);
- USE(n53);
- op = common()->Phi(kMachAnyTagged, 2);
- Node* n36 = graph()->NewNode(op, nil, nil, nil);
- USE(n36);
- op = common()->EffectPhi(2);
- Node* n37 = graph()->NewNode(op, nil, nil, nil);
- USE(n37);
- op = common()->Branch();
- Node* n41 = graph()->NewNode(op, nil, nil);
- USE(n41);
- op = js()->StackCheck();
- Node* n46 = graph()->NewNode(op, nil, nil, nil, nil);
- USE(n46);
- op = common()->IfSuccess();
- Node* n47 = graph()->NewNode(op, nil);
- USE(n47);
- op = common()->Phi(kMachAnyTagged, 2);
- Node* n16 = graph()->NewNode(op, nil, nil, nil);
- USE(n16);
- op = js()->ToBoolean();
- Node* n40 = graph()->NewNode(op, nil, nil);
- USE(n40);
- op = common()->IfSuccess();
- Node* n39 = graph()->NewNode(op, nil);
- USE(n39);
- op = common()->IfTrue();
- Node* n42 = graph()->NewNode(op, nil);
- USE(n42);
- op = common()->Parameter(3);
- Node* n4 = graph()->NewNode(op, nil);
- USE(n4);
- op = common()->Phi(kMachAnyTagged, 2);
- Node* n58 = graph()->NewNode(op, nil, nil, nil);
- USE(n58);
- n86->ReplaceInput(0, n84);
- n84->ReplaceInput(0, n82);
- n84->ReplaceInput(1, n82);
- n84->ReplaceInput(2, n83);
- n82->ReplaceInput(0, n15);
- n82->ReplaceInput(1, n17);
- n82->ReplaceInput(2, n6);
- n82->ReplaceInput(3, n12);
- n82->ReplaceInput(4, n12);
- n82->ReplaceInput(5, n19);
- n82->ReplaceInput(6, n25);
- n83->ReplaceInput(0, n82);
- n15->ReplaceInput(0, n2);
- n15->ReplaceInput(1, n35);
- n15->ReplaceInput(2, n14);
- n17->ReplaceInput(0, n11);
- n17->ReplaceInput(1, n81);
- n17->ReplaceInput(2, n14);
- n6->ReplaceInput(0, n0);
- n12->ReplaceInput(0, n10);
- n12->ReplaceInput(1, n10);
- n12->ReplaceInput(2, n10);
- n12->ReplaceInput(3, n11);
- n12->ReplaceInput(4, n5);
- n19->ReplaceInput(0, n15);
- n19->ReplaceInput(1, n3);
- n19->ReplaceInput(2, n6);
- n19->ReplaceInput(3, n12);
- n19->ReplaceInput(4, n18);
- n19->ReplaceInput(5, n14);
- n25->ReplaceInput(0, n22);
- n2->ReplaceInput(0, n0);
- n35->ReplaceInput(0, n32);
- n35->ReplaceInput(1, n64);
- n35->ReplaceInput(2, n34);
- n14->ReplaceInput(0, n9);
- n14->ReplaceInput(1, n72);
- n81->ReplaceInput(0, n17);
- n81->ReplaceInput(1, n78);
- n81->ReplaceInput(2, n72);
- n3->ReplaceInput(0, n0);
- n18->ReplaceInput(0, n8);
- n18->ReplaceInput(1, n80);
- n18->ReplaceInput(2, n14);
- n22->ReplaceInput(0, n21);
- n22->ReplaceInput(1, n20);
- n32->ReplaceInput(0, n29);
- n32->ReplaceInput(1, n31);
- n32->ReplaceInput(2, n6);
- n32->ReplaceInput(3, n12);
- n32->ReplaceInput(4, n12);
- n32->ReplaceInput(5, n29);
- n32->ReplaceInput(6, n30);
- n64->ReplaceInput(0, n62);
- n64->ReplaceInput(1, n31);
- n64->ReplaceInput(2, n6);
- n64->ReplaceInput(3, n12);
- n64->ReplaceInput(4, n12);
- n64->ReplaceInput(5, n62);
- n64->ReplaceInput(6, n63);
- n34->ReplaceInput(0, n33);
- n34->ReplaceInput(1, n65);
- n9->ReplaceInput(0, n8);
- n72->ReplaceInput(0, n71);
- n72->ReplaceInput(1, n79);
- n78->ReplaceInput(0, n76);
- n78->ReplaceInput(1, n31);
- n78->ReplaceInput(2, n6);
- n78->ReplaceInput(3, n12);
- n78->ReplaceInput(4, n12);
- n78->ReplaceInput(5, n76);
- n78->ReplaceInput(6, n77);
- n8->ReplaceInput(0, n6);
- n8->ReplaceInput(1, n12);
- n8->ReplaceInput(2, n0);
- n8->ReplaceInput(3, n0);
- n80->ReplaceInput(0, n67);
- n80->ReplaceInput(1, n78);
- n80->ReplaceInput(2, n72);
- n21->ReplaceInput(0, n19);
- n21->ReplaceInput(1, n6);
- n20->ReplaceInput(0, n19);
- n29->ReplaceInput(0, n15);
- n29->ReplaceInput(1, n6);
- n29->ReplaceInput(2, n12);
- n29->ReplaceInput(3, n27);
- n29->ReplaceInput(4, n28);
- n30->ReplaceInput(0, n29);
- n62->ReplaceInput(0, n35);
- n62->ReplaceInput(1, n6);
- n62->ReplaceInput(2, n12);
- n62->ReplaceInput(3, n52);
- n62->ReplaceInput(4, n60);
- n63->ReplaceInput(0, n62);
- n33->ReplaceInput(0, n32);
- n65->ReplaceInput(0, n64);
- n71->ReplaceInput(0, n70);
- n79->ReplaceInput(0, n78);
- n76->ReplaceInput(0, n17);
- n76->ReplaceInput(1, n6);
- n76->ReplaceInput(2, n12);
- n76->ReplaceInput(3, n67);
- n76->ReplaceInput(4, n74);
- n77->ReplaceInput(0, n76);
- n67->ReplaceInput(0, n35);
- n67->ReplaceInput(1, n31);
- n67->ReplaceInput(2, n6);
- n67->ReplaceInput(3, n12);
- n67->ReplaceInput(4, n57);
- n67->ReplaceInput(5, n45);
- n27->ReplaceInput(0, n6);
- n27->ReplaceInput(1, n12);
- n27->ReplaceInput(2, n19);
- n27->ReplaceInput(3, n23);
- n28->ReplaceInput(0, n27);
- n52->ReplaceInput(0, n17);
- n52->ReplaceInput(1, n11);
- n52->ReplaceInput(2, n6);
- n52->ReplaceInput(3, n12);
- n52->ReplaceInput(4, n50);
- n52->ReplaceInput(5, n51);
- n60->ReplaceInput(0, n55);
- n70->ReplaceInput(0, n69);
- n70->ReplaceInput(1, n68);
- n74->ReplaceInput(0, n70);
- n57->ReplaceInput(0, n38);
- n57->ReplaceInput(1, n52);
- n57->ReplaceInput(2, n45);
- n45->ReplaceInput(0, n44);
- n45->ReplaceInput(1, n56);
- n23->ReplaceInput(0, n22);
- n50->ReplaceInput(0, n48);
- n50->ReplaceInput(1, n31);
- n50->ReplaceInput(2, n6);
- n50->ReplaceInput(3, n12);
- n50->ReplaceInput(4, n12);
- n50->ReplaceInput(5, n48);
- n50->ReplaceInput(6, n49);
- n51->ReplaceInput(0, n50);
- n55->ReplaceInput(0, n54);
- n55->ReplaceInput(1, n53);
- n69->ReplaceInput(0, n67);
- n69->ReplaceInput(1, n6);
- n68->ReplaceInput(0, n67);
- n38->ReplaceInput(0, n36);
- n38->ReplaceInput(1, n3);
- n38->ReplaceInput(2, n6);
- n38->ReplaceInput(3, n12);
- n38->ReplaceInput(4, n37);
- n38->ReplaceInput(5, n34);
- n44->ReplaceInput(0, n41);
- n56->ReplaceInput(0, n55);
- n48->ReplaceInput(0, n36);
- n48->ReplaceInput(1, n6);
- n48->ReplaceInput(2, n12);
- n48->ReplaceInput(3, n46);
- n48->ReplaceInput(4, n47);
- n49->ReplaceInput(0, n48);
- n54->ReplaceInput(0, n52);
- n54->ReplaceInput(1, n6);
- n53->ReplaceInput(0, n52);
- n36->ReplaceInput(0, n16);
- n36->ReplaceInput(1, n50);
- n36->ReplaceInput(2, n34);
- n37->ReplaceInput(0, n32);
- n37->ReplaceInput(1, n64);
- n37->ReplaceInput(2, n34);
- n41->ReplaceInput(0, n40);
- n41->ReplaceInput(1, n39);
- n46->ReplaceInput(0, n6);
- n46->ReplaceInput(1, n12);
- n46->ReplaceInput(2, n38);
- n46->ReplaceInput(3, n42);
- n47->ReplaceInput(0, n46);
- n16->ReplaceInput(0, n4);
- n16->ReplaceInput(1, n58);
- n16->ReplaceInput(2, n14);
- n40->ReplaceInput(0, n38);
- n40->ReplaceInput(1, n6);
- n39->ReplaceInput(0, n38);
- n42->ReplaceInput(0, n41);
- n4->ReplaceInput(0, n0);
- n58->ReplaceInput(0, n36);
- n58->ReplaceInput(1, n50);
- n58->ReplaceInput(2, n45);
-
- graph()->SetStart(n0);
- graph()->SetEnd(n86);
-
- ComputeAndVerifySchedule(83);
-}
-
-
-TEST_F(SchedulerTest, BuildScheduleSimpleLoopWithCodeMotion) {
- const Operator* op;
- Unique<HeapObject> unique_constant =
- Unique<HeapObject>::CreateImmovable(factory()->undefined_value());
-
- // Manually transcripted code for:
- // function turbo_fan_test(a, b, c) {
- // while (a < b) {
- // a += b + c;
- // }
- // return a;
- // }
- Node* nil = graph()->NewNode(common()->Dead());
- op = common()->End();
- Node* n34 = graph()->NewNode(op, nil);
- USE(n34);
- op = common()->Return();
- Node* n32 = graph()->NewNode(op, nil, nil, nil);
- USE(n32);
- op = common()->Phi(kMachAnyTagged, 2);
- Node* n14 = graph()->NewNode(op, nil, nil, nil);
- USE(n14);
- op = js()->LessThan(LanguageMode::SLOPPY);
- Node* n17 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil);
- USE(n17);
- op = common()->IfFalse();
- Node* n23 = graph()->NewNode(op, nil);
- USE(n23);
- op = common()->Parameter(1);
- Node* n2 = graph()->NewNode(op, nil);
- USE(n2);
- op = js()->Add(LanguageMode::SLOPPY);
- Node* n29 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n29);
- op = common()->Loop(2);
- Node* n13 = graph()->NewNode(op, nil, nil);
- USE(n13);
- op = common()->Parameter(2);
- Node* n3 = graph()->NewNode(op, nil);
- USE(n3);
- op = common()->Parameter(4);
- Node* n6 = graph()->NewNode(op, nil);
- USE(n6);
- op = common()->FrameState(JS_FRAME, BailoutId(-1),
- OutputFrameStateCombine::Ignore());
- Node* n12 = graph()->NewNode(op, nil, nil, nil, nil, nil);
- USE(n12);
- op = common()->EffectPhi(2);
- Node* n15 = graph()->NewNode(op, nil, nil, nil);
- USE(n15);
- op = common()->Branch();
- Node* n20 = graph()->NewNode(op, nil, nil);
- USE(n20);
- op = common()->Start(3);
- Node* n0 = graph()->NewNode(op);
- USE(n0);
- op = js()->Add(LanguageMode::SLOPPY);
- Node* n27 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil);
- USE(n27);
- op = common()->IfSuccess();
- Node* n28 = graph()->NewNode(op, nil);
- USE(n28);
- op = common()->IfSuccess();
- Node* n9 = graph()->NewNode(op, nil);
- USE(n9);
- op = common()->IfSuccess();
- Node* n30 = graph()->NewNode(op, nil);
- USE(n30);
- op = common()->StateValues(0);
- Node* n10 = graph()->NewNode(op);
- USE(n10);
- op = common()->NumberConstant(0);
- Node* n11 = graph()->NewNode(op);
- USE(n11);
- op = common()->HeapConstant(unique_constant);
- Node* n5 = graph()->NewNode(op);
- USE(n5);
- op = js()->StackCheck();
- Node* n8 = graph()->NewNode(op, nil, nil, nil, nil);
- USE(n8);
- op = js()->ToBoolean();
- Node* n19 = graph()->NewNode(op, nil, nil);
- USE(n19);
- op = common()->IfSuccess();
- Node* n18 = graph()->NewNode(op, nil);
- USE(n18);
- op = common()->Parameter(3);
- Node* n4 = graph()->NewNode(op, nil);
- USE(n4);
- op = js()->StackCheck();
- Node* n25 = graph()->NewNode(op, nil, nil, nil, nil);
- USE(n25);
- op = common()->IfSuccess();
- Node* n26 = graph()->NewNode(op, nil);
- USE(n26);
- op = common()->IfTrue();
- Node* n21 = graph()->NewNode(op, nil);
- USE(n21);
- n34->ReplaceInput(0, n32);
- n32->ReplaceInput(0, n14);
- n32->ReplaceInput(1, n17);
- n32->ReplaceInput(2, n23);
- n14->ReplaceInput(0, n2);
- n14->ReplaceInput(1, n29);
- n14->ReplaceInput(2, n13);
- n17->ReplaceInput(0, n14);
- n17->ReplaceInput(1, n3);
- n17->ReplaceInput(2, n6);
- n17->ReplaceInput(3, n12);
- n17->ReplaceInput(4, n15);
- n17->ReplaceInput(5, n13);
- n23->ReplaceInput(0, n20);
- n2->ReplaceInput(0, n0);
- n29->ReplaceInput(0, n14);
- n29->ReplaceInput(1, n27);
- n29->ReplaceInput(2, n6);
- n29->ReplaceInput(3, n12);
- n29->ReplaceInput(4, n12);
- n29->ReplaceInput(5, n27);
- n29->ReplaceInput(6, n28);
- n13->ReplaceInput(0, n9);
- n13->ReplaceInput(1, n30);
- n3->ReplaceInput(0, n0);
- n6->ReplaceInput(0, n0);
- n12->ReplaceInput(0, n10);
- n12->ReplaceInput(1, n10);
- n12->ReplaceInput(2, n10);
- n12->ReplaceInput(3, n11);
- n12->ReplaceInput(4, n5);
- n15->ReplaceInput(0, n8);
- n15->ReplaceInput(1, n29);
- n15->ReplaceInput(2, n13);
- n20->ReplaceInput(0, n19);
- n20->ReplaceInput(1, n18);
- n27->ReplaceInput(0, n3);
- n27->ReplaceInput(1, n4);
- n27->ReplaceInput(2, n6);
- n27->ReplaceInput(3, n12);
- n27->ReplaceInput(4, n12);
- n27->ReplaceInput(5, n25);
- n27->ReplaceInput(6, n26);
- n28->ReplaceInput(0, n27);
- n9->ReplaceInput(0, n8);
- n30->ReplaceInput(0, n29);
- n8->ReplaceInput(0, n6);
- n8->ReplaceInput(1, n12);
- n8->ReplaceInput(2, n0);
- n8->ReplaceInput(3, n0);
- n19->ReplaceInput(0, n17);
- n19->ReplaceInput(1, n6);
- n18->ReplaceInput(0, n17);
- n4->ReplaceInput(0, n0);
- n25->ReplaceInput(0, n6);
- n25->ReplaceInput(1, n12);
- n25->ReplaceInput(2, n17);
- n25->ReplaceInput(3, n21);
- n26->ReplaceInput(0, n25);
- n21->ReplaceInput(0, n20);
-
- graph()->SetStart(n0);
- graph()->SetEnd(n34);
-
- ComputeAndVerifySchedule(30);
-}
-
-
namespace {
Node* CreateDiamond(Graph* graph, CommonOperatorBuilder* common, Node* cond) {
@@ -2025,7 +697,7 @@ TARGET_TEST_F(SchedulerTest, FloatingDiamond1) {
Node* p0 = graph()->NewNode(common()->Parameter(0), start);
Node* d1 = CreateDiamond(graph(), common(), p0);
Node* ret = graph()->NewNode(common()->Return(), d1, start, start);
- Node* end = graph()->NewNode(common()->End(), ret, start);
+ Node* end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
@@ -2043,7 +715,7 @@ TARGET_TEST_F(SchedulerTest, FloatingDiamond2) {
Node* d2 = CreateDiamond(graph(), common(), p1);
Node* add = graph()->NewNode(&kIntAdd, d1, d2);
Node* ret = graph()->NewNode(common()->Return(), add, start, start);
- Node* end = graph()->NewNode(common()->End(), ret, start);
+ Node* end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
@@ -2062,7 +734,7 @@ TARGET_TEST_F(SchedulerTest, FloatingDiamond3) {
Node* add = graph()->NewNode(&kIntAdd, d1, d2);
Node* d3 = CreateDiamond(graph(), common(), add);
Node* ret = graph()->NewNode(common()->Return(), d3, start, start);
- Node* end = graph()->NewNode(common()->End(), ret, start);
+ Node* end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
@@ -2099,7 +771,7 @@ TARGET_TEST_F(SchedulerTest, NestedFloatingDiamonds) {
Node* ephi1 = graph()->NewNode(common()->EffectPhi(2), start, map, m);
Node* ret = graph()->NewNode(common()->Return(), phi, ephi1, start);
- Node* end = graph()->NewNode(common()->End(), ret, start);
+ Node* end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
@@ -2143,7 +815,7 @@ TARGET_TEST_F(SchedulerTest, NestedFloatingDiamondWithChain) {
Node* add = graph()->NewNode(&kIntAdd, phiA2, phiB2);
Node* ret = graph()->NewNode(common()->Return(), add, start, start);
- Node* end = graph()->NewNode(common()->End(), ret, start);
+ Node* end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
@@ -2177,7 +849,7 @@ TARGET_TEST_F(SchedulerTest, NestedFloatingDiamondWithLoop) {
Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), fv, ind, m);
Node* ret = graph()->NewNode(common()->Return(), phi, start, start);
- Node* end = graph()->NewNode(common()->End(), ret, start);
+ Node* end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
@@ -2210,7 +882,7 @@ TARGET_TEST_F(SchedulerTest, LoopedFloatingDiamond1) {
ind->ReplaceInput(1, phi1); // close induction variable.
Node* ret = graph()->NewNode(common()->Return(), ind, start, f);
- Node* end = graph()->NewNode(common()->End(), ret, f);
+ Node* end = graph()->NewNode(common()->End(2), ret, f);
graph()->SetEnd(end);
@@ -2244,7 +916,7 @@ TARGET_TEST_F(SchedulerTest, LoopedFloatingDiamond2) {
ind->ReplaceInput(1, add); // close induction variable.
Node* ret = graph()->NewNode(common()->Return(), ind, start, f);
- Node* end = graph()->NewNode(common()->End(), ret, f);
+ Node* end = graph()->NewNode(common()->End(2), ret, f);
graph()->SetEnd(end);
@@ -2290,7 +962,7 @@ TARGET_TEST_F(SchedulerTest, LoopedFloatingDiamond3) {
ind->ReplaceInput(1, add); // close induction variable.
Node* ret = graph()->NewNode(common()->Return(), ind, start, f);
- Node* end = graph()->NewNode(common()->End(), ret, f);
+ Node* end = graph()->NewNode(common()->End(2), ret, f);
graph()->SetEnd(end);
@@ -2324,7 +996,7 @@ TARGET_TEST_F(SchedulerTest, PhisPushedDownToDifferentBranches) {
graph()->NewNode(common()->Phi(kMachAnyTagged, 2), phi, phi2, m2);
Node* ret = graph()->NewNode(common()->Return(), phi3, start, start);
- Node* end = graph()->NewNode(common()->End(), ret, start);
+ Node* end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
@@ -2345,7 +1017,7 @@ TARGET_TEST_F(SchedulerTest, BranchHintTrue) {
Node* m = graph()->NewNode(common()->Merge(2), t, f);
Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), tv, fv, m);
Node* ret = graph()->NewNode(common()->Return(), phi, start, start);
- Node* end = graph()->NewNode(common()->End(), ret, start);
+ Node* end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
@@ -2369,7 +1041,7 @@ TARGET_TEST_F(SchedulerTest, BranchHintFalse) {
Node* m = graph()->NewNode(common()->Merge(2), t, f);
Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), tv, fv, m);
Node* ret = graph()->NewNode(common()->Return(), phi, start, start);
- Node* end = graph()->NewNode(common()->End(), ret, start);
+ Node* end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
@@ -2387,15 +1059,17 @@ TARGET_TEST_F(SchedulerTest, CallException) {
Node* p0 = graph()->NewNode(common()->Parameter(0), start);
Node* c1 = graph()->NewNode(&kMockCall, start);
Node* ok1 = graph()->NewNode(common()->IfSuccess(), c1);
- Node* ex1 = graph()->NewNode(common()->IfException(), c1);
+ Node* ex1 = graph()->NewNode(
+ common()->IfException(IfExceptionHint::kLocallyUncaught), c1, c1);
Node* c2 = graph()->NewNode(&kMockCall, ok1);
Node* ok2 = graph()->NewNode(common()->IfSuccess(), c2);
- Node* ex2 = graph()->NewNode(common()->IfException(), c2);
+ Node* ex2 = graph()->NewNode(
+ common()->IfException(IfExceptionHint::kLocallyUncaught), c2, c2);
Node* hdl = graph()->NewNode(common()->Merge(2), ex1, ex2);
Node* m = graph()->NewNode(common()->Merge(2), ok2, hdl);
Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), c2, p0, m);
Node* ret = graph()->NewNode(common()->Return(), phi, start, m);
- Node* end = graph()->NewNode(common()->End(), ret);
+ Node* end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
@@ -2414,7 +1088,7 @@ TARGET_TEST_F(SchedulerTest, TailCall) {
Node* p0 = graph()->NewNode(common()->Parameter(0), start);
Node* call = graph()->NewNode(&kMockTailCall, p0, start, start);
- Node* end = graph()->NewNode(common()->End(), call);
+ Node* end = graph()->NewNode(common()->End(1), call);
graph()->SetEnd(end);
@@ -2437,7 +1111,7 @@ TARGET_TEST_F(SchedulerTest, Switch) {
Node* m = graph()->NewNode(common()->Merge(3), c0, c1, d);
Node* phi = graph()->NewNode(common()->Phi(kMachInt32, 3), v0, v1, vd, m);
Node* ret = graph()->NewNode(common()->Return(), phi, start, m);
- Node* end = graph()->NewNode(common()->End(), ret);
+ Node* end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
@@ -2460,7 +1134,7 @@ TARGET_TEST_F(SchedulerTest, FloatingSwitch) {
Node* m = graph()->NewNode(common()->Merge(3), c0, c1, d);
Node* phi = graph()->NewNode(common()->Phi(kMachInt32, 3), v0, v1, vd, m);
Node* ret = graph()->NewNode(common()->Return(), phi, start, start);
- Node* end = graph()->NewNode(common()->End(), ret);
+ Node* end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
@@ -2480,7 +1154,7 @@ TARGET_TEST_F(SchedulerTest, Terminate) {
Node* terminate = graph()->NewNode(common()->Terminate(), effect, loop);
effect->ReplaceInput(1, terminate);
- Node* end = graph()->NewNode(common()->End(), terminate);
+ Node* end = graph()->NewNode(common()->End(1), terminate);
graph()->SetEnd(end);
diff --git a/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc b/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc
index a5dad5a415..07728913b1 100644
--- a/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc
+++ b/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc
@@ -54,7 +54,6 @@ const PureOperator kPureOperators[] = {
PURE(StringEqual, Operator::kCommutative, 2),
PURE(StringLessThan, Operator::kNoProperties, 2),
PURE(StringLessThanOrEqual, Operator::kNoProperties, 2),
- PURE(StringAdd, Operator::kNoProperties, 2),
PURE(ChangeTaggedToInt32, Operator::kNoProperties, 1),
PURE(ChangeTaggedToUint32, Operator::kNoProperties, 1),
PURE(ChangeTaggedToFloat64, Operator::kNoProperties, 1),
diff --git a/deps/v8/test/unittests/compiler/tail-call-optimization-unittest.cc b/deps/v8/test/unittests/compiler/tail-call-optimization-unittest.cc
index 5ac1f8e796..449299bb1d 100644
--- a/deps/v8/test/unittests/compiler/tail-call-optimization-unittest.cc
+++ b/deps/v8/test/unittests/compiler/tail-call-optimization-unittest.cc
@@ -33,7 +33,7 @@ TEST_F(TailCallOptimizationTest, CallCodeObject0) {
CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0),
new (zone()) MachineSignature(1, 1, kMachineSignature),
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
- Operator::kNoProperties, 0, CallDescriptor::kNoFlags);
+ Operator::kNoProperties, 0, 0, CallDescriptor::kNoFlags);
Node* p0 = Parameter(0);
Node* p1 = Parameter(1);
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
@@ -53,15 +53,16 @@ TEST_F(TailCallOptimizationTest, CallCodeObject1) {
CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0),
new (zone()) MachineSignature(1, 1, kMachineSignature),
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
- Operator::kNoProperties, 0, CallDescriptor::kSupportsTailCalls);
+ Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
Node* p0 = Parameter(0);
Node* p1 = Parameter(1);
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
graph()->start(), graph()->start());
Node* if_success = graph()->NewNode(common()->IfSuccess(), call);
- Node* if_exception = graph()->NewNode(common()->IfException(), call);
+ Node* if_exception = graph()->NewNode(
+ common()->IfException(IfExceptionHint::kLocallyUncaught), call, call);
Node* ret = graph()->NewNode(common()->Return(), call, call, if_success);
- Node* end = graph()->NewNode(common()->End(), if_exception);
+ Node* end = graph()->NewNode(common()->End(1), if_exception);
graph()->SetEnd(end);
Reduction r = Reduce(ret);
ASSERT_FALSE(r.Changed());
@@ -76,7 +77,7 @@ TEST_F(TailCallOptimizationTest, CallCodeObject2) {
CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0),
new (zone()) MachineSignature(1, 1, kMachineSignature),
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
- Operator::kNoProperties, 0, CallDescriptor::kSupportsTailCalls);
+ Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
Node* p0 = Parameter(0);
Node* p1 = Parameter(1);
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
@@ -98,7 +99,7 @@ TEST_F(TailCallOptimizationTest, CallJSFunction0) {
CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0),
new (zone()) MachineSignature(1, 1, kMachineSignature),
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
- Operator::kNoProperties, 0, CallDescriptor::kNoFlags);
+ Operator::kNoProperties, 0, 0, CallDescriptor::kNoFlags);
Node* p0 = Parameter(0);
Node* p1 = Parameter(1);
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
@@ -118,15 +119,16 @@ TEST_F(TailCallOptimizationTest, CallJSFunction1) {
CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0),
new (zone()) MachineSignature(1, 1, kMachineSignature),
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
- Operator::kNoProperties, 0, CallDescriptor::kSupportsTailCalls);
+ Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
Node* p0 = Parameter(0);
Node* p1 = Parameter(1);
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
graph()->start(), graph()->start());
Node* if_success = graph()->NewNode(common()->IfSuccess(), call);
- Node* if_exception = graph()->NewNode(common()->IfException(), call);
+ Node* if_exception = graph()->NewNode(
+ common()->IfException(IfExceptionHint::kLocallyUncaught), call, call);
Node* ret = graph()->NewNode(common()->Return(), call, call, if_success);
- Node* end = graph()->NewNode(common()->End(), if_exception);
+ Node* end = graph()->NewNode(common()->End(1), if_exception);
graph()->SetEnd(end);
Reduction r = Reduce(ret);
ASSERT_FALSE(r.Changed());
@@ -141,7 +143,7 @@ TEST_F(TailCallOptimizationTest, CallJSFunction2) {
CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0),
new (zone()) MachineSignature(1, 1, kMachineSignature),
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
- Operator::kNoProperties, 0, CallDescriptor::kSupportsTailCalls);
+ Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
Node* p0 = Parameter(0);
Node* p1 = Parameter(1);
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
diff --git a/deps/v8/test/unittests/counters-unittest.cc b/deps/v8/test/unittests/counters-unittest.cc
index dd60a0d9c1..822a5c552e 100644
--- a/deps/v8/test/unittests/counters-unittest.cc
+++ b/deps/v8/test/unittests/counters-unittest.cc
@@ -49,7 +49,7 @@ TEST_F(AggregatedMemoryHistogramTest, OneSample1) {
FLAG_histogram_interval = 10;
AddSample(10, 1000);
AddSample(20, 1000);
- EXPECT_EQ(1, samples()->size());
+ EXPECT_EQ(1U, samples()->size());
EXPECT_EQ(1000, (*samples())[0]);
}
@@ -58,7 +58,7 @@ TEST_F(AggregatedMemoryHistogramTest, OneSample2) {
FLAG_histogram_interval = 10;
AddSample(10, 500);
AddSample(20, 1000);
- EXPECT_EQ(1, samples()->size());
+ EXPECT_EQ(1U, samples()->size());
EXPECT_EQ(750, (*samples())[0]);
}
@@ -69,7 +69,7 @@ TEST_F(AggregatedMemoryHistogramTest, OneSample3) {
AddSample(15, 500);
AddSample(15, 1000);
AddSample(20, 1000);
- EXPECT_EQ(1, samples()->size());
+ EXPECT_EQ(1U, samples()->size());
EXPECT_EQ(750, (*samples())[0]);
}
@@ -79,7 +79,7 @@ TEST_F(AggregatedMemoryHistogramTest, OneSample4) {
AddSample(10, 500);
AddSample(15, 750);
AddSample(20, 1000);
- EXPECT_EQ(1, samples()->size());
+ EXPECT_EQ(1U, samples()->size());
EXPECT_EQ(750, (*samples())[0]);
}
@@ -88,7 +88,7 @@ TEST_F(AggregatedMemoryHistogramTest, TwoSamples1) {
FLAG_histogram_interval = 10;
AddSample(10, 1000);
AddSample(30, 1000);
- EXPECT_EQ(2, samples()->size());
+ EXPECT_EQ(2U, samples()->size());
EXPECT_EQ(1000, (*samples())[0]);
EXPECT_EQ(1000, (*samples())[1]);
}
@@ -99,7 +99,7 @@ TEST_F(AggregatedMemoryHistogramTest, TwoSamples2) {
AddSample(10, 1000);
AddSample(20, 1000);
AddSample(30, 1000);
- EXPECT_EQ(2, samples()->size());
+ EXPECT_EQ(2U, samples()->size());
EXPECT_EQ(1000, (*samples())[0]);
EXPECT_EQ(1000, (*samples())[1]);
}
@@ -111,7 +111,7 @@ TEST_F(AggregatedMemoryHistogramTest, TwoSamples3) {
AddSample(20, 1000);
AddSample(20, 500);
AddSample(30, 500);
- EXPECT_EQ(2, samples()->size());
+ EXPECT_EQ(2U, samples()->size());
EXPECT_EQ(1000, (*samples())[0]);
EXPECT_EQ(500, (*samples())[1]);
}
@@ -121,7 +121,7 @@ TEST_F(AggregatedMemoryHistogramTest, TwoSamples4) {
FLAG_histogram_interval = 10;
AddSample(10, 1000);
AddSample(30, 0);
- EXPECT_EQ(2, samples()->size());
+ EXPECT_EQ(2U, samples()->size());
EXPECT_EQ(750, (*samples())[0]);
EXPECT_EQ(250, (*samples())[1]);
}
@@ -131,7 +131,7 @@ TEST_F(AggregatedMemoryHistogramTest, TwoSamples5) {
FLAG_histogram_interval = 10;
AddSample(10, 0);
AddSample(30, 1000);
- EXPECT_EQ(2, samples()->size());
+ EXPECT_EQ(2U, samples()->size());
EXPECT_EQ(250, (*samples())[0]);
EXPECT_EQ(750, (*samples())[1]);
}
@@ -142,7 +142,7 @@ TEST_F(AggregatedMemoryHistogramTest, TwoSamples6) {
AddSample(10, 0);
AddSample(15, 1000);
AddSample(30, 1000);
- EXPECT_EQ(2, samples()->size());
+ EXPECT_EQ(2U, samples()->size());
EXPECT_EQ((500 + 1000) / 2, (*samples())[0]);
EXPECT_EQ(1000, (*samples())[1]);
}
@@ -154,7 +154,7 @@ TEST_F(AggregatedMemoryHistogramTest, TwoSamples7) {
AddSample(15, 1000);
AddSample(25, 0);
AddSample(30, 1000);
- EXPECT_EQ(2, samples()->size());
+ EXPECT_EQ(2U, samples()->size());
EXPECT_EQ((500 + 750) / 2, (*samples())[0]);
EXPECT_EQ((250 + 500) / 2, (*samples())[1]);
}
@@ -166,7 +166,7 @@ TEST_F(AggregatedMemoryHistogramTest, TwoSamples8) {
AddSample(15, 0);
AddSample(25, 1000);
AddSample(30, 0);
- EXPECT_EQ(2, samples()->size());
+ EXPECT_EQ(2U, samples()->size());
EXPECT_EQ((500 + 250) / 2, (*samples())[0]);
EXPECT_EQ((750 + 500) / 2, (*samples())[1]);
}
@@ -177,7 +177,7 @@ TEST_F(AggregatedMemoryHistogramTest, ManySamples1) {
const int kMaxSamples = 1000;
AddSample(0, 0);
AddSample(10 * kMaxSamples, 10 * kMaxSamples);
- EXPECT_EQ(kMaxSamples, samples()->size());
+ EXPECT_EQ(static_cast<unsigned>(kMaxSamples), samples()->size());
for (int i = 0; i < kMaxSamples; i++) {
EXPECT_EQ(i * 10 + 5, (*samples())[i]);
}
@@ -189,7 +189,7 @@ TEST_F(AggregatedMemoryHistogramTest, ManySamples2) {
const int kMaxSamples = 1000;
AddSample(0, 0);
AddSample(10 * (2 * kMaxSamples), 10 * (2 * kMaxSamples));
- EXPECT_EQ(kMaxSamples, samples()->size());
+ EXPECT_EQ(static_cast<unsigned>(kMaxSamples), samples()->size());
for (int i = 0; i < kMaxSamples; i++) {
EXPECT_EQ(i * 10 + 5, (*samples())[i]);
}
diff --git a/deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc b/deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc
index 54d3bd52bb..c75fde492e 100644
--- a/deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc
+++ b/deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc
@@ -25,7 +25,6 @@ class GCIdleTimeHandlerTest : public ::testing::Test {
result.contexts_disposal_rate = GCIdleTimeHandler::kHighContextDisposalRate;
result.size_of_objects = kSizeOfObjects;
result.incremental_marking_stopped = false;
- result.can_start_incremental_marking = true;
result.sweeping_in_progress = false;
result.sweeping_completed = false;
result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed;
@@ -38,56 +37,6 @@ class GCIdleTimeHandlerTest : public ::testing::Test {
return result;
}
- void TransitionToReduceMemoryMode(
- const GCIdleTimeHandler::HeapState& heap_state) {
- handler()->NotifyScavenge();
- EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
- double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
- int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle;
- bool incremental = !heap_state.incremental_marking_stopped ||
- heap_state.can_start_incremental_marking;
- for (int i = 0; i < limit; i++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- if (incremental) {
- EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
- } else {
- EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
- }
- }
- handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
- }
-
- void TransitionToDoneMode(const GCIdleTimeHandler::HeapState& heap_state,
- double idle_time_ms,
- GCIdleTimeActionType expected) {
- EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
- int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts;
- for (int i = 0; i < limit; i++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(expected, action.type);
- EXPECT_TRUE(action.reduce_memory);
- handler()->NotifyMarkCompact();
- handler()->NotifyIdleMarkCompact();
- }
- handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(GCIdleTimeHandler::kDone, handler()->mode());
- }
-
- void TransitionToReduceLatencyMode(
- const GCIdleTimeHandler::HeapState& heap_state) {
- EXPECT_EQ(GCIdleTimeHandler::kDone, handler()->mode());
- int limit = GCIdleTimeHandler::kMarkCompactsBeforeMutatorIsActive;
- double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
- for (int i = 0; i < limit; i++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DONE, action.type);
- handler()->NotifyMarkCompact();
- }
- handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
- }
-
static const size_t kSizeOfObjects = 100 * MB;
static const size_t kMarkCompactSpeed = 200 * KB;
static const size_t kMarkingSpeed = 200 * KB;
@@ -219,6 +168,18 @@ TEST_F(GCIdleTimeHandlerTest, DoScavengeHighScavengeSpeed) {
}
+TEST_F(GCIdleTimeHandlerTest, DoNotScavengeSmallNewSpaceSize) {
+ GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ heap_state.used_new_space_size = (MB / 2) - 1;
+ heap_state.scavenge_speed_in_bytes_per_ms = kNewSpaceCapacity;
+ int idle_time_ms = 16;
+ EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge(
+ idle_time_ms, heap_state.new_space_capacity,
+ heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
+ heap_state.new_space_allocation_throughput_in_bytes_per_ms));
+}
+
+
TEST_F(GCIdleTimeHandlerTest, ShouldDoMarkCompact) {
size_t idle_time_ms = GCIdleTimeHandler::kMaxScheduledIdleTime;
EXPECT_TRUE(GCIdleTimeHandler::ShouldDoMarkCompact(idle_time_ms, 0, 0));
@@ -251,11 +212,8 @@ TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) {
heap_state.contexts_disposed = 1;
heap_state.incremental_marking_stopped = true;
double idle_time_ms = 0;
- for (int mode = 0; mode < 1; mode++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_NOTHING, action.type);
- TransitionToReduceMemoryMode(heap_state);
- }
+ GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+ EXPECT_EQ(DO_NOTHING, action.type);
}
@@ -266,11 +224,8 @@ TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) {
GCIdleTimeHandler::kHighContextDisposalRate - 1;
heap_state.incremental_marking_stopped = true;
double idle_time_ms = 0;
- for (int mode = 0; mode < 1; mode++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_FULL_GC, action.type);
- TransitionToReduceMemoryMode(heap_state);
- }
+ GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+ EXPECT_EQ(DO_FULL_GC, action.type);
}
@@ -280,42 +235,34 @@ TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) {
heap_state.contexts_disposal_rate = 1.0;
heap_state.incremental_marking_stopped = true;
double idle_time_ms = 0;
- for (int mode = 0; mode < 1; mode++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_FULL_GC, action.type);
- TransitionToReduceMemoryMode(heap_state);
- }
+ GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+ EXPECT_EQ(DO_FULL_GC, action.type);
}
TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.contexts_disposed = 1;
- heap_state.contexts_disposal_rate = 1.0;
- heap_state.incremental_marking_stopped = true;
+ heap_state.contexts_disposal_rate =
+ GCIdleTimeHandler::kHighContextDisposalRate;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
double idle_time_ms =
static_cast<double>(heap_state.size_of_objects / speed - 1);
- for (int mode = 0; mode < 1; mode++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
- TransitionToReduceMemoryMode(heap_state);
- }
+ GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+ EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
}
TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.contexts_disposed = 1;
- heap_state.contexts_disposal_rate = 1.0;
+ heap_state.contexts_disposal_rate =
+ GCIdleTimeHandler::kHighContextDisposalRate;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
double idle_time_ms =
static_cast<double>(heap_state.size_of_objects / speed - 1);
- for (int mode = 0; mode < 1; mode++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
- TransitionToReduceMemoryMode(heap_state);
- }
+ GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+ EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
}
@@ -323,197 +270,106 @@ TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
double idle_time_ms = 10;
- for (int mode = 0; mode < 1; mode++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
- EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
- static_cast<size_t>(action.parameter));
- EXPECT_LT(0, action.parameter);
- TransitionToReduceMemoryMode(heap_state);
- }
+ GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+ EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
+ EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
+ static_cast<size_t>(action.parameter));
+ EXPECT_LT(0, action.parameter);
}
TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
- heap_state.incremental_marking_stopped = true;
size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
double idle_time_ms = 10;
- for (int mode = 0; mode < 1; mode++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
- EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
- static_cast<size_t>(action.parameter));
- EXPECT_LT(0, action.parameter);
- TransitionToReduceMemoryMode(heap_state);
- }
+ GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+ EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
+ EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
+ static_cast<size_t>(action.parameter));
+ EXPECT_LT(0, action.parameter);
}
TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
double idle_time_ms =
static_cast<double>(heap_state.size_of_objects / speed - 1);
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_NOTHING, action.type);
- TransitionToReduceMemoryMode(heap_state);
- action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
+ EXPECT_EQ(DONE, action.type);
}
TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
- for (int mode = 0; mode < 1; mode++) {
- heap_state.sweeping_in_progress = true;
- heap_state.sweeping_completed = true;
- double idle_time_ms = 10.0;
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type);
- heap_state.sweeping_in_progress = false;
- heap_state.sweeping_completed = false;
- TransitionToReduceMemoryMode(heap_state);
- }
+ heap_state.sweeping_in_progress = true;
+ heap_state.sweeping_completed = true;
+ double idle_time_ms = 10.0;
+ GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+ EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type);
}
TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
- for (int mode = 0; mode < 1; mode++) {
- heap_state.sweeping_in_progress = true;
- heap_state.sweeping_completed = false;
- double idle_time_ms = 10.0;
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_NOTHING, action.type);
- heap_state.sweeping_in_progress = false;
- heap_state.sweeping_completed = false;
- TransitionToReduceMemoryMode(heap_state);
- }
+ heap_state.sweeping_in_progress = true;
+ heap_state.sweeping_completed = false;
+ double idle_time_ms = 10.0;
+ GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+ EXPECT_EQ(DO_NOTHING, action.type);
}
TEST_F(GCIdleTimeHandlerTest, Scavenge) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
int idle_time_ms = 10;
- for (int mode = 0; mode < 1; mode++) {
- heap_state.used_new_space_size =
- heap_state.new_space_capacity -
- (kNewSpaceAllocationThroughput * idle_time_ms);
- GCIdleTimeAction action =
- handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
- EXPECT_EQ(DO_SCAVENGE, action.type);
- heap_state.used_new_space_size = 0;
- TransitionToReduceMemoryMode(heap_state);
- }
+ heap_state.used_new_space_size =
+ heap_state.new_space_capacity -
+ (kNewSpaceAllocationThroughput * idle_time_ms);
+ GCIdleTimeAction action =
+ handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
+ EXPECT_EQ(DO_SCAVENGE, action.type);
+ heap_state.used_new_space_size = 0;
}
TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
int idle_time_ms = 10;
- heap_state.can_start_incremental_marking = false;
- heap_state.incremental_marking_stopped = true;
- for (int mode = 0; mode < 1; mode++) {
- heap_state.used_new_space_size =
- heap_state.new_space_capacity -
- (kNewSpaceAllocationThroughput * idle_time_ms);
- GCIdleTimeAction action =
- handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
- EXPECT_EQ(DO_SCAVENGE, action.type);
- heap_state.used_new_space_size = 0;
- action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
- EXPECT_EQ(DO_NOTHING, action.type);
- TransitionToReduceMemoryMode(heap_state);
- }
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, StopEventually1) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
- double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
- bool stopped = false;
- for (int i = 0; i < kMaxNotifications && !stopped; i++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- if (action.type == DO_INCREMENTAL_MARKING || action.type == DO_FULL_GC) {
- handler()->NotifyMarkCompact();
- handler()->NotifyIdleMarkCompact();
- }
- if (action.type == DONE) stopped = true;
- }
- EXPECT_TRUE(stopped);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, StopEventually2) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
- heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
- size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
- double idle_time_ms =
- static_cast<double>(heap_state.size_of_objects / speed + 1);
- TransitionToReduceMemoryMode(heap_state);
- TransitionToDoneMode(heap_state, idle_time_ms, DO_FULL_GC);
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+ heap_state.used_new_space_size =
+ heap_state.new_space_capacity -
+ (kNewSpaceAllocationThroughput * idle_time_ms);
+ GCIdleTimeAction action =
+ handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
+ EXPECT_EQ(DO_SCAVENGE, action.type);
+ heap_state.used_new_space_size = 0;
+ action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
EXPECT_EQ(DONE, action.type);
}
-TEST_F(GCIdleTimeHandlerTest, StopEventually3) {
+TEST_F(GCIdleTimeHandlerTest, DoNotStartIncrementalMarking) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
- double idle_time_ms = 10;
- TransitionToReduceMemoryMode(heap_state);
- TransitionToDoneMode(heap_state, idle_time_ms, DO_INCREMENTAL_MARKING);
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DONE, action.type);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
- heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
- size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
- double idle_time_ms =
- static_cast<double>(heap_state.size_of_objects / speed + 1);
- TransitionToReduceMemoryMode(heap_state);
- TransitionToDoneMode(heap_state, idle_time_ms, DO_FULL_GC);
+ double idle_time_ms = 10.0;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DONE, action.type);
- TransitionToReduceLatencyMode(heap_state);
- heap_state.can_start_incremental_marking = true;
- action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
- EXPECT_FALSE(action.reduce_memory);
- EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
}
-TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) {
+TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
- double idle_time_ms = 10;
- TransitionToReduceMemoryMode(heap_state);
- TransitionToDoneMode(heap_state, idle_time_ms, DO_INCREMENTAL_MARKING);
+ double idle_time_ms = 10.0;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DONE, action.type);
- TransitionToReduceLatencyMode(heap_state);
- heap_state.can_start_incremental_marking = true;
+ heap_state.incremental_marking_stopped = false;
action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
- EXPECT_FALSE(action.reduce_memory);
- EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
}
@@ -529,7 +385,6 @@ TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
for (int i = 0; i < kMaxNotifications; i++) {
GCIdleTimeAction action = handler()->Compute(10, heap_state);
EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
@@ -537,105 +392,16 @@ TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) {
}
-TEST_F(GCIdleTimeHandlerTest, StayInReduceLatencyModeBecauseOfScavenges) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
- heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
- double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
- int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle;
- for (int i = 0; i < kMaxNotifications; i++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
- if ((i + 1) % limit == 0) handler()->NotifyScavenge();
- EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
- }
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, StayInReduceLatencyModeBecauseOfMarkCompacts) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
- heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
- double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
- int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle;
- for (int i = 0; i < kMaxNotifications; i++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
- if ((i + 1) % limit == 0) handler()->NotifyMarkCompact();
- EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
- }
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, ReduceMemoryToReduceLatency) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
- heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
- double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
- int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts;
- for (int idle_gc = 0; idle_gc < limit; idle_gc++) {
- TransitionToReduceMemoryMode(heap_state);
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
- EXPECT_TRUE(action.reduce_memory);
- EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
- for (int i = 0; i < idle_gc; i++) {
- action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
- EXPECT_TRUE(action.reduce_memory);
- // ReduceMemory mode should tolerate one mutator GC per idle GC.
- handler()->NotifyScavenge();
- // Notify idle GC.
- handler()->NotifyMarkCompact();
- handler()->NotifyIdleMarkCompact();
- }
- // Transition to ReduceLatency mode after doing |idle_gc| idle GCs.
- handler()->NotifyScavenge();
- action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_NOTHING, action.type);
- EXPECT_FALSE(action.reduce_memory);
- EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
- }
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, ReduceMemoryToDone) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
- heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
- double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
- int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts;
- TransitionToReduceMemoryMode(heap_state);
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
- EXPECT_TRUE(action.reduce_memory);
- for (int i = 0; i < limit; i++) {
- action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
- EXPECT_TRUE(action.reduce_memory);
- EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
- // ReduceMemory mode should tolerate one mutator GC per idle GC.
- handler()->NotifyScavenge();
- // Notify idle GC.
- handler()->NotifyMarkCompact();
- handler()->NotifyIdleMarkCompact();
- }
- action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DONE, action.type);
-}
-
-
TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnSweeping) {
// Regression test for crbug.com/489323.
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
// Simulate sweeping being in-progress but not complete.
heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
heap_state.sweeping_in_progress = true;
heap_state.sweeping_completed = false;
double idle_time_ms = 10.0;
- for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerMode; i++) {
+ for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimes; i++) {
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_NOTHING, action.type);
}
@@ -651,34 +417,11 @@ TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) {
// Simulate incremental marking stopped and not eligible to start.
heap_state.incremental_marking_stopped = true;
- heap_state.can_start_incremental_marking = false;
double idle_time_ms = 10.0;
- for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerMode; i++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_NOTHING, action.type);
- }
- // We should return DONE after not making progress for some time.
+ // We should return DONE if we cannot start incremental marking.
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DONE, action.type);
}
-
-TEST_F(GCIdleTimeHandlerTest, BackgroundReduceLatencyToReduceMemory) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
- heap_state.incremental_marking_stopped = false;
- heap_state.can_start_incremental_marking = true;
- double idle_time_ms = GCIdleTimeHandler::kMinBackgroundIdleTime;
- handler()->NotifyScavenge();
- EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
- int limit =
- GCIdleTimeHandler::kBackgroundIdleNotificationsBeforeMutatorIsIdle;
- for (int i = 0; i < limit; i++) {
- GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
- }
- handler()->Compute(idle_time_ms, heap_state);
- EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
-}
-
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/heap/heap-unittest.cc b/deps/v8/test/unittests/heap/heap-unittest.cc
new file mode 100644
index 0000000000..9492faf9f3
--- /dev/null
+++ b/deps/v8/test/unittests/heap/heap-unittest.cc
@@ -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.
+
+#include <cmath>
+#include <limits>
+
+#include "src/objects.h"
+#include "src/objects-inl.h"
+
+#include "src/handles.h"
+#include "src/handles-inl.h"
+
+#include "src/heap/heap.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace internal {
+
+double Round(double x) {
+ // Round to three digits.
+ return floor(x * 1000 + 0.5) / 1000;
+}
+
+
+void CheckEqualRounded(double expected, double actual) {
+ expected = Round(expected);
+ actual = Round(actual);
+ EXPECT_DOUBLE_EQ(expected, actual);
+}
+
+
+TEST(Heap, HeapGrowingFactor) {
+ CheckEqualRounded(Heap::kMaxHeapGrowingFactor,
+ Heap::HeapGrowingFactor(34, 1));
+ CheckEqualRounded(3.553, Heap::HeapGrowingFactor(45, 1));
+ CheckEqualRounded(2.830, Heap::HeapGrowingFactor(50, 1));
+ CheckEqualRounded(1.478, Heap::HeapGrowingFactor(100, 1));
+ CheckEqualRounded(1.193, Heap::HeapGrowingFactor(200, 1));
+ CheckEqualRounded(1.121, Heap::HeapGrowingFactor(300, 1));
+ CheckEqualRounded(Heap::HeapGrowingFactor(300, 1),
+ Heap::HeapGrowingFactor(600, 2));
+ CheckEqualRounded(Heap::kMinHeapGrowingFactor,
+ Heap::HeapGrowingFactor(400, 1));
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/heap/memory-reducer-unittest.cc b/deps/v8/test/unittests/heap/memory-reducer-unittest.cc
new file mode 100644
index 0000000000..3301d13b7e
--- /dev/null
+++ b/deps/v8/test/unittests/heap/memory-reducer-unittest.cc
@@ -0,0 +1,331 @@
+// 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/flags.h"
+#include "src/heap/memory-reducer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace internal {
+
+MemoryReducer::State DoneState() {
+ return MemoryReducer::State(MemoryReducer::kDone, 0, 0.0, 1.0);
+}
+
+
+MemoryReducer::State WaitState(int started_gcs, double next_gc_start_ms) {
+ return MemoryReducer::State(MemoryReducer::kWait, started_gcs,
+ next_gc_start_ms, 1.0);
+}
+
+
+MemoryReducer::State RunState(int started_gcs, double next_gc_start_ms) {
+ return MemoryReducer::State(MemoryReducer::kRun, started_gcs,
+ next_gc_start_ms, 1.0);
+}
+
+
+MemoryReducer::Event MarkCompactEvent(double time_ms,
+ bool next_gc_likely_to_collect_more) {
+ MemoryReducer::Event event;
+ event.type = MemoryReducer::kMarkCompact;
+ event.time_ms = time_ms;
+ event.next_gc_likely_to_collect_more = next_gc_likely_to_collect_more;
+ return event;
+}
+
+
+MemoryReducer::Event MarkCompactEventGarbageLeft(double time_ms) {
+ return MarkCompactEvent(time_ms, true);
+}
+
+
+MemoryReducer::Event MarkCompactEventNoGarbageLeft(double time_ms) {
+ return MarkCompactEvent(time_ms, false);
+}
+
+
+MemoryReducer::Event TimerEvent(double time_ms, bool low_allocation_rate,
+ bool can_start_incremental_gc) {
+ MemoryReducer::Event event;
+ event.type = MemoryReducer::kTimer;
+ event.time_ms = time_ms;
+ event.low_allocation_rate = low_allocation_rate;
+ event.can_start_incremental_gc = can_start_incremental_gc;
+ return event;
+}
+
+
+MemoryReducer::Event TimerEventLowAllocationRate(double time_ms) {
+ return TimerEvent(time_ms, true, true);
+}
+
+
+MemoryReducer::Event TimerEventHighAllocationRate(double time_ms) {
+ return TimerEvent(time_ms, false, true);
+}
+
+
+MemoryReducer::Event TimerEventPendingGC(double time_ms) {
+ return TimerEvent(time_ms, true, false);
+}
+
+
+MemoryReducer::Event ContextDisposedEvent(double time_ms) {
+ MemoryReducer::Event event;
+ event.type = MemoryReducer::kContextDisposed;
+ event.time_ms = time_ms;
+ return event;
+}
+
+
+MemoryReducer::Event BackgroundIdleNotificationEvent(
+ double time_ms, bool can_start_incremental_gc = true) {
+ MemoryReducer::Event event;
+ event.type = MemoryReducer::kBackgroundIdleNotification;
+ event.time_ms = time_ms;
+ event.can_start_incremental_gc = can_start_incremental_gc;
+ return event;
+}
+
+
+TEST(MemoryReducer, FromDoneToDone) {
+ MemoryReducer::State state0(DoneState()), state1(DoneState());
+
+ state1 = MemoryReducer::Step(state0, TimerEventLowAllocationRate(0));
+ EXPECT_EQ(MemoryReducer::kDone, state1.action);
+
+ state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(0));
+ EXPECT_EQ(MemoryReducer::kDone, state1.action);
+
+ state1 = MemoryReducer::Step(state0, TimerEventPendingGC(0));
+ EXPECT_EQ(MemoryReducer::kDone, state1.action);
+
+ state1 = MemoryReducer::Step(state0, BackgroundIdleNotificationEvent(0));
+ EXPECT_EQ(MemoryReducer::kDone, state1.action);
+}
+
+
+TEST(MemoryReducer, FromDoneToWait) {
+ if (!FLAG_incremental_marking) return;
+
+ MemoryReducer::State state0(DoneState()), state1(DoneState());
+
+ state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(MemoryReducer::kLongDelayMs + 2, state1.next_gc_start_ms);
+ EXPECT_EQ(0, state1.started_gcs);
+ EXPECT_EQ(2, state1.last_gc_time_ms);
+
+ state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(MemoryReducer::kLongDelayMs + 2, state1.next_gc_start_ms);
+ EXPECT_EQ(0, state1.started_gcs);
+ EXPECT_EQ(2, state1.last_gc_time_ms);
+
+ state1 = MemoryReducer::Step(state0, ContextDisposedEvent(0));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(MemoryReducer::kLongDelayMs, state1.next_gc_start_ms);
+ EXPECT_EQ(0, state1.started_gcs);
+ EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
+}
+
+
+TEST(MemoryReducer, FromWaitToWait) {
+ if (!FLAG_incremental_marking) return;
+
+ MemoryReducer::State state0(WaitState(2, 1000.0)), state1(DoneState());
+
+ state1 = MemoryReducer::Step(state0, ContextDisposedEvent(2000));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+
+ state1 = MemoryReducer::Step(
+ state0, TimerEventLowAllocationRate(state0.next_gc_start_ms - 1));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+
+ state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(2000));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+
+ state1 = MemoryReducer::Step(state0, TimerEventPendingGC(2000));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+
+ state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2000));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+ EXPECT_EQ(2000, state1.last_gc_time_ms);
+
+ state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2000));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+ EXPECT_EQ(2000, state1.last_gc_time_ms);
+
+ state1 = MemoryReducer::Step(state0, BackgroundIdleNotificationEvent(2000));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs + 1, state1.started_gcs);
+
+ state1 =
+ MemoryReducer::Step(state0, BackgroundIdleNotificationEvent(2000, false));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+
+ state0.last_gc_time_ms = 0;
+ state1 = MemoryReducer::Step(
+ state0,
+ TimerEventHighAllocationRate(MemoryReducer::kWatchdogDelayMs + 1));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(MemoryReducer::kWatchdogDelayMs + 1 + MemoryReducer::kLongDelayMs,
+ state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+ EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
+
+ state0.last_gc_time_ms = 1;
+ state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(2000));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+ EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
+
+ state0.started_gcs = MemoryReducer::kMaxNumberOfGCs;
+ state1 = MemoryReducer::Step(state0, BackgroundIdleNotificationEvent(2000));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+}
+
+
+TEST(MemoryReducer, FromWaitToRun) {
+ if (!FLAG_incremental_marking) return;
+
+ MemoryReducer::State state0(WaitState(0, 1000.0)), state1(DoneState());
+
+ state1 = MemoryReducer::Step(
+ state0, TimerEventLowAllocationRate(state0.next_gc_start_ms + 1));
+ EXPECT_EQ(MemoryReducer::kRun, state1.action);
+ EXPECT_EQ(0, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs + 1, state1.started_gcs);
+
+ state1 = MemoryReducer::Step(
+ state0,
+ TimerEventHighAllocationRate(MemoryReducer::kWatchdogDelayMs + 2));
+ EXPECT_EQ(MemoryReducer::kRun, state1.action);
+ EXPECT_EQ(0, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs + 1, state1.started_gcs);
+ EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
+}
+
+
+TEST(MemoryReducer, FromWaitToDone) {
+ if (!FLAG_incremental_marking) return;
+
+ MemoryReducer::State state0(WaitState(2, 0.0)), state1(DoneState());
+
+ state0.started_gcs = MemoryReducer::kMaxNumberOfGCs;
+
+ state1 = MemoryReducer::Step(state0, TimerEventLowAllocationRate(2000));
+ EXPECT_EQ(MemoryReducer::kDone, state1.action);
+ EXPECT_EQ(0, state1.next_gc_start_ms);
+ EXPECT_EQ(MemoryReducer::kMaxNumberOfGCs, state1.started_gcs);
+ EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
+
+ state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(2000));
+ EXPECT_EQ(MemoryReducer::kDone, state1.action);
+ EXPECT_EQ(0, state1.next_gc_start_ms);
+ EXPECT_EQ(MemoryReducer::kMaxNumberOfGCs, state1.started_gcs);
+ EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
+
+ state1 = MemoryReducer::Step(state0, TimerEventPendingGC(2000));
+ EXPECT_EQ(MemoryReducer::kDone, state1.action);
+ EXPECT_EQ(0, state1.next_gc_start_ms);
+ EXPECT_EQ(MemoryReducer::kMaxNumberOfGCs, state1.started_gcs);
+ EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
+}
+
+
+TEST(MemoryReducer, FromRunToRun) {
+ if (!FLAG_incremental_marking) return;
+
+ MemoryReducer::State state0(RunState(1, 0.0)), state1(DoneState());
+
+ state1 = MemoryReducer::Step(state0, TimerEventLowAllocationRate(2000));
+ EXPECT_EQ(MemoryReducer::kRun, state1.action);
+ EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+ EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
+
+ state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(2000));
+ EXPECT_EQ(MemoryReducer::kRun, state1.action);
+ EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+ EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
+
+ state1 = MemoryReducer::Step(state0, TimerEventPendingGC(2000));
+ EXPECT_EQ(MemoryReducer::kRun, state1.action);
+ EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+ EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
+
+ state1 = MemoryReducer::Step(state0, ContextDisposedEvent(2000));
+ EXPECT_EQ(MemoryReducer::kRun, state1.action);
+ EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+ EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
+}
+
+
+TEST(MemoryReducer, FromRunToDone) {
+ if (!FLAG_incremental_marking) return;
+
+ MemoryReducer::State state0(RunState(2, 0.0)), state1(DoneState());
+
+ state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2000));
+ EXPECT_EQ(MemoryReducer::kDone, state1.action);
+ EXPECT_EQ(0, state1.next_gc_start_ms);
+ EXPECT_EQ(MemoryReducer::kMaxNumberOfGCs, state1.started_gcs);
+ EXPECT_EQ(2000, state1.last_gc_time_ms);
+
+ state0.started_gcs = MemoryReducer::kMaxNumberOfGCs;
+
+ state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2000));
+ EXPECT_EQ(MemoryReducer::kDone, state1.action);
+ EXPECT_EQ(0, state1.next_gc_start_ms);
+ EXPECT_EQ(2000, state1.last_gc_time_ms);
+}
+
+
+TEST(MemoryReducer, FromRunToWait) {
+ if (!FLAG_incremental_marking) return;
+
+ MemoryReducer::State state0(RunState(2, 0.0)), state1(DoneState());
+
+ state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2000));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(2000 + MemoryReducer::kShortDelayMs, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+ EXPECT_EQ(2000, state1.last_gc_time_ms);
+
+ state0.started_gcs = 1;
+
+ state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2000));
+ EXPECT_EQ(MemoryReducer::kWait, state1.action);
+ EXPECT_EQ(2000 + MemoryReducer::kShortDelayMs, state1.next_gc_start_ms);
+ EXPECT_EQ(state0.started_gcs, state1.started_gcs);
+ EXPECT_EQ(2000, state1.last_gc_time_ms);
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/libplatform/default-platform-unittest.cc b/deps/v8/test/unittests/libplatform/default-platform-unittest.cc
index d2c160e558..814b27bc51 100644
--- a/deps/v8/test/unittests/libplatform/default-platform-unittest.cc
+++ b/deps/v8/test/unittests/libplatform/default-platform-unittest.cc
@@ -19,6 +19,17 @@ struct MockTask : public Task {
MOCK_METHOD0(Die, void());
};
+
+class DefaultPlatformWithMockTime : public DefaultPlatform {
+ public:
+ DefaultPlatformWithMockTime() : time_(0) {}
+ double MonotonicallyIncreasingTime() override { return time_; }
+ void IncreaseTime(double seconds) { time_ += seconds; }
+
+ private:
+ double time_;
+};
+
} // namespace
@@ -39,5 +50,82 @@ TEST(DefaultPlatformTest, PumpMessageLoop) {
EXPECT_FALSE(platform.PumpMessageLoop(isolate));
}
+
+TEST(DefaultPlatformTest, PumpMessageLoopDelayed) {
+ InSequence s;
+
+ int dummy;
+ Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
+
+ DefaultPlatformWithMockTime platform;
+ EXPECT_FALSE(platform.PumpMessageLoop(isolate));
+
+ StrictMock<MockTask>* task1 = new StrictMock<MockTask>;
+ StrictMock<MockTask>* task2 = new StrictMock<MockTask>;
+ platform.CallDelayedOnForegroundThread(isolate, task2, 100);
+ platform.CallDelayedOnForegroundThread(isolate, task1, 10);
+
+ EXPECT_FALSE(platform.PumpMessageLoop(isolate));
+
+ platform.IncreaseTime(11);
+ EXPECT_CALL(*task1, Run());
+ EXPECT_CALL(*task1, Die());
+ EXPECT_TRUE(platform.PumpMessageLoop(isolate));
+
+ EXPECT_FALSE(platform.PumpMessageLoop(isolate));
+
+ platform.IncreaseTime(90);
+ EXPECT_CALL(*task2, Run());
+ EXPECT_CALL(*task2, Die());
+ EXPECT_TRUE(platform.PumpMessageLoop(isolate));
+}
+
+
+TEST(DefaultPlatformTest, PumpMessageLoopNoStarvation) {
+ InSequence s;
+
+ int dummy;
+ Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
+
+ DefaultPlatformWithMockTime platform;
+ EXPECT_FALSE(platform.PumpMessageLoop(isolate));
+
+ StrictMock<MockTask>* task1 = new StrictMock<MockTask>;
+ StrictMock<MockTask>* task2 = new StrictMock<MockTask>;
+ StrictMock<MockTask>* task3 = new StrictMock<MockTask>;
+ platform.CallOnForegroundThread(isolate, task1);
+ platform.CallDelayedOnForegroundThread(isolate, task2, 10);
+ platform.IncreaseTime(11);
+
+ EXPECT_CALL(*task1, Run());
+ EXPECT_CALL(*task1, Die());
+ EXPECT_TRUE(platform.PumpMessageLoop(isolate));
+
+ platform.CallOnForegroundThread(isolate, task3);
+
+ EXPECT_CALL(*task2, Run());
+ EXPECT_CALL(*task2, Die());
+ EXPECT_TRUE(platform.PumpMessageLoop(isolate));
+ EXPECT_CALL(*task3, Run());
+ EXPECT_CALL(*task3, Die());
+ EXPECT_TRUE(platform.PumpMessageLoop(isolate));
+}
+
+
+TEST(DefaultPlatformTest, PendingDelayedTasksAreDestroyedOnShutdown) {
+ InSequence s;
+
+ int dummy;
+ Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
+
+ {
+ DefaultPlatformWithMockTime platform;
+ StrictMock<MockTask>* task = new StrictMock<MockTask>;
+ platform.CallDelayedOnForegroundThread(isolate, task, 10);
+ EXPECT_CALL(*task, Die());
+ }
+}
+
+
} // namespace platform
} // namespace v8
diff --git a/deps/v8/test/unittests/unittests.gyp b/deps/v8/test/unittests/unittests.gyp
index 7a298a9074..00658b3fda 100644
--- a/deps/v8/test/unittests/unittests.gyp
+++ b/deps/v8/test/unittests/unittests.gyp
@@ -44,10 +44,11 @@
'compiler/compiler-test-utils.h',
'compiler/control-equivalence-unittest.cc',
'compiler/control-flow-optimizer-unittest.cc',
- 'compiler/control-reducer-unittest.cc',
+ 'compiler/dead-code-elimination-unittest.cc',
'compiler/diamond-unittest.cc',
'compiler/graph-reducer-unittest.cc',
'compiler/graph-reducer-unittest.h',
+ 'compiler/graph-trimmer-unittest.cc',
'compiler/graph-unittest.cc',
'compiler/graph-unittest.h',
'compiler/instruction-selector-unittest.cc',
@@ -88,6 +89,8 @@
'libplatform/task-queue-unittest.cc',
'libplatform/worker-thread-unittest.cc',
'heap/gc-idle-time-handler-unittest.cc',
+ 'heap/memory-reducer-unittest.cc',
+ 'heap/heap-unittest.cc',
'run-all-unittests.cc',
'test-utils.h',
'test-utils.cc',
diff --git a/deps/v8/test/webkit/class-syntax-extends-expected.txt b/deps/v8/test/webkit/class-syntax-extends-expected.txt
index b3b4c8ee60..1eede9c60b 100644
--- a/deps/v8/test/webkit/class-syntax-extends-expected.txt
+++ b/deps/v8/test/webkit/class-syntax-extends-expected.txt
@@ -58,12 +58,12 @@ PASS new (class extends undefined { constructor () { this } }) threw exception T
PASS new (class extends undefined { constructor () { super(); } }) threw exception TypeError: Class extends value undefined is not a function or null.
PASS x = {}; new (class extends undefined { constructor () { return x; } }) threw exception TypeError: Class extends value undefined is not a function or null.
PASS y = 12; new (class extends undefined { constructor () { return y; } }) threw exception TypeError: Class extends value undefined is not a function or null.
-FAIL class x {}; new (class extends null { constructor () { return new x; } }) instanceof x should be true. Threw exception TypeError: x is not a function
+PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x is true
PASS new (class extends null { constructor () { this; } }) threw exception ReferenceError: this is not defined.
PASS new (class extends null { constructor () { super(); } }) threw exception TypeError: function () {} is not a constructor.
PASS x = {}; new (class extends null { constructor () { return x } }) is x
PASS y = 12; new (class extends null { constructor () { return y; } }) threw exception TypeError: Derived constructors may only return object or undefined.
-FAIL class x {}; new (class extends null { constructor () { return new x; } }) instanceof x should be true. Threw exception TypeError: x is not a function
+PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x is true
PASS x = null; Object.getPrototypeOf((class extends x { }).prototype) is null
PASS Object.prototype.isPrototypeOf(class { }) is true
PASS Function.prototype.isPrototypeOf(class { }) is true
diff --git a/deps/v8/test/webkit/cyclic-prototypes-expected.txt b/deps/v8/test/webkit/cyclic-prototypes-expected.txt
index 7ac87b04ca..34bdb04a73 100644
--- a/deps/v8/test/webkit/cyclic-prototypes-expected.txt
+++ b/deps/v8/test/webkit/cyclic-prototypes-expected.txt
@@ -26,7 +26,7 @@ This test makes sure we don't hang when setting cyclic prototype values: http://
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS o1.__proto__ = o3; threw exception Error: Cyclic __proto__ value.
+PASS o1.__proto__ = o3; threw exception TypeError: Cyclic __proto__ value.
PASS ({}).hasOwnProperty.call(o1, '__proto__') is false
PASS ({}).hasOwnProperty.call(o1, '__proto__') is true
PASS Object.getPrototypeOf(o1) is null
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 1948700fca..7731a98671 100644
--- a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
+++ b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
@@ -44,12 +44,12 @@ PASS getSortedOwnPropertyNames(decodeURI) is ['length', 'name']
PASS getSortedOwnPropertyNames(decodeURIComponent) is ['length', 'name']
PASS getSortedOwnPropertyNames(encodeURI) is ['length', 'name']
PASS getSortedOwnPropertyNames(encodeURIComponent) is ['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) is ['arguments', 'assign', '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']
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']
+PASS getSortedOwnPropertyNames(Array) is ['arguments', 'caller', 'from', 'isArray', 'length', 'name', 'observe', 'of', 'prototype', 'unobserve']
+PASS getSortedOwnPropertyNames(Array.prototype) is ['concat', 'constructor', 'copyWithin', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']
PASS getSortedOwnPropertyNames(String) is ['arguments', 'caller', 'fromCharCode', 'fromCodePoint', 'length', 'name', 'prototype', 'raw']
PASS getSortedOwnPropertyNames(String.prototype) is ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'codePointAt', 'concat', 'constructor', 'endsWith', 'fixed', 'fontcolor', 'fontsize', 'includes', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'repeat', 'replace', 'search', 'slice', 'small', 'split', 'startsWith', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']
PASS getSortedOwnPropertyNames(Boolean) is ['arguments', 'caller', 'length', 'name', 'prototype']
diff --git a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js
index 20e509ba96..e34562f5ba 100644
--- a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js
+++ b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js
@@ -71,12 +71,12 @@ var expectedPropertyNamesSet = {
"encodeURI": "['length', 'name']",
"encodeURIComponent": "['length', 'name']",
// Built-in ECMA objects
- "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": "['arguments', 'assign', '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": "['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']",
+ "Array": "['arguments', 'caller', 'from', 'isArray', 'length', 'name', 'observe', 'of', 'prototype', 'unobserve']",
+ "Array.prototype": "['concat', 'constructor', 'copyWithin', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']",
"String": "['arguments', 'caller', 'fromCharCode', 'fromCodePoint', 'length', 'name', 'prototype', 'raw']",
"String.prototype": "['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'codePointAt', 'concat', 'constructor', 'endsWith', 'fixed', 'fontcolor', 'fontsize', 'includes', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'repeat', 'replace', 'search', 'slice', 'small', 'split', 'startsWith', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']",
"Boolean": "['arguments', 'caller', 'length', 'name', 'prototype']",
diff --git a/deps/v8/test/webkit/fast/js/arguments-expected.txt b/deps/v8/test/webkit/fast/js/arguments-expected.txt
index f5bbb72936..4f0150033d 100644
--- a/deps/v8/test/webkit/fast/js/arguments-expected.txt
+++ b/deps/v8/test/webkit/fast/js/arguments-expected.txt
@@ -157,7 +157,7 @@ PASS access_after_delete_extra_5(1, 2, 3, 4, 5) is 5
PASS argumentsParam(true) is true
PASS argumentsFunctionConstructorParam(true) is true
PASS argumentsVarUndefined() is '[object Arguments]'
-FAIL argumentsConstUndefined() should be [object Arguments]. Threw exception TypeError: Identifier 'arguments' has already been declared
+FAIL argumentsConstUndefined() should be [object Arguments]. Threw exception SyntaxError: Identifier 'arguments' has already been declared
PASS argumentCalleeInException() is argumentCalleeInException
PASS shadowedArgumentsApply([true]) is true
PASS shadowedArgumentsLength([]) is 0
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 cc273dfba0..df66f4eba4 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
@@ -56,9 +56,9 @@ PASS checkNumericGet(true, Boolean) is true
FAIL checkNumericSet(1, Number) should be true. Was false.
FAIL checkNumericSet('hello', String) should be true. Was false.
FAIL checkNumericSet(true, Boolean) should be true. Was false.
-FAIL checkNumericGetStrict(1, Number) should be true. Was false.
-FAIL checkNumericGetStrict('hello', String) should be true. Was false.
-FAIL checkNumericGetStrict(true, Boolean) should be true. Was false.
+PASS checkNumericGetStrict(1, Number) is true
+PASS checkNumericGetStrict('hello', String) is true
+PASS checkNumericGetStrict(true, Boolean) is true
FAIL checkNumericSetStrict(1, Number) should be true. Was false.
FAIL checkNumericSetStrict('hello', String) should be true. Was false.
FAIL checkNumericSetStrict(true, Boolean) should be true. Was false.
diff --git a/deps/v8/test/webkit/webkit.status b/deps/v8/test/webkit/webkit.status
index d8c6864105..57d86cb921 100644
--- a/deps/v8/test/webkit/webkit.status
+++ b/deps/v8/test/webkit/webkit.status
@@ -49,9 +49,11 @@
}], # 'mode == debug'
['simulator', {
# Skip tests that timeout with turbofan.
- 'dfg-int-overflow-in-loop': [PASS, NO_VARIANTS],
'array-iterate-backwards': [PASS, NO_VARIANTS],
'function-apply-aliased': [SKIP],
+
+ # Skip tests that are too slow for simulators.
+ 'dfg-int-overflow-in-loop': [SKIP],
}], # 'simulator'
['arch == arm64 and simulator_run == True', {
'dfg-int-overflow-in-loop': [SKIP],