1// Copyright 2015 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Flags: --allow-natives-syntax --expose-debug-as debug 6 7"use strict"; 8 9// Test non-JSObject receiver. 10function f(o) { 11 var result = []; 12 for (var i in o) { 13 result.push(i); 14 } 15 return result; 16} 17 18assertEquals(["0"], f("a")); 19assertEquals(["0"], f("a")); 20 21%OptimizeFunctionOnNextCall(f); 22assertEquals(["0","1","2"], f("bla")); 23 24// Test the lazy deopt points. 25var keys = ["a", "b", "c", "d"]; 26var property_descriptor_keys = []; 27var deopt_enum = false; 28var deopt_property_descriptor = false; 29 30var handler = { 31 ownKeys() { 32 if (deopt_enum) { 33 %DeoptimizeFunction(f2); 34 deopt_enum = false; 35 } 36 return keys; 37 }, 38 getOwnPropertyDescriptor(target, k) { 39 if (deopt_property_descriptor) { 40 %DeoptimizeFunction(f2); 41 deopt_property_descriptor = false; 42 } 43 property_descriptor_keys.push(k); 44 return { enumerable: true, configurable: true } 45 }, 46}; 47 48 49var proxy = new Proxy({}, handler); 50var o = {__proto__: proxy}; 51 52function f2(o) { 53 var result = []; 54 for (var i in o) { 55 result.push(i); 56 } 57 return result; 58} 59 60function check_f2() { 61 assertEquals(keys, f2(o)); 62 assertEquals(keys, property_descriptor_keys); 63 property_descriptor_keys.length = 0; 64} 65 66check_f2(); 67check_f2(); 68 69// Test lazy deopt after ForInEnumerate 70%OptimizeFunctionOnNextCall(f2); 71deopt_enum = true; 72check_f2(); 73 74// Test lazy deopt after FILTER_KEY 75%OptimizeFunctionOnNextCall(f2); 76deopt_property_descriptor = true; 77check_f2(); 78 79 80function f3(o) { 81 for (var i in o) { 82 } 83} 84 85f3({__proto__:{x:1}}); 86f3({__proto__:{x:1}}); 87 88%OptimizeFunctionOnNextCall(f3); 89f3(undefined); 90f3(null); 91 92// Reliable repro for an issue previously flushed out by GC stress. 93var p = {x: "x"} 94 95function f4(o, p) { 96 var result = []; 97 for (var i in o) { 98 var j = p.x + "str"; 99 result.push(i); 100 } 101 return result; 102} 103 104function check_f4() { 105 assertEquals(keys, f4(o, p)); 106 assertEquals(keys, property_descriptor_keys); 107 property_descriptor_keys.length = 0; 108} 109 110check_f4(); 111check_f4(); 112 113%OptimizeFunctionOnNextCall(f4); 114 115p.y = "y"; // Change map, cause eager deopt. 116check_f4(); 117 118// Repro for Turbofan equivalent. 119var x; 120var count = 0; 121 122var Debug = debug.Debug; 123 124function listener(event, exec_state, event_data, data) { 125 if (event == Debug.DebugEvent.Break) { 126 %DeoptimizeFunction(f5); 127 } 128} 129 130var handler3 = { 131 ownKeys() { return ["a", "b"] }, 132 getOwnPropertyDescriptor(target, k) { 133 if (k == "a") count++; 134 if (x) %ScheduleBreak() 135 return { enumerable: true, configurable: true } 136 } 137}; 138 139var proxy3 = new Proxy({}, handler3); 140var o3 = {__proto__: proxy3}; 141 142function f5() { 143 for (var p in o3) { 144 print(p); 145 } 146} 147 148x = false; 149 150f5(); f5(); f5(); 151%OptimizeFunctionOnNextCall(f5); 152x = true; 153count = 0; 154Debug.setListener(listener); 155f5(); 156Debug.setListener(null); 157assertEquals(1, count); 158