Skip to content

Commit

Permalink
Merge pull request #20 from marianrai/Add_jetstream2_benchmark_suite
Browse files Browse the repository at this point in the history
Add jetstream2 benchmark suite
  • Loading branch information
Rob Wood authored Jun 28, 2019
2 parents 002edb0 + 72f9147 commit e19a086
Show file tree
Hide file tree
Showing 952 changed files with 2,392,689 additions and 0 deletions.
1 change: 1 addition & 0 deletions benchmarks/JetStream2/.svn/entries
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
12
1 change: 1 addition & 0 deletions benchmarks/JetStream2/.svn/format
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
12
Original file line number Diff line number Diff line change
@@ -0,0 +1,332 @@
/*
* Copyright (C) 2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
"use strict";

// This is a combined LHS/RHS evaluator that passes around EPtr's to everything.
class Evaluator extends Visitor {
constructor(program)
{
super();
this._program = program;
}

// You must snapshot if you use a value in rvalue context. For example, a call expression will
// snapshot all of its arguments immedaitely upon executing them. In general, it should not be
// possible for a pointer returned from a visit method in rvalue context to live across any effects.
_snapshot(type, dstPtr, srcPtr)
{
let size = type.size;
if (size == null)
throw new Error("Cannot get size of type: " + type + " (size = " + size + ", constructor = " + type.constructor.name + ")");
if (!dstPtr)
dstPtr = new EPtr(new EBuffer(size), 0);
dstPtr.copyFrom(srcPtr, size);
return dstPtr;
}

runFunc(func)
{
return EBuffer.disallowAllocation(
() => this._runBody(func.returnType, func.returnEPtr, func.body));
}

_runBody(type, ptr, block)
{
if (!ptr)
throw new Error("Null ptr");
try {
block.visit(this);
// FIXME: We should have a check that there is no way to drop out of a function without
// returning unless the function returns void.
return null;
} catch (e) {
if (e == BreakException || e == ContinueException)
throw new Error("Should not see break/continue at function scope");
if (e instanceof ReturnException) {
let result = this._snapshot(type, ptr, e.value);
return result;
}
throw e;
}
}

visitFunctionLikeBlock(node)
{
for (let i = 0; i < node.argumentList.length; ++i) {
node.parameters[i].ePtr.copyFrom(
node.argumentList[i].visit(this),
node.parameters[i].type.size);
}
let result = this._runBody(node.returnType, node.returnEPtr, node.body);
return result;
}

visitReturn(node)
{
throw new ReturnException(node.value ? node.value.visit(this) : null);
}

visitVariableDecl(node)
{
if (!node.ePtr.buffer)
throw new Error("eptr without buffer in " + node);
node.type.populateDefaultValue(node.ePtr.buffer, node.ePtr.offset);
if (node.initializer)
node.ePtr.copyFrom(node.initializer.visit(this), node.type.size);
}

visitAssignment(node)
{
let target = node.lhs.visit(this);
let source = node.rhs.visit(this);
target.copyFrom(source, node.type.size);
return target;
}

visitIdentityExpression(node)
{
return node.target.visit(this);
}

visitDereferenceExpression(node)
{
let ptr = node.ptr.visit(this).loadValue();
if (!ptr)
throw new WTrapError(node.origin.originString, "Null dereference");
return ptr;
}

visitMakePtrExpression(node)
{
let ptr = node.lValue.visit(this);
return node.ePtr.box(ptr);
}

visitMakeArrayRefExpression(node)
{
return node.ePtr.box(new EArrayRef(node.lValue.visit(this), node.numElements.visit(this).loadValue()));
}

visitConvertPtrToArrayRefExpression(node)
{
return node.ePtr.box(new EArrayRef(node.lValue.visit(this).loadValue(), 1));
}

visitCommaExpression(node)
{
let result;
for (let expression of node.list)
result = expression.visit(this);
// This should almost snapshot, except that tail-returning a pointer is totally OK.
return result;
}

visitVariableRef(node)
{
return node.variable.ePtr;
}

visitGenericLiteral(node)
{
return node.ePtr.box(node.valueForSelectedType);
}

visitNullLiteral(node)
{
return node.ePtr.box(null);
}

visitBoolLiteral(node)
{
return node.ePtr.box(node.value);
}

visitEnumLiteral(node)
{
return node.ePtr.box(node.member.value.unifyNode.valueForSelectedType);
}

visitLogicalNot(node)
{
let result = !node.operand.visit(this).loadValue();
return node.ePtr.box(result);
}

visitLogicalExpression(node)
{
let lhs = node.left.visit(this).loadValue();
let rhs = node.right.visit(this).loadValue();
let result;
switch (node.text) {
case "&&":
result = lhs && rhs;
break;
case "||":
result = lhs || rhs;
break;
default:
throw new Error("Unknown type of logical expression");
}
return node.ePtr.box(result);
}

visitIfStatement(node)
{
if (node.conditional.visit(this).loadValue())
return node.body.visit(this);
else if (node.elseBody)
return node.elseBody.visit(this);
}

visitWhileLoop(node)
{
while (node.conditional.visit(this).loadValue()) {
try {
node.body.visit(this);
} catch (e) {
if (e == BreakException)
break;
if (e == ContinueException)
continue;
throw e;
}
}
}

visitDoWhileLoop(node)
{
do {
try {
node.body.visit(this);
} catch (e) {
if (e == BreakException)
break;
if (e == ContinueException)
continue;
throw e;
}
} while (node.conditional.visit(this).loadValue());
}

visitForLoop(node)
{
for (node.initialization ? node.initialization.visit(this) : true;
node.condition ? node.condition.visit(this).loadValue() : true;
node.increment ? node.increment.visit(this) : true) {
try {
node.body.visit(this);
} catch (e) {
if (e == BreakException)
break;
if (e == ContinueException)
continue;
throw e;
}
}
}

visitSwitchStatement(node)
{
let findAndRunCast = predicate => {
for (let i = 0; i < node.switchCases.length; ++i) {
let switchCase = node.switchCases[i];
if (predicate(switchCase)) {
try {
for (let j = i; j < node.switchCases.length; ++j)
node.switchCases[j].visit(this);
} catch (e) {
if (e != BreakException)
throw e;
}
return true;
}
}
return false;
};

let value = node.value.visit(this).loadValue();

let found = findAndRunCast(switchCase => {
if (switchCase.isDefault)
return false;
return node.type.unifyNode.valuesEqual(
value, switchCase.value.unifyNode.valueForSelectedType);
});
if (found)
return;

found = findAndRunCast(switchCase => switchCase.isDefault);
if (!found)
throw new Error("Switch statement did not find case");
}

visitBreak(node)
{
throw BreakException;
}

visitContinue(node)
{
throw ContinueException;
}

visitTrapStatement(node)
{
throw new WTrapError(node.origin.originString, "Trap statement");
}

visitAnonymousVariable(node)
{
node.type.populateDefaultValue(node.ePtr.buffer, node.ePtr.offset);
}

visitCallExpression(node)
{
// We evaluate inlined ASTs, so this can only be a native call.
let callArguments = [];
for (let i = 0; i < node.argumentList.length; ++i) {
let argument = node.argumentList[i];
let type = node.nativeFuncInstance.parameterTypes[i];
if (!type || !argument)
throw new Error("Cannot get type or argument; i = " + i + ", argument = " + argument + ", type = " + type + "; in " + node);
let argumentValue = argument.visit(this);
if (!argumentValue)
throw new Error("Null argument value, i = " + i + ", node = " + node);
callArguments.push(() => {
let result = this._snapshot(type, null, argumentValue);
return result;
});
}

// For simplicity, we allow intrinsics to just allocate new buffers, and we allocate new
// buffers when snapshotting their arguments. This is not observable to the user, so it's OK.
let result = EBuffer.allowAllocation(
() => node.func.implementation(callArguments.map(thunk => thunk()), node));

result = this._snapshot(node.nativeFuncInstance.returnType, node.resultEPtr, result);
return result;
}
}

Loading

0 comments on commit e19a086

Please sign in to comment.