for-in-opt.js 3.05 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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.


"use strict";

// Test non-JSObject receiver.
function f(o) {
  var result = [];
  for (var i in o) {
    result.push(i);
  }
  return result;
}

17 18
%PrepareFunctionForOptimization(f);

19 20
assertEquals(["0"], f("a"));
assertEquals(["0"], f("a"));
21

22 23 24 25 26
%OptimizeFunctionOnNextCall(f);
assertEquals(["0","1","2"], f("bla"));

// Test the lazy deopt points.
var keys = ["a", "b", "c", "d"];
27
var property_descriptor_keys = [];
28
var deopt_enum = false;
29
var deopt_property_descriptor = false;
30 31

var handler = {
32
  ownKeys() {
33 34 35 36
    if (deopt_enum) {
      %DeoptimizeFunction(f2);
      deopt_enum = false;
    }
37
    return keys;
38
  },
39 40
  getOwnPropertyDescriptor(target, k) {
    if (deopt_property_descriptor) {
41
      %DeoptimizeFunction(f2);
42
      deopt_property_descriptor = false;
43
    }
44 45 46
    property_descriptor_keys.push(k);
    return { enumerable: true, configurable: true }
  },
47 48 49
};


50
var proxy = new Proxy({}, handler);
51 52 53 54 55 56 57 58 59 60 61 62
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));
63 64
  assertEquals(keys, property_descriptor_keys);
  property_descriptor_keys.length = 0;
65 66
}

67 68
%PrepareFunctionForOptimization(f2);

69 70
check_f2();
check_f2();
71

72
// Test lazy deopt after ForInEnumerate
73 74 75
%OptimizeFunctionOnNextCall(f2);
deopt_enum = true;
check_f2();
76

77
// Test lazy deopt after FILTER_KEY
78
%PrepareFunctionForOptimization(f2);
79
%OptimizeFunctionOnNextCall(f2);
80
deopt_property_descriptor = true;
81 82
check_f2();

83

84 85 86 87 88
function f3(o) {
  for (var i in o) {
  }
}

89
%PrepareFunctionForOptimization(f3);
90 91
f3({__proto__:{x:1}});
f3({__proto__:{x:1}});
92

93 94 95
%OptimizeFunctionOnNextCall(f3);
f3(undefined);
f3(null);
96 97 98 99 100 101 102 103 104 105 106 107

// 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;
}
108

109 110
function check_f4() {
  assertEquals(keys, f4(o, p));
111 112
  assertEquals(keys, property_descriptor_keys);
  property_descriptor_keys.length = 0;
113
}
114

115 116
%PrepareFunctionForOptimization(f4);

117 118
check_f4();
check_f4();
119

120
%OptimizeFunctionOnNextCall(f4);
121

122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
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 = {
138
  ownKeys() { return ["a", "b"] },
139
  getOwnPropertyDescriptor(target, k) {
140
    if (k == "a") count++;
141 142
    if (x) %ScheduleBreak()
    return { enumerable: true, configurable: true }
143 144 145
  }
};

146
var proxy3 = new Proxy({}, handler3);
147 148 149 150 151 152 153 154 155 156
var o3 = {__proto__: proxy3};

function f5() {
  for (var p in o3) {
    print(p);
  }
}

x = false;

157
%PrepareFunctionForOptimization(f5);
158 159 160 161 162 163 164 165
f5(); f5(); f5();
%OptimizeFunctionOnNextCall(f5);
x = true;
count = 0;
Debug.setListener(listener);
f5();
Debug.setListener(null);
assertEquals(1, count);