//------------------------------------------------------------------------------------------------------- | |
// Copyright (C) Microsoft. All rights reserved. | |
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. | |
//------------------------------------------------------------------------------------------------------- | |
// Switches: -bgJit- -maxInterpretCount:2 | |
// Test 1: Invalidate constructor cache by changing the constructor's prototype property. | |
WScript.Echo("Test 1:"); | |
var SimpleObject1 = function () { | |
this.a = 0; | |
this.b = 1; | |
} | |
var proto1a = { p: 100 }; | |
var proto1b = { p: 200 }; | |
SimpleObject1.prototype = proto1a; | |
var test1 = function () { | |
var o = new SimpleObject1(); | |
o.x = 10; | |
o.y = 11; | |
return o; | |
} | |
var oa1 = new Array(); | |
// Run twice in the interpreter to populate add property caches and kick off JIT compilation. | |
oa1.push(test1()); | |
oa1.push(test1()); | |
// Run once along the happy path. | |
oa1.push(test1()); | |
// Now change the prototype object to invalidate the constructor cache and cause a bailout. | |
SimpleObject1.prototype = proto1b; | |
oa1.push(test1()); | |
// Run a few more times (bailing out every time) to force a re-JIT. After re-JIT the optimization | |
// should be disabled because the constructor cache is now marked as polymorphic. | |
oa1.push(test1()); | |
oa1.push(test1()); | |
oa1.push(test1()); | |
oa1.push(test1()); | |
oa1.push(test1()); | |
for (var i = 0; i < oa1.length; i++) { | |
var o = oa1[i]; | |
WScript.Echo("oa1[" + i + "]: " + "{ a: " + o.a + ", b: " + o.b + ", p: " + o.p + ", x: " + o.x + ", y: " + o.y + " }"); | |
} | |
WScript.Echo(""); | |
// Test 2: Invalidate the constructor cache by making one of the properties added in the | |
// constructor read-only | |
WScript.Echo("Test 2:"); | |
var SimpleObject2 = function () { | |
this.a = 0; | |
this.b = 1; | |
this.c = 2; | |
} | |
var proto2a = { p: 100 }; | |
SimpleObject2.prototype = proto2a; | |
var test2 = function () { | |
var o = new SimpleObject2(); | |
o.x = 10; | |
o.y = 11; | |
return o; | |
} | |
var oa2 = new Array(); | |
// Run twice in the interpreter to populate add property caches and kick off JIT compilation. | |
oa2.push(test2()); | |
oa2.push(test2()); | |
// Run once along the happy path. | |
oa2.push(test2()); | |
// Now invalidate the constructor cache by making one of the properties added in the constructor | |
// read-only. | |
Object.defineProperty(proto2a, "a", { value: 101, writable: false }); | |
oa2.push(test2()); | |
// Run a few more times (bailing out every time) to force a re-JIT. After re-JIT, we should no longer | |
// have the offending property access object type specialized, and thus protected by the ctor guard. | |
oa2.push(test2()); | |
oa2.push(test2()); | |
oa2.push(test2()); | |
oa2.push(test2()); | |
oa2.push(test2()); | |
for (var i = 0; i < oa2.length; i++) { | |
var o = oa2[i]; | |
WScript.Echo("oa2[" + i + "]: " + "{ a: " + o.a + ", b: " + o.b + ", c: " + o.c + ", p: " + o.p + ", x: " + o.x + ", y: " + o.y + " }"); | |
} | |
WScript.Echo(""); | |
// Test 3: Invalidate the constructor cache by making one of the properties added after the | |
// constructor read-only | |
WScript.Echo("Test 3:"); | |
var SimpleObject3 = function () { | |
this.a = 0; | |
this.b = 1; | |
} | |
var proto3a = { p: 100 }; | |
SimpleObject3.prototype = proto3a; | |
var test3 = function () { | |
var o = new SimpleObject3(); | |
o.x = 10; | |
o.y = 11; | |
return o; | |
} | |
var oa3 = new Array(); | |
// Run twice in the interpreter to populate add property caches and kick off JIT compilation. | |
oa3.push(test3()); | |
oa3.push(test3()); | |
// Run once along the happy path. | |
oa3.push(test3()); | |
// Now invalidate the constructor cache by making one of the properties added in the constructor | |
// read-only. | |
Object.defineProperty(proto3a, "x", { value: 102, writable: false }); | |
oa3.push(test3()); | |
// Run a few more times (bailing out every time) to force a re-JIT. After re-JIT, we should no longer | |
// have the offending property access object type specialized, and thus protected by the ctor guard. | |
oa3.push(test3()); | |
oa3.push(test3()); | |
oa3.push(test3()); | |
oa3.push(test3()); | |
oa3.push(test3()); | |
for (var i = 0; i < oa3.length; i++) { | |
var o = oa3[i]; | |
WScript.Echo("oa3[" + i + "]: " + "{ a: " + o.a + ", b: " + o.b + ", p: " + o.p + ", x: " + o.x + ", y: " + o.y + " }"); | |
} | |
WScript.Echo(""); | |
// Test 4: Invalidate constructor cache by changing the constructor's prototype property. | |
WScript.Echo("Test 4:"); | |
var SimpleObject4 = function () { | |
this.a = this.p + 0; | |
this.b = this.p + 1; | |
this.c = this.p + 2; | |
this.d = this.p + 3; | |
this.e = this.p + 4; | |
this.f = this.p + 5; | |
this.g = this.p + 6; | |
this.h = this.p + 7; | |
this.i = this.p + 8; | |
this.j = this.p + 9; | |
} | |
var proto4a = { p: 100 }; | |
var proto4b = Object.create(proto4a); | |
SimpleObject4.prototype = proto4b; | |
var test4 = function () { | |
var o = new SimpleObject4(); | |
o.x = o.p + 10; | |
o.y = o.p + 11; | |
return o; | |
} | |
var oa4 = new Array(); | |
// Run twice in the interpreter to populate add property caches and kick off JIT compilation. | |
oa4.push(test4()); | |
oa4.push(test4()); | |
// Run once along the happy path. | |
oa4.push(test4()); | |
// Now change the prototype object to invalidate the constructor cache and cause a bailout. | |
proto4b.p = 200; | |
oa4.push(test4()); | |
// Run a few more times (bailing out every time) to force a re-JIT. After re-JIT, we should no longer | |
// have the offending property access object type specialized, and thus protected by the ctor guard. | |
// This time all the other property operations should remain object type specialized, because the type | |
// of the object created is not affected by this change to the prototype chain. | |
oa4.push(test4()); | |
oa4.push(test4()); | |
oa4.push(test4()); | |
oa4.push(test4()); | |
oa4.push(test4()); | |
for (var i = 0; i < oa4.length; i++) { | |
var o = oa4[i]; | |
WScript.Echo("oa4[" + i + "]: " + "{ a: " + o.a + ", b: " + o.b + ", c: " + o.c + ", i: " + o.i + ", j: " + o.j + ", p: " + o.p + ", x: " + o.x + ", y: " + o.y + " }"); | |
} | |
WScript.Echo(""); |