Reland: Use simple/fast inline function version of MinMax in JS

Use the simple inline function version of {Min, Max} where possible to
improve performance

Now uses an forced inline js function instead of a python macro
to avoid expressions be evaluated twice

Follow-up to CR: https://codereview.chromium.org/1331993004

Review URL: https://codereview.chromium.org/1410473002

Cr-Commit-Position: refs/heads/master@{#31411}
This commit is contained in:
karl 2015-10-20 06:43:44 -07:00 committed by Commit bot
parent 81ee94b650
commit b00371b423
11 changed files with 95 additions and 48 deletions

View File

@ -16,7 +16,7 @@ var FLAG_harmony_tolength;
var GlobalArray = global.Array;
var InternalArray = utils.InternalArray;
var InternalPackedArray = utils.InternalPackedArray;
var MathMin;
var MinSimple;
var ObjectHasOwnProperty;
var ObjectIsFrozen;
var ObjectIsSealed;
@ -28,7 +28,7 @@ var unscopablesSymbol = utils.ImportNow("unscopables_symbol");
utils.Import(function(from) {
Delete = from.Delete;
MathMin = from.MathMin;
MinSimple = from.MinSimple;
ObjectHasOwnProperty = from.ObjectHasOwnProperty;
ObjectIsFrozen = from.ObjectIsFrozen;
ObjectIsSealed = from.ObjectIsSealed;
@ -271,7 +271,7 @@ function SparseMove(array, start_i, del_count, len, num_additional_args) {
// Move data to new array.
var new_array = new InternalArray(
// Clamp array length to 2^32-1 to avoid early RangeError.
MathMin(len - del_count + num_additional_args, 0xffffffff));
MinSimple(len - del_count + num_additional_args, 0xffffffff));
var big_indices;
var indices = %GetArrayKeys(array, len);
if (IS_NUMBER(indices)) {

View File

@ -13,14 +13,14 @@
var GlobalArrayBuffer = global.ArrayBuffer;
var GlobalObject = global.Object;
var MathMax;
var MathMin;
var MaxSimple;
var MinSimple;
var ToPositiveInteger;
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
utils.Import(function(from) {
MathMax = from.MathMax;
MathMin = from.MathMin;
MaxSimple = from.MaxSimple;
MinSimple = from.MinSimple;
ToPositiveInteger = from.ToPositiveInteger;
});
@ -57,16 +57,16 @@ function ArrayBufferSlice(start, end) {
var first;
var byte_length = %_ArrayBufferGetByteLength(this);
if (relativeStart < 0) {
first = MathMax(byte_length + relativeStart, 0);
first = MaxSimple(byte_length + relativeStart, 0);
} else {
first = MathMin(relativeStart, byte_length);
first = MinSimple(relativeStart, byte_length);
}
var relativeEnd = IS_UNDEFINED(end) ? byte_length : end;
var fin;
if (relativeEnd < 0) {
fin = MathMax(byte_length + relativeEnd, 0);
fin = MaxSimple(byte_length + relativeEnd, 0);
} else {
fin = MathMin(relativeEnd, byte_length);
fin = MinSimple(relativeEnd, byte_length);
}
if (fin < first) {

View File

@ -16,8 +16,8 @@ var GetIterator;
var GetMethod;
var GlobalArray = global.Array;
var iteratorSymbol = utils.ImportNow("iterator_symbol");
var MathMax;
var MathMin;
var MaxSimple;
var MinSimple;
var ObjectIsFrozen;
var ObjectDefineProperty;
@ -25,8 +25,8 @@ utils.Import(function(from) {
FLAG_harmony_tolength = from.FLAG_harmony_tolength;
GetIterator = from.GetIterator;
GetMethod = from.GetMethod;
MathMax = from.MathMax;
MathMin = from.MathMin;
MaxSimple = from.MaxSimple;
MinSimple = from.MinSimple;
ObjectIsFrozen = from.ObjectIsFrozen;
ObjectDefineProperty = from.ObjectDefineProperty;
});
@ -37,28 +37,28 @@ function InnerArrayCopyWithin(target, start, end, array, length) {
target = TO_INTEGER(target);
var to;
if (target < 0) {
to = MathMax(length + target, 0);
to = MaxSimple(length + target, 0);
} else {
to = MathMin(target, length);
to = MinSimple(target, length);
}
start = TO_INTEGER(start);
var from;
if (start < 0) {
from = MathMax(length + start, 0);
from = MaxSimple(length + start, 0);
} else {
from = MathMin(start, length);
from = MinSimple(start, length);
}
end = IS_UNDEFINED(end) ? length : TO_INTEGER(end);
var final;
if (end < 0) {
final = MathMax(length + end, 0);
final = MaxSimple(length + end, 0);
} else {
final = MathMin(end, length);
final = MinSimple(end, length);
}
var count = MathMin(final - from, length - to);
var count = MinSimple(final - from, length - to);
var direction = 1;
if (from < to && to < (from + count)) {
direction = -1;

View File

@ -12,11 +12,11 @@
// Imports
var GlobalObject = global.Object;
var MathMax;
var MaxSimple;
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
utils.Import(function(from) {
MathMax = from.MathMax;
MaxSimple = from.MaxSimple;
});
// -------------------------------------------------------------------
@ -146,7 +146,7 @@ function AtomicsFutexWaitJS(ia, index, value, timeout) {
if (NUMBER_IS_NAN(timeout)) {
timeout = INFINITY;
} else {
timeout = MathMax(0, timeout);
timeout = MaxSimple(0, timeout);
}
}
return %AtomicsFutexWait(ia, index, value, timeout);
@ -158,14 +158,14 @@ function AtomicsFutexWakeJS(ia, index, count) {
if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
return UNDEFINED;
}
count = MathMax(0, TO_INTEGER(count));
count = MaxSimple(0, TO_INTEGER(count));
return %AtomicsFutexWake(ia, index, count);
}
function AtomicsFutexWakeOrRequeueJS(ia, index1, count, value, index2) {
CheckSharedInteger32TypedArray(ia);
index1 = TO_INTEGER(index1);
count = MathMax(0, TO_INTEGER(count));
count = MaxSimple(0, TO_INTEGER(count));
value = TO_INT32(value);
index2 = TO_INTEGER(index2);
if (index1 < 0 || index1 >= %_TypedArrayGetLength(ia) ||

View File

@ -48,8 +48,8 @@ var InnerArraySome;
var InnerArraySort;
var InnerArrayToLocaleString;
var IsNaN;
var MathMax;
var MathMin;
var MaxSimple;
var MinSimple;
var PackedArrayReverse;
utils.Import(function(from) {
@ -72,8 +72,8 @@ utils.Import(function(from) {
InnerArraySort = from.InnerArraySort;
InnerArrayToLocaleString = from.InnerArrayToLocaleString;
IsNaN = from.IsNaN;
MathMax = from.MathMax;
MathMin = from.MathMin;
MaxSimple = from.MaxSimple;
MinSimple = from.MinSimple;
PackedArrayReverse = from.PackedArrayReverse;
});
@ -319,9 +319,9 @@ function TypedArraySlice(start, end) {
var k;
if (relativeStart < 0) {
k = MathMax(len + relativeStart, 0);
k = MaxSimple(len + relativeStart, 0);
} else {
k = MathMin(relativeStart, len);
k = MinSimple(relativeStart, len);
}
var relativeEnd;
@ -333,12 +333,12 @@ function TypedArraySlice(start, end) {
var final;
if (relativeEnd < 0) {
final = MathMax(len + relativeEnd, 0);
final = MaxSimple(len + relativeEnd, 0);
} else {
final = MathMin(relativeEnd, len);
final = MinSimple(relativeEnd, len);
}
var count = MathMax(final - k, 0);
var count = MaxSimple(final - k, 0);
var array = ConstructTypedArrayLike(this, count);
// The code below is the 'then' branch; the 'else' branch species
// a memcpy. Because V8 doesn't canonicalize NaN, the difference is

View File

@ -13,14 +13,14 @@
var GlobalJSON = global.JSON;
var InternalArray = utils.InternalArray;
var MathMax;
var MathMin;
var MaxSimple;
var MinSimple;
var ObjectHasOwnProperty;
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
utils.Import(function(from) {
MathMax = from.MathMax;
MathMin = from.MathMin;
MaxSimple = from.MaxSimple;
MinSimple = from.MinSimple;
ObjectHasOwnProperty = from.ObjectHasOwnProperty;
});
@ -215,7 +215,7 @@ function JSONStringify(value, replacer, space) {
}
var gap;
if (IS_NUMBER(space)) {
space = MathMax(0, MathMin(TO_INTEGER(space), 10));
space = MaxSimple(0, MinSimple(TO_INTEGER(space), 10));
gap = %_SubString(" ", 0, space);
} else if (IS_STRING(space)) {
if (space.length > 10) {

View File

@ -159,8 +159,6 @@ macro TO_NAME(arg) = (%_ToName(arg));
macro JSON_NUMBER_TO_STRING(arg) = ((%_IsSmi(%IS_VAR(arg)) || arg - arg == 0) ? %_NumberToString(arg) : "null");
macro HAS_OWN_PROPERTY(arg, index) = (%_CallFunction(arg, index, ObjectHasOwnProperty));
macro HAS_INDEX(array, index, is_array) = ((is_array && %_HasFastPackedElements(%IS_VAR(array))) ? (index < array.length) : (index in array));
macro MAX_SIMPLE(argA, argB) = (argA < argB ? argB : argA);
macro MIN_SIMPLE(argA, argB) = (argA < argB ? argA : argB);
# Private names.
macro IS_PRIVATE(sym) = (%SymbolIsPrivate(sym));

View File

@ -186,6 +186,8 @@ function PostNatives(utils) {
"MapIteratorNext",
"MathMax",
"MathMin",
"MaxSimple",
"MinSimple",
"ObjectIsFrozen",
"ObjectDefineProperty",
"ObserveArrayMethods",

View File

@ -216,6 +216,20 @@ function ToPositiveInteger(x, rangeErrorIndex) {
return i;
}
function MaxSimple(a, b) {
return a > b ? a : b;
}
function MinSimple(a, b) {
return a > b ? b : a;
}
%SetForceInlineFlag(MaxSimple);
%SetForceInlineFlag(MinSimple);
//----------------------------------------------------------------------------
// NOTE: Setting the prototype for Array must take place as early as
@ -229,9 +243,11 @@ function ToPositiveInteger(x, rangeErrorIndex) {
// Exports
utils.Export(function(to) {
to.ToPositiveInteger = ToPositiveInteger;
to.MaxSimple = MaxSimple;
to.MinSimple = MinSimple;
to.SameValue = SameValue;
to.SameValueZero = SameValueZero;
to.ToPositiveInteger = ToPositiveInteger;
});
%InstallToContext([

View File

@ -18,6 +18,8 @@ var GlobalDataView = global.DataView;
var GlobalObject = global.Object;
var InternalArray = utils.InternalArray;
var iteratorSymbol = utils.ImportNow("iterator_symbol");
var MaxSimple;
var MinSimple;
var ToPositiveInteger;
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
@ -42,6 +44,8 @@ TYPED_ARRAYS(DECLARE_GLOBALS)
utils.Import(function(from) {
ArrayValues = from.ArrayValues;
MaxSimple = from.MaxSimple;
MinSimple = from.MinSimple;
ToPositiveInteger = from.ToPositiveInteger;
});
@ -213,15 +217,15 @@ function NAMESubArray(begin, end) {
}
if (beginInt < 0) {
beginInt = MAX_SIMPLE(0, srcLength + beginInt);
beginInt = MaxSimple(0, srcLength + beginInt);
} else {
beginInt = MIN_SIMPLE(beginInt, srcLength);
beginInt = MinSimple(beginInt, srcLength);
}
if (endInt < 0) {
endInt = MAX_SIMPLE(0, srcLength + endInt);
endInt = MaxSimple(0, srcLength + endInt);
} else {
endInt = MIN_SIMPLE(endInt, srcLength);
endInt = MinSimple(endInt, srcLength);
}
if (endInt < beginInt) {

View File

@ -0,0 +1,27 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-natives-as natives
// Test the MaxSimple and MinSimple internal methods in runtime.js
var MaxSimple = natives.ImportNow("MaxSimple");
var MinSimple = natives.ImportNow("MinSimple");
function checkEvaluations(target) {
var evaluations = 0;
var observedNumber = {
valueOf: function() {
evaluations++;
return 0;
}
};
target(observedNumber, observedNumber);
return evaluations;
}
assertEquals(1, MaxSimple(-1, 1));
assertEquals(2, checkEvaluations(MaxSimple));
assertEquals(-1, MinSimple(-1, 1));
assertEquals(2, checkEvaluations(MinSimple));