special-casing vector-ref and vector-set

This commit is contained in:
Danny Yoo 2012-02-21 14:43:21 -05:00
parent def882c23d
commit 018f1b2559
5 changed files with 105 additions and 4 deletions

View File

@ -1303,6 +1303,8 @@
(box? (Const-const knowledge))]
[(list)
(list? (Const-const knowledge))]
[(vector)
(vector? (Const-const knowledge))]
[(pair)
(pair? (Const-const knowledge))]
[(caarpair)

View File

@ -6,6 +6,7 @@
"../type-helpers.rkt")
(define-type OperandDomain (U 'number
'string
'vector
'box
'list
'pair
@ -178,6 +179,8 @@
'null?
'not
'eq?
'vector-ref
'vector-set!
))
(ensure-type-subsetof KernelPrimitiveName/Inline KernelPrimitiveName)
@ -288,4 +291,10 @@
(list 'any)]
[(eq? prim 'eq?)
(list 'any 'any)]))
(list 'any 'any)]
[(eq? prim 'vector-ref)
(list 'vector 'number)]
[(eq? prim 'vector-set!)
(list 'vector 'number 'any)]))

View File

@ -52,8 +52,10 @@
[(*)
(cond [(empty? checked-operands)
(assemble-numeric-constant 1)]
[(< (length operands) MAX-JAVASCRIPT-ARGS-AT-ONCE)
(format "RT.checkedMul(M, ~a)" (string-join operands ","))]
[else
(assemble-binop-chain "plt.baselib.numbers.multiply" checked-operands)])]
(format "RT.checkedMulSlowPath(M, [~a])" (string-join operands ","))])]
[(/)
(assemble-binop-chain "plt.baselib.numbers.divide" checked-operands)]
@ -111,6 +113,14 @@
[(list?)
(format "RT.isList(~a)"
(first checked-operands))]
[(vector-ref)
(format "RT.checkedVectorRef(M, ~a)"
(string-join operands ","))]
[(vector-set!)
(format "RT.checkedVectorSet(M, ~a)"
(string-join operands ","))]
[(pair?)
(format "RT.isPair(~a)"
@ -186,7 +196,9 @@
[(caarpair)
(format "RT.isCaarPair")]
[(box)
(format "RT.isBox")])])
(format "RT.isBox")]
[(vector)
(format "RT.isVector")])])
(format "RT.testArgument(M,~s,~a,~a,~a,~s)"
(symbol->string domain)
predicate

View File

@ -1057,7 +1057,8 @@
2,
function (M) {
var elts = checkVector(M, 'vector-ref', 0).elts;
var index = M.e[M.e.length-2];
var index = baselib.numbers.toFixnum(
checkNaturalInRange(M, 'vector-ref', 1, 0, elts.length));
return elts[index];
});

View File

@ -860,6 +860,34 @@
return sum;
};
var checkedMul = function(M, x, y) {
var prod;
// fast path optimization: binop addition on fixnums
if (arguments.length === 3) {
if (typeof(x) === 'number' && typeof(y) === 'number') {
prod = x * y;
if (prod < -9e15 || prod > 9e15) {
return checkedMulSlowPath(M, Array.prototype.slice.call(arguments, 1));
}
return prod;
}
}
return checkedMulSlowPath(M, Array.prototype.slice.call(arguments, 1));
};
var checkedMulSlowPath = function(M, args) {
var i;
var prod = 1;
for (i = 0; i < args.length; i++) {
if (! isNumber(args[i])) {
raiseArgumentTypeError(M, '*', 'number', i, args[i]);
}
prod = plt.baselib.numbers.multiply(prod, args[i]);
}
return prod;
};
var checkedSub = function(M, x, y) {
// Assumption: at least two arguments to subtract.
var sum;
@ -969,6 +997,51 @@
raiseArgumentTypeError(M, 'cdr', 'pair', 0, v);
};
var checkedVectorRef = function(M, vec, i) {
var expectedTypeName;
if (isVector(vec)) {
if (typeof(i) === 'number') {
if (i >= 0 && i < vec.elts.length) {
return vec.elts[i];
}
} else if (isNumber(i)) {
i = baselib.numbers.toFixnum(i);
if (i >= 0 && i < vec.elts.length) {
return vec.elts[i];
}
}
expectedTypeName = baselib.format.format('natural between 0 and ~a',
[vec.elts.length]);
raiseArgumentTypeError(M, 'vector-ref', expectedTypeName, 1, i);
} else {
raiseArgumentTypeError(M, 'vector-ref', 'vector', 0, vec);
}
};
var checkedVectorSet = function(M, vec, i, val) {
var expectedTypeName;
if (isVector(vec)) {
if (typeof(i) === 'number') {
if (i >= 0 && i < vec.elts.length) {
vec.elts[i] = val;
return VOID;
}
} else if (isNumber(i)) {
i = baselib.numbers.toFixnum(i);
if (i >= 0 && i < vec.elts.length) {
vec.elts[i] = val;
return VOID;
}
}
expectedTypeName = baselib.format.format('natural between 0 and ~a',
[vec.elts.length]);
raiseArgumentTypeError(M, 'vector-set!', expectedTypeName, 1, i);
} else {
raiseArgumentTypeError(M, 'vector-set!', 'vector', 0, vec);
}
};
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
@ -1111,6 +1184,8 @@
exports['checkedNegate'] = checkedNegate;
exports['checkedAdd'] = checkedAdd;
exports['checkedAddSlowPath'] = checkedAddSlowPath;
exports['checkedMul'] = checkedMul;
exports['checkedMulSlowPath'] = checkedMulSlowPath;
exports['checkedSub'] = checkedSub;
exports['checkedSubSlowPath'] = checkedSubSlowPath;
exports['checkedNumEquals'] = checkedNumEquals;
@ -1119,4 +1194,6 @@
exports['checkedGreaterThanSlowPath'] = checkedGreaterThanSlowPath;
exports['checkedCar'] = checkedCar;
exports['checkedCdr'] = checkedCdr;
exports['checkedVectorRef'] = checkedVectorRef;
exports['checkedVectorSet'] = checkedVectorSet;
}(this.plt, this.plt.baselib));