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))] (box? (Const-const knowledge))]
[(list) [(list)
(list? (Const-const knowledge))] (list? (Const-const knowledge))]
[(vector)
(vector? (Const-const knowledge))]
[(pair) [(pair)
(pair? (Const-const knowledge))] (pair? (Const-const knowledge))]
[(caarpair) [(caarpair)

View File

@ -6,6 +6,7 @@
"../type-helpers.rkt") "../type-helpers.rkt")
(define-type OperandDomain (U 'number (define-type OperandDomain (U 'number
'string 'string
'vector
'box 'box
'list 'list
'pair 'pair
@ -178,6 +179,8 @@
'null? 'null?
'not 'not
'eq? 'eq?
'vector-ref
'vector-set!
)) ))
(ensure-type-subsetof KernelPrimitiveName/Inline KernelPrimitiveName) (ensure-type-subsetof KernelPrimitiveName/Inline KernelPrimitiveName)
@ -288,4 +291,10 @@
(list 'any)] (list 'any)]
[(eq? prim 'eq?) [(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) (cond [(empty? checked-operands)
(assemble-numeric-constant 1)] (assemble-numeric-constant 1)]
[(< (length operands) MAX-JAVASCRIPT-ARGS-AT-ONCE)
(format "RT.checkedMul(M, ~a)" (string-join operands ","))]
[else [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)] (assemble-binop-chain "plt.baselib.numbers.divide" checked-operands)]
@ -111,6 +113,14 @@
[(list?) [(list?)
(format "RT.isList(~a)" (format "RT.isList(~a)"
(first checked-operands))] (first checked-operands))]
[(vector-ref)
(format "RT.checkedVectorRef(M, ~a)"
(string-join operands ","))]
[(vector-set!)
(format "RT.checkedVectorSet(M, ~a)"
(string-join operands ","))]
[(pair?) [(pair?)
(format "RT.isPair(~a)" (format "RT.isPair(~a)"
@ -186,7 +196,9 @@
[(caarpair) [(caarpair)
(format "RT.isCaarPair")] (format "RT.isCaarPair")]
[(box) [(box)
(format "RT.isBox")])]) (format "RT.isBox")]
[(vector)
(format "RT.isVector")])])
(format "RT.testArgument(M,~s,~a,~a,~a,~s)" (format "RT.testArgument(M,~s,~a,~a,~a,~s)"
(symbol->string domain) (symbol->string domain)
predicate predicate

View File

@ -1057,7 +1057,8 @@
2, 2,
function (M) { function (M) {
var elts = checkVector(M, 'vector-ref', 0).elts; 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]; return elts[index];
}); });

View File

@ -860,6 +860,34 @@
return sum; 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) { var checkedSub = function(M, x, y) {
// Assumption: at least two arguments to subtract. // Assumption: at least two arguments to subtract.
var sum; var sum;
@ -969,6 +997,51 @@
raiseArgumentTypeError(M, 'cdr', 'pair', 0, v); 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['checkedNegate'] = checkedNegate;
exports['checkedAdd'] = checkedAdd; exports['checkedAdd'] = checkedAdd;
exports['checkedAddSlowPath'] = checkedAddSlowPath; exports['checkedAddSlowPath'] = checkedAddSlowPath;
exports['checkedMul'] = checkedMul;
exports['checkedMulSlowPath'] = checkedMulSlowPath;
exports['checkedSub'] = checkedSub; exports['checkedSub'] = checkedSub;
exports['checkedSubSlowPath'] = checkedSubSlowPath; exports['checkedSubSlowPath'] = checkedSubSlowPath;
exports['checkedNumEquals'] = checkedNumEquals; exports['checkedNumEquals'] = checkedNumEquals;
@ -1119,4 +1194,6 @@
exports['checkedGreaterThanSlowPath'] = checkedGreaterThanSlowPath; exports['checkedGreaterThanSlowPath'] = checkedGreaterThanSlowPath;
exports['checkedCar'] = checkedCar; exports['checkedCar'] = checkedCar;
exports['checkedCdr'] = checkedCdr; exports['checkedCdr'] = checkedCdr;
exports['checkedVectorRef'] = checkedVectorRef;
exports['checkedVectorSet'] = checkedVectorSet;
}(this.plt, this.plt.baselib)); }(this.plt, this.plt.baselib));