blob: 322b26d26f4e16ebc69a1ce03ad574708e028eec [file] [log] [blame]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
function testMonoInlineSlots() {
var iterations = 10;
var a = new Array(iterations);
for (var i = 0; i < iterations; i++) {
// This object will have 4 inlined slots
var o = { a: 0 };
WScript.Echo("...");
// This is the field add we want the fast path for.
o.p = 1;
WScript.Echo("...");
// Use o to verify the type got written correctly to the object.
o.z = -1;
a[i] = o;
}
for (var i = 0; i < iterations; i++) {
WScript.Echo("{ a: " + a[i].a + ", p: " + a[i].p + ", z: " + a[i].z + "}");
}
}
WScript.Echo("testMonoInlineSlots: ");
testMonoInlineSlots();
testMonoInlineSlots();
WScript.Echo();
function testMonoInlineSlotsSetOrAdd() {
var iterations = 10;
var a = new Array(iterations);
for (var i = 0; i < iterations; i++) {
// This object will have 4 inlined slots
var o = { a: 0 };
// This adds a property ahead of time for every other object, so the profile indicates we either set or add a property.
if (i % 2 == 0) {
o.p = 1;
}
WScript.Echo("...");
// This is the field add we want the fast path for.
o.p = 1;
WScript.Echo("...");
// Use o to verify the type got written correctly to the object.
o.z = -1;
a[i] = o;
}
for (var i = 0; i < iterations; i++) {
WScript.Echo("{ a: " + a[i].a + ", p: " + a[i].p + ", z: " + a[i].z + "}");
}
}
WScript.Echo("testMonoInlineSlotsSetOrAdd: ");
testMonoInlineSlotsSetOrAdd();
testMonoInlineSlotsSetOrAdd();
WScript.Echo();
function testMonoAuxSlots() {
var iterations = 10;
var a = new Array(iterations);
for (var i = 0; i < iterations; i++) {
// This object will have 0 inlined slots.
var o = {};
// This will add aux slot array.
o.a = 1;
WScript.Echo("...");
// This is the field add we want the fast path for.
// Adding property now will stick it into an aux slot but won't require slot array re-allocation.
o.p = 1;
WScript.Echo("...");
// Use o to verify the type got written correctly to the object.
o.z = -1;
a[i] = o;
}
for (var i = 0; i < iterations; i++) {
WScript.Echo("{ a: " + a[i].a + ", p: " + a[i].p + ", z: " + a[i].z + "}");
}
}
WScript.Echo("testMonoAuxSlots: ");
testMonoAuxSlots();
testMonoAuxSlots();
WScript.Echo();
function testMonoAuxSlotsAdjustmentRequired1() {
var iterations = 10;
var a = new Array(iterations);
for (var i = 0; i < iterations; i++) {
// This object will have 0 inlined slots.
var o = {};
WScript.Echo("...");
// This is the field add we want the fast path for.
// Adding property now will require slot array allocation and then will stick it into an aux slot.
o.p = 1;
WScript.Echo("...");
// Use o to verify the type got written correctly to the object.
o.z = -1;
a[i] = o;
}
for (var i = 0; i < iterations; i++) {
WScript.Echo("{ p: " + a[i].p + ", z: " + a[i].z + "}");
}
}
WScript.Echo("testMonoAuxSlotsAdjustmentRequired1: ");
testMonoAuxSlotsAdjustmentRequired1();
testMonoAuxSlotsAdjustmentRequired1();
WScript.Echo();
function testMonoAuxSlotsAdjustmentRequired2() {
var iterations = 10;
var a = new Array(iterations);
for (var i = 0; i < iterations; i++) {
// This object will have 0 inlined slots.
var o = {};
// This will add aux slot array of size 4, but it will fill every slot.
o.a = 0;
o.b = 1;
o.c = 2;
o.d = 3;
WScript.Echo("...");
// This is the field add we want the fast path for.
// Adding property now will require slot array allocation and then will stick it into an aux slot.
o.p = 1;
WScript.Echo("...");
// Use o to verify the type got written correctly to the object.
o.z = -1;
a[i] = o;
}
for (var i = 0; i < iterations; i++) {
WScript.Echo("{ a: " + a[i].a + ", b: " + a[i].b + ", c: " + a[i].c + ", d: " + a[i].d + ", p: " + a[i].p + ", z: " + a[i].z + "}");
}
}
WScript.Echo("testMonoAuxSlotsAdjustmentRequired2: ");
testMonoAuxSlotsAdjustmentRequired2();
testMonoAuxSlotsAdjustmentRequired2();
WScript.Echo();
function testPoly() {
var iterations = 25;
var a = new Array(iterations);
for (var i = 0; i < iterations; i++) {
var o;
switch (i % 3) {
case 0:
o = {};
break;
case 1:
o = { a: 0 };
break;
case 2:
o = { b: 0 };
break;
}
if (i % 6 >= 3) {
o.p = 0;
}
WScript.Echo("...");
// This is the field add we want the fast path for.
o.p = 1;
WScript.Echo("...");
o.z = -1;
a[i] = o;
}
for (var i = 0; i < iterations; i++) {
WScript.Echo("{ a: " + a[i].a + ", b: " + a[i].b + ", p: " + a[i].p + ", z: " + a[i].z + "}");
}
}
WScript.Echo("testPoly: ");
testPoly();
testPoly();
WScript.Echo();
(function () {
var Blank = function () {
}
Blank.prototype = { a: 0, b: 0, c: 0 }
function setUpMonoStoreFieldCacheInvalidation() {
// Make sure properties a, b, and c are not marked as fixed on Blank's type handler, so that
// add property inline caches can be populated.
var o = new Blank();
o.a = 1;
o.b = 2;
o.c = 3;
var o = new Blank();
o.a = 1;
o.b = 2;
o.c = 3;
}
function testMonoStoreFieldCacheInvalidation(o, isNative) {
// Do this only for the JIT-ed iteration to be sure caches aren't populated and we don't do
// object type spec.
if (isNative) {
o.a = 1;
o.b = 2;
o.c = 3;
}
}
WScript.Echo("testMonoStoreFieldCacheInvalidation: ");
setUpMonoStoreFieldCacheInvalidation();
var o = new Blank();
testMonoStoreFieldCacheInvalidation(o, false);
WScript.Echo("{ a: " + o.a + ", b: " + o.b + ", c: " + o.c + "}");
var o = new Blank();
testMonoStoreFieldCacheInvalidation(o, true);
WScript.Echo("{ a: " + o.a + ", b: " + o.b + ", c: " + o.c + "}");
// Change the writable attribute without actually adding or deleting any properties.
// This should invalidate all inline caches for property b.
Object.defineProperty(Blank.prototype, "b", { writable: false });
var o = new Blank();
testMonoStoreFieldCacheInvalidation(o, true);
WScript.Echo("{ a: " + o.a + ", b: " + o.b + ", c: " + o.c + "}");
})();
WScript.Echo();
(function () {
var Blank = function () {
}
Blank.prototype = { a: 0, b: 0, c: 0 }
function setUpPolyStoreFieldCacheInvalidation() {
// Make sure properties a, b, and c are not marked as fixed on Blank's type handler, so that
// add property inline caches can be populated.
var o = new Blank();
o.a = 1;
o.b = 2;
o.c = 3;
o.d = 4;
var o = new Blank();
o.a = 1;
o.b = 2;
o.c = 3;
o.d = 4;
}
function testPolyStoreFieldCacheInvalidation(objects, isNative) {
// This loop ensures that inline caches for a and b become polymorphic on the second iteration.
// That's because the type encountered the second time around is the final type with all properties present.
var o;
for (var i = 0; i < 2; i++) {
o = objects[i];
o.a = 1;
o.b = 2;
o.c = 3;
}
}
function reportResults(objects) {
for (var i = 0; i < 2; i++) {
var o = objects[i];
WScript.Echo("{ a: " + o.a + ", b: " + o.b + ", c: " + o.c + "}");
}
}
WScript.Echo("testPolyStoreFieldCacheInvalidation: ");
setUpPolyStoreFieldCacheInvalidation();
var warmUpObjects = new Array(2);
warmUpObjects[0] = new Blank();
var o = new Blank();
o.a = 1;
o.b = 2;
o.c = 3;
warmUpObjects[1] = o;
testPolyStoreFieldCacheInvalidation(warmUpObjects, false);
reportResults(warmUpObjects);
// Change the writable attribute without actually adding or deleting any properties.
// This should invalidate all inline caches for property b, including those that are part of a
// polymorphic inline cache - provided they got registered for invalidation properly.
Object.defineProperty(Blank.prototype, "b", { writable: false });
var testObjects = new Array(2);
testObjects[0] = new Blank();
testObjects[1] = new Blank();
testPolyStoreFieldCacheInvalidation(testObjects, true);
reportResults(testObjects);
})();