0001: /*
0002: * Copyright (c) 2006 Mo DeJong
0003: *
0004: * See the file "license.amd" for information on usage and
0005: * redistribution of this file, and for a DISCLAIMER OF ALL
0006: * WARRANTIES.
0007: *
0008: * RCS: @(#) $Id: TJCBench.java,v 1.13 2006/06/28 02:15:52 mdejong Exp $
0009: *
0010: */
0011:
0012: // This class is an ungly workaround for a bug in the
0013: // JDK 1.4 JVM that makes it impossible to load code
0014: // in the tcl.lang.* package via a classloader. This
0015: // class define Tcl tests that check implementation
0016: // runtimes for the Tcl Bench suite. These tests
0017: // should be defined in code compiled by Tcl Bench
0018: // but compiling code inside a package does not
0019: // work when classes access other package members.
0020: package tcl.lang;
0021:
0022: public class TJCBench extends TJC.CompiledCommand {
0023:
0024: public void cmdProc(Interp interp, TclObject[] objv)
0025: throws TclException {
0026: if (objv.length != 2) {
0027: throw new TclNumArgsException(interp, 2, objv, "testname");
0028: }
0029: String testname = objv[1].toString();
0030:
0031: if (testname.equals("InternalTclObjectPreserve")) {
0032: InternalTclObjectPreserve(interp);
0033: } else if (testname.equals("InternalTclObjectPreserveRelease")) {
0034: InternalTclObjectPreserveRelease(interp);
0035: } else if (testname.equals("InternalExprParseIntValue")) {
0036: InternalExprParseIntValue(interp);
0037: } else if (testname.equals("InternalExprParseDoubleValue")) {
0038: InternalExprParseDoubleValue(interp);
0039: } else if (testname.equals("InternalExprGetBooleanInt")) {
0040: InternalExprGetBooleanInt(interp);
0041: } else if (testname.equals("InternalExprGetBooleanDouble")) {
0042: InternalExprGetBooleanDouble(interp);
0043: } else if (testname.equals("InternalExprGetBooleanString")) {
0044: InternalExprGetBooleanString(interp);
0045: } else if (testname.equals("InternalIncr")) {
0046: InternalIncr(interp);
0047: } else if (testname.equals("InternalTclListAppend")) {
0048: InternalTclListAppend(interp);
0049: } else if (testname.equals("InternalTclListLength")) {
0050: InternalTclListLength(interp);
0051: } else if (testname.equals("InternalTclListLindex")) {
0052: InternalTclListLindex(interp);
0053: } else if (testname.equals("InternalTclStringNewInstance")) {
0054: InternalTclStringNewInstance(interp);
0055: } else if (testname.equals("InternalTclIntegerNewInstance")) {
0056: InternalTclIntegerNewInstance(interp);
0057: } else if (testname.equals("InternalTclDoubleNewInstance")) {
0058: InternalTclDoubleNewInstance(interp);
0059: } else if (testname.equals("InternalTclListNewInstance")) {
0060: InternalTclListNewInstance(interp);
0061: } else if (testname.equals("InternalTclStringDuplicate")) {
0062: InternalTclStringDuplicate(interp);
0063: } else if (testname.equals("InternalTclIntegerDuplicate")) {
0064: InternalTclIntegerDuplicate(interp);
0065: } else if (testname.equals("InternalTclDoubleDuplicate")) {
0066: InternalTclDoubleDuplicate(interp);
0067: } else if (testname.equals("InternalTclListDuplicate")) {
0068: InternalTclListDuplicate(interp);
0069: } else if (testname.equals("InternalTclIntegerType")) {
0070: InternalTclIntegerType(interp);
0071: } else if (testname.equals("InternalTclDoubleType")) {
0072: InternalTclDoubleType(interp);
0073: } else if (testname.equals("InternalTclStringType")) {
0074: InternalTclStringType(interp);
0075: } else if (testname.equals("InternalTclListType")) {
0076: InternalTclListType(interp);
0077: } else if (testname.equals("InternalTclIntegerGet")) {
0078: InternalTclIntegerGet(interp);
0079: } else if (testname.equals("InternalExprGetKnownInt")) {
0080: InternalExprGetKnownInt(interp);
0081: } else if (testname.equals("InternalExprInlineGetInt")) {
0082: InternalExprInlineGetInt(interp);
0083: } else if (testname.equals("InternalTclDoubleGet")) {
0084: InternalTclDoubleGet(interp);
0085: } else if (testname.equals("InternalExprGetKnownDouble")) {
0086: InternalExprGetKnownDouble(interp);
0087: } else if (testname.equals("InternalExprInlinedIntNotOperator")) {
0088: InternalExprInlinedIntNotOperator(interp);
0089: } else if (testname
0090: .equals("InternalExprInlinedIntNotBitwiseOperator")) {
0091: InternalExprInlinedIntNotBitwiseOperator(interp);
0092: } else if (testname.equals("InternalExprValueIntNotOperator")) {
0093: InternalExprValueIntNotOperator(interp);
0094: } else if (testname
0095: .equals("InternalExprValueIntNotNstrOperator")) {
0096: InternalExprValueIntNotNstrOperator(interp);
0097: } else if (testname.equals("InternalSetTclObjectResult")) {
0098: InternalSetTclObjectResult(interp);
0099: } else if (testname.equals("InternalSetSameTclObjectResult")) {
0100: InternalSetSameTclObjectResult(interp);
0101: } else if (testname.equals("InternalResetResult")) {
0102: InternalResetResult(interp);
0103: } else if (testname.equals("InternalSetBooleanResult")) {
0104: InternalSetBooleanResult(interp);
0105: } else if (testname.equals("InternalSetIntResult")) {
0106: InternalSetIntResult(interp);
0107: } else if (testname.equals("InternalSetUncommonIntResult")) {
0108: InternalSetUncommonIntResult(interp);
0109: } else if (testname.equals("InternalSetUncommonDoubleResult")) {
0110: InternalSetUncommonDoubleResult(interp);
0111: } else if (testname.equals("InternalSetUncommonStringResult")) {
0112: InternalSetUncommonStringResult(interp);
0113: } else if (testname.equals("InternalSetIntResultViaExprValue")) {
0114: InternalSetIntResultViaExprValue(interp);
0115: } else if (testname.equals("InternalExprSetIntResult")) {
0116: InternalExprSetIntResult(interp);
0117: } else if (testname.equals("InternalExprOpIntNot")) {
0118: InternalExprOpIntNot(interp);
0119: } else if (testname
0120: .equals("InternalExprOpIntNotGrabReleaseResult")) {
0121: InternalExprOpIntNotGrabReleaseResult(interp);
0122: } else if (testname
0123: .equals("InternalExprOpIntNotStackValueResult")) {
0124: InternalExprOpIntNotStackValueResult(interp);
0125: } else if (testname
0126: .equals("InternalExprOpIntNotStackValueIntResult")) {
0127: InternalExprOpIntNotStackValueIntResult(interp);
0128: } else if (testname
0129: .equals("InternalExprOpIntNotStackValueBooleanResult")) {
0130: InternalExprOpIntNotStackValueBooleanResult(interp);
0131: } else if (testname
0132: .equals("InternalExprOpIntInlinedNotStackValueResult")) {
0133: InternalExprOpIntInlinedNotStackValueResult(interp);
0134: } else if (testname
0135: .equals("InternalExprOpIntInlinedNotNstrStackValueResult")) {
0136: InternalExprOpIntInlinedNotNstrStackValueResult(interp);
0137: } else if (testname
0138: .equals("InternalExprOpIntInlinedNotNstrStackValueIntResult")) {
0139: InternalExprOpIntInlinedNotNstrStackValueIntResult(interp);
0140: } else if (testname
0141: .equals("InternalExprOpIntInlinedNotNstrStackValueBooleanResult")) {
0142: InternalExprOpIntInlinedNotNstrStackValueBooleanResult(interp);
0143: } else if (testname
0144: .equals("InternalExprOpIntInlinedNotKnownIntResult")) {
0145: InternalExprOpIntInlinedNotKnownIntResult(interp);
0146: } else if (testname
0147: .equals("InternalExprOpIntInlinedNotKnownIntInlineResult")) {
0148: InternalExprOpIntInlinedNotKnownIntInlineResult(interp);
0149: } else if (testname
0150: .equals("InternalExprOpIntInlinedNotKnownIntInlineBooleanResult")) {
0151: InternalExprOpIntInlinedNotKnownIntInlineBooleanResult(interp);
0152: } else if (testname
0153: .equals("InternalExprOpIntInlinedNotNstrAsBoolean")) {
0154: InternalExprOpIntInlinedNotNstrAsBoolean(interp);
0155: } else if (testname
0156: .equals("InternalExprOpIntInlinedNotNstrKnownIntAsBoolean")) {
0157: InternalExprOpIntInlinedNotNstrKnownIntAsBoolean(interp);
0158: } else if (testname
0159: .equals("InternalExprOpIntInlinedNotNstrLocalAsBoolean")) {
0160: InternalExprOpIntInlinedNotNstrLocalAsBoolean(interp);
0161: } else if (testname.equals("InternalExprOpIntPlus")) {
0162: InternalExprOpIntPlus(interp);
0163: } else if (testname
0164: .equals("InternalExprOpIntPlusGrabReleaseResult")) {
0165: InternalExprOpIntPlusGrabReleaseResult(interp);
0166: } else if (testname
0167: .equals("InternalExprOpIntPlusStackValueResult")) {
0168: InternalExprOpIntPlusStackValueResult(interp);
0169: } else if (testname
0170: .equals("InternalExprOpIntPlusStackValueIntResult")) {
0171: InternalExprOpIntPlusStackValueIntResult(interp);
0172: } else if (testname
0173: .equals("InternalExprOpIntInlinedPlusStackValueIntResult")) {
0174: InternalExprOpIntInlinedPlusStackValueIntResult(interp);
0175: } else if (testname
0176: .equals("InternalExprOpIntInlinedPlusNBStackValueIntResult")) {
0177: InternalExprOpIntInlinedPlusNBStackValueIntResult(interp);
0178: } else if (testname
0179: .equals("InternalExprOpIntInlinedPlusIMStackValueIntResult")) {
0180: InternalExprOpIntInlinedPlusIMStackValueIntResult(interp);
0181: } else if (testname
0182: .equals("InternalExprOpIntInlinedPlusIMRStackValueIntResult")) {
0183: InternalExprOpIntInlinedPlusIMRStackValueIntResult(interp);
0184: } else if (testname.equals("InternalExprOpDoublePlus")) {
0185: InternalExprOpDoublePlus(interp);
0186: } else if (testname.equals("InternalExprOpLogicalOrResult")) {
0187: InternalExprOpLogicalOrResult(interp);
0188: } else if (testname
0189: .equals("InternalExprOpInlinedLogicalOrResult")) {
0190: InternalExprOpInlinedLogicalOrResult(interp);
0191: } else if (testname
0192: .equals("InternalExprOpInlinedIntLogicalOrResult")) {
0193: InternalExprOpInlinedIntLogicalOrResult(interp);
0194: } else if (testname
0195: .equals("InternalExprOpInlinedNoExprLogicalOrResult")) {
0196: InternalExprOpInlinedNoExprLogicalOrResult(interp);
0197: } else if (testname.equals("InternalObjvInvoke")) {
0198: InternalObjvInvoke(interp);
0199: } else if (testname.equals("InternalObjvInvokeOnStack")) {
0200: InternalObjvInvokeOnStack(interp);
0201: } else if (testname.equals("InternalObjvInvokeOnStackAssigned")) {
0202: InternalObjvInvokeOnStackAssigned(interp);
0203: } else if (testname
0204: .equals("InternalObjvInvokeOnStackAssignedIndex")) {
0205: InternalObjvInvokeOnStackAssignedIndex(interp);
0206: } else if (testname.equals("InternalObjvInvokeOnStackStack")) {
0207: InternalObjvInvokeOnStackStack(interp);
0208: } else if (testname.equals("InternalObjvInvokeOnStackTryStack")) {
0209: InternalObjvInvokeOnStackTryStack(interp);
0210: } else {
0211: throw new TclException(interp, "unknown test name \""
0212: + testname + "\"");
0213: }
0214: }
0215:
0216: // Each test must take special care to save
0217: // the result of operations to a variable
0218: // so that the optimizer does not incorrectly
0219: // eliminate what it thinks is dead code.
0220:
0221: static int RESULT_INT = 0;
0222: static Object RESULT_OBJ = null;
0223:
0224: // Invoke TclObject.preserve() over and over again
0225: // on a new TclObject.
0226:
0227: void InternalTclObjectPreserve(Interp interp) throws TclException {
0228: TclObject tobj = TclInteger.newInstance(1);
0229:
0230: for (int i = 0; i < 5000; i++) {
0231: tobj.preserve();
0232: }
0233: RESULT_INT = tobj.getRefCount();
0234: }
0235:
0236: // Invoke preserve() and release() on a TclObject.
0237:
0238: void InternalTclObjectPreserveRelease(Interp interp)
0239: throws TclException {
0240: TclObject tobj = TclInteger.newInstance(1);
0241: tobj.preserve(); // refcount = 1
0242: tobj.preserve(); // refcount = 2
0243:
0244: for (int i = 0; i < 5000; i++) {
0245: tobj.preserve();
0246: tobj.release();
0247: }
0248: RESULT_INT = tobj.getRefCount();
0249: }
0250:
0251: // Invoke ExprParseObject() over and over again on a
0252: // TclObject with a TclInteger internal rep.
0253:
0254: void InternalExprParseIntValue(Interp interp) throws TclException {
0255: TclObject tobj = TclInteger.newInstance(1);
0256: ExprValue value = new ExprValue(0, null);
0257:
0258: for (int i = 0; i < 5000; i++) {
0259: Expression.ExprParseObject(interp, tobj, value);
0260: }
0261: RESULT_INT = TclInteger.get(interp, tobj);
0262: }
0263:
0264: // Invoke ExprParseObject() over and over again on a
0265: // TclObject with a TclDouble internal rep.
0266:
0267: void InternalExprParseDoubleValue(Interp interp)
0268: throws TclException {
0269: TclObject tobj = TclDouble.newInstance(1.0);
0270: ExprValue value = new ExprValue(0, null);
0271:
0272: for (int i = 0; i < 5000; i++) {
0273: Expression.ExprParseObject(interp, tobj, value);
0274: }
0275: RESULT_INT = (int) TclDouble.get(interp, tobj);
0276: }
0277:
0278: // Invoke TJC.getBoolean() over and over with a TclInteger
0279:
0280: void InternalExprGetBooleanInt(Interp interp) throws TclException {
0281: TclObject tobj = TclInteger.newInstance(1);
0282: boolean b = false;
0283:
0284: for (int i = 0; i < 5000; i++) {
0285: b = TJC.getBoolean(interp, tobj);
0286: }
0287: RESULT_INT = (b ? 1 : 0);
0288: }
0289:
0290: // Invoke TJC.getBoolean() over and over with a TclDouble
0291:
0292: void InternalExprGetBooleanDouble(Interp interp)
0293: throws TclException {
0294: TclObject tobj = TclDouble.newInstance(1.0);
0295: boolean b = false;
0296:
0297: for (int i = 0; i < 5000; i++) {
0298: b = TJC.getBoolean(interp, tobj);
0299: }
0300: RESULT_INT = (b ? 1 : 0);
0301: }
0302:
0303: // Invoke TJC.getBoolean() over and over with a TclString
0304:
0305: void InternalExprGetBooleanString(Interp interp)
0306: throws TclException {
0307: TclObject tobj = TclString.newInstance("true");
0308: boolean b = false;
0309:
0310: for (int i = 0; i < 5000; i++) {
0311: b = TJC.getBoolean(interp, tobj);
0312: }
0313: RESULT_INT = (b ? 1 : 0);
0314: }
0315:
0316: // Invoke "incr" operation on an unshared TclInteger.
0317: // This checks the runtime execution speed
0318: // of the TclInteger.incr() operation in the
0319: // most common case of an unshared int.
0320:
0321: void InternalIncr(Interp interp) throws TclException {
0322: TclObject tobj = TclInteger.newInstance(0);
0323:
0324: for (int i = 0; i < 5000; i++) {
0325: TclInteger.incr(interp, tobj, 1);
0326: }
0327: RESULT_INT = TclInteger.get(interp, tobj);
0328: }
0329:
0330: // Invoke TclList.getLength() on an unshared
0331: // TclObject with the TclList type. This
0332: // will get timing info for this commonly
0333: // used low level operation.
0334:
0335: void InternalTclListLength(Interp interp) throws TclException {
0336: TclObject tlist = TclList.newInstance();
0337: TclObject tobj = interp.checkCommonString(null); // Empty string
0338:
0339: // Create list of length 3
0340: TclList.append(interp, tlist, tobj);
0341: TclList.append(interp, tlist, tobj);
0342: TclList.append(interp, tlist, tobj);
0343: int size = 0;
0344:
0345: for (int i = 0; i < 5000; i++) {
0346: size += TclList.getLength(interp, tlist);
0347: }
0348: RESULT_INT = size;
0349: }
0350:
0351: // Invoke TclList.index() in a loop to get
0352: // timing info for this low level operation.
0353:
0354: void InternalTclListLindex(Interp interp) throws TclException {
0355: TclObject tlist = TclList.newInstance();
0356: TclObject tobj = interp.checkCommonString(null); // Empty string
0357:
0358: // Create list of length 10
0359: TclList.append(interp, tlist, tobj);
0360: TclList.append(interp, tlist, tobj);
0361: TclList.append(interp, tlist, tobj);
0362: TclList.append(interp, tlist, tobj);
0363: TclList.append(interp, tlist, tobj);
0364: TclList.append(interp, tlist, tobj);
0365: TclList.append(interp, tlist, tobj);
0366: TclList.append(interp, tlist, tobj);
0367: TclList.append(interp, tlist, tobj);
0368: TclList.append(interp, tlist, tobj);
0369:
0370: for (int i = 0; i < 5000; i++) {
0371: tobj = TclList.index(interp, tlist, 6);
0372: }
0373: RESULT_OBJ = tobj;
0374: }
0375:
0376: // Invoke TclList.append() on an unshared
0377: // TclObject with the TclList type. This
0378: // will get timing info for TclList.append(),
0379: // a low level and commonly used operation.
0380:
0381: void InternalTclListAppend(Interp interp) throws TclException {
0382: TclObject tlist = TclList.newInstance();
0383: TclObject tobj = interp.checkCommonString(null); // Empty string
0384:
0385: for (int i = 0; i < 5000; i++) {
0386: TclList.append(interp, tlist, tobj);
0387: }
0388: RESULT_OBJ = tlist;
0389: }
0390:
0391: // Establish timing results for allocation of a
0392: // TclObject with a TclString internal rep.
0393:
0394: void InternalTclStringNewInstance(Interp interp)
0395: throws TclException {
0396: TclObject tobj = null;
0397:
0398: for (int i = 0; i < 5000; i++) {
0399: tobj = TclString.newInstance("foo");
0400: }
0401: RESULT_OBJ = tobj;
0402: }
0403:
0404: // Establish timing results for allocation of a
0405: // TclObject with a TclInteger internal rep.
0406:
0407: void InternalTclIntegerNewInstance(Interp interp)
0408: throws TclException {
0409: TclObject tobj = null;
0410:
0411: for (int i = 0; i < 5000; i++) {
0412: tobj = TclInteger.newInstance(1);
0413: }
0414: RESULT_OBJ = tobj;
0415: }
0416:
0417: // Establish timing results for allocation of a
0418: // TclObject with a TclDouble internal rep.
0419:
0420: void InternalTclDoubleNewInstance(Interp interp)
0421: throws TclException {
0422: TclObject tobj = null;
0423:
0424: for (int i = 0; i < 5000; i++) {
0425: tobj = TclDouble.newInstance(1.0);
0426: }
0427: RESULT_OBJ = tobj;
0428: }
0429:
0430: // Establish timing results for allocation of a
0431: // TclObject with a TclList internal rep.
0432:
0433: void InternalTclListNewInstance(Interp interp) throws TclException {
0434: TclObject tobj = null;
0435:
0436: for (int i = 0; i < 5000; i++) {
0437: tobj = TclList.newInstance();
0438: }
0439: RESULT_OBJ = tobj;
0440: }
0441:
0442: // Establish timing results for TclObject.duplicate()
0443: // of TclObject with a TclString internal rep.
0444:
0445: void InternalTclStringDuplicate(Interp interp) throws TclException {
0446: TclObject tobj = TclString.newInstance("foo");
0447: ;
0448:
0449: for (int i = 0; i < 5000; i++) {
0450: tobj = tobj.duplicate();
0451: }
0452: RESULT_OBJ = tobj;
0453: }
0454:
0455: // Establish timing results for TclObject.duplicate()
0456: // of TclObject with a TclInteger internal rep.
0457:
0458: void InternalTclIntegerDuplicate(Interp interp) throws TclException {
0459: TclObject tobj = TclInteger.newInstance(1);
0460:
0461: for (int i = 0; i < 5000; i++) {
0462: tobj = tobj.duplicate();
0463: }
0464: RESULT_OBJ = tobj;
0465: }
0466:
0467: // Establish timing results for TclObject.duplicate()
0468: // of TclObject with a TclDouble internal rep.
0469:
0470: void InternalTclDoubleDuplicate(Interp interp) throws TclException {
0471: TclObject tobj = TclDouble.newInstance(1.0);
0472:
0473: for (int i = 0; i < 5000; i++) {
0474: tobj = tobj.duplicate();
0475: }
0476: RESULT_OBJ = tobj;
0477: }
0478:
0479: // Establish timing results for TclObject.duplicate()
0480: // of TclObject with a TclList internal rep.
0481:
0482: void InternalTclListDuplicate(Interp interp) throws TclException {
0483: TclObject tobj = TclList.newInstance();
0484:
0485: for (int i = 0; i < 5000; i++) {
0486: tobj = tobj.duplicate();
0487: }
0488: RESULT_OBJ = tobj;
0489: }
0490:
0491: // Establish timing results for TclObject.isIntType() API.
0492:
0493: void InternalTclIntegerType(Interp interp) throws TclException {
0494: TclObject tobj = TclInteger.newInstance(1);
0495: boolean b = false;
0496:
0497: for (int i = 0; i < 5000; i++) {
0498: b = tobj.isIntType();
0499: }
0500: RESULT_INT = (b ? 1 : 0);
0501: }
0502:
0503: // Establish timing results for TclObject.isDoubleType() API.
0504:
0505: void InternalTclDoubleType(Interp interp) throws TclException {
0506: TclObject tobj = TclDouble.newInstance(1.0);
0507: boolean b = false;
0508:
0509: for (int i = 0; i < 5000; i++) {
0510: b = tobj.isDoubleType();
0511: }
0512: RESULT_INT = (b ? 1 : 0);
0513: }
0514:
0515: // Establish timing results for TclObject.isStringType() API.
0516:
0517: void InternalTclStringType(Interp interp) throws TclException {
0518: TclObject tobj = TclString.newInstance("foo");
0519: boolean b = false;
0520:
0521: for (int i = 0; i < 5000; i++) {
0522: b = tobj.isStringType();
0523: }
0524: RESULT_INT = (b ? 1 : 0);
0525: }
0526:
0527: // Establish timing results for TclObject.isListType() API.
0528:
0529: void InternalTclListType(Interp interp) throws TclException {
0530: TclObject tobj = TclList.newInstance();
0531: boolean b = false;
0532:
0533: for (int i = 0; i < 5000; i++) {
0534: b = tobj.isListType();
0535: }
0536: RESULT_INT = (b ? 1 : 0);
0537: }
0538:
0539: // Establish timing results for TclInteger.get().
0540:
0541: void InternalTclIntegerGet(Interp interp) throws TclException {
0542: TclObject tobj = TclInteger.newInstance(1);
0543: int ivalue = 0;
0544:
0545: for (int i = 0; i < 5000; i++) {
0546: ivalue = TclInteger.get(interp, tobj);
0547: }
0548: RESULT_INT = ivalue;
0549: }
0550:
0551: // Establish timing results for TJC.exprGetKnownInt(),
0552: // this API is used to access the int value inside
0553: // a TclObject known to contain an int in expr code.
0554:
0555: void InternalExprGetKnownInt(Interp interp) throws TclException {
0556: TclObject tobj = TclInteger.newInstance(1);
0557: int ivalue = 0;
0558:
0559: for (int i = 0; i < 5000; i++) {
0560: ivalue = TJC.exprGetKnownInt(tobj);
0561: }
0562: RESULT_INT = ivalue;
0563: }
0564:
0565: // Grab the int value out of a TclObject by
0566: // directly accessing the package protected
0567: // field. Testing seems to indicate that
0568: // the method inliner is working well and
0569: // that the TJC.exprGetKnownInt() method
0570: // works just as fast as directly accessing
0571: // the field in this case.
0572:
0573: void InternalExprInlineGetInt(Interp interp) throws TclException {
0574: TclObject tobj = TclInteger.newInstance(1);
0575: int ivalue = 0;
0576:
0577: for (int i = 0; i < 5000; i++) {
0578: ivalue = tobj.ivalue;
0579: }
0580: RESULT_INT = ivalue;
0581: }
0582:
0583: // Establish timing results for TclDouble.get().
0584:
0585: void InternalTclDoubleGet(Interp interp) throws TclException {
0586: TclObject tobj = TclDouble.newInstance(1.0);
0587: double d = 0.0;
0588:
0589: for (int i = 0; i < 5000; i++) {
0590: d = TclDouble.get(interp, tobj);
0591: }
0592: RESULT_INT = (int) d;
0593: }
0594:
0595: // Establish timing results for TJC.exprGetKnownInt(),
0596: // this API is used to access the int value inside
0597: // a TclObject known to contain an int in expr code.
0598:
0599: void InternalExprGetKnownDouble(Interp interp) throws TclException {
0600: TclObject tobj = TclDouble.newInstance(1.0);
0601: double d = 0.0;
0602:
0603: for (int i = 0; i < 5000; i++) {
0604: d = TJC.exprGetKnownDouble(tobj);
0605: }
0606: RESULT_INT = (int) d;
0607: }
0608:
0609: // Note that there is no test like
0610: // InternalExprInlineGetInt since there
0611: // is no double field to access.
0612:
0613: // Integer not operator as inlined logic
0614:
0615: void InternalExprInlinedIntNotOperator(Interp interp)
0616: throws TclException {
0617: int v = 1;
0618:
0619: for (int i = 0; i < 5000; i++) {
0620: v = ((v == 0) ? 1 : 0);
0621: }
0622: RESULT_INT = v;
0623: }
0624:
0625: // Integer not operator as inlined bitwise operation
0626:
0627: void InternalExprInlinedIntNotBitwiseOperator(Interp interp)
0628: throws TclException {
0629: int v = 1;
0630:
0631: for (int i = 0; i < 5000; i++) {
0632: v = ((v | -v) >>> 31) ^ 1;
0633: }
0634: RESULT_INT = v;
0635: }
0636:
0637: // Integer not operator via ExprValue.optIntUnaryNot() method
0638:
0639: void InternalExprValueIntNotOperator(Interp interp)
0640: throws TclException {
0641: ExprValue ev = new ExprValue(1, null);
0642:
0643: for (int i = 0; i < 5000; i++) {
0644: ev.optIntUnaryNot();
0645: }
0646: RESULT_INT = ev.getIntValue();
0647: }
0648:
0649: // Integer not operator via ExprValue.optIntUnaryNotNstr() method.
0650: // Unlike optIntUnaryNot, this method does not null out the
0651: // string value.
0652:
0653: void InternalExprValueIntNotNstrOperator(Interp interp)
0654: throws TclException {
0655: ExprValue ev = new ExprValue(1, null);
0656:
0657: for (int i = 0; i < 5000; i++) {
0658: ev.optIntUnaryNotNstr();
0659: }
0660: RESULT_INT = ev.getIntValue();
0661: }
0662:
0663: // Establish timing results for integer.setResult(TclObject).
0664: // Note that we need to use two different TclObject values
0665: // here to avoid an optimization in setResult() that
0666: // returns right away when the same result is set again.
0667: // There also need to be two set operations in the loop
0668: // so we can compare to the int/boolean operations below.
0669:
0670: void InternalSetTclObjectResult(Interp interp) throws TclException {
0671: TclObject tobj1 = TclInteger.newInstance(1);
0672: TclObject tobj2 = TclInteger.newInstance(2);
0673:
0674: // Make the objects shared so that they don't
0675: // get deallocated when the interp result
0676: // is changed.
0677: tobj1.preserve();
0678: tobj1.preserve();
0679: tobj2.preserve();
0680: tobj2.preserve();
0681:
0682: for (int i = 0; i < 5000; i++) {
0683: interp.setResult(tobj1);
0684: interp.setResult(tobj2);
0685: }
0686: RESULT_INT = TclInteger.get(interp, interp.getResult());
0687: }
0688:
0689: // Invoke integer.setResult(TclObject) over and over
0690: // again on the same TclObject. This should execute
0691: // very quickly since the setResult() API contains
0692: // a short circut return in this case.
0693:
0694: void InternalSetSameTclObjectResult(Interp interp)
0695: throws TclException {
0696: TclObject tobj1 = TclInteger.newInstance(1);
0697: tobj1.preserve();
0698: tobj1.preserve();
0699:
0700: for (int i = 0; i < 5000; i++) {
0701: interp.setResult(tobj1);
0702: interp.setResult(tobj1);
0703: }
0704: RESULT_INT = TclInteger.get(interp, interp.getResult());
0705: }
0706:
0707: // Establish timing results for integer.resetResult().
0708:
0709: void InternalResetResult(Interp interp) throws TclException {
0710: for (int i = 0; i < 5000; i++) {
0711: interp.resetResult();
0712: interp.resetResult();
0713: }
0714: RESULT_OBJ = interp.getResult();
0715: }
0716:
0717: // Establish timing results for integer.setResult(boolean).
0718: // Both the true and false values have a shared object.
0719:
0720: void InternalSetBooleanResult(Interp interp) throws TclException {
0721: boolean b1 = true;
0722: boolean b2 = false;
0723: if (RESULT_INT == 0) {
0724: // Make sure booleans are not seen as compile
0725: // time constant values.
0726: b1 = false;
0727: b2 = true;
0728: }
0729:
0730: for (int i = 0; i < 5000; i++) {
0731: interp.setResult(b1);
0732: interp.setResult(b2);
0733: }
0734: RESULT_INT = (TclBoolean.get(interp, interp.getResult()) ? 1
0735: : 0);
0736: }
0737:
0738: // Establish timing results for integer.setResult(int).
0739: // Both the 0 and 1 values have a shared object.
0740:
0741: void InternalSetIntResult(Interp interp) throws TclException {
0742: int i1 = 1;
0743: int i2 = 0;
0744: if (RESULT_INT == 0) {
0745: // Make sure ints are not seen as compile
0746: // time constant values.
0747: i1 = 0;
0748: i2 = 1;
0749: }
0750:
0751: for (int i = 0; i < 5000; i++) {
0752: interp.setResult(i1);
0753: interp.setResult(i2);
0754: }
0755: RESULT_INT = TclInteger.get(interp, interp.getResult());
0756: }
0757:
0758: // Establish timing results for integer.setResult(int).
0759: // These int values are not common shared results.
0760: // This might allocate 5000 new TclObject values
0761: // during the setResult() operation, or it might
0762: // reuse a recycled TclObject value.
0763:
0764: void InternalSetUncommonIntResult(Interp interp)
0765: throws TclException {
0766: for (int i = 0; i < 5000; i++) {
0767: interp.setResult(i * 2);
0768: interp.setResult(i * 3);
0769: }
0770: RESULT_INT = TclInteger.get(interp, interp.getResult());
0771: }
0772:
0773: // Establish timing results for integer.setResult(double)
0774: // when the double is not a common value.
0775: // This might allocate 5000 new TclObject values
0776: // during the setResult() operation, or it might
0777: // reuse a recycled TclObject value.
0778:
0779: void InternalSetUncommonDoubleResult(Interp interp)
0780: throws TclException {
0781: for (int i = 0; i < 5000; i++) {
0782: interp.setResult(i * 2.0);
0783: interp.setResult(i * 3.0);
0784: }
0785: RESULT_INT = (int) TclDouble.get(interp, interp.getResult());
0786: }
0787:
0788: // Establish timing results for integer.setResult(String)
0789: // when the string is not the empty string. This operation
0790: // is executed frequently in real code, so a recycled
0791: // object optimization here would be a big diff.
0792:
0793: void InternalSetUncommonStringResult(Interp interp)
0794: throws TclException {
0795: for (int i = 0; i < 5000; i++) {
0796: interp.setResult("2" + i);
0797: interp.setResult("3" + i);
0798: }
0799: RESULT_OBJ = interp.getResult();
0800: }
0801:
0802: // Invoke integer.setResult(int) with a result
0803: // stored in an ExprValue. This is like the
0804: // test above except that it includes execution
0805: // time for getting the int value out of the
0806: // ExprValue object. In that way, it is like
0807: // TJC.exprSetResult() but without a type switch.
0808:
0809: void InternalSetIntResultViaExprValue(Interp interp)
0810: throws TclException {
0811: int i1 = 1;
0812: int i2 = 0;
0813: if (RESULT_INT == 0) {
0814: // Make sure ints are not seen as compile
0815: // time constant values.
0816: i1 = 0;
0817: i2 = 1;
0818: }
0819: ExprValue value1 = TJC.exprGetValue(interp, i1, null);
0820: ExprValue value2 = TJC.exprGetValue(interp, i2, null);
0821:
0822: for (int i = 0; i < 5000; i++) {
0823: interp.setResult(value1.getIntValue());
0824: interp.setResult(value2.getIntValue());
0825: }
0826: RESULT_INT = TclInteger.get(interp, interp.getResult());
0827: }
0828:
0829: // Establish timing results for TJC.exprSetResult()
0830: // when invoked with an int type. These results
0831: // can be compared to InternalSetIntResultViaExprValue
0832: // to see how long the type query and branch
0833: // operation is taking.
0834:
0835: void InternalExprSetIntResult(Interp interp) throws TclException {
0836: int i1 = 1;
0837: int i2 = 0;
0838: if (RESULT_INT == 0) {
0839: // Make sure ints are not seen as compile
0840: // time constant values.
0841: i1 = 0;
0842: i2 = 1;
0843: }
0844: ExprValue value1 = TJC.exprGetValue(interp, i1, null);
0845: ExprValue value2 = TJC.exprGetValue(interp, i2, null);
0846:
0847: for (int i = 0; i < 5000; i++) {
0848: TJC.exprSetResult(interp, value1);
0849: TJC.exprSetResult(interp, value2);
0850: }
0851: RESULT_INT = TclInteger.get(interp, interp.getResult());
0852: }
0853:
0854: // Invoke unary ! operator on a TclInteger.
0855: // This tests the execution time for just the
0856: // Expression.evalBinaryOperator() API.
0857:
0858: void InternalExprOpIntNot(Interp interp) throws TclException {
0859: ExprValue value = new ExprValue(1, null);
0860:
0861: for (int i = 0; i < 5000; i++) {
0862: Expression.evalUnaryOperator(interp, TJC.EXPR_OP_UNARY_NOT,
0863: value);
0864: }
0865: RESULT_INT = value.getIntValue();
0866: }
0867:
0868: // This is the logic emitted for a unary
0869: // logical ! operator with +inline-containers.
0870: // This code will grab an ExprValue, init it,
0871: // invoke the operator method, and then
0872: // set the interp result. Note that because
0873: // the interp is set to the int 0 over
0874: // and over again, short circut logic
0875: // in the setResult(TclObject) method
0876: // will return right away since the new
0877: // value is the same as the existing result.
0878:
0879: void InternalExprOpIntNotGrabReleaseResult(Interp interp)
0880: throws TclException {
0881: // expr {!1}
0882:
0883: for (int i = 0; i < 5000; i++) {
0884: ExprValue tmp0 = TJC.exprGetValue(interp, 1, null);
0885: TJC.exprUnaryOperator(interp, TJC.EXPR_OP_UNARY_NOT, tmp0);
0886: TJC.exprSetResult(interp, tmp0);
0887: TJC.exprReleaseValue(interp, tmp0);
0888: }
0889: RESULT_INT = TclInteger.get(interp, interp.getResult());
0890: }
0891:
0892: // This is the logic emitted for a unary
0893: // logical ! operator with +inline-expr.
0894: // Unlike InternalExprOpIntNotGrabReleaseResult
0895: // this implementation will reuse an ExprValue
0896: // saved on the stack and avoid having to
0897: // grab and release during each loop iteration.
0898: // This implementation should be the baseline
0899: // for optimized not operator implementations.
0900:
0901: void InternalExprOpIntNotStackValueResult(Interp interp)
0902: throws TclException {
0903: // expr {!1}
0904:
0905: ExprValue evs0 = TJC.exprGetValue(interp);
0906:
0907: for (int i = 0; i < 5000; i++) {
0908: ExprValue tmp0 = evs0;
0909: tmp0.setIntValue(1);
0910: TJC.exprUnaryOperator(interp, TJC.EXPR_OP_UNARY_NOT, tmp0);
0911: TJC.exprSetResult(interp, tmp0);
0912: }
0913: RESULT_INT = TclInteger.get(interp, interp.getResult());
0914: }
0915:
0916: // This method is like InternalExprOpIntNotStackValueResult
0917: // except that it invokes the Interp.setResult(int) method
0918: // directly instead of calling TJC.exprSetResult().
0919: // This optimization is valid because we know the result
0920: // of a unary not is always of type int. This optimization
0921: // avoids a method invocation, a branching operation,
0922: // and a call to ExprValue.getType() for each iteration
0923: // of the loop.
0924:
0925: void InternalExprOpIntNotStackValueIntResult(Interp interp)
0926: throws TclException {
0927: // expr {!1}
0928:
0929: ExprValue evs0 = TJC.exprGetValue(interp);
0930:
0931: for (int i = 0; i < 5000; i++) {
0932: ExprValue tmp0 = evs0;
0933: tmp0.setIntValue(1);
0934: TJC.exprUnaryOperator(interp, TJC.EXPR_OP_UNARY_NOT, tmp0);
0935: interp.setResult(tmp0.getIntValue());
0936: }
0937: RESULT_INT = TclInteger.get(interp, interp.getResult());
0938: }
0939:
0940: // This method is like InternalExprOpIntNotStackValueIntResult
0941: // except that it invokes Interp.setResult(boolean) to
0942: // directly set the result to a boolean value.
0943:
0944: void InternalExprOpIntNotStackValueBooleanResult(Interp interp)
0945: throws TclException {
0946: // expr {!1}
0947:
0948: ExprValue evs0 = TJC.exprGetValue(interp);
0949:
0950: for (int i = 0; i < 5000; i++) {
0951: ExprValue tmp0 = evs0;
0952: tmp0.setIntValue(1);
0953: TJC.exprUnaryOperator(interp, TJC.EXPR_OP_UNARY_NOT, tmp0);
0954: interp.setResult((tmp0.getIntValue() != 0));
0955: }
0956: RESULT_INT = TclInteger.get(interp, interp.getResult());
0957: }
0958:
0959: // This optimized logic will check the type of an
0960: // ExprValue operand and inline a call to a
0961: // specific optimized method for the ExprValue.
0962: // This should execute significantly faster
0963: // than the TJC.exprUnaryOperator() call found in
0964: // InternalExprOpIntNotStackValueResult().
0965: // Note that exprSetResult() can end up executing
0966: // very quickly when the same value is set
0967: // as the result twice.
0968:
0969: void InternalExprOpIntInlinedNotStackValueResult(Interp interp)
0970: throws TclException {
0971: // expr {!1}
0972:
0973: ExprValue evs0 = TJC.exprGetValue(interp);
0974:
0975: for (int i = 0; i < 5000; i++) {
0976: ExprValue tmp0 = evs0;
0977: tmp0.setIntValue(1);
0978: // Use optimized impl when ExprValue is known to be an int.
0979: if (tmp0.isIntType()) {
0980: tmp0.optIntUnaryNot();
0981: } else {
0982: //TJC.exprUnaryOperator(interp, TJC.EXPR_OP_UNARY_NOT, tmp0);
0983: throw new TclRuntimeError("else branch reached");
0984: }
0985: TJC.exprSetResult(interp, tmp0);
0986: }
0987: RESULT_INT = TclInteger.get(interp, interp.getResult());
0988: }
0989:
0990: // This implementation is like InternalExprOpIntInlinedNotStackValueResult
0991: // except that it invokes optIntUnaryNotNstr() which does not null
0992: // the string value. If this shaves a few ms off the execution time
0993: // then it is worthwhile to implement in compiled code.
0994:
0995: void InternalExprOpIntInlinedNotNstrStackValueResult(Interp interp)
0996: throws TclException {
0997: // expr {!1}
0998:
0999: ExprValue evs0 = TJC.exprGetValue(interp);
1000:
1001: for (int i = 0; i < 5000; i++) {
1002: ExprValue tmp0 = evs0;
1003: tmp0.setIntValue(1);
1004: // Use optimized impl when ExprValue is known to be an int
1005: // that has no string value.
1006: if (tmp0.isIntType()) {
1007: tmp0.optIntUnaryNotNstr();
1008: } else {
1009: //TJC.exprUnaryOperator(interp, TJC.EXPR_OP_UNARY_NOT, tmp0);
1010: throw new TclRuntimeError("else branch reached");
1011: }
1012: TJC.exprSetResult(interp, tmp0);
1013: }
1014: RESULT_INT = TclInteger.get(interp, interp.getResult());
1015: }
1016:
1017: // This implementation takes advantage of the inlined not
1018: // operator logic and the int result set logic. This method
1019: // should indicate how much faster the implementation can
1020: // be made compared to InternalExprOpIntNotStackValueResult.
1021:
1022: void InternalExprOpIntInlinedNotNstrStackValueIntResult(
1023: Interp interp) throws TclException {
1024: // expr {!1}
1025:
1026: ExprValue evs0 = TJC.exprGetValue(interp);
1027:
1028: for (int i = 0; i < 5000; i++) {
1029: ExprValue tmp0 = evs0;
1030: tmp0.setIntValue(1);
1031: // Use optimized impl when ExprValue is known to be an int
1032: // that has no string value.
1033: if (tmp0.isIntType()) {
1034: tmp0.optIntUnaryNotNstr();
1035: } else {
1036: //TJC.exprUnaryOperator(interp, TJC.EXPR_OP_UNARY_NOT, tmp0);
1037: throw new TclRuntimeError("else branch reached");
1038: }
1039: interp.setResult(tmp0.getIntValue());
1040: }
1041: RESULT_INT = TclInteger.get(interp, interp.getResult());
1042: }
1043:
1044: // Like InternalExprOpIntInlinedNotNstrStackValueIntResult
1045: // except makes use of interp.setResult(boolean).
1046:
1047: void InternalExprOpIntInlinedNotNstrStackValueBooleanResult(
1048: Interp interp) throws TclException {
1049: // expr {!1}
1050:
1051: ExprValue evs0 = TJC.exprGetValue(interp);
1052:
1053: for (int i = 0; i < 5000; i++) {
1054: ExprValue tmp0 = evs0;
1055: tmp0.setIntValue(0);
1056: // Use optimized impl when ExprValue is known to be an int
1057: // that has no string value.
1058: if (tmp0.isIntType()) {
1059: tmp0.optIntUnaryNotNstr();
1060: } else {
1061: //TJC.exprUnaryOperator(interp, TJC.EXPR_OP_UNARY_NOT, tmp0);
1062: throw new TclRuntimeError("else branch reached");
1063: }
1064: interp.setResult((tmp0.getIntValue() != 0));
1065: }
1066: RESULT_INT = TclInteger.get(interp, interp.getResult());
1067: }
1068:
1069: // Invoke TJC.exprUnaryNotOperatorKnownInt() to set an
1070: // ExprValue to the result of a not operation run
1071: // on the contents of a TclObject known to be an
1072: // int.
1073:
1074: void InternalExprOpIntInlinedNotKnownIntResult(Interp interp)
1075: throws TclException {
1076: // expr {!1}
1077:
1078: ExprValue evs0 = TJC.exprGetValue(interp);
1079: TclObject tobj = TclInteger.newInstance(1);
1080:
1081: for (int i = 0; i < 5000; i++) {
1082: ExprValue tmp0 = evs0;
1083: // Use optimized impl when TclObject is an int.
1084: if (tobj.isIntType()) {
1085: TJC.exprUnaryNotOperatorKnownInt(tmp0, tobj);
1086: } else {
1087: //TJC.exprUnaryOperator(interp, TJC.EXPR_OP_UNARY_NOT, tmp0);
1088: throw new TclRuntimeError("else branch reached");
1089: }
1090: interp.setResult((tmp0.getIntValue() != 0));
1091: }
1092: RESULT_INT = TclInteger.get(interp, interp.getResult());
1093: }
1094:
1095: // Inline the logic found in exprUnaryNotOperatorKnownInt()
1096: // to see if including the branch operations inline makes
1097: // the code execute faster.
1098:
1099: void InternalExprOpIntInlinedNotKnownIntInlineResult(Interp interp)
1100: throws TclException {
1101: // expr {!1}
1102:
1103: ExprValue evs0 = TJC.exprGetValue(interp);
1104: TclObject tobj = TclInteger.newInstance(1);
1105:
1106: for (int i = 0; i < 5000; i++) {
1107: ExprValue tmp0 = evs0;
1108: // Use optimized impl when TclObject is an int.
1109: if (tobj.isIntType()) {
1110: //TJC.exprUnaryNotOperatorKnownInt(tmp0, tobj);
1111: tmp0.setIntValue((TJC.exprGetKnownInt(tobj) == 0) ? 1
1112: : 0);
1113: } else {
1114: //TJC.exprUnaryOperator(interp, TJC.EXPR_OP_UNARY_NOT, tmp0);
1115: throw new TclRuntimeError("else branch reached");
1116: }
1117: interp.setResult((tmp0.getIntValue() != 0));
1118: }
1119: RESULT_INT = TclInteger.get(interp, interp.getResult());
1120: }
1121:
1122: // Inline the logic found in exprUnaryNotOperatorKnownInt()
1123: // to see if including the branch operations inline makes
1124: // the code execute faster.
1125:
1126: void InternalExprOpIntInlinedNotKnownIntInlineBooleanResult(
1127: Interp interp) throws TclException {
1128: // expr {!1}
1129:
1130: ExprValue evs0 = TJC.exprGetValue(interp);
1131: TclObject tobj = TclInteger.newInstance(1);
1132:
1133: for (int i = 0; i < 5000; i++) {
1134: ExprValue tmp0 = evs0;
1135: // Use optimized impl when TclObject is an int.
1136: if (tobj.isIntType()) {
1137: //TJC.exprUnaryNotOperatorKnownInt(tmp0, tobj);
1138: tmp0.setIntValue(TJC.exprGetKnownInt(tobj) == 0);
1139: } else {
1140: //TJC.exprUnaryOperator(interp, TJC.EXPR_OP_UNARY_NOT, tmp0);
1141: throw new TclRuntimeError("else branch reached");
1142: }
1143: interp.setResult((tmp0.getIntValue() != 0));
1144: }
1145: RESULT_INT = TclInteger.get(interp, interp.getResult());
1146: }
1147:
1148: // Code emitted via +inline-expr with no specific
1149: // optimizations to take advantage of the fact
1150: // that the result will be a boolean condition.
1151:
1152: void InternalExprOpIntInlinedNotNstrAsBoolean(Interp interp)
1153: throws TclException {
1154: // if {!1} {}
1155:
1156: ExprValue evs0 = TJC.exprGetValue(interp);
1157:
1158: for (int i = 0; i < 5000; i++) {
1159: ExprValue tmp0 = evs0;
1160: tmp0.setIntValue(1);
1161: // ExprValue is known to be an int with no string value.
1162: tmp0.optIntUnaryNotNstr();
1163: // This call to getBooleanValue() does not take
1164: // advantage of compile time info re ExprValue type.
1165: boolean tmp1 = tmp0.getBooleanValue(interp);
1166: if (tmp1) {
1167: RESULT_INT = 1;
1168: } else {
1169: RESULT_INT = 0;
1170: }
1171: }
1172: }
1173:
1174: // When an expression is evaluated to a boolean
1175: // condition, inlined code can be emitted
1176: // when the type of the expression is known
1177: // at compile time. This test shows what type
1178: // of speedup can be expected when the ExprValue
1179: // is known to be an int at compile time.
1180: // This implementation executes about 4x faster
1181: // than InternalExprOpIntInlinedNotNstrAsBoolean.
1182:
1183: void InternalExprOpIntInlinedNotNstrKnownIntAsBoolean(Interp interp)
1184: throws TclException {
1185: // if {!1} {}
1186:
1187: ExprValue evs0 = TJC.exprGetValue(interp);
1188:
1189: for (int i = 0; i < 5000; i++) {
1190: ExprValue tmp0 = evs0;
1191: tmp0.setIntValue(1);
1192: // ExprValue is known to be an int with no string value.
1193: tmp0.optIntUnaryNotNstr();
1194: // ExprValue is known to be an int
1195: boolean tmp1 = (tmp0.getIntValue() != 0);
1196: if (tmp1) {
1197: RESULT_INT = 1;
1198: } else {
1199: RESULT_INT = 0;
1200: }
1201: }
1202: }
1203:
1204: // This implementation will declare a boolean condition
1205: // at the start of the expr evaluation and use the
1206: // local to implement the not operation. This local
1207: // will then be read in the if block. This implementation
1208: // is just slightly faster than
1209: // InternalExprOpIntInlinedNotNstrKnownIntAsBoolean
1210: // with -client but is about the same with -server.
1211: // More testing is needed to see if it is worth it
1212: // to muck around with declaring a local on a
1213: // per-expr basis to support this implementation.
1214: // This is the optimal implementation, putting the
1215: // (tmp1.getIntValue() != 0) logic in an ExprValue
1216: // method is actually a touch slower than just
1217: // inlining the int->boolean conversion.
1218:
1219: void InternalExprOpIntInlinedNotNstrLocalAsBoolean(Interp interp)
1220: throws TclException {
1221: // if {!1} {}
1222:
1223: ExprValue evs0 = TJC.exprGetValue(interp);
1224:
1225: for (int i = 0; i < 5000; i++) {
1226: boolean result0;
1227:
1228: ExprValue tmp1 = evs0;
1229: tmp1.setIntValue(1);
1230: // ExprValue is known to be an int with no string value.
1231: result0 = (tmp1.getIntValue() != 0);
1232:
1233: // Result now saved in boolean local, the code above
1234: // implements the not operator. This ignores the
1235: // string value completely.
1236:
1237: if (result0) {
1238: RESULT_INT = 1;
1239: } else {
1240: RESULT_INT = 0;
1241: }
1242: }
1243: }
1244:
1245: // Invoke binary + operator on a TclInteger.
1246: // This tests the execution time for just the
1247: // Expression.evalBinaryOperator() API.
1248:
1249: void InternalExprOpIntPlus(Interp interp) throws TclException {
1250: ExprValue value1 = new ExprValue(1, null);
1251: ExprValue value2 = new ExprValue(2, null);
1252:
1253: for (int i = 0; i < 5000; i++) {
1254: Expression.evalBinaryOperator(interp, TJC.EXPR_OP_PLUS,
1255: value1, value2);
1256: }
1257: RESULT_INT = value1.getIntValue();
1258: }
1259:
1260: // This is the logic emitted for a binary
1261: // plus operator with +inline-containers.
1262: // This code will grab two ExprValues,
1263: // init them, and then pass these
1264: // values to the exprBinaryOperator()
1265:
1266: void InternalExprOpIntPlusGrabReleaseResult(Interp interp)
1267: throws TclException {
1268: // expr {1 + 2}
1269:
1270: for (int i = 0; i < 5000; i++) {
1271: ExprValue tmp0 = TJC.exprGetValue(interp, 1, null);
1272: ExprValue tmp1 = TJC.exprGetValue(interp, 2, null);
1273: TJC
1274: .exprBinaryOperator(interp, TJC.EXPR_OP_PLUS, tmp0,
1275: tmp1);
1276: TJC.exprReleaseValue(interp, tmp1);
1277: TJC.exprSetResult(interp, tmp0);
1278: TJC.exprReleaseValue(interp, tmp0);
1279: }
1280: RESULT_INT = TclInteger.get(interp, interp.getResult());
1281: }
1282:
1283: // This is the logic emitted for a binary
1284: // plus operator with +inline-expr.
1285: // Unlike InternalExprOpIntPlusGrabReleaseResult
1286: // this implementation will reuse two ExprValues
1287: // saved on the stack and avoid having to
1288: // grab and release during each loop iteration.
1289: // This implementation should be the baseline
1290: // for optimized plus operator implementations.
1291: // Note that the integer 3 is not a common value
1292: // so a new TclObject is allocated during each
1293: // result set operation.
1294:
1295: void InternalExprOpIntPlusStackValueResult(Interp interp)
1296: throws TclException {
1297: // expr {1 + 2}
1298:
1299: ExprValue evs0 = TJC.exprGetValue(interp);
1300: ExprValue evs1 = TJC.exprGetValue(interp);
1301:
1302: for (int i = 0; i < 5000; i++) {
1303: ExprValue tmp0 = evs0;
1304: tmp0.setIntValue(1);
1305: ExprValue tmp1 = evs1;
1306: tmp1.setIntValue(2);
1307: TJC
1308: .exprBinaryOperator(interp, TJC.EXPR_OP_PLUS, tmp0,
1309: tmp1);
1310: TJC.exprSetResult(interp, tmp0);
1311: }
1312: RESULT_INT = TclInteger.get(interp, interp.getResult());
1313: }
1314:
1315: // This method is like InternalExprOpIntPlusStackValueResult
1316: // except that it invokes the Interp.setResult(int) method
1317: // directly instead of calling TJC.exprSetResult().
1318: // This optimization is only valid when both operands are
1319: // known to be of type int.
1320:
1321: void InternalExprOpIntPlusStackValueIntResult(Interp interp)
1322: throws TclException {
1323: // expr {1 + 2}
1324:
1325: ExprValue evs0 = TJC.exprGetValue(interp);
1326: ExprValue evs1 = TJC.exprGetValue(interp);
1327:
1328: for (int i = 0; i < 5000; i++) {
1329: ExprValue tmp0 = evs0;
1330: tmp0.setIntValue(1);
1331: ExprValue tmp1 = evs1;
1332: tmp1.setIntValue(2);
1333: TJC
1334: .exprBinaryOperator(interp, TJC.EXPR_OP_PLUS, tmp0,
1335: tmp1);
1336: interp.setResult(tmp0.getIntValue());
1337: }
1338: RESULT_INT = TclInteger.get(interp, interp.getResult());
1339: }
1340:
1341: // This methods makes use of an inline plus operator
1342: // method using inlined logic when both operands are
1343: // ExprValues of type int (at runtime). This inlined
1344: // method execution time depends on the implementation
1345: // of Interp.setResult(int), if the setResult() method
1346: // uses a shared constant object it would execute
1347: // about about 3x faster. The new implementation of
1348: // recycled int objects significantly reduces the
1349: // performance hit when the int value is not a common
1350: // constant.
1351:
1352: void InternalExprOpIntInlinedPlusStackValueIntResult(Interp interp)
1353: throws TclException {
1354: // expr {1 + 2}
1355:
1356: ExprValue evs0 = TJC.exprGetValue(interp);
1357: ExprValue evs1 = TJC.exprGetValue(interp);
1358:
1359: for (int i = 0; i < 5000; i++) {
1360: ExprValue tmp0 = evs0;
1361: tmp0.setIntValue(1);
1362: ExprValue tmp1 = evs1;
1363: tmp1.setIntValue(2);
1364: if (tmp0.isIntType() && tmp1.isIntType()) {
1365: tmp0.optIntPlus(tmp1);
1366: } else {
1367: //TJC.exprBinaryOperator(interp, TJC.EXPR_OP_PLUS, tmp0, tmp1);
1368: throw new TclRuntimeError("else branch reached");
1369: }
1370: interp.setResult(tmp0.getIntValue());
1371: }
1372: RESULT_INT = TclInteger.get(interp, interp.getResult());
1373: }
1374:
1375: // This implementation avoids a runtime branch operation
1376: // by assuming that the compiler knows that both operands
1377: // are ExprValues that contain an int.
1378:
1379: void InternalExprOpIntInlinedPlusNBStackValueIntResult(Interp interp)
1380: throws TclException {
1381: // expr {1 + 2}
1382:
1383: ExprValue evs0 = TJC.exprGetValue(interp);
1384: ExprValue evs1 = TJC.exprGetValue(interp);
1385:
1386: for (int i = 0; i < 5000; i++) {
1387: ExprValue tmp0 = evs0;
1388: tmp0.setIntValue(1);
1389: ExprValue tmp1 = evs1;
1390: tmp1.setIntValue(2);
1391: tmp0.optIntPlus(tmp1);
1392: interp.setResult(tmp0.getIntValue());
1393: }
1394: RESULT_INT = TclInteger.get(interp, interp.getResult());
1395: }
1396:
1397: // This implementation executes the int plus operation
1398: // with two immediate int operands and then assigns the
1399: // value to an ExprValue.
1400:
1401: void InternalExprOpIntInlinedPlusIMStackValueIntResult(Interp interp)
1402: throws TclException {
1403: // expr {1 + 2}
1404:
1405: ExprValue evs0 = TJC.exprGetValue(interp);
1406:
1407: for (int i = 0; i < 5000; i++) {
1408: ExprValue tmp0 = evs0;
1409: tmp0.setIntValue(1 + 2);
1410: interp.setResult(tmp0.getIntValue());
1411: }
1412: RESULT_INT = TclInteger.get(interp, interp.getResult());
1413: }
1414:
1415: // This implementation saves the plus operator result into
1416: // an int local and then sets the interp result to that
1417: // value. This assumes that the compiler is smart enough
1418: // to declare an int and use it in the calculation instead
1419: // of using an ExprValue.
1420:
1421: void InternalExprOpIntInlinedPlusIMRStackValueIntResult(
1422: Interp interp) throws TclException {
1423: // expr {1 + 2}
1424:
1425: for (int i = 0; i < 5000; i++) {
1426: int tmp0 = 1 + 2;
1427: interp.setResult(tmp0);
1428: }
1429: RESULT_INT = TclInteger.get(interp, interp.getResult());
1430: }
1431:
1432: // Invoke binary + operator on a TclDouble.
1433: // This tests the execution time for just the
1434: // Expression.evalBinaryOperator() API.
1435:
1436: void InternalExprOpDoublePlus(Interp interp) throws TclException {
1437: ExprValue value1 = new ExprValue(1.0, null);
1438: ExprValue value2 = new ExprValue(2.0, null);
1439:
1440: for (int i = 0; i < 5000; i++) {
1441: Expression.evalBinaryOperator(interp, TJC.EXPR_OP_PLUS,
1442: value1, value2);
1443: }
1444: RESULT_INT = (int) value1.getDoubleValue();
1445: }
1446:
1447: // This logic is currently emitted with +inline-expr
1448: // for a logical || operator. It makes use of two
1449: // ExprValues on the stack.
1450:
1451: void InternalExprOpLogicalOrResult(Interp interp)
1452: throws TclException {
1453: // expr {0 || 1}
1454:
1455: ExprValue evs0 = TJC.exprGetValue(interp);
1456: ExprValue evs1 = TJC.exprGetValue(interp);
1457:
1458: for (int i = 0; i < 5000; i++) {
1459: ExprValue tmp0 = evs0;
1460: tmp0.setIntValue(0);
1461: if (!tmp0.getBooleanValue(interp)) {
1462: ExprValue tmp1 = evs1;
1463: tmp1.setIntValue(1);
1464: tmp0.setIntValue(tmp1.getBooleanValue(interp));
1465: } else {
1466: tmp0.setIntValue(1);
1467: } // End if: !0
1468: TJC.exprSetResult(interp, tmp0);
1469: }
1470: RESULT_INT = TclInteger.get(interp, interp.getResult());
1471: }
1472:
1473: // This implementation will use a boolean value
1474: // on the stack. A second ExprValue will not
1475: // be needed and the result will be set as a boolean.
1476:
1477: void InternalExprOpInlinedLogicalOrResult(Interp interp)
1478: throws TclException {
1479: // expr {0 || 1}
1480:
1481: ExprValue evs0 = TJC.exprGetValue(interp);
1482:
1483: for (int i = 0; i < 5000; i++) {
1484: boolean tmp0;
1485: ExprValue tmp1 = evs0;
1486: tmp1.setIntValue(0);
1487: tmp0 = tmp1.getBooleanValue(interp);
1488: if (!tmp0) {
1489: ExprValue tmp2 = evs0;
1490: tmp2.setIntValue(1);
1491: tmp0 = tmp2.getBooleanValue(interp);
1492: }
1493: interp.setResult(tmp0);
1494: }
1495: RESULT_INT = TclInteger.get(interp, interp.getResult());
1496: }
1497:
1498: // If an operand is known to be of type int, an inlined
1499: // boolean condition check can be used.
1500:
1501: void InternalExprOpInlinedIntLogicalOrResult(Interp interp)
1502: throws TclException {
1503: // expr {0 || 1}
1504:
1505: ExprValue evs0 = TJC.exprGetValue(interp);
1506:
1507: for (int i = 0; i < 5000; i++) {
1508: boolean tmp0;
1509: ExprValue tmp1 = evs0;
1510: tmp1.setIntValue(0);
1511: tmp0 = (tmp1.getIntValue() != 0);
1512: if (!tmp0) {
1513: ExprValue tmp2 = evs0;
1514: tmp2.setIntValue(1);
1515: tmp0 = (tmp2.getIntValue() != 0);
1516: }
1517: interp.setResult(tmp0);
1518: }
1519: RESULT_INT = TclInteger.get(interp, interp.getResult());
1520: }
1521:
1522: // If an operand is known to be of type int and the
1523: // expr module is able to pass around an int value
1524: // already declared on the stack, then no ExprValue
1525: // would be needed for the || operator.
1526:
1527: void InternalExprOpInlinedNoExprLogicalOrResult(Interp interp)
1528: throws TclException {
1529: // expr {0 || 1}
1530:
1531: for (int i = 0; i < 5000; i++) {
1532: boolean tmp0;
1533: int value;
1534: value = 0;
1535: tmp0 = (value != 0);
1536: if (!tmp0) {
1537: value = 1;
1538: tmp0 = (value != 0);
1539: }
1540: interp.setResult(tmp0);
1541: }
1542: RESULT_INT = TclInteger.get(interp, interp.getResult());
1543: }
1544:
1545: // This method will grab an objv array and fill it
1546: // with values over and over again. This logic
1547: // is executed when invoking a command.
1548:
1549: void InternalObjvInvoke(Interp interp) throws TclException {
1550: // objv[0]
1551: TclObject const0 = TclString.newInstance("cmd");
1552: // objv[1]
1553: TclObject var1 = TclString.newInstance("value1");
1554: var1.preserve();
1555: // objv[2]
1556: TclObject const1 = TclString.newInstance("const1");
1557: // objv[3]
1558: TclObject var2 = TclString.newInstance("value2");
1559: var2.preserve();
1560:
1561: for (int i = 0; i < 5000; i++) {
1562: TclObject[] objv0 = TJC.grabObjv(interp, 4);
1563: TclObject tmp1;
1564: try {
1565: // Arg 0 constant: cmd
1566: objv0[0] = const0;
1567: // Arg 1 variable:
1568: tmp1 = var1;
1569: tmp1.preserve();
1570: objv0[1] = tmp1;
1571: // Arg 2 constant:
1572: objv0[2] = const1;
1573: // Arg 3 variable:
1574: tmp1 = var2;
1575: tmp1.preserve();
1576: objv0[3] = tmp1;
1577:
1578: //TJC.invoke(interp, null, objv0, 0);
1579: RESULT_OBJ = objv0;
1580: } finally {
1581: tmp1 = objv0[1];
1582: if (tmp1 != null) {
1583: tmp1.release();
1584: }
1585: tmp1 = objv0[3];
1586: if (tmp1 != null) {
1587: tmp1.release();
1588: }
1589: TJC.releaseObjv(interp, objv0, 4);
1590: }
1591: }
1592: }
1593:
1594: // This optimized version of InternalObjvInvoke
1595: // will use a TclObject[] saves on the stack
1596: // much like ExprValue object are reused.
1597: // This method will also inline logic to
1598: // null out each element in the array.
1599:
1600: void InternalObjvInvokeOnStack(Interp interp) throws TclException {
1601: // Array ref saved in a local var, each
1602: // element is known to be null.
1603: TclObject[] objvOnStack = TJC.grabObjv(interp, 4);
1604:
1605: // objv[0]
1606: TclObject const0 = TclString.newInstance("cmd");
1607: // objv[1]
1608: TclObject var1 = TclString.newInstance("value1");
1609: var1.preserve();
1610: // objv[2]
1611: TclObject const1 = TclString.newInstance("const1");
1612: // objv[3]
1613: TclObject var2 = TclString.newInstance("value2");
1614: var2.preserve();
1615:
1616: for (int i = 0; i < 5000; i++) {
1617: TclObject[] objv0 = objvOnStack;
1618: TclObject tmp1;
1619: try {
1620: // Arg 0 constant: cmd
1621: objv0[0] = const0;
1622: // Arg 1 variable:
1623: tmp1 = var1;
1624: tmp1.preserve();
1625: objv0[1] = tmp1;
1626: // Arg 2 constant:
1627: objv0[2] = const1;
1628: // Arg 3 variable:
1629: tmp1 = var2;
1630: tmp1.preserve();
1631: objv0[3] = tmp1;
1632:
1633: //TJC.invoke(interp, null, objv0, 0);
1634: RESULT_OBJ = objv0;
1635: } finally {
1636: objv0[0] = null;
1637: tmp1 = objv0[1];
1638: if (tmp1 != null) {
1639: tmp1.release();
1640: }
1641: objv0[1] = null;
1642: objv0[2] = null;
1643: tmp1 = objv0[3];
1644: if (tmp1 != null) {
1645: tmp1.release();
1646: }
1647: objv0[3] = null;
1648: }
1649: }
1650:
1651: TJC.releaseObjv(interp, objvOnStack, 4);
1652: }
1653:
1654: // This optimized version will save the
1655: // objv array on the stack and also
1656: // use logic to determine when all
1657: // arguments were assigned.
1658:
1659: void InternalObjvInvokeOnStackAssigned(Interp interp)
1660: throws TclException {
1661: // Array ref saved in a local var, each
1662: // element is known to be null.
1663: TclObject[] objvOnStack = TJC.grabObjv(interp, 4);
1664:
1665: // objv[0]
1666: TclObject const0 = TclString.newInstance("cmd");
1667: // objv[1]
1668: TclObject var1 = TclString.newInstance("value1");
1669: var1.preserve();
1670: // objv[2]
1671: TclObject const1 = TclString.newInstance("const1");
1672: // objv[3]
1673: TclObject var2 = TclString.newInstance("value2");
1674: var2.preserve();
1675:
1676: // Dummy ref
1677: TclObject ASSIGNED = TclString.newInstance("");
1678:
1679: for (int i = 0; i < 5000; i++) {
1680: TclObject[] objv0 = objvOnStack;
1681: TclObject tmp1 = null;
1682: try {
1683: // Arg 0 constant: cmd
1684: objv0[0] = const0;
1685: // Arg 1 variable:
1686: tmp1 = var1;
1687: tmp1.preserve();
1688: objv0[1] = tmp1;
1689: // Arg 2 constant:
1690: objv0[2] = const1;
1691: // Arg 3 variable:
1692: tmp1 = var2;
1693: tmp1.preserve();
1694: objv0[3] = tmp1;
1695:
1696: tmp1 = ASSIGNED;
1697: //TJC.invoke(interp, null, objv0, 0);
1698: RESULT_OBJ = objv0;
1699: } finally {
1700: objv0[0] = null;
1701: objv0[2] = null;
1702:
1703: if (tmp1 != ASSIGNED) {
1704: // Exception before all arguments
1705: // were assigned. This could also
1706: // be a generic method invocation
1707: // that for loops over the array
1708: // instead of emitting this code.
1709: tmp1 = objv0[1];
1710: if (tmp1 != null) {
1711: tmp1.release();
1712: }
1713: objv0[1] = null;
1714: tmp1 = objv0[3];
1715: if (tmp1 != null) {
1716: tmp1.release();
1717: }
1718: objv0[3] = null;
1719: } else {
1720: // No exception, we can be sure
1721: // that all non-const elements
1722: // were assigned values. Just
1723: // need to release the ones
1724: // that were preserved and null
1725: // the slots.
1726: objv0[1].release();
1727: objv0[1] = null;
1728: objv0[3].release();
1729: objv0[3] = null;
1730: }
1731: }
1732: }
1733:
1734: TJC.releaseObjv(interp, objvOnStack, 4);
1735: }
1736:
1737: // This optimized version will maintain an
1738: // int index indicating how many arguments
1739: // were assigned. In this way, only the
1740: // values that were changed will get
1741: // released in the exception case. If
1742: // all arguments are assigned, then the
1743: // ones that need it will be released and
1744: // the array elements will not be reset to
1745: // null in the loop.
1746:
1747: void InternalObjvInvokeOnStackAssignedIndex(Interp interp)
1748: throws TclException {
1749: // Array ref saved in a local var, each
1750: // element is known to be null.
1751: TclObject[] objvOnStack = TJC.grabObjv(interp, 4);
1752:
1753: // objv[0]
1754: TclObject const0 = TclString.newInstance("cmd");
1755: // objv[1]
1756: TclObject var1 = TclString.newInstance("value1");
1757: var1.preserve();
1758: // objv[2]
1759: TclObject const1 = TclString.newInstance("const1");
1760: // objv[3]
1761: TclObject var2 = TclString.newInstance("value2");
1762: var2.preserve();
1763:
1764: // Dummy ref
1765: TclObject ASSIGNED = TclString.newInstance("");
1766:
1767: for (int i = 0; i < 5000; i++) {
1768: TclObject[] objv0 = objvOnStack;
1769: TclObject tmp1;
1770: int assignedIndex = -1;
1771:
1772: try {
1773: // Arg 0 constant: cmd
1774: objv0[0] = const0;
1775: assignedIndex = 0;
1776: // Arg 1 variable:
1777: tmp1 = var1;
1778: tmp1.preserve();
1779: objv0[1] = tmp1;
1780: assignedIndex = 1;
1781: // Arg 2 constant:
1782: objv0[2] = const1;
1783: assignedIndex = 2;
1784: // Arg 3 variable:
1785: tmp1 = var2;
1786: tmp1.preserve();
1787: objv0[3] = tmp1;
1788: assignedIndex = 3;
1789:
1790: //TJC.invoke(interp, null, objv0, 0);
1791: RESULT_OBJ = objv0;
1792: } finally {
1793: if (assignedIndex < 3) {
1794: // Exception before all arguments
1795: // were assigned.
1796:
1797: objv0[0] = null;
1798: objv0[2] = null;
1799:
1800: for (int j = 0; j <= assignedIndex; j++) {
1801: tmp1 = objv0[j];
1802: if (tmp1 != null) {
1803: tmp1.release();
1804: }
1805: }
1806: } else {
1807: // No exception, all arguments assigned.
1808: objv0[1].release();
1809: objv0[3].release();
1810: }
1811: }
1812: }
1813:
1814: // This invocation will reset all the
1815: // elements to null.
1816: TJC.releaseObjv(interp, objvOnStack, 4);
1817: }
1818:
1819: // This optimized version will store TclObject
1820: // pointers for incremented refrences on the
1821: // stack. This seems to be the optimal implementation,
1822: // putting values on the stack is not a big deal
1823: // and it means we can skip nulling the array
1824: // values in the loop body.
1825:
1826: void InternalObjvInvokeOnStackStack(Interp interp)
1827: throws TclException {
1828: // Array ref saved in a local var, each
1829: // element is known to be null.
1830: TclObject[] objv0 = TJC.grabObjv(interp, 4);
1831:
1832: // objv[0]
1833: TclObject const0 = TclString.newInstance("cmd");
1834: // objv[1]
1835: TclObject var1 = TclString.newInstance("value1");
1836: var1.preserve();
1837: // objv[2]
1838: TclObject const1 = TclString.newInstance("const1");
1839: // objv[3]
1840: TclObject var2 = TclString.newInstance("value2");
1841: var2.preserve();
1842:
1843: for (int i = 0; i < 5000; i++) {
1844: TclObject tmp1 = null;
1845: TclObject tmp2 = null;
1846:
1847: try {
1848: // Arg 0 constant: cmd
1849: objv0[0] = const0;
1850: // Arg 1 variable:
1851: tmp1 = var1;
1852: tmp1.preserve();
1853: objv0[1] = tmp1;
1854: // Arg 2 constant:
1855: objv0[2] = const1;
1856: // Arg 3 variable:
1857: tmp2 = var2;
1858: tmp2.preserve();
1859: objv0[3] = tmp2;
1860:
1861: //TJC.invoke(interp, null, objv0, 0);
1862: RESULT_OBJ = objv0;
1863: } finally {
1864: if (tmp1 != null) {
1865: tmp1.release();
1866: }
1867: if (tmp2 != null) {
1868: tmp2.release();
1869: }
1870: }
1871: }
1872:
1873: // This invocation will reset all the
1874: // elements to null.
1875: TJC.releaseObjv(interp, objv0, 4);
1876: }
1877:
1878: // Split into two try blocks. One for the arguments
1879: // and one for the command itself. This approach
1880: // is not much faster and it would be very complex
1881: // in the generator layer.
1882:
1883: void InternalObjvInvokeOnStackTryStack(Interp interp)
1884: throws TclException {
1885: // Array ref saved in a local var, each
1886: // element is known to be null.
1887: TclObject[] objv0 = TJC.grabObjv(interp, 4);
1888:
1889: // objv[0]
1890: TclObject const0 = TclString.newInstance("cmd");
1891: // objv[1]
1892: TclObject var1 = TclString.newInstance("value1");
1893: var1.preserve();
1894: // objv[2]
1895: TclObject const1 = TclString.newInstance("const1");
1896: // objv[3]
1897: TclObject var2 = TclString.newInstance("value2");
1898: var2.preserve();
1899:
1900: for (int i = 0; i < 5000; i++) {
1901: TclObject tmp1 = null;
1902: TclObject tmp2 = null;
1903:
1904: try {
1905: // Arg 0 constant: cmd
1906: objv0[0] = const0;
1907: // Arg 1 variable:
1908: tmp1 = var1;
1909: tmp1.preserve();
1910: objv0[1] = tmp1;
1911: // Arg 2 constant:
1912: objv0[2] = const1;
1913: // Arg 3 variable:
1914: tmp2 = var2;
1915: tmp2.preserve();
1916: objv0[3] = tmp2;
1917: } finally {
1918: if (tmp2 == null) {
1919: // Not all arguments were assigned, so
1920: // exception must have been raised.
1921: if (tmp1 != null) {
1922: tmp1.release();
1923: }
1924: }
1925: }
1926:
1927: try {
1928: // If the code makes it to here, then
1929: // all arguments must have been assigned
1930:
1931: //TJC.invoke(interp, null, objv0, 0);
1932: RESULT_OBJ = objv0;
1933: } finally {
1934: tmp1.release();
1935: tmp2.release();
1936: }
1937: }
1938:
1939: // This invocation will reset all the
1940: // elements to null.
1941: TJC.releaseObjv(interp, objv0, 4);
1942: }
1943:
1944: } // end class TJCBench
|