Commit b2ce346d authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[torque] improve witness struct

Change-Id: I56321f49894612e80e8e3f5d85a759718be6ef10
Reviewed-on: https://chromium-review.googlesource.com/c/1433786
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Reviewed-by: 's avatarDaniel Clifford <danno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59067}
parent ac1e76e9
...@@ -104,33 +104,29 @@ namespace array { ...@@ -104,33 +104,29 @@ namespace array {
thisArg: Object, a: JSArray) labels Bailout(Smi, Smi) { thisArg: Object, a: JSArray) labels Bailout(Smi, Smi) {
let k: Smi = 0; let k: Smi = 0;
let to: Smi = 0; let to: Smi = 0;
const fastOWitness: FastJSArrayWitness = let fastO =
MakeWitness(Cast<FastJSArray>(o) otherwise goto Bailout(k, to)); FastJSArrayWitness{Cast<FastJSArray>(o) otherwise goto Bailout(k, to)};
const fastAWitness: FastJSArrayWitness = let fastA =
MakeWitness(Cast<FastJSArray>(a) otherwise goto Bailout(k, to)); FastJSArrayWitness{Cast<FastJSArray>(a) otherwise goto Bailout(k, to)};
// Build a fast loop over the smi array. // Build a fast loop over the smi array.
for (; k < len; k++) { for (; k < len; k++) {
let fastO: FastJSArray =
Testify(fastOWitness) otherwise goto Bailout(k, to);
// Ensure that we haven't walked beyond a possibly updated length. // Ensure that we haven't walked beyond a possibly updated length.
if (k >= fastO.length) goto Bailout(k, to); if (k >= fastO.Get().length) goto Bailout(k, to);
try { try {
const value: Object = const value: Object = LoadElementNoHole<FixedArrayType>(fastO.Get(), k)
LoadElementNoHole<FixedArrayType>(fastO, k) otherwise FoundHole; otherwise FoundHole;
const result: Object = const result: Object =
Call(context, callbackfn, thisArg, value, k, fastO); Call(context, callbackfn, thisArg, value, k, fastO.Get());
if (ToBoolean(result)) { if (ToBoolean(result)) {
try { try {
// Since the call to {callbackfn} is observable, we can't // Since the call to {callbackfn} is observable, we can't
// use the Bailout label until we've successfully stored. // use the Bailout label until we've successfully stored.
// Hence the {SlowStore} label. // Hence the {SlowStore} label.
const fastA: FastJSArray = fastA.Recheck() otherwise SlowStore;
Testify(fastAWitness) otherwise SlowStore; if (fastA.Get().length != to) goto SlowStore;
if (fastA.length != to) goto SlowStore; BuildAppendJSArray(kind, fastA.Get(), value)
BuildAppendJSArray(kind, fastA, value)
otherwise SlowStore; otherwise SlowStore;
} }
label SlowStore { label SlowStore {
...@@ -138,6 +134,7 @@ namespace array { ...@@ -138,6 +134,7 @@ namespace array {
} }
to = to + 1; to = to + 1;
} }
fastO.Recheck() otherwise goto Bailout(k + 1, to);
} }
label FoundHole {} label FoundHole {}
} }
......
...@@ -74,20 +74,19 @@ namespace array { ...@@ -74,20 +74,19 @@ namespace array {
o: JSArray, len: Smi, callbackfn: Callable, thisArg: Object) labels o: JSArray, len: Smi, callbackfn: Callable, thisArg: Object) labels
Bailout(Smi) { Bailout(Smi) {
let k: Smi = 0; let k: Smi = 0;
const fastOWitness: FastJSArrayWitness = let fastO =
MakeWitness(Cast<FastJSArray>(o) otherwise goto Bailout(k)); FastJSArrayWitness{Cast<FastJSArray>(o) otherwise goto Bailout(k)};
// Build a fast loop over the smi array. // Build a fast loop over the smi array.
for (; k < len; k++) { for (; k < len; k++) {
let fastO: FastJSArray = Testify(fastOWitness) otherwise goto Bailout(k);
// Ensure that we haven't walked beyond a possibly updated length. // Ensure that we haven't walked beyond a possibly updated length.
if (k >= fastO.length) goto Bailout(k); if (k >= fastO.Get().length) goto Bailout(k);
try { try {
const value: Object = const value: Object = LoadElementNoHole<FixedArrayType>(fastO.Get(), k)
LoadElementNoHole<FixedArrayType>(fastO, k) otherwise FoundHole; otherwise FoundHole;
Call(context, callbackfn, thisArg, value, k, fastO); Call(context, callbackfn, thisArg, value, k, fastO.Get());
fastO.Recheck() otherwise goto Bailout(k + 1);
} }
label FoundHole {} label FoundHole {}
} }
......
...@@ -189,24 +189,22 @@ namespace array { ...@@ -189,24 +189,22 @@ namespace array {
vector: Vector): Vector labels Bailout(Vector, Smi) { vector: Vector): Vector labels Bailout(Vector, Smi) {
let k: Smi = 0; let k: Smi = 0;
let v: Vector = vector; let v: Vector = vector;
const fastOWitness: FastJSArrayWitness = let fastO =
MakeWitness(Cast<FastJSArray>(o) otherwise goto Bailout(v, k)); FastJSArrayWitness{Cast<FastJSArray>(o) otherwise goto Bailout(v, k)};
// Build a fast loop over the smi array. // Build a fast loop over the smi array.
// 7. Repeat, while k < len. // 7. Repeat, while k < len.
for (; k < len; k = k + 1) { for (; k < len; k++) {
let fastO: FastJSArray =
Testify(fastOWitness) otherwise goto Bailout(v, k);
// Ensure that we haven't walked beyond a possibly updated length. // Ensure that we haven't walked beyond a possibly updated length.
if (k >= fastO.length) goto Bailout(v, k); if (k >= fastO.Get().length) goto Bailout(v, k);
try { try {
const value: Object = const value: Object = LoadElementNoHole<FixedArrayType>(fastO.Get(), k)
LoadElementNoHole<FixedArrayType>(fastO, k) otherwise FoundHole; otherwise FoundHole;
const result: Object = const result: Object =
Call(context, callbackfn, thisArg, value, k, fastO); Call(context, callbackfn, thisArg, value, k, fastO.Get());
v.StoreResult(k, result); v.StoreResult(k, result);
fastO.Recheck() otherwise goto Bailout(v, k + 1);
} }
label FoundHole { label FoundHole {
// Our output array must necessarily be holey because of holes in // Our output array must necessarily be holey because of holes in
......
...@@ -778,24 +778,30 @@ CastHeapObject<FastJSArray>(implicit context: Context)(o: HeapObject): ...@@ -778,24 +778,30 @@ CastHeapObject<FastJSArray>(implicit context: Context)(o: HeapObject):
} }
struct FastJSArrayWitness { struct FastJSArrayWitness {
array: HeapObject; constructor(array: FastJSArray) {
map: Map; this.stable = this.unstable = array;
} this.map = array.map;
}
macro MakeWitness(array: FastJSArray): FastJSArrayWitness { Get(): FastJSArray {
return FastJSArrayWitness{array, array.map}; return this.unstable;
} }
macro Testify(witness: FastJSArrayWitness): FastJSArray labels CastError { Recheck() labels CastError {
if (witness.array.map != witness.map) goto CastError; if (this.stable.map != this.map) goto CastError;
// We don't need to check elements kind or whether the prototype // We don't need to check elements kind or whether the prototype
// has changed away from the default JSArray prototype, because // has changed away from the default JSArray prototype, because
// if the map remains the same then those properties hold. // if the map remains the same then those properties hold.
// //
// However, we have to make sure there are no elements in the // However, we have to make sure there are no elements in the
// prototype chain. // prototype chain.
if (IsNoElementsProtectorCellInvalid()) goto CastError; if (IsNoElementsProtectorCellInvalid()) goto CastError;
return %RawObjectCast<FastJSArray>(witness.array); this.unstable = %RawObjectCast<FastJSArray>(this.stable);
}
stable: JSArray;
unstable: FastJSArray;
map: Map;
} }
CastHeapObject<FastJSArrayForCopy>(implicit context: Context)(o: HeapObject): CastHeapObject<FastJSArrayForCopy>(implicit context: Context)(o: HeapObject):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment