Changeset 34258 in webkit for trunk/JavaScriptCore/VM/Machine.cpp


Ignore:
Timestamp:
May 30, 2008, 2:10:42 AM (17 years ago)
Author:
[email protected]
Message:

Reviewed by Oliver Hunt.

https://bugs.webkit.org/show_bug.cgi?id=19180
speed up SunSpider by optimizing immediate number cases

Also fixed three JavaScriptCore regressions seen on PowerPC - we didn't clip right shift
parameter to 0...31.

1.6% improvement on SunSpider, without significant regressions on any tests.

  • VM/Machine.cpp: (KJS::Machine::privateExecute): Added fast paths for >>, ==, ===, !=, !==. Changed order of memory accesses in many cases, making them less dependent on gcc's ability to properly assign registers. With this, I could move exception checks back into slow code paths, and saw less randomness in general.
  • kjs/JSImmediate.h: (KJS::JSImmediate::rightShiftImmediateNumbers): Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/VM/Machine.cpp

    r34182 r34258  
    988988           as a boolean in register dst.
    989989        */
    990         int dst = (++vPC)->u.operand;
    991         int src1 = (++vPC)->u.operand;
    992         int src2 = (++vPC)->u.operand;
    993         JSValue* result = jsBoolean(equal(exec, r[src1].u.jsValue, r[src2].u.jsValue));
    994         VM_CHECK_EXCEPTION();
    995         r[dst].u.jsValue = result;
     990        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     991        JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
     992        JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
     993        JSValue* result;
     994        if (JSImmediate::areBothImmediateNumbers(src1, src2))
     995            result = jsBoolean(reinterpret_cast<intptr_t>(src1) == reinterpret_cast<intptr_t>(src2));
     996        else {
     997            result = jsBoolean(equal(exec, src1, src2));
     998            VM_CHECK_EXCEPTION();
     999        }
     1000        dst = result;
    9961001
    9971002        ++vPC;
     
    10051010           result as a boolean in register dst.
    10061011        */
    1007         int dst = (++vPC)->u.operand;
    1008         int src1 = (++vPC)->u.operand;
    1009         int src2 = (++vPC)->u.operand;
    1010         JSValue* result = jsBoolean(!equal(exec, r[src1].u.jsValue, r[src2].u.jsValue));
    1011         VM_CHECK_EXCEPTION();
    1012         r[dst].u.jsValue = result;
     1012        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1013        JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
     1014        JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
     1015        JSValue* result;
     1016        if (JSImmediate::areBothImmediateNumbers(src1, src2))
     1017            result = jsBoolean(reinterpret_cast<intptr_t>(src1) != reinterpret_cast<intptr_t>(src2));
     1018        else {
     1019            result = jsBoolean(!equal(exec, src1, src2));
     1020            VM_CHECK_EXCEPTION();
     1021        }
     1022        dst = result;
    10131023
    10141024        ++vPC;
     
    10221032           result as a boolean in register dst.
    10231033        */
    1024         int dst = (++vPC)->u.operand;
    1025         int src1 = (++vPC)->u.operand;
    1026         int src2 = (++vPC)->u.operand;
    1027         r[dst].u.jsValue = jsBoolean(strictEqual(r[src1].u.jsValue, r[src2].u.jsValue));
     1034        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1035        JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
     1036        JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
     1037        if (JSImmediate::areBothImmediateNumbers(src1, src2))
     1038            dst = jsBoolean(reinterpret_cast<intptr_t>(src1) == reinterpret_cast<intptr_t>(src2));
     1039        else
     1040            dst = jsBoolean(strictEqual(src1, src2));
    10281041       
    10291042        ++vPC;
     
    10371050           puts the result as a boolean in register dst.
    10381051        */
    1039         int dst = (++vPC)->u.operand;
    1040         int src1 = (++vPC)->u.operand;
    1041         int src2 = (++vPC)->u.operand;
    1042         r[dst].u.jsValue = jsBoolean(!strictEqual(r[src1].u.jsValue, r[src2].u.jsValue));
     1052        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1053        JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
     1054        JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
     1055        if (JSImmediate::areBothImmediateNumbers(src1, src2))
     1056            dst = jsBoolean(reinterpret_cast<intptr_t>(src1) != reinterpret_cast<intptr_t>(src2));
     1057        else
     1058            dst = jsBoolean(!strictEqual(src1, src2));
    10431059
    10441060        ++vPC;
     
    10521068           a boolean in register dst.
    10531069        */
    1054         int dst = (++vPC)->u.operand;
    1055         int src1 = (++vPC)->u.operand;
    1056         int src2 = (++vPC)->u.operand;
    1057         JSValue* result = jsBoolean(jsLess(exec, r[src1].u.jsValue, r[src2].u.jsValue));
     1070        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1071        JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
     1072        JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
     1073        JSValue* result = jsBoolean(jsLess(exec, src1, src2));
    10581074        VM_CHECK_EXCEPTION();
    1059         r[dst].u.jsValue = result;
     1075        dst = result;
    10601076
    10611077        ++vPC;
     
    10691085           puts the result as a boolean in register dst.
    10701086        */
    1071         int dst = (++vPC)->u.operand;
    1072         int src1 = (++vPC)->u.operand;
    1073         int src2 = (++vPC)->u.operand;
    1074         JSValue* result = jsBoolean(jsLessEq(exec, r[src1].u.jsValue, r[src2].u.jsValue));
     1087        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1088        JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
     1089        JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
     1090        JSValue* result = jsBoolean(jsLessEq(exec, src1, src2));
    10751091        VM_CHECK_EXCEPTION();
    1076         r[dst].u.jsValue = result;
     1092        dst = result;
    10771093
    10781094        ++vPC;
     
    12091225           numeric add, depending on the types of the operands.)
    12101226        */
    1211         int dst = (++vPC)->u.operand;
    1212         int src1 = (++vPC)->u.operand;
    1213         int src2 = (++vPC)->u.operand;
    1214         JSValue* v1 = r[src1].u.jsValue;
    1215         JSValue* v2 = r[src2].u.jsValue;
     1227        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1228        JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
     1229        JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
    12161230        JSValue* result;
    1217         if (JSImmediate::canDoFastAdditiveOperations(v1) && JSImmediate::canDoFastAdditiveOperations(v2))
    1218             result = JSImmediate::addImmediateNumbers(v1, v2);
    1219         else
    1220             result = jsAdd(exec, v1, v2);
    1221         VM_CHECK_EXCEPTION();
    1222         r[dst].u.jsValue = result;
     1231        if (JSImmediate::canDoFastAdditiveOperations(src1) && JSImmediate::canDoFastAdditiveOperations(src2))
     1232            result = JSImmediate::addImmediateNumbers(src1, src2);
     1233        else {
     1234            result = jsAdd(exec, src1, src2);
     1235            VM_CHECK_EXCEPTION();
     1236        }
     1237        dst = result;
    12231238        ++vPC;
    12241239        NEXT_OPCODE;
     
    12301245           numbers), and puts the product in register dst.
    12311246        */
    1232         int dst = (++vPC)->u.operand;
    1233         int src1 = (++vPC)->u.operand;
    1234         int src2 = (++vPC)->u.operand;
    1235         JSValue* result = jsNumber(r[src1].u.jsValue->toNumber(exec) * r[src2].u.jsValue->toNumber(exec));
     1247        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1248        JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
     1249        JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
     1250        JSValue* result = jsNumber(src1->toNumber(exec) * src2->toNumber(exec));
    12361251        VM_CHECK_EXCEPTION();
    1237         r[dst].u.jsValue = result;
     1252        dst = result;
    12381253
    12391254        ++vPC;
     
    12801295           register dst.
    12811296        */
    1282         int dst = (++vPC)->u.operand;
    1283         int src1 = (++vPC)->u.operand;
    1284         int src2 = (++vPC)->u.operand;
    1285         JSValue* v1 = r[src1].u.jsValue;
    1286         JSValue* v2 = r[src2].u.jsValue;
     1297        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1298        JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
     1299        JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
    12871300        JSValue* result;
    1288         if (JSImmediate::canDoFastAdditiveOperations(v1) && JSImmediate::canDoFastAdditiveOperations(v2))
    1289             result = JSImmediate::subImmediateNumbers(v1, v2);
    1290         else
    1291             result = jsNumber(v1->toNumber(exec) - v2->toNumber(exec));
    1292         VM_CHECK_EXCEPTION();
    1293         r[dst].u.jsValue = result;
     1301        if (JSImmediate::canDoFastAdditiveOperations(src1) && JSImmediate::canDoFastAdditiveOperations(src2))
     1302            result = JSImmediate::subImmediateNumbers(src1, src2);
     1303        else {
     1304            result = jsNumber(src1->toNumber(exec) - src2->toNumber(exec));
     1305            VM_CHECK_EXCEPTION();
     1306        }
     1307        dst = result;
    12941308        ++vPC;
    12951309        NEXT_OPCODE;
     
    13021316           in register dst.
    13031317        */
    1304         int dst = (++vPC)->u.operand;
    1305         int val = (++vPC)->u.operand;
    1306         int shift = (++vPC)->u.operand;
    1307         JSValue* result = jsNumber((r[val].u.jsValue->toInt32(exec)) << (r[shift].u.jsValue->toUInt32(exec)));
     1318        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1319        JSValue* val = r[(++vPC)->u.operand].u.jsValue;
     1320        JSValue* shift = r[(++vPC)->u.operand].u.jsValue;
     1321        JSValue* result = jsNumber((val->toInt32(exec)) << (shift->toUInt32(exec)));
    13081322        VM_CHECK_EXCEPTION();
    1309         r[dst].u.jsValue = result;
     1323        dst = result;
    13101324       
    13111325        ++vPC;
     
    13191333           uint32), and puts the result in register dst.
    13201334        */
    1321         int dst = (++vPC)->u.operand;
    1322         int val = (++vPC)->u.operand;
    1323         int shift = (++vPC)->u.operand;
    1324         JSValue* result = jsNumber((r[val].u.jsValue->toInt32(exec)) >> (r[shift].u.jsValue->toUInt32(exec)));
    1325         VM_CHECK_EXCEPTION();
    1326         r[dst].u.jsValue = result;
     1335        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1336        JSValue* val = r[(++vPC)->u.operand].u.jsValue;
     1337        JSValue* shift = r[(++vPC)->u.operand].u.jsValue;
     1338        JSValue* result;
     1339        if (JSImmediate::areBothImmediateNumbers(val, shift))
     1340            result = JSImmediate::rightShiftImmediateNumbers(val, shift);
     1341        else {
     1342            result = jsNumber((val->toInt32(exec)) >> (shift->toUInt32(exec) & 0x1f));
     1343            VM_CHECK_EXCEPTION();
     1344        }
     1345        dst = result;
    13271346       
    13281347        ++vPC;
     
    13361355           uint32), and puts the result in register dst.
    13371356        */
    1338         int dst = (++vPC)->u.operand;
    1339         int val = (++vPC)->u.operand;
    1340         int shift = (++vPC)->u.operand;
    1341         JSValue* result = jsNumber((r[val].u.jsValue->toUInt32(exec)) >> (r[shift].u.jsValue->toUInt32(exec)));
     1357        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1358        JSValue* val = r[(++vPC)->u.operand].u.jsValue;
     1359        JSValue* shift = r[(++vPC)->u.operand].u.jsValue;
     1360        JSValue* result;
     1361        result = jsNumber((val->toUInt32(exec)) >> (shift->toUInt32(exec) & 0x1f));
    13421362        VM_CHECK_EXCEPTION();
    1343         r[dst].u.jsValue = result;
     1363        dst = result;
    13441364       
    13451365        ++vPC;
     
    13531373           in register dst.
    13541374        */
    1355         int dst = (++vPC)->u.operand;
    1356         int src1 = (++vPC)->u.operand;
    1357         int src2 = (++vPC)->u.operand;
    1358         JSValue* v1 = r[src1].u.jsValue;
    1359         JSValue* v2 = r[src2].u.jsValue;
     1375        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1376        JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
     1377        JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
    13601378        JSValue* result;
    1361         if (JSImmediate::areBothImmediateNumbers(v1, v2))
    1362             result = JSImmediate::andImmediateNumbers(v1, v2);
     1379        if (JSImmediate::areBothImmediateNumbers(src1, src2))
     1380            result = JSImmediate::andImmediateNumbers(src1, src2);
    13631381        else {
    1364             result = jsNumber(v1->toInt32(exec) & v2->toInt32(exec));
     1382            result = jsNumber(src1->toInt32(exec) & src2->toInt32(exec));
    13651383            VM_CHECK_EXCEPTION();
    13661384        }
    1367         r[dst].u.jsValue = result;
     1385        dst = result;
    13681386       
    13691387        ++vPC;
     
    13771395           in register dst.
    13781396        */
    1379         int dst = (++vPC)->u.operand;
    1380         int src1 = (++vPC)->u.operand;
    1381         int src2 = (++vPC)->u.operand;
    1382         JSValue* v1 = r[src1].u.jsValue;
    1383         JSValue* v2 = r[src2].u.jsValue;
     1397        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1398        JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
     1399        JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
    13841400        JSValue* result;
    1385         if (JSImmediate::areBothImmediateNumbers(v1, v2))
    1386             result = JSImmediate::xorImmediateNumbers(v1, v2);
     1401        if (JSImmediate::areBothImmediateNumbers(src1, src2))
     1402            result = JSImmediate::xorImmediateNumbers(src1, src2);
    13871403        else {
    1388             result = jsNumber(v1->toInt32(exec) ^ v2->toInt32(exec));
     1404            result = jsNumber(src1->toInt32(exec) ^ src2->toInt32(exec));
    13891405            VM_CHECK_EXCEPTION();
    13901406        }
    1391         r[dst].u.jsValue = result;
     1407        dst = result;
    13921408       
    13931409        ++vPC;
     
    14011417           result in register dst.
    14021418        */
    1403         int dst = (++vPC)->u.operand;
    1404         int src1 = (++vPC)->u.operand;
    1405         int src2 = (++vPC)->u.operand;
    1406         JSValue* v1 = r[src1].u.jsValue;
    1407         JSValue* v2 = r[src2].u.jsValue;
     1419        JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
     1420        JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
     1421        JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
    14081422        JSValue* result;
    1409         if (JSImmediate::areBothImmediateNumbers(v1, v2))
    1410             result = JSImmediate::orImmediateNumbers(v1, v2);
     1423        if (JSImmediate::areBothImmediateNumbers(src1, src2))
     1424            result = JSImmediate::orImmediateNumbers(src1, src2);
    14111425        else {
    1412             result = jsNumber(v1->toInt32(exec) | v2->toInt32(exec));
     1426            result = jsNumber(src1->toInt32(exec) | src2->toInt32(exec));
    14131427            VM_CHECK_EXCEPTION();
    14141428        }
    1415         r[dst].u.jsValue = result;
     1429        dst = result;
    14161430       
    14171431        ++vPC;
Note: See TracChangeset for help on using the changeset viewer.