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-gc --block-concurrent-recompilation 6 7function Inner() { 8 this.property = "OK"; 9 this.prop2 = 1; 10} 11 12function Outer() { 13 this.o = "u"; 14} 15function KeepMapAlive(o) { 16 return o.o; 17} 18function SetInner(o, i) { 19 o.inner_field = i; 20} 21function Crash(o) { 22 return o.inner_field.property; 23} 24 25var inner = new Inner(); 26var outer = new Outer(); 27 28// Collect type feedback. 29SetInner(new Outer(), inner); 30SetInner(outer, inner); 31 32// This function's only purpose is to stash away a Handle that keeps 33// outer's map alive during the gc() call below. We store this handle 34// on the compiler thread :-) 35KeepMapAlive(outer); 36KeepMapAlive(outer); 37%OptimizeFunctionOnNextCall(KeepMapAlive, "concurrent"); 38KeepMapAlive(outer); 39 40// So far, all is well. Collect type feedback and optimize. 41print(Crash(outer)); 42print(Crash(outer)); 43%OptimizeFunctionOnNextCall(Crash); 44print(Crash(outer)); 45 46// Null out references and perform GC. This will keep outer's map alive 47// (due to the handle created above), but will let inner's map die. Hence, 48// inner_field's field type stored in outer's map will get cleared. 49inner = undefined; 50outer = undefined; 51gc(); 52 53// We could unblock the compiler thread now. But why bother? 54 55// Now optimize SetInner while inner_field's type is still cleared! 56// This will generate optimized code that stores arbitrary objects 57// into inner_field without checking their type against the field type. 58%OptimizeFunctionOnNextCall(SetInner); 59 60// Use the optimized code to store an arbitrary object into 61// o2's inner_field, without triggering any dependent code deopts... 62var o2 = new Outer(); 63SetInner(o2, { invalid: 1.51, property: "OK" }); 64// ...and then use the existing code expecting an Inner-class object to 65// read invalid data (in this case, a raw double). 66// We crash trying to convert the raw double into a printable string. 67print(Crash(o2)); 68