| Index: test/mjsunit/for-in-opt.js
|
| diff --git a/test/mjsunit/for-in-opt.js b/test/mjsunit/for-in-opt.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..bc59a1b0877e0ebd687d4698ac4b32ab724d7869
|
| --- /dev/null
|
| +++ b/test/mjsunit/for-in-opt.js
|
| @@ -0,0 +1,157 @@
|
| +// 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 --expose-debug-as debug
|
| +
|
| +"use strict";
|
| +
|
| +// Test non-JSObject receiver.
|
| +function f(o) {
|
| + var result = [];
|
| + for (var i in o) {
|
| + result.push(i);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +assertEquals(["0"], f("a"));
|
| +assertEquals(["0"], f("a"));
|
| +
|
| +%OptimizeFunctionOnNextCall(f);
|
| +assertEquals(["0","1","2"], f("bla"));
|
| +
|
| +// Test the lazy deopt points.
|
| +var keys = ["a", "b", "c", "d"];
|
| +var property_descriptor_keys = [];
|
| +var deopt_enum = false;
|
| +var deopt_property_descriptor = false;
|
| +
|
| +var handler = {
|
| + ownKeys() {
|
| + if (deopt_enum) {
|
| + %DeoptimizeFunction(f2);
|
| + deopt_enum = false;
|
| + }
|
| + return keys;
|
| + },
|
| + getOwnPropertyDescriptor(target, k) {
|
| + if (deopt_property_descriptor) {
|
| + %DeoptimizeFunction(f2);
|
| + deopt_property_descriptor = false;
|
| + }
|
| + property_descriptor_keys.push(k);
|
| + return { enumerable: true, configurable: true }
|
| + },
|
| +};
|
| +
|
| +
|
| +var proxy = new Proxy({}, handler);
|
| +var o = {__proto__: proxy};
|
| +
|
| +function f2(o) {
|
| + var result = [];
|
| + for (var i in o) {
|
| + result.push(i);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +function check_f2() {
|
| + assertEquals(keys, f2(o));
|
| + assertEquals(keys, property_descriptor_keys);
|
| + property_descriptor_keys.length = 0;
|
| +}
|
| +
|
| +check_f2();
|
| +check_f2();
|
| +
|
| +// Test lazy deopt after ForInEnumerate
|
| +%OptimizeFunctionOnNextCall(f2);
|
| +deopt_enum = true;
|
| +check_f2();
|
| +
|
| +// Test lazy deopt after FILTER_KEY
|
| +%OptimizeFunctionOnNextCall(f2);
|
| +deopt_property_descriptor = true;
|
| +check_f2();
|
| +
|
| +
|
| +function f3(o) {
|
| + for (var i in o) {
|
| + }
|
| +}
|
| +
|
| +f3({__proto__:{x:1}});
|
| +f3({__proto__:{x:1}});
|
| +
|
| +%OptimizeFunctionOnNextCall(f3);
|
| +f3(undefined);
|
| +f3(null);
|
| +
|
| +// Reliable repro for an issue previously flushed out by GC stress.
|
| +var p = {x: "x"}
|
| +
|
| +function f4(o, p) {
|
| + var result = [];
|
| + for (var i in o) {
|
| + var j = p.x + "str";
|
| + result.push(i);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +function check_f4() {
|
| + assertEquals(keys, f4(o, p));
|
| + assertEquals(keys, property_descriptor_keys);
|
| + property_descriptor_keys.length = 0;
|
| +}
|
| +
|
| +check_f4();
|
| +check_f4();
|
| +
|
| +%OptimizeFunctionOnNextCall(f4);
|
| +
|
| +p.y = "y"; // Change map, cause eager deopt.
|
| +check_f4();
|
| +
|
| +// Repro for Turbofan equivalent.
|
| +var x;
|
| +var count = 0;
|
| +
|
| +var Debug = debug.Debug;
|
| +
|
| +function listener(event, exec_state, event_data, data) {
|
| + if (event == Debug.DebugEvent.Break) {
|
| + %DeoptimizeFunction(f5);
|
| + }
|
| +}
|
| +
|
| +var handler3 = {
|
| + ownKeys() { return ["a", "b"] },
|
| + getOwnPropertyDescriptor(target, k) {
|
| + if (k == "a") count++;
|
| + if (x) %ScheduleBreak()
|
| + return { enumerable: true, configurable: true }
|
| + }
|
| +};
|
| +
|
| +var proxy3 = new Proxy({}, handler3);
|
| +var o3 = {__proto__: proxy3};
|
| +
|
| +function f5() {
|
| + for (var p in o3) {
|
| + print(p);
|
| + }
|
| +}
|
| +
|
| +x = false;
|
| +
|
| +f5(); f5(); f5();
|
| +%OptimizeFunctionOnNextCall(f5);
|
| +x = true;
|
| +count = 0;
|
| +Debug.setListener(listener);
|
| +f5();
|
| +Debug.setListener(null);
|
| +assertEquals(1, count);
|
|
|