Changeset 37891 in webkit for trunk/JavaScriptCore/VM
- Timestamp:
- Oct 25, 2008, 12:59:47 PM (17 years ago)
- Location:
- trunk/JavaScriptCore/VM
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/VM/CTI.cpp
r37888 r37891 35 35 #include "wrec/WREC.h" 36 36 #include "ResultType.h" 37 #include "SamplingTool.h" 37 38 38 39 #ifndef NDEBUG … … 262 263 // FIXME: #ifndef NDEBUG, Write the correct m_type to the register. 263 264 } 264 265 #if ENABLE(SAMPLING_TOOL)266 unsigned inCalledCode = 0;267 #endif268 265 269 266 void ctiSetReturnAddress(void** where, void* what) … … 330 327 } 331 328 332 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(unsigned opcodeIndex, CTIHelper_j helper) 333 { 334 #if ENABLE(SAMPLING_TOOL) 335 m_jit.movl_i32m(1, &inCalledCode); 329 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_j helper) 330 { 331 #if ENABLE(OPCODE_SAMPLING) 332 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot()); 333 #else 334 UNUSED_PARAM(vPC); 336 335 #endif 337 336 m_jit.emitRestoreArgumentReference(); … … 339 338 X86Assembler::JmpSrc call = m_jit.emitCall(); 340 339 m_calls.append(CallRecord(call, helper, opcodeIndex)); 341 #if ENABLE( SAMPLING_TOOL)342 m_jit.movl_i32m( 0, &inCalledCode);340 #if ENABLE(OPCODE_SAMPLING) 341 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot()); 343 342 #endif 344 343 … … 346 345 } 347 346 348 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(unsigned opcodeIndex, CTIHelper_o helper) 349 { 350 #if ENABLE(SAMPLING_TOOL) 351 m_jit.movl_i32m(1, &inCalledCode); 347 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_o helper) 348 { 349 #if ENABLE(OPCODE_SAMPLING) 350 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot()); 351 #else 352 UNUSED_PARAM(vPC); 352 353 #endif 353 354 m_jit.emitRestoreArgumentReference(); … … 355 356 X86Assembler::JmpSrc call = m_jit.emitCall(); 356 357 m_calls.append(CallRecord(call, helper, opcodeIndex)); 357 #if ENABLE( SAMPLING_TOOL)358 m_jit.movl_i32m( 0, &inCalledCode);358 #if ENABLE(OPCODE_SAMPLING) 359 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot()); 359 360 #endif 360 361 … … 362 363 } 363 364 364 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(unsigned opcodeIndex, CTIHelper_p helper) 365 { 366 #if ENABLE(SAMPLING_TOOL) 367 m_jit.movl_i32m(1, &inCalledCode); 365 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_p helper) 366 { 367 #if ENABLE(OPCODE_SAMPLING) 368 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot()); 369 #else 370 UNUSED_PARAM(vPC); 368 371 #endif 369 372 m_jit.emitRestoreArgumentReference(); … … 371 374 X86Assembler::JmpSrc call = m_jit.emitCall(); 372 375 m_calls.append(CallRecord(call, helper, opcodeIndex)); 373 #if ENABLE( SAMPLING_TOOL)374 m_jit.movl_i32m( 0, &inCalledCode);376 #if ENABLE(OPCODE_SAMPLING) 377 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot()); 375 378 #endif 376 379 … … 378 381 } 379 382 380 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(unsigned opcodeIndex, CTIHelper_b helper) 381 { 382 #if ENABLE(SAMPLING_TOOL) 383 m_jit.movl_i32m(1, &inCalledCode); 383 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_b helper) 384 { 385 #if ENABLE(OPCODE_SAMPLING) 386 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot()); 387 #else 388 UNUSED_PARAM(vPC); 384 389 #endif 385 390 m_jit.emitRestoreArgumentReference(); … … 387 392 X86Assembler::JmpSrc call = m_jit.emitCall(); 388 393 m_calls.append(CallRecord(call, helper, opcodeIndex)); 389 #if ENABLE( SAMPLING_TOOL)390 m_jit.movl_i32m( 0, &inCalledCode);394 #if ENABLE(OPCODE_SAMPLING) 395 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot()); 391 396 #endif 392 397 … … 394 399 } 395 400 396 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(unsigned opcodeIndex, CTIHelper_v helper) 397 { 398 #if ENABLE(SAMPLING_TOOL) 399 m_jit.movl_i32m(1, &inCalledCode); 401 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_v helper) 402 { 403 #if ENABLE(OPCODE_SAMPLING) 404 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot()); 405 #else 406 UNUSED_PARAM(vPC); 400 407 #endif 401 408 m_jit.emitRestoreArgumentReference(); … … 403 410 X86Assembler::JmpSrc call = m_jit.emitCall(); 404 411 m_calls.append(CallRecord(call, helper, opcodeIndex)); 405 #if ENABLE( SAMPLING_TOOL)406 m_jit.movl_i32m( 0, &inCalledCode);412 #if ENABLE(OPCODE_SAMPLING) 413 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot()); 407 414 #endif 408 415 … … 410 417 } 411 418 412 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(unsigned opcodeIndex, CTIHelper_s helper) 413 { 414 #if ENABLE(SAMPLING_TOOL) 415 m_jit.movl_i32m(1, &inCalledCode); 419 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_s helper) 420 { 421 #if ENABLE(OPCODE_SAMPLING) 422 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot()); 423 #else 424 UNUSED_PARAM(vPC); 416 425 #endif 417 426 m_jit.emitRestoreArgumentReference(); … … 419 428 X86Assembler::JmpSrc call = m_jit.emitCall(); 420 429 m_calls.append(CallRecord(call, helper, opcodeIndex)); 421 #if ENABLE( SAMPLING_TOOL)422 m_jit.movl_i32m( 0, &inCalledCode);430 #if ENABLE(OPCODE_SAMPLING) 431 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot()); 423 432 #endif 424 433 … … 426 435 } 427 436 428 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(unsigned opcodeIndex, CTIHelper_2 helper) 429 { 430 #if ENABLE(SAMPLING_TOOL) 431 m_jit.movl_i32m(1, &inCalledCode); 437 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_2 helper) 438 { 439 #if ENABLE(OPCODE_SAMPLING) 440 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot()); 441 #else 442 UNUSED_PARAM(vPC); 432 443 #endif 433 444 m_jit.emitRestoreArgumentReference(); … … 435 446 X86Assembler::JmpSrc call = m_jit.emitCall(); 436 447 m_calls.append(CallRecord(call, helper, opcodeIndex)); 437 #if ENABLE( SAMPLING_TOOL)438 m_jit.movl_i32m( 0, &inCalledCode);448 #if ENABLE(OPCODE_SAMPLING) 449 m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot()); 439 450 #endif 440 451 … … 527 538 emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); \ 528 539 emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); \ 529 emitCTICall(i , Machine::cti_##name); \540 emitCTICall(instruction + i, i, Machine::cti_##name); \ 530 541 emitPutResult(instruction[i + 1].u.operand); \ 531 542 i += 4; \ … … 536 547 case name: { \ 537 548 emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); \ 538 emitCTICall(i , Machine::cti_##name); \549 emitCTICall(instruction + i, i, Machine::cti_##name); \ 539 550 emitPutResult(instruction[i + 1].u.operand); \ 540 551 i += 3; \ 541 552 break; \ 542 553 } 543 544 #if ENABLE(SAMPLING_TOOL)545 OpcodeID currentOpcodeID = static_cast<OpcodeID>(-1);546 #endif547 554 548 555 static void unreachable() … … 582 589 } 583 590 584 void CTI::compileOpCall( Instruction* instruction, unsigned i, unsigned callLinkInfoIndex, CompileOpCallType type)591 void CTI::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned i, unsigned callLinkInfoIndex) 585 592 { 586 593 int dst = instruction[1].u.operand; … … 591 598 592 599 // Setup this value as the first argument (does not apply to constructors) 593 if ( type != OpConstruct) {600 if (opcodeID != op_construct) { 594 601 int thisVal = instruction[3].u.operand; 595 602 if (thisVal == missingThisObjectMarker()) { … … 604 611 // Handle eval 605 612 X86Assembler::JmpSrc wasEval; 606 if ( type == OpCallEval) {613 if (opcodeID == op_call_eval) { 607 614 emitGetArg(callee, X86::ecx); 608 615 compileOpCallSetupArgs(instruction, false, true); 609 616 610 emitCTICall(i , Machine::cti_op_call_eval);617 emitCTICall(instruction, i, Machine::cti_op_call_eval); 611 618 m_jit.cmpl_i32r(asInteger(JSImmediate::impossibleValue()), X86::eax); 612 619 wasEval = m_jit.emitUnlinkedJne(); … … 625 632 626 633 // In the case of OpConstruct, call oout to a cti_ function to create the new object. 627 if ( type == OpConstruct) {634 if (opcodeID == op_construct) { 628 635 emitPutArg(X86::ecx, 0); 629 636 emitGetPutArg(instruction[3].u.operand, 4, X86::eax); 630 emitCTICall(i , Machine::cti_op_construct_JSConstructFast);637 emitCTICall(instruction, i, Machine::cti_op_construct_JSConstructFast); 631 638 emitPutResult(instruction[4].u.operand); 632 639 emitGetArg(callee, X86::ecx); … … 646 653 m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(i, unreachable); 647 654 648 if ( type == OpCallEval)655 if (opcodeID == op_call_eval) 649 656 m_jit.link(wasEval, m_jit.label()); 650 657 651 658 // Put the return value in dst. In the interpreter, op_ret does this. 652 659 emitPutResult(dst); 660 661 #if ENABLE(CODEBLOCK_SAMPLING) 662 m_jit.movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_machine->sampler()->codeBlockSlot()); 663 #endif 653 664 } 654 665 … … 709 720 } 710 721 711 void CTI::emitSlowScriptCheck( unsigned opcodeIndex)722 void CTI::emitSlowScriptCheck(Instruction* vPC, unsigned opcodeIndex) 712 723 { 713 724 m_jit.subl_i8r(1, X86::esi); 714 725 X86Assembler::JmpSrc skipTimeout = m_jit.emitUnlinkedJne(); 715 emitCTICall( opcodeIndex, Machine::cti_timeout_check);726 emitCTICall(vPC, opcodeIndex, Machine::cti_timeout_check); 716 727 717 728 emitGetCTIParam(CTI_ARGS_globalData, X86::ecx); … … 906 917 } 907 918 908 void CTI::compileBinaryArithOpSlowCase( OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes types, unsigned i)919 void CTI::compileBinaryArithOpSlowCase(Instruction* vPC, OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes types, unsigned i) 909 920 { 910 921 X86Assembler::JmpDst here = m_jit.label(); … … 940 951 emitGetPutArg(src2, 4, X86::ecx); 941 952 if (opcodeID == op_add) 942 emitCTICall( i, Machine::cti_op_add);953 emitCTICall(vPC, i, Machine::cti_op_add); 943 954 else if (opcodeID == op_sub) 944 emitCTICall( i, Machine::cti_op_sub);955 emitCTICall(vPC, i, Machine::cti_op_sub); 945 956 else { 946 957 ASSERT(opcodeID == op_mul); 947 emitCTICall( i, Machine::cti_op_mul);958 emitCTICall(vPC, i, Machine::cti_op_mul); 948 959 } 949 960 emitPutResult(dst); … … 959 970 960 971 for (unsigned i = 0; i < instructionCount; ) { 972 ASSERT_WITH_MESSAGE(m_machine->isOpcode(instruction[i].u.opcode), "privateCompileMainPass gone bad @ %d", i); 973 974 #if ENABLE(OPCODE_SAMPLING) 975 m_jit.movl_i32m(m_machine->sampler()->encodeSample(instruction + i), m_machine->sampler()->sampleSlot()); 976 #endif 977 961 978 m_labels[i] = m_jit.label(); 962 963 #if ENABLE(SAMPLING_TOOL) 964 m_jit.movl_i32m(m_machine->getOpcodeID(instruction[i].u.opcode), ¤tOpcodeID); 965 #endif 966 967 ASSERT_WITH_MESSAGE(m_machine->isOpcode(instruction[i].u.opcode), "privateCompileMainPass gone bad @ %d", i); 968 switch (m_machine->getOpcodeID(instruction[i].u.opcode)) { 979 OpcodeID opcodeID = m_machine->getOpcodeID(instruction[i].u.opcode); 980 switch (opcodeID) { 969 981 case op_mov: { 970 982 unsigned src = instruction[i + 2].u.operand; … … 1001 1013 emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); 1002 1014 emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); 1003 emitCTICall(i , Machine::cti_op_add);1015 emitCTICall(instruction + i, i, Machine::cti_op_add); 1004 1016 emitPutResult(instruction[i + 1].u.operand); 1005 1017 } … … 1011 1023 case op_end: { 1012 1024 if (m_codeBlock->needsFullScopeChain) 1013 emitCTICall(i , Machine::cti_op_end);1025 emitCTICall(instruction + i, i, Machine::cti_op_end); 1014 1026 emitGetArg(instruction[i + 1].u.operand, X86::eax); 1015 #if ENABLE(SAMPLING_TOOL)1016 m_jit.movl_i32m(-1, ¤tOpcodeID);1017 #endif1018 1027 m_jit.pushl_m(RegisterFile::ReturnPC * static_cast<int>(sizeof(Register)), X86::edi); 1019 1028 m_jit.ret(); … … 1038 1047 } 1039 1048 case op_loop: { 1040 emitSlowScriptCheck(i );1049 emitSlowScriptCheck(instruction, i); 1041 1050 1042 1051 unsigned target = instruction[i + 1].u.operand; … … 1046 1055 } 1047 1056 case op_loop_if_less: { 1048 emitSlowScriptCheck(i );1057 emitSlowScriptCheck(instruction, i); 1049 1058 1050 1059 unsigned target = instruction[i + 3].u.operand; … … 1067 1076 } 1068 1077 case op_loop_if_lesseq: { 1069 emitSlowScriptCheck(i );1078 emitSlowScriptCheck(instruction, i); 1070 1079 1071 1080 unsigned target = instruction[i + 3].u.operand; … … 1088 1097 } 1089 1098 case op_new_object: { 1090 emitCTICall(i , Machine::cti_op_new_object);1099 emitCTICall(instruction + i, i, Machine::cti_op_new_object); 1091 1100 emitPutResult(instruction[i + 1].u.operand); 1092 1101 i += 2; … … 1214 1223 Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]); 1215 1224 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4); 1216 emitCTICall(i , Machine::cti_op_del_by_id);1225 emitCTICall(instruction + i, i, Machine::cti_op_del_by_id); 1217 1226 emitPutResult(instruction[i + 1].u.operand); 1218 1227 i += 4; … … 1253 1262 FuncDeclNode* func = (m_codeBlock->functions[instruction[i + 2].u.operand]).get(); 1254 1263 emitPutArgConstant(reinterpret_cast<unsigned>(func), 0); 1255 emitCTICall(i , Machine::cti_op_new_func);1264 emitCTICall(instruction + i, i, Machine::cti_op_new_func); 1256 1265 emitPutResult(instruction[i + 1].u.operand); 1257 1266 i += 3; … … 1259 1268 } 1260 1269 case op_call: { 1261 compileOpCall( instruction + i, i, callLinkInfoIndex++);1270 compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++); 1262 1271 i += 7; 1263 1272 break; … … 1307 1316 case op_tear_off_activation: { 1308 1317 emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx); 1309 emitCTICall(i , Machine::cti_op_tear_off_activation);1318 emitCTICall(instruction + i, i, Machine::cti_op_tear_off_activation); 1310 1319 i += 2; 1311 1320 break; 1312 1321 } 1313 1322 case op_tear_off_arguments: { 1314 emitCTICall(i , Machine::cti_op_tear_off_arguments);1323 emitCTICall(instruction + i, i, Machine::cti_op_tear_off_arguments); 1315 1324 i += 1; 1316 1325 break; … … 1319 1328 // We could JIT generate the deref, only calling out to C when the refcount hits zero. 1320 1329 if (m_codeBlock->needsFullScopeChain) 1321 emitCTICall(i , Machine::cti_op_ret_scopeChain);1330 emitCTICall(instruction + i, i, Machine::cti_op_ret_scopeChain); 1322 1331 1323 1332 // Return the result in %eax. … … 1341 1350 emitPutArg(X86::edx, 0); 1342 1351 emitPutArgConstant(instruction[i + 3].u.operand, 4); 1343 emitCTICall(i , Machine::cti_op_new_array);1352 emitCTICall(instruction + i, i, Machine::cti_op_new_array); 1344 1353 emitPutResult(instruction[i + 1].u.operand); 1345 1354 i += 4; … … 1349 1358 Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]); 1350 1359 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0); 1351 emitCTICall(i , Machine::cti_op_resolve);1360 emitCTICall(instruction + i, i, Machine::cti_op_resolve); 1352 1361 emitPutResult(instruction[i + 1].u.operand); 1353 1362 i += 3; … … 1355 1364 } 1356 1365 case op_construct: { 1357 compileOpCall( instruction + i, i, callLinkInfoIndex++, OpConstruct);1366 compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++); 1358 1367 i += 7; 1359 1368 break; … … 1400 1409 Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]); 1401 1410 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0); 1402 emitCTICall(i , Machine::cti_op_resolve_func);1411 emitCTICall(instruction + i, i, Machine::cti_op_resolve_func); 1403 1412 emitPutResult(instruction[i + 1].u.operand); 1404 1413 emitPutResult(instruction[i + 2].u.operand, X86::edx); … … 1443 1452 CTI_COMPILE_BINARY_OP(op_lesseq) 1444 1453 case op_loop_if_true: { 1445 emitSlowScriptCheck(i );1454 emitSlowScriptCheck(instruction, i); 1446 1455 1447 1456 unsigned target = instruction[i + 2].u.operand; … … 1465 1474 Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]); 1466 1475 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0); 1467 emitCTICall(i , Machine::cti_op_resolve_base);1476 emitCTICall(instruction + i, i, Machine::cti_op_resolve_base); 1468 1477 emitPutResult(instruction[i + 1].u.operand); 1469 1478 i += 3; … … 1472 1481 case op_negate: { 1473 1482 emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); 1474 emitCTICall(i , Machine::cti_op_negate);1483 emitCTICall(instruction + i, i, Machine::cti_op_negate); 1475 1484 emitPutResult(instruction[i + 1].u.operand); 1476 1485 i += 3; … … 1481 1490 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0); 1482 1491 emitPutArgConstant(instruction[i + 3].u.operand + m_codeBlock->needsFullScopeChain, 4); 1483 emitCTICall(i , Machine::cti_op_resolve_skip);1492 emitCTICall(instruction + i, i, Machine::cti_op_resolve_skip); 1484 1493 emitPutResult(instruction[i + 1].u.operand); 1485 1494 i += 4; … … 1511 1520 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4); 1512 1521 emitPutArgConstant(reinterpret_cast<unsigned>(instruction + i), 8); 1513 emitCTICall(i , Machine::cti_op_resolve_global);1522 emitCTICall(instruction + i, i, Machine::cti_op_resolve_global); 1514 1523 emitPutResult(instruction[i + 1].u.operand); 1515 1524 m_jit.link(end, m_jit.label()); … … 1742 1751 Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]); 1743 1752 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0); 1744 emitCTICall(i , Machine::cti_op_resolve_with_base);1753 emitCTICall(instruction + i, i, Machine::cti_op_resolve_with_base); 1745 1754 emitPutResult(instruction[i + 1].u.operand); 1746 1755 emitPutResult(instruction[i + 2].u.operand, X86::edx); … … 1751 1760 FuncExprNode* func = (m_codeBlock->functionExpressions[instruction[i + 2].u.operand]).get(); 1752 1761 emitPutArgConstant(reinterpret_cast<unsigned>(func), 0); 1753 emitCTICall(i , Machine::cti_op_new_func_exp);1762 emitCTICall(instruction + i, i, Machine::cti_op_new_func_exp); 1754 1763 emitPutResult(instruction[i + 1].u.operand); 1755 1764 i += 3; … … 1831 1840 RegExp* regExp = m_codeBlock->regexps[instruction[i + 2].u.operand].get(); 1832 1841 emitPutArgConstant(reinterpret_cast<unsigned>(regExp), 0); 1833 emitCTICall(i , Machine::cti_op_new_regexp);1842 emitCTICall(instruction + i, i, Machine::cti_op_new_regexp); 1834 1843 emitPutResult(instruction[i + 1].u.operand); 1835 1844 i += 3; … … 1846 1855 } 1847 1856 case op_call_eval: { 1848 compileOpCall( instruction + i, i, callLinkInfoIndex++, OpCallEval);1857 compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++); 1849 1858 i += 7; 1850 1859 break; … … 1852 1861 case op_throw: { 1853 1862 emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx); 1854 emitCTICall(i , Machine::cti_op_throw);1863 emitCTICall(instruction + i, i, Machine::cti_op_throw); 1855 1864 m_jit.addl_i8r(0x20, X86::esp); 1856 1865 m_jit.popl_r(X86::ebx); … … 1863 1872 case op_get_pnames: { 1864 1873 emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); 1865 emitCTICall(i , Machine::cti_op_get_pnames);1874 emitCTICall(instruction + i, i, Machine::cti_op_get_pnames); 1866 1875 emitPutResult(instruction[i + 1].u.operand); 1867 1876 i += 3; … … 1871 1880 emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); 1872 1881 unsigned target = instruction[i + 3].u.operand; 1873 emitCTICall(i , Machine::cti_op_next_pname);1882 emitCTICall(instruction + i, i, Machine::cti_op_next_pname); 1874 1883 m_jit.testl_rr(X86::eax, X86::eax); 1875 1884 X86Assembler::JmpSrc endOfIter = m_jit.emitUnlinkedJe(); … … 1882 1891 case op_push_scope: { 1883 1892 emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx); 1884 emitCTICall(i , Machine::cti_op_push_scope);1893 emitCTICall(instruction + i, i, Machine::cti_op_push_scope); 1885 1894 i += 2; 1886 1895 break; 1887 1896 } 1888 1897 case op_pop_scope: { 1889 emitCTICall(i , Machine::cti_op_pop_scope);1898 emitCTICall(instruction + i, i, Machine::cti_op_pop_scope); 1890 1899 i += 1; 1891 1900 break; … … 1930 1939 emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); 1931 1940 emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); 1932 emitCTICall(i , Machine::cti_op_in);1941 emitCTICall(instruction + i, i, Machine::cti_op_in); 1933 1942 emitPutResult(instruction[i + 1].u.operand); 1934 1943 i += 4; … … 1939 1948 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0); 1940 1949 emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); 1941 emitCTICall(i , Machine::cti_op_push_new_scope);1950 emitCTICall(instruction + i, i, Machine::cti_op_push_new_scope); 1942 1951 emitPutResult(instruction[i + 1].u.operand); 1943 1952 i += 4; … … 1953 1962 unsigned count = instruction[i + 1].u.operand; 1954 1963 emitPutArgConstant(count, 0); 1955 emitCTICall(i , Machine::cti_op_jmp_scopes);1964 emitCTICall(instruction + i, i, Machine::cti_op_jmp_scopes); 1956 1965 unsigned target = instruction[i + 2].u.operand; 1957 1966 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 2 + target)); … … 1963 1972 emitPutArgConstant(instruction[i + 2].u.operand, 4); 1964 1973 emitGetPutArg(instruction[i + 3].u.operand, 8, X86::ecx); 1965 emitCTICall(i , Machine::cti_op_put_by_index);1974 emitCTICall(instruction + i, i, Machine::cti_op_put_by_index); 1966 1975 i += 4; 1967 1976 break; … … 1979 1988 emitGetPutArg(scrutinee, 0, X86::ecx); 1980 1989 emitPutArgConstant(tableIndex, 4); 1981 emitCTICall(i , Machine::cti_op_switch_imm);1990 emitCTICall(instruction + i, i, Machine::cti_op_switch_imm); 1982 1991 m_jit.jmp_r(X86::eax); 1983 1992 i += 4; … … 1996 2005 emitGetPutArg(scrutinee, 0, X86::ecx); 1997 2006 emitPutArgConstant(tableIndex, 4); 1998 emitCTICall(i , Machine::cti_op_switch_char);2007 emitCTICall(instruction + i, i, Machine::cti_op_switch_char); 1999 2008 m_jit.jmp_r(X86::eax); 2000 2009 i += 4; … … 2012 2021 emitGetPutArg(scrutinee, 0, X86::ecx); 2013 2022 emitPutArgConstant(tableIndex, 4); 2014 emitCTICall(i , Machine::cti_op_switch_string);2023 emitCTICall(instruction + i, i, Machine::cti_op_switch_string); 2015 2024 m_jit.jmp_r(X86::eax); 2016 2025 i += 4; … … 2020 2029 emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); 2021 2030 emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); 2022 emitCTICall(i , Machine::cti_op_del_by_val);2031 emitCTICall(instruction + i, i, Machine::cti_op_del_by_val); 2023 2032 emitPutResult(instruction[i + 1].u.operand); 2024 2033 i += 4; … … 2030 2039 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4); 2031 2040 emitGetPutArg(instruction[i + 3].u.operand, 8, X86::ecx); 2032 emitCTICall(i , Machine::cti_op_put_getter);2041 emitCTICall(instruction + i, i, Machine::cti_op_put_getter); 2033 2042 i += 4; 2034 2043 break; … … 2039 2048 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4); 2040 2049 emitGetPutArg(instruction[i + 3].u.operand, 8, X86::ecx); 2041 emitCTICall(i , Machine::cti_op_put_setter);2050 emitCTICall(instruction + i, i, Machine::cti_op_put_setter); 2042 2051 i += 4; 2043 2052 break; … … 2048 2057 emitPutArgConstant(asInteger(message), 4); 2049 2058 emitPutArgConstant(m_codeBlock->lineNumberForVPC(&instruction[i]), 8); 2050 emitCTICall(i , Machine::cti_op_new_error);2059 emitCTICall(instruction + i, i, Machine::cti_op_new_error); 2051 2060 emitPutResult(instruction[i + 1].u.operand); 2052 2061 i += 4; … … 2057 2066 emitPutArgConstant(instruction[i + 2].u.operand, 4); 2058 2067 emitPutArgConstant(instruction[i + 3].u.operand, 8); 2059 emitCTICall(i , Machine::cti_op_debug);2068 emitCTICall(instruction + i, i, Machine::cti_op_debug); 2060 2069 i += 4; 2061 2070 break; … … 2140 2149 emitInitRegister(j); 2141 2150 2142 emitCTICall(i , Machine::cti_op_push_activation);2151 emitCTICall(instruction + i, i, Machine::cti_op_push_activation); 2143 2152 emitPutResult(instruction[i + 1].u.operand); 2144 2153 … … 2147 2156 } 2148 2157 case op_create_arguments: { 2149 emitCTICall(i , (m_codeBlock->numParameters == 1) ? Machine::cti_op_create_arguments_no_params : Machine::cti_op_create_arguments);2158 emitCTICall(instruction + i, i, (m_codeBlock->numParameters == 1) ? Machine::cti_op_create_arguments_no_params : Machine::cti_op_create_arguments); 2150 2159 i += 1; 2151 2160 break; … … 2167 2176 X86Assembler::JmpSrc noProfiler = m_jit.emitUnlinkedJe(); 2168 2177 emitGetPutArg(instruction[i + 1].u.operand, 0, X86::eax); 2169 emitCTICall(i , Machine::cti_op_profile_will_call);2178 emitCTICall(instruction + i, i, Machine::cti_op_profile_will_call); 2170 2179 m_jit.link(noProfiler, m_jit.label()); 2171 2180 … … 2178 2187 X86Assembler::JmpSrc noProfiler = m_jit.emitUnlinkedJe(); 2179 2188 emitGetPutArg(instruction[i + 1].u.operand, 0, X86::eax); 2180 emitCTICall(i , Machine::cti_op_profile_did_call);2189 emitCTICall(instruction + i, i, Machine::cti_op_profile_did_call); 2181 2190 m_jit.link(noProfiler, m_jit.label()); 2182 2191 … … 2215 2224 emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); \ 2216 2225 emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); \ 2217 emitCTICall(i , Machine::cti_##name); \2226 emitCTICall(instruction + i, i, Machine::cti_##name); \ 2218 2227 emitPutResult(instruction[i + 1].u.operand); \ 2219 2228 i += 4; \ … … 2234 2243 m_jit.link((++iter)->from, m_jit.label()); 2235 2244 emitPutArg(X86::eax, 0); 2236 emitCTICall(i , Machine::cti_op_convert_this);2245 emitCTICall(instruction + i, i, Machine::cti_op_convert_this); 2237 2246 emitPutResult(instruction[i + 1].u.operand); 2238 2247 i += 2; … … 2250 2259 emitGetPutArg(src1, 0, X86::ecx); 2251 2260 emitPutArg(X86::edx, 4); 2252 emitCTICall(i , Machine::cti_op_add);2261 emitCTICall(instruction + i, i, Machine::cti_op_add); 2253 2262 emitPutResult(dst); 2254 2263 } else if (JSValue* value = getConstantImmediateNumericArg(src2)) { … … 2259 2268 emitPutArg(X86::eax, 0); 2260 2269 emitGetPutArg(src2, 4, X86::ecx); 2261 emitCTICall(i , Machine::cti_op_add);2270 emitCTICall(instruction + i, i, Machine::cti_op_add); 2262 2271 emitPutResult(dst); 2263 2272 } else { 2264 2273 OperandTypes types = OperandTypes::fromInt(instruction[i + 4].u.operand); 2265 2274 if (types.first().mightBeNumber() && types.second().mightBeNumber()) 2266 compileBinaryArithOpSlowCase( op_add, iter, dst, src1, src2, types, i);2275 compileBinaryArithOpSlowCase(instruction, op_add, iter, dst, src1, src2, types, i); 2267 2276 else 2268 2277 ASSERT_NOT_REACHED(); … … 2283 2292 emitPutArg(X86::eax, 0); 2284 2293 emitPutArg(X86::edx, 4); 2285 emitCTICall(i , Machine::cti_op_get_by_val);2294 emitCTICall(instruction + i, i, Machine::cti_op_get_by_val); 2286 2295 emitPutResult(instruction[i + 1].u.operand); 2287 2296 m_jit.link(m_jit.emitUnlinkedJmp(), m_labels[i + 4]); … … 2304 2313 } 2305 2314 case op_sub: { 2306 compileBinaryArithOpSlowCase( op_sub, iter, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i);2315 compileBinaryArithOpSlowCase(instruction, op_sub, iter, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i); 2307 2316 i += 5; 2308 2317 break; … … 2313 2322 emitPutArg(X86::eax, 0); 2314 2323 emitPutArg(X86::ecx, 4); 2315 emitCTICall(i , Machine::cti_op_rshift);2324 emitCTICall(instruction + i, i, Machine::cti_op_rshift); 2316 2325 emitPutResult(instruction[i + 1].u.operand); 2317 2326 i += 4; … … 2328 2337 emitPutArg(X86::eax, 0); 2329 2338 emitPutArg(X86::ecx, 4); 2330 emitCTICall(i , Machine::cti_op_lshift);2339 emitCTICall(instruction + i, i, Machine::cti_op_lshift); 2331 2340 emitPutResult(instruction[i + 1].u.operand); 2332 2341 i += 4; … … 2334 2343 } 2335 2344 case op_loop_if_less: { 2336 emitSlowScriptCheck(i );2345 emitSlowScriptCheck(instruction, i); 2337 2346 2338 2347 unsigned target = instruction[i + 3].u.operand; … … 2342 2351 emitPutArg(X86::edx, 0); 2343 2352 emitGetPutArg(instruction[i + 2].u.operand, 4, X86::ecx); 2344 emitCTICall(i , Machine::cti_op_loop_if_less);2353 emitCTICall(instruction + i, i, Machine::cti_op_loop_if_less); 2345 2354 m_jit.testl_rr(X86::eax, X86::eax); 2346 2355 m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]); … … 2350 2359 emitPutArg(X86::eax, 0); 2351 2360 emitPutArg(X86::edx, 4); 2352 emitCTICall(i , Machine::cti_op_loop_if_less);2361 emitCTICall(instruction + i, i, Machine::cti_op_loop_if_less); 2353 2362 m_jit.testl_rr(X86::eax, X86::eax); 2354 2363 m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]); … … 2365 2374 emitPutArg(X86::eax, 0); 2366 2375 emitPutArg(X86::edx, 8); 2367 X86Assembler::JmpSrc call = emitCTICall(i , Machine::cti_op_put_by_id);2376 X86Assembler::JmpSrc call = emitCTICall(instruction + i, i, Machine::cti_op_put_by_id); 2368 2377 2369 2378 // Track the location of the call; this will be used to recover repatch information. … … 2391 2400 Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]); 2392 2401 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4); 2393 X86Assembler::JmpSrc call = emitCTICall(i , Machine::cti_op_get_by_id);2402 X86Assembler::JmpSrc call = emitCTICall(instruction + i, i, Machine::cti_op_get_by_id); 2394 2403 ASSERT(X86Assembler::getDifferenceBetweenLabels(coldPathBegin, call) == repatchOffsetGetByIdSlowCaseCall); 2395 2404 emitPutResult(instruction[i + 1].u.operand); … … 2404 2413 } 2405 2414 case op_loop_if_lesseq: { 2406 emitSlowScriptCheck(i );2415 emitSlowScriptCheck(instruction, i); 2407 2416 2408 2417 unsigned target = instruction[i + 3].u.operand; … … 2412 2421 emitPutArg(X86::edx, 0); 2413 2422 emitGetPutArg(instruction[i + 2].u.operand, 4, X86::ecx); 2414 emitCTICall(i , Machine::cti_op_loop_if_lesseq);2423 emitCTICall(instruction + i, i, Machine::cti_op_loop_if_lesseq); 2415 2424 m_jit.testl_rr(X86::eax, X86::eax); 2416 2425 m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]); … … 2420 2429 emitPutArg(X86::eax, 0); 2421 2430 emitPutArg(X86::edx, 4); 2422 emitCTICall(i , Machine::cti_op_loop_if_lesseq);2431 emitCTICall(instruction + i, i, Machine::cti_op_loop_if_lesseq); 2423 2432 m_jit.testl_rr(X86::eax, X86::eax); 2424 2433 m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]); … … 2434 2443 m_jit.link(notImm, m_jit.label()); 2435 2444 emitPutArg(X86::eax, 0); 2436 emitCTICall(i , Machine::cti_op_pre_inc);2445 emitCTICall(instruction + i, i, Machine::cti_op_pre_inc); 2437 2446 emitPutResult(srcDst); 2438 2447 i += 2; … … 2450 2459 emitPutArg(X86::edx, 4); 2451 2460 emitPutArg(X86::ecx, 8); 2452 emitCTICall(i , Machine::cti_op_put_by_val);2461 emitCTICall(instruction + i, i, Machine::cti_op_put_by_val); 2453 2462 m_jit.link(m_jit.emitUnlinkedJmp(), m_labels[i + 4]); 2454 2463 … … 2460 2469 emitPutArg(X86::edx, 4); 2461 2470 emitPutArg(X86::ecx, 8); 2462 emitCTICall(i , Machine::cti_op_put_by_val_array);2471 emitCTICall(instruction + i, i, Machine::cti_op_put_by_val_array); 2463 2472 2464 2473 i += 4; … … 2466 2475 } 2467 2476 case op_loop_if_true: { 2468 emitSlowScriptCheck(i );2477 emitSlowScriptCheck(instruction, i); 2469 2478 2470 2479 m_jit.link(iter->from, m_jit.label()); 2471 2480 emitPutArg(X86::eax, 0); 2472 emitCTICall(i , Machine::cti_op_jtrue);2481 emitCTICall(instruction + i, i, Machine::cti_op_jtrue); 2473 2482 m_jit.testl_rr(X86::eax, X86::eax); 2474 2483 unsigned target = instruction[i + 2].u.operand; … … 2484 2493 m_jit.link(notImm, m_jit.label()); 2485 2494 emitPutArg(X86::eax, 0); 2486 emitCTICall(i , Machine::cti_op_pre_dec);2495 emitCTICall(instruction + i, i, Machine::cti_op_pre_dec); 2487 2496 emitPutResult(srcDst); 2488 2497 i += 2; … … 2496 2505 emitPutArg(X86::edx, 0); 2497 2506 emitGetPutArg(instruction[i + 2].u.operand, 4, X86::ecx); 2498 emitCTICall(i , Machine::cti_op_jless);2507 emitCTICall(instruction + i, i, Machine::cti_op_jless); 2499 2508 m_jit.testl_rr(X86::eax, X86::eax); 2500 2509 m_jit.link(m_jit.emitUnlinkedJe(), m_labels[i + 3 + target]); … … 2504 2513 emitPutArg(X86::eax, 0); 2505 2514 emitPutArg(X86::edx, 4); 2506 emitCTICall(i , Machine::cti_op_jless);2515 emitCTICall(instruction + i, i, Machine::cti_op_jless); 2507 2516 m_jit.testl_rr(X86::eax, X86::eax); 2508 2517 m_jit.link(m_jit.emitUnlinkedJe(), m_labels[i + 3 + target]); … … 2515 2524 m_jit.xorl_i8r(JSImmediate::FullTagTypeBool, X86::eax); 2516 2525 emitPutArg(X86::eax, 0); 2517 emitCTICall(i , Machine::cti_op_not);2526 emitCTICall(instruction + i, i, Machine::cti_op_not); 2518 2527 emitPutResult(instruction[i + 1].u.operand); 2519 2528 i += 3; … … 2523 2532 m_jit.link(iter->from, m_jit.label()); 2524 2533 emitPutArg(X86::eax, 0); 2525 emitCTICall(i , Machine::cti_op_jtrue);2534 emitCTICall(instruction + i, i, Machine::cti_op_jtrue); 2526 2535 m_jit.testl_rr(X86::eax, X86::eax); 2527 2536 unsigned target = instruction[i + 2].u.operand; … … 2535 2544 m_jit.link((++iter)->from, m_jit.label()); 2536 2545 emitPutArg(X86::eax, 0); 2537 emitCTICall(i , Machine::cti_op_post_inc);2546 emitCTICall(instruction + i, i, Machine::cti_op_post_inc); 2538 2547 emitPutResult(instruction[i + 1].u.operand); 2539 2548 emitPutResult(srcDst, X86::edx); … … 2544 2553 m_jit.link(iter->from, m_jit.label()); 2545 2554 emitPutArg(X86::eax, 0); 2546 emitCTICall(i , Machine::cti_op_bitnot);2555 emitCTICall(instruction + i, i, Machine::cti_op_bitnot); 2547 2556 emitPutResult(instruction[i + 1].u.operand); 2548 2557 i += 3; … … 2557 2566 emitGetPutArg(src1, 0, X86::ecx); 2558 2567 emitPutArg(X86::eax, 4); 2559 emitCTICall(i , Machine::cti_op_bitand);2568 emitCTICall(instruction + i, i, Machine::cti_op_bitand); 2560 2569 emitPutResult(dst); 2561 2570 } else if (getConstantImmediateNumericArg(src2)) { … … 2563 2572 emitPutArg(X86::eax, 0); 2564 2573 emitGetPutArg(src2, 4, X86::ecx); 2565 emitCTICall(i , Machine::cti_op_bitand);2574 emitCTICall(instruction + i, i, Machine::cti_op_bitand); 2566 2575 emitPutResult(dst); 2567 2576 } else { … … 2569 2578 emitGetPutArg(src1, 0, X86::ecx); 2570 2579 emitPutArg(X86::edx, 4); 2571 emitCTICall(i , Machine::cti_op_bitand);2580 emitCTICall(instruction + i, i, Machine::cti_op_bitand); 2572 2581 emitPutResult(dst); 2573 2582 } … … 2578 2587 m_jit.link(iter->from, m_jit.label()); 2579 2588 emitPutArg(X86::eax, 0); 2580 emitCTICall(i , Machine::cti_op_jtrue);2589 emitCTICall(instruction + i, i, Machine::cti_op_jtrue); 2581 2590 m_jit.testl_rr(X86::eax, X86::eax); 2582 2591 unsigned target = instruction[i + 2].u.operand; … … 2590 2599 m_jit.link((++iter)->from, m_jit.label()); 2591 2600 emitPutArg(X86::eax, 0); 2592 emitCTICall(i , Machine::cti_op_post_dec);2601 emitCTICall(instruction + i, i, Machine::cti_op_post_dec); 2593 2602 emitPutResult(instruction[i + 1].u.operand); 2594 2603 emitPutResult(srcDst, X86::edx); … … 2600 2609 emitPutArg(X86::eax, 0); 2601 2610 emitPutArg(X86::edx, 4); 2602 emitCTICall(i , Machine::cti_op_bitxor);2611 emitCTICall(instruction + i, i, Machine::cti_op_bitxor); 2603 2612 emitPutResult(instruction[i + 1].u.operand); 2604 2613 i += 5; … … 2609 2618 emitPutArg(X86::eax, 0); 2610 2619 emitPutArg(X86::edx, 4); 2611 emitCTICall(i , Machine::cti_op_bitor);2620 emitCTICall(instruction + i, i, Machine::cti_op_bitor); 2612 2621 emitPutResult(instruction[i + 1].u.operand); 2613 2622 i += 5; … … 2618 2627 emitPutArg(X86::eax, 0); 2619 2628 emitPutArg(X86::edx, 4); 2620 emitCTICall(i , Machine::cti_op_eq);2629 emitCTICall(instruction + i, i, Machine::cti_op_eq); 2621 2630 emitPutResult(instruction[i + 1].u.operand); 2622 2631 i += 4; … … 2627 2636 emitPutArg(X86::eax, 0); 2628 2637 emitPutArg(X86::edx, 4); 2629 emitCTICall(i , Machine::cti_op_neq);2638 emitCTICall(instruction + i, i, Machine::cti_op_neq); 2630 2639 emitPutResult(instruction[i + 1].u.operand); 2631 2640 i += 4; … … 2639 2648 emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); 2640 2649 emitGetPutArg(instruction[i + 4].u.operand, 8, X86::ecx); 2641 emitCTICall(i , Machine::cti_op_instanceof);2650 emitCTICall(instruction + i, i, Machine::cti_op_instanceof); 2642 2651 emitPutResult(instruction[i + 1].u.operand); 2643 2652 i += 5; … … 2654 2663 emitPutArg(X86::eax, 0); 2655 2664 emitPutArg(X86::ecx, 4); 2656 emitCTICall(i , Machine::cti_op_mod);2665 emitCTICall(instruction + i, i, Machine::cti_op_mod); 2657 2666 emitPutResult(instruction[i + 1].u.operand); 2658 2667 i += 4; … … 2671 2680 emitGetPutArg(src1, 0, X86::ecx); 2672 2681 emitGetPutArg(src2, 4, X86::ecx); 2673 emitCTICall(i , Machine::cti_op_mul);2682 emitCTICall(instruction + i, i, Machine::cti_op_mul); 2674 2683 emitPutResult(dst); 2675 2684 } else if (src2Value && ((value = JSImmediate::intValue(src2Value)) > 0)) { … … 2678 2687 emitGetPutArg(src1, 0, X86::ecx); 2679 2688 emitGetPutArg(src2, 4, X86::ecx); 2680 emitCTICall(i , Machine::cti_op_mul);2689 emitCTICall(instruction + i, i, Machine::cti_op_mul); 2681 2690 emitPutResult(dst); 2682 2691 } else 2683 compileBinaryArithOpSlowCase( op_mul, iter, dst, src1, src2, OperandTypes::fromInt(instruction[i + 4].u.operand), i);2692 compileBinaryArithOpSlowCase(instruction, op_mul, iter, dst, src1, src2, OperandTypes::fromInt(instruction[i + 4].u.operand), i); 2684 2693 i += 5; 2685 2694 break; … … 2706 2715 2707 2716 // This handles JSFunctions 2708 emitCTICall(i , (opcodeID == op_construct) ? Machine::cti_op_construct_JSConstruct : Machine::cti_op_call_JSFunction);2717 emitCTICall(instruction + i, i, (opcodeID == op_construct) ? Machine::cti_op_construct_JSConstruct : Machine::cti_op_call_JSFunction); 2709 2718 // initialize the new call frame (pointed to by edx, after the last call), then set edi to point to it. 2710 2719 compileOpCallInitializeCallFrame(callee, argCount); … … 2715 2724 emitPutArgConstant(reinterpret_cast<unsigned>(info), 4); 2716 2725 m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = 2717 emitCTICall(i , Machine::cti_vm_lazyLinkCall);2726 emitCTICall(instruction + i, i, Machine::cti_vm_lazyLinkCall); 2718 2727 emitNakedCall(i, X86::eax); 2719 2728 X86Assembler::JmpSrc storeResultForFirstRun = m_jit.emitUnlinkedJmp(); … … 2737 2746 m_jit.link(callLinkFailNotObject, notJSFunctionlabel); 2738 2747 m_jit.link(callLinkFailNotJSFunction, notJSFunctionlabel); 2739 emitCTICall(i , ((opcodeID == op_construct) ? Machine::cti_op_construct_NotJSConstruct : Machine::cti_op_call_NotJSFunction));2748 emitCTICall(instruction + i, i, ((opcodeID == op_construct) ? Machine::cti_op_construct_NotJSConstruct : Machine::cti_op_call_NotJSFunction)); 2740 2749 X86Assembler::JmpSrc wasNotJSFunction = m_jit.emitUnlinkedJmp(); 2741 2750 2742 2751 // Next, handle JSFunctions... 2743 2752 m_jit.link(isJSFunction, m_jit.label()); 2744 emitCTICall(i , (opcodeID == op_construct) ? Machine::cti_op_construct_JSConstruct : Machine::cti_op_call_JSFunction);2753 emitCTICall(instruction + i, i, (opcodeID == op_construct) ? Machine::cti_op_construct_JSConstruct : Machine::cti_op_call_JSFunction); 2745 2754 // initialize the new call frame (pointed to by edx, after the last call). 2746 2755 compileOpCallInitializeCallFrame(callee, argCount); … … 2756 2765 m_jit.testl_rr(X86::eax, X86::eax); 2757 2766 X86Assembler::JmpSrc hasCode = m_jit.emitUnlinkedJne(); 2758 emitCTICall(i , Machine::cti_vm_compile);2767 emitCTICall(instruction + i, i, Machine::cti_vm_compile); 2759 2768 m_jit.link(hasCode, m_jit.label()); 2760 2769 … … 2767 2776 emitPutResult(dst); 2768 2777 2778 #if ENABLE(CODEBLOCK_SAMPLING) 2779 m_jit.movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_machine->sampler()->codeBlockSlot()); 2780 #endif 2769 2781 ++callLinkInfoIndex; 2782 2770 2783 i += 7; 2771 2784 break; … … 2776 2789 2777 2790 emitPutArg(X86::eax, 0); 2778 emitCTICall(i , Machine::cti_op_to_jsnumber);2791 emitCTICall(instruction + i, i, Machine::cti_op_to_jsnumber); 2779 2792 2780 2793 emitPutResult(instruction[i + 1].u.operand); … … 2797 2810 void CTI::privateCompile() 2798 2811 { 2812 #if ENABLE(CODEBLOCK_SAMPLING) 2813 m_jit.movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_machine->sampler()->codeBlockSlot()); 2814 #endif 2815 #if ENABLE(OPCODE_SAMPLING) 2816 m_jit.movl_i32m(m_machine->sampler()->encodeSample(m_codeBlock->instructions.begin()), m_machine->sampler()->sampleSlot()); 2817 #endif 2818 2799 2819 // Could use a popl_m, but would need to offset the following instruction if so. 2800 2820 m_jit.popl_r(X86::ecx); … … 2820 2840 if (m_codeBlock->codeType == FunctionCode) { 2821 2841 m_jit.link(slowRegisterFileCheck, m_jit.label()); 2822 emitCTICall( 0, Machine::cti_register_file_check);2842 emitCTICall(m_codeBlock->instructions.begin(), 0, Machine::cti_register_file_check); 2823 2843 X86Assembler::JmpSrc backToBody = m_jit.emitUnlinkedJmp(); 2824 2844 m_jit.link(backToBody, afterRegisterFileCheck); -
trunk/JavaScriptCore/VM/CTI.h
r37845 r37891 267 267 static const int repatchOffsetGetByIdBranchToSlowCase = 25; 268 268 static const int repatchOffsetGetByIdPropertyMapOffset = 34; 269 #if ENABLE( SAMPLING_TOOL)269 #if ENABLE(OPCODE_SAMPLING) 270 270 static const int repatchOffsetGetByIdSlowCaseCall = 27 + 4 + ctiArgumentInitSize; 271 271 #else … … 366 366 void privateCompilePatchGetArrayLength(void* returnAddress); 367 367 368 enum CompileOpCallType { OpCallNormal, OpCallEval, OpConstruct }; 369 void compileOpCall(Instruction* instruction, unsigned i, unsigned structureIDInstructionIndex, CompileOpCallType type = OpCallNormal); 368 void compileOpCall(OpcodeID, Instruction* instruction, unsigned i, unsigned callLinkInfoIndex); 370 369 void compileOpCallInitializeCallFrame(unsigned callee, unsigned argCount); 371 370 void compileOpCallSetupArgs(Instruction* instruction, bool isConstruct, bool isEval); … … 374 373 void putDoubleResultToJSNumberCellOrJSImmediate(X86::XMMRegisterID xmmSource, X86::RegisterID jsNumberCell, unsigned dst, X86Assembler::JmpSrc* wroteJSNumberCell, X86::XMMRegisterID tempXmm, X86::RegisterID tempReg1, X86::RegisterID tempReg2); 375 374 void compileBinaryArithOp(OpcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi, unsigned i); 376 void compileBinaryArithOpSlowCase( OpcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi, unsigned i);375 void compileBinaryArithOpSlowCase(Instruction*, OpcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi, unsigned i); 377 376 378 377 void emitGetArg(int src, X86Assembler::RegisterID dst); … … 412 411 X86Assembler::JmpSrc emitNakedCall(unsigned opcodeIndex, X86::RegisterID); 413 412 X86Assembler::JmpSrc emitNakedCall(unsigned opcodeIndex, void(*function)()); 414 X86Assembler::JmpSrc emitCTICall( unsigned opcodeIndex, CTIHelper_j);415 X86Assembler::JmpSrc emitCTICall( unsigned opcodeIndex, CTIHelper_o);416 X86Assembler::JmpSrc emitCTICall( unsigned opcodeIndex, CTIHelper_p);417 X86Assembler::JmpSrc emitCTICall( unsigned opcodeIndex, CTIHelper_v);418 X86Assembler::JmpSrc emitCTICall( unsigned opcodeIndex, CTIHelper_s);419 X86Assembler::JmpSrc emitCTICall( unsigned opcodeIndex, CTIHelper_b);420 X86Assembler::JmpSrc emitCTICall( unsigned opcodeIndex, CTIHelper_2);413 X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_j); 414 X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_o); 415 X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_p); 416 X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_v); 417 X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_s); 418 X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_b); 419 X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_2); 421 420 422 421 void emitGetVariableObjectRegister(X86Assembler::RegisterID variableObject, int index, X86Assembler::RegisterID dst); 423 422 void emitPutVariableObjectRegister(X86Assembler::RegisterID src, X86Assembler::RegisterID variableObject, int index); 424 423 425 void emitSlowScriptCheck( unsigned opcodeIndex);424 void emitSlowScriptCheck(Instruction*, unsigned opcodeIndex); 426 425 #ifndef NDEBUG 427 426 void printOpcodeOperandTypes(unsigned src1, unsigned src2); -
trunk/JavaScriptCore/VM/CodeBlock.cpp
r37845 r37891 40 40 namespace JSC { 41 41 42 #if !defined(NDEBUG) || ENABLE( SAMPLING_TOOL)42 #if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING) 43 43 44 44 static UString escapeQuotes(const UString& str) … … 947 947 } 948 948 949 #endif // !defined(NDEBUG) || ENABLE( SAMPLING_TOOL)949 #endif // !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING) 950 950 951 951 CodeBlock::~CodeBlock() … … 1111 1111 int CodeBlock::lineNumberForVPC(const Instruction* vPC) 1112 1112 { 1113 ASSERT(lineInfo.size());1114 1113 unsigned instructionOffset = vPC - instructions.begin(); 1115 1114 ASSERT(instructionOffset < instructions.size()); 1116 1115 1117 1116 if (!lineInfo.size()) 1118 return 1; // Empty function1117 return ownerNode->source().firstLine(); // Empty function 1119 1118 1120 1119 int low = 0; … … 1127 1126 high = mid; 1128 1127 } 1128 1129 if (!low) 1130 return ownerNode->source().firstLine(); 1129 1131 return lineInfo[low - 1].lineNumber; 1130 1132 } -
trunk/JavaScriptCore/VM/CodeBlock.h
r37845 r37891 290 290 } 291 291 292 #if !defined(NDEBUG) || ENABLE_ SAMPLING_TOOL292 #if !defined(NDEBUG) || ENABLE_OPCODE_SAMPLING 293 293 void dump(ExecState*) const; 294 294 void printStructureIDs(const Instruction*) const; … … 362 362 363 363 private: 364 #if !defined(NDEBUG) || ENABLE( SAMPLING_TOOL)364 #if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING) 365 365 void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const; 366 366 #endif -
trunk/JavaScriptCore/VM/Machine.cpp
r37845 r37891 924 924 (*profiler)->willExecute(newCallFrame, programNode->sourceURL(), programNode->lineNo()); 925 925 926 m_reentryDepth++; 926 JSValue* result; 927 { 928 SamplingTool::CallRecord callRecord(m_sampler); 929 930 m_reentryDepth++; 927 931 #if ENABLE(CTI) 928 if (!codeBlock->ctiCode)929 CTI::compile(this, newCallFrame, codeBlock);930 JSValue*result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);932 if (!codeBlock->ctiCode) 933 CTI::compile(this, newCallFrame, codeBlock); 934 result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception); 931 935 #else 932 JSValue*result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);936 result = privateExecute(Normal, &m_registerFile, newCallFrame, exception); 933 937 #endif 934 m_reentryDepth--; 935 936 MACHINE_SAMPLING_privateExecuteReturned(); 938 m_reentryDepth--; 939 } 937 940 938 941 if (*profiler) … … 987 990 (*profiler)->willExecute(newCallFrame, function); 988 991 989 m_reentryDepth++; 992 JSValue* result; 993 { 994 SamplingTool::CallRecord callRecord(m_sampler); 995 996 m_reentryDepth++; 990 997 #if ENABLE(CTI) 991 if (!codeBlock->ctiCode)992 CTI::compile(this, newCallFrame, codeBlock);993 JSValue*result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);998 if (!codeBlock->ctiCode) 999 CTI::compile(this, newCallFrame, codeBlock); 1000 result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception); 994 1001 #else 995 JSValue*result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);1002 result = privateExecute(Normal, &m_registerFile, newCallFrame, exception); 996 1003 #endif 997 m_reentryDepth--; 1004 m_reentryDepth--; 1005 } 998 1006 999 1007 if (*profiler) 1000 1008 (*profiler)->didExecute(newCallFrame, function); 1001 1002 MACHINE_SAMPLING_privateExecuteReturned();1003 1009 1004 1010 m_registerFile.shrink(oldEnd); … … 1076 1082 (*profiler)->willExecute(newCallFrame, evalNode->sourceURL(), evalNode->lineNo()); 1077 1083 1078 m_reentryDepth++; 1084 JSValue* result; 1085 { 1086 SamplingTool::CallRecord callRecord(m_sampler); 1087 1088 m_reentryDepth++; 1079 1089 #if ENABLE(CTI) 1080 if (!codeBlock->ctiCode)1081 CTI::compile(this, newCallFrame, codeBlock);1082 JSValue*result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);1090 if (!codeBlock->ctiCode) 1091 CTI::compile(this, newCallFrame, codeBlock); 1092 result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception); 1083 1093 #else 1084 JSValue*result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);1094 result = privateExecute(Normal, &m_registerFile, newCallFrame, exception); 1085 1095 #endif 1086 m_reentryDepth--; 1087 1088 MACHINE_SAMPLING_privateExecuteReturned(); 1096 m_reentryDepth--; 1097 } 1089 1098 1090 1099 if (*profiler) … … 1473 1482 } while (0) 1474 1483 1475 #if DUMP_OPCODE_STATS1484 #if ENABLE(OPCODE_STATS) 1476 1485 OpcodeStats::resetLastInstruction(); 1477 1486 #endif … … 1483 1492 tickCount = m_ticksUntilNextTimeoutCheck; \ 1484 1493 } 1494 1495 #if ENABLE(OPCODE_SAMPLING) 1496 #define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC) 1497 #define CTI_SAMPLER ARG_globalData->machine->sampler() 1498 #else 1499 #define SAMPLE(codeBlock, vPC) 1500 #define CTI_SAMPLER 1501 #endif 1485 1502 1486 1503 #if HAVE(COMPUTED_GOTO) 1487 #define NEXT_OPCODE MACHINE_SAMPLING_sample(callFrame->codeBlock(), vPC); goto *vPC->u.opcode1488 #if DUMP_OPCODE_STATS1504 #define NEXT_OPCODE SAMPLE(callFrame->codeBlock(), vPC); goto *vPC->u.opcode 1505 #if ENABLE(OPCODE_STATS) 1489 1506 #define BEGIN_OPCODE(opcode) opcode: OpcodeStats::recordInstruction(opcode); 1490 1507 #else … … 1493 1510 NEXT_OPCODE; 1494 1511 #else 1495 #define NEXT_OPCODE MACHINE_SAMPLING_sample(callFrame->codeBlock(), vPC); goto interpreterLoopStart1496 #if DUMP_OPCODE_STATS1512 #define NEXT_OPCODE SAMPLE(callFrame->codeBlock(), vPC); goto interpreterLoopStart 1513 #if ENABLE(OPCODE_STATS) 1497 1514 #define BEGIN_OPCODE(opcode) case opcode: OpcodeStats::recordInstruction(opcode); 1498 1515 #else … … 2959 2976 the JS timeout is reached. 2960 2977 */ 2961 #if DUMP_OPCODE_STATS2978 #if ENABLE(OPCODE_STATS) 2962 2979 OpcodeStats::resetLastInstruction(); 2963 2980 #endif … … 2973 2990 instruction. 2974 2991 */ 2975 #if DUMP_OPCODE_STATS2992 #if ENABLE(OPCODE_STATS) 2976 2993 OpcodeStats::resetLastInstruction(); 2977 2994 #endif … … 3354 3371 vPC = newCodeBlock->instructions.begin(); 3355 3372 3356 #if DUMP_OPCODE_STATS3373 #if ENABLE(OPCODE_STATS) 3357 3374 OpcodeStats::resetLastInstruction(); 3358 3375 #endif … … 3369 3386 newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0); 3370 3387 3371 MACHINE_SAMPLING_callingHostFunction(); 3372 3373 JSValue* returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args); 3388 JSValue* returnValue; 3389 { 3390 SamplingTool::HostCallRecord callRecord(m_sampler); 3391 returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args); 3392 } 3374 3393 VM_CHECK_EXCEPTION(); 3375 3394 … … 3599 3618 vPC = newCodeBlock->instructions.begin(); 3600 3619 3601 #if DUMP_OPCODE_STATS3620 #if ENABLE(OPCODE_STATS) 3602 3621 OpcodeStats::resetLastInstruction(); 3603 3622 #endif … … 3613 3632 newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0); 3614 3633 3615 MACHINE_SAMPLING_callingHostFunction(); 3616 3617 JSValue* returnValue = constructData.native.function(newCallFrame, asObject(v), args); 3618 3634 JSValue* returnValue; 3635 { 3636 SamplingTool::HostCallRecord callRecord(m_sampler); 3637 returnValue = constructData.native.function(newCallFrame, asObject(v), args); 3638 } 3619 3639 VM_CHECK_EXCEPTION(); 3620 3640 callFrame[dst] = returnValue; … … 4795 4815 ArgList argList(argv + 1, argCount - 1); 4796 4816 4797 CTI_MACHINE_SAMPLING_callingHostFunction(); 4798 4799 JSValue* returnValue = callData.native.function(callFrame, asObject(funcVal), argv[0].jsValue(callFrame), argList); 4817 JSValue* returnValue; 4818 { 4819 SamplingTool::HostCallRecord callRecord(CTI_SAMPLER); 4820 returnValue = callData.native.function(callFrame, asObject(funcVal), argv[0].jsValue(callFrame), argList); 4821 } 4800 4822 ARG_setCallFrame(previousCallFrame); 4801 4823 VM_CHECK_EXCEPTION(); … … 5000 5022 ArgList argList(callFrame->registers() + firstArg + 1, argCount - 1); 5001 5023 5002 CTI_MACHINE_SAMPLING_callingHostFunction(); 5003 5004 JSValue* returnValue = constructData.native.function(callFrame, asObject(constrVal), argList); 5024 JSValue* returnValue; 5025 { 5026 SamplingTool::HostCallRecord callRecord(CTI_SAMPLER); 5027 returnValue = constructData.native.function(callFrame, asObject(constrVal), argList); 5028 } 5005 5029 VM_CHECK_EXCEPTION(); 5006 5030 -
trunk/JavaScriptCore/VM/Machine.h
r37845 r37891 158 158 } 159 159 160 SamplingTool* m_sampler; 160 void setSampler(SamplingTool* sampler) { m_sampler = sampler; } 161 SamplingTool* sampler() { return m_sampler; } 161 162 162 163 #if ENABLE(CTI) … … 319 320 void* getCTIStringLengthTrampoline(CallFrame*, CodeBlock*); 320 321 322 JITCodeBuffer* jitCodeBuffer() const { return m_jitCodeBuffer.get(); } 323 #endif 324 325 SamplingTool* m_sampler; 326 327 #if ENABLE(CTI) 321 328 void* m_ctiArrayLengthTrampoline; 322 329 void* m_ctiStringLengthTrampoline; 323 330 324 331 OwnPtr<JITCodeBuffer> m_jitCodeBuffer; 325 JITCodeBuffer* jitCodeBuffer() const { return m_jitCodeBuffer.get(); }326 332 #endif 327 333 -
trunk/JavaScriptCore/VM/Opcode.cpp
r36263 r37891 35 35 namespace JSC { 36 36 37 #if ENABLE( SAMPLING_TOOL) || DUMP_OPCODE_STATS37 #if ENABLE(OPCODE_SAMPLING) || ENABLE(CODEBLOCK_SAMPLING) || ENABLE(OPCODE_STATS) 38 38 39 39 const char* const opcodeNames[] = { … … 45 45 #endif 46 46 47 #if DUMP_OPCODE_STATS47 #if ENABLE(OPCODE_STATS) 48 48 49 49 long long OpcodeStats::opcodeCounts[numOpcodeIDs]; … … 122 122 for (int i = 0; i < numOpcodeIDs; ++i) { 123 123 int index = sortedIndices[i]; 124 printf("%s:%s %lld - %.2f%%\n", opcodeNames[index], padOpcodeName((OpcodeID)index, 2 4), opcodeCounts[index], ((double) opcodeCounts[index]) / ((double) totalInstructions) * 100.0);124 printf("%s:%s %lld - %.2f%%\n", opcodeNames[index], padOpcodeName((OpcodeID)index, 28), opcodeCounts[index], ((double) opcodeCounts[index]) / ((double) totalInstructions) * 100.0); 125 125 } 126 126 … … 135 135 break; 136 136 137 printf("%s%s %s:%s %lld %.2f%%\n", opcodeNames[indexPair.first], padOpcodeName((OpcodeID)indexPair.first, 2 4), opcodeNames[indexPair.second], padOpcodeName((OpcodeID)indexPair.second, 24), count, ((double) count) / ((double) totalInstructionPairs) * 100.0);137 printf("%s%s %s:%s %lld %.2f%%\n", opcodeNames[indexPair.first], padOpcodeName((OpcodeID)indexPair.first, 28), opcodeNames[indexPair.second], padOpcodeName((OpcodeID)indexPair.second, 28), count, ((double) count) / ((double) totalInstructionPairs) * 100.0); 138 138 } 139 139 … … 147 147 if (opcodeProportion < 0.0001) 148 148 break; 149 printf("\n%s:%s %lld - %.2f%%\n", opcodeNames[index], padOpcodeName((OpcodeID)index, 2 4), opcodeCount, opcodeProportion * 100.0);149 printf("\n%s:%s %lld - %.2f%%\n", opcodeNames[index], padOpcodeName((OpcodeID)index, 28), opcodeCount, opcodeProportion * 100.0); 150 150 151 151 for (int j = 0; j < numOpcodeIDs * numOpcodeIDs; ++j) { … … 160 160 continue; 161 161 162 printf(" %s%s %s:%s %lld - %.2f%%\n", opcodeNames[indexPair.first], padOpcodeName((OpcodeID)indexPair.first, 2 4), opcodeNames[indexPair.second], padOpcodeName((OpcodeID)indexPair.second, 24), pairCount, pairProportion * 100.0);162 printf(" %s%s %s:%s %lld - %.2f%%\n", opcodeNames[indexPair.first], padOpcodeName((OpcodeID)indexPair.first, 28), opcodeNames[indexPair.second], padOpcodeName((OpcodeID)indexPair.second, 28), pairCount, pairProportion * 100.0); 163 163 } 164 164 -
trunk/JavaScriptCore/VM/Opcode.h
r37789 r37891 38 38 namespace JSC { 39 39 40 #define DUMP_OPCODE_STATS 041 42 40 #define FOR_EACH_OPCODE_ID(macro) \ 43 41 macro(op_enter) \ … … 183 181 #endif 184 182 185 #if ENABLE( SAMPLING_TOOL) || DUMP_OPCODE_STATS183 #if ENABLE(OPCODE_SAMPLING) || ENABLE(CODEBLOCK_SAMPLING) || ENABLE(OPCODE_STATS) 186 184 187 185 #define PADDING_STRING " " … … 202 200 #endif 203 201 204 #if DUMP_OPCODE_STATS202 #if ENABLE(OPCODE_STATS) 205 203 206 204 struct OpcodeStats { -
trunk/JavaScriptCore/VM/SamplingTool.cpp
r36402 r37891 42 42 void ScopeSampleRecord::sample(CodeBlock* codeBlock, Instruction* vPC) 43 43 { 44 m_totalCount++;45 46 44 if (!m_vpcCounts) { 47 45 m_size = codeBlock->instructions.size(); … … 50 48 } 51 49 52 unsigned codeOffset = static_cast<unsigned>(reinterpret_cast<ptrdiff_t>(vPC) - reinterpret_cast<ptrdiff_t>(codeBlock->instructions.begin())) / sizeof(Instruction*); 53 // This could occur if codeBlock & vPC are not consistent - e.g. sample mid op_call/op_ret. 54 if (codeOffset < m_size) 50 unsigned codeOffset = vPC - codeBlock->instructions.begin(); 51 // Since we don't read and write codeBlock and vPC atomically, this check 52 // can fail if we sample mid op_call / op_ret. 53 if (codeOffset < m_size) { 55 54 m_vpcCounts[codeOffset]++; 55 m_totalCount++; 56 } 56 57 } 57 58 … … 80 81 } 81 82 82 #if ENABLE(SAMPLING_TOOL)83 unsigned totalOpcodeIDCount = 0;84 unsigned opcodeIDCountInCalledCode[numOpcodeIDs] = {0};85 unsigned opcodeIDCountInJITCode[numOpcodeIDs] = {0};86 #endif87 88 83 void SamplingTool::run() 89 84 { … … 91 86 sleepForMicroseconds(hertz2us(m_hertz)); 92 87 93 m_totalSamples++; 94 #if ENABLE(SAMPLING_TOOL) 95 if (currentOpcodeID != static_cast<OpcodeID>(-1)) { 96 ++totalOpcodeIDCount; 97 if (inCalledCode) 98 opcodeIDCountInCalledCode[currentOpcodeID]++; 99 else 100 opcodeIDCountInJITCode[currentOpcodeID]++; 88 Sample sample(m_sample, m_codeBlock); 89 ++m_sampleCount; 90 91 if (sample.isNull()) 92 continue; 93 94 if (!sample.inHostFunction()) { 95 unsigned opcodeID = m_machine->getOpcodeID(sample.vPC()[0].u.opcode); 96 97 ++m_opcodeSampleCount; 98 ++m_opcodeSamples[opcodeID]; 99 100 if (sample.inCTIFunction()) 101 m_opcodeSamplesInCTIFunctions[opcodeID]++; 101 102 } 102 #endif 103 CodeBlock* codeBlock = m_recordedCodeBlock; 104 Instruction* vPC = m_recordedVPC; 105 106 if (codeBlock && vPC) { 107 if (ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerNode)) 108 record->sample(codeBlock, vPC); 109 } 103 104 #if ENABLE(CODEBLOCK_SAMPLING) 105 ScopeSampleRecord* record = m_scopeSampleMap->get(sample.codeBlock()->ownerNode); 106 ASSERT(record); 107 record->sample(sample.codeBlock(), sample.vPC()); 108 #endif 110 109 } 111 110 } … … 138 137 } 139 138 140 #if ENABLE( SAMPLING_TOOL)139 #if ENABLE(OPCODE_SAMPLING) 141 140 142 141 struct OpcodeSampleInfo { 143 142 OpcodeID opcode; 144 143 long long count; 145 long long countInC alledCode;144 long long countInCTIFunctions; 146 145 }; 147 146 … … 178 177 { 179 178 // Tidies up SunSpider output by removing short scripts - such a small number of samples would likely not be useful anyhow. 180 if (m_ totalSamples< 10)179 if (m_sampleCount < 10) 181 180 return; 182 181 183 // (1) Calculate 'totalCodeBlockSamples', build and sort 'codeBlockSamples' array. 182 // (1) Build and sort 'opcodeSampleInfo' array. 183 184 OpcodeSampleInfo opcodeSampleInfo[numOpcodeIDs]; 185 for (int i = 0; i < numOpcodeIDs; ++i) { 186 opcodeSampleInfo[i].opcode = static_cast<OpcodeID>(i); 187 opcodeSampleInfo[i].count = m_opcodeSamples[i]; 188 opcodeSampleInfo[i].countInCTIFunctions = m_opcodeSamplesInCTIFunctions[i]; 189 } 190 191 qsort(opcodeSampleInfo, numOpcodeIDs, sizeof(OpcodeSampleInfo), compareOpcodeIndicesSampling); 192 193 // (2) Print Opcode sampling results. 194 195 printf("\nOpcode samples [*]\n"); 196 printf(" sample %% of %% of | cti cti %%\n"); 197 printf("opcode count VM total | count of self\n"); 198 printf("------------------------------------------------------- | ----------------\n"); 199 200 for (int i = 0; i < numOpcodeIDs; ++i) { 201 long long count = opcodeSampleInfo[i].count; 202 if (!count) 203 continue; 204 205 OpcodeID opcode = opcodeSampleInfo[i].opcode; 206 207 const char* opcodeName = opcodeNames[opcode]; 208 const char* opcodePadding = padOpcodeName(opcode, 28); 209 double percentOfVM = (static_cast<double>(count) * 100) / m_opcodeSampleCount; 210 double percentOfTotal = (static_cast<double>(count) * 100) / m_sampleCount; 211 long long countInCTIFunctions = opcodeSampleInfo[i].countInCTIFunctions; 212 double percentInCTIFunctions = (static_cast<double>(countInCTIFunctions) * 100) / count; 213 fprintf(stdout, "%s:%s%-6lld %.3f%%\t%.3f%%\t | %-6lld %.3f%%\n", opcodeName, opcodePadding, count, percentOfVM, percentOfTotal, countInCTIFunctions, percentInCTIFunctions); 214 } 215 216 printf("\n[*] Samples inside host code are not charged to any Opcode.\n\n"); 217 printf("\tSamples inside VM:\t\t%lld / %lld (%.3f%%)\n", m_opcodeSampleCount, m_sampleCount, (static_cast<double>(m_opcodeSampleCount) * 100) / m_sampleCount); 218 printf("\tSamples inside host code:\t%lld / %lld (%.3f%%)\n\n", m_sampleCount - m_opcodeSampleCount, m_sampleCount, (static_cast<double>(m_sampleCount - m_opcodeSampleCount) * 100) / m_sampleCount); 219 printf("\tsample count:\tsamples inside this opcode\n"); 220 printf("\t%% of VM:\tsample count / all opcode samples\n"); 221 printf("\t%% of total:\tsample count / all samples\n"); 222 printf("\t--------------\n"); 223 printf("\tcti count:\tsamples inside a CTI function called by this opcode\n"); 224 printf("\tcti %% of self:\tcti count / sample count\n"); 225 226 // (3) Calculate 'codeBlockSampleCount', build and sort 'codeBlockSamples' array. 184 227 185 228 int scopeCount = m_scopeSampleMap->size(); 186 long long totalCodeBlockSamples= 0;229 long long codeBlockSampleCount = 0; 187 230 Vector<ScopeSampleRecord*> codeBlockSamples(scopeCount); 188 231 ScopeSampleRecordMap::iterator iter = m_scopeSampleMap->begin(); 189 232 for (int i = 0; i < scopeCount; ++i, ++iter) { 190 233 codeBlockSamples[i] = iter->second; 191 totalCodeBlockSamples+= codeBlockSamples[i]->m_totalCount;234 codeBlockSampleCount += codeBlockSamples[i]->m_totalCount; 192 235 } 193 236 194 237 qsort(codeBlockSamples.begin(), scopeCount, sizeof(ScopeSampleRecord*), compareScopeSampleRecords); 195 238 196 // (2) Print data from 'codeBlockSamples' array, calculate 'totalOpcodeSamples', populate 'opcodeSampleCounts' array. 197 198 long long totalOpcodeSamples = 0; 199 long long opcodeSampleCounts[numOpcodeIDs] = { 0 }; 200 201 printf("\nBlock sampling results\n\n"); 202 printf("Total blocks sampled (total samples): %lld (%lld)\n\n", totalCodeBlockSamples, m_totalSamples); 239 // (4) Print data from 'codeBlockSamples' array. 240 241 printf("\nCodeBlock samples [*]\n\n"); 203 242 204 243 for (int i = 0; i < scopeCount; ++i) { … … 206 245 CodeBlock* codeBlock = record->m_codeBlock; 207 246 208 double totalPercent = (record->m_totalCount * 100.0)/m_totalSamples; 209 double blockPercent = (record->m_totalCount * 100.0)/totalCodeBlockSamples; 210 211 if ((blockPercent >= 1) && codeBlock) { 247 double blockPercent = (record->m_totalCount * 100.0) / codeBlockSampleCount; 248 249 if (blockPercent >= 1) { 212 250 Instruction* code = codeBlock->instructions.begin(); 213 printf("#%d: %s:%d: sampled %d times - %.3f%% (%.3f%%)\n", i + 1, record->m_scope->sourceURL().UTF8String().c_str(), codeBlock->lineNumberForVPC(code), record->m_totalCount, blockPercent, totalPercent);251 printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_scope->sourceURL().UTF8String().c_str(), codeBlock->lineNumberForVPC(code), record->m_totalCount, codeBlockSampleCount, blockPercent); 214 252 if (i < 10) { 215 253 HashMap<unsigned,unsigned> lineCounts; … … 240 278 } 241 279 } 242 243 if (record->m_vpcCounts && codeBlock) { 244 Instruction* instructions = codeBlock->instructions.begin(); 245 for (unsigned op = 0; op < record->m_size; ++op) { 246 Opcode opcode = instructions[op].u.opcode; 247 if (exec->machine()->isOpcode(opcode)) { 248 totalOpcodeSamples += record->m_vpcCounts[op]; 249 opcodeSampleCounts[exec->machine()->getOpcodeID(opcode)] += record->m_vpcCounts[op]; 250 } 251 } 252 } 253 } 254 printf("\n"); 255 256 // (3) Build and sort 'opcodeSampleInfo' array. 257 258 OpcodeSampleInfo opcodeSampleInfo[numOpcodeIDs]; 259 for (int i = 0; i < numOpcodeIDs; ++i) { 260 opcodeSampleInfo[i].opcode = static_cast<OpcodeID>(i); 261 opcodeSampleInfo[i].count = opcodeIDCountInJITCode[i] + opcodeIDCountInCalledCode[i]; 262 opcodeSampleInfo[i].countInCalledCode = opcodeIDCountInCalledCode[i]; 263 } 264 265 qsort(opcodeSampleInfo, numOpcodeIDs, sizeof(OpcodeSampleInfo), compareOpcodeIndicesSampling); 266 267 // (4) Print Opcode sampling results. 268 269 printf("\nOpcode sampling results\n\n"); 270 271 for (int i = 0; i < numOpcodeIDs; ++i) { 272 OpcodeID opcode = opcodeSampleInfo[i].opcode; 273 long long count = opcodeSampleInfo[i].count; 274 long long countInCalledCode = opcodeSampleInfo[i].countInCalledCode; 275 fprintf(stdout, "%s:%s%6lld\t%6lld\t%.3f%%\t%.3f%%\t(%.3f%%)\n", opcodeNames[opcode], padOpcodeName(opcode, 20), count, countInCalledCode, (static_cast<double>(count) * 100) / totalOpcodeIDCount, (static_cast<double>(count) * 100) / m_totalSamples, (static_cast<double>(countInCalledCode) * 100) / m_totalSamples); 276 } 277 printf("\n"); 280 } 281 282 printf("\n[*] Samples inside host code are charged to the calling Opcode.\n"); 283 printf(" Samples that fall on a call / return boundary are discarded.\n\n"); 284 printf("\tSamples discarded:\t\t%lld / %lld (%.3f%%)\n\n", m_sampleCount - codeBlockSampleCount, m_sampleCount, (static_cast<double>(m_sampleCount - codeBlockSampleCount) * 100) / m_sampleCount); 278 285 } 279 286 -
trunk/JavaScriptCore/VM/SamplingTool.h
r37316 r37891 34 34 #include <wtf/Threading.h> 35 35 36 #include <nodes.h>37 #include <Opcode.h>36 #include "nodes.h" 37 #include "Opcode.h" 38 38 39 39 namespace JSC { 40 40 41 class CodeBlock; 41 42 class ExecState; 43 class Machine; 42 44 class ScopeNode; 43 class CodeBlock;44 45 struct Instruction; 45 46 #if ENABLE(SAMPLING_TOOL)47 extern OpcodeID currentOpcodeID;48 extern unsigned inCalledCode;49 #endif50 46 51 47 struct ScopeSampleRecord { … … 71 67 } 72 68 73 void sample(CodeBlock* codeBlock, Instruction* vPC);69 void sample(CodeBlock*, Instruction*); 74 70 }; 75 71 … … 78 74 class SamplingTool { 79 75 public: 80 SamplingTool() 81 : m_running(false) 82 , m_recordedCodeBlock(0) 83 , m_recordedVPC(0) 84 , m_totalSamples(0) 76 friend class CallRecord; 77 friend class HostCallRecord; 78 79 #if ENABLE(OPCODE_SAMPLING) 80 class CallRecord : Noncopyable { 81 public: 82 CallRecord(SamplingTool* samplingTool) 83 : m_samplingTool(samplingTool) 84 , m_savedSample(samplingTool->m_sample) 85 , m_savedCodeBlock(samplingTool->m_codeBlock) 86 { 87 } 88 89 ~CallRecord() 90 { 91 m_samplingTool->m_sample = m_savedSample; 92 m_samplingTool->m_codeBlock = m_savedCodeBlock; 93 } 94 95 private: 96 SamplingTool* m_samplingTool; 97 intptr_t m_savedSample; 98 CodeBlock* m_savedCodeBlock; 99 }; 100 101 class HostCallRecord : public CallRecord { 102 public: 103 HostCallRecord(SamplingTool* samplingTool) 104 : CallRecord(samplingTool) 105 { 106 samplingTool->m_sample |= 0x1; 107 } 108 }; 109 #else 110 class CallRecord : Noncopyable { 111 public: 112 CallRecord(SamplingTool*) 113 { 114 } 115 }; 116 117 class HostCallRecord : public CallRecord { 118 public: 119 HostCallRecord(SamplingTool* samplingTool) 120 : CallRecord(samplingTool) 121 { 122 } 123 }; 124 #endif 125 126 SamplingTool(Machine* machine) 127 : m_machine(machine) 128 , m_running(false) 129 , m_codeBlock(0) 130 , m_sample(0) 131 , m_sampleCount(0) 132 , m_opcodeSampleCount(0) 85 133 , m_scopeSampleMap(new ScopeSampleRecordMap()) 86 134 { 135 memset(m_opcodeSamples, 0, sizeof(m_opcodeSamples)); 136 memset(m_opcodeSamplesInCTIFunctions, 0, sizeof(m_opcodeSamplesInCTIFunctions)); 87 137 } 88 138 … … 98 148 void notifyOfScope(ScopeNode* scope); 99 149 100 void sample(CodeBlock* recordedCodeBlock, Instruction* recordedVPC) 101 { 102 m_recordedCodeBlock = recordedCodeBlock; 103 m_recordedVPC = recordedVPC; 104 } 105 106 void privateExecuteReturned() 107 { 108 m_recordedCodeBlock = 0; 109 m_recordedVPC = 0; 110 #if ENABLE(SAMPLING_TOOL) 111 currentOpcodeID = static_cast<OpcodeID>(-1); 112 #endif 113 } 114 115 void callingHostFunction() 116 { 117 m_recordedCodeBlock = 0; 118 m_recordedVPC = 0; 119 #if ENABLE(SAMPLING_TOOL) 120 currentOpcodeID = static_cast<OpcodeID>(-1); 121 #endif 150 void sample(CodeBlock* codeBlock, Instruction* vPC) 151 { 152 ASSERT(!(reinterpret_cast<intptr_t>(vPC) & 0x3)); 153 m_codeBlock = codeBlock; 154 m_sample = reinterpret_cast<intptr_t>(vPC); 155 } 156 157 CodeBlock** codeBlockSlot() { return &m_codeBlock; } 158 intptr_t* sampleSlot() { return &m_sample; } 159 160 unsigned encodeSample(Instruction* vPC, bool inCTIFunction = false, bool inHostFunction = false) 161 { 162 ASSERT(!(reinterpret_cast<intptr_t>(vPC) & 0x3)); 163 return reinterpret_cast<intptr_t>(vPC) | (inCTIFunction << 1) | inHostFunction; 122 164 } 123 165 124 166 private: 167 class Sample { 168 public: 169 Sample(volatile intptr_t sample, CodeBlock* volatile codeBlock) 170 : m_sample(sample) 171 , m_codeBlock(codeBlock) 172 { 173 } 174 175 bool isNull() { return !m_sample || !m_codeBlock; } 176 CodeBlock* codeBlock() { return m_codeBlock; } 177 Instruction* vPC() { return reinterpret_cast<Instruction*>(m_sample & ~0x3); } 178 bool inHostFunction() { return m_sample & 0x1; } 179 bool inCTIFunction() { return m_sample & 0x2; } 180 181 private: 182 intptr_t m_sample; 183 CodeBlock* m_codeBlock; 184 }; 185 125 186 static void* threadStartFunc(void*); 126 187 void run(); 188 189 Machine* m_machine; 127 190 128 191 // Sampling thread state. … … 132 195 133 196 // State tracked by the main thread, used by the sampling thread. 134 CodeBlock* m_ recordedCodeBlock;135 Instruction* m_recordedVPC;197 CodeBlock* m_codeBlock; 198 intptr_t m_sample; 136 199 137 200 // Gathered sample data. 138 long long m_totalSamples; 201 long long m_sampleCount; 202 long long m_opcodeSampleCount; 203 unsigned m_opcodeSamples[numOpcodeIDs]; 204 unsigned m_opcodeSamplesInCTIFunctions[numOpcodeIDs]; 139 205 OwnPtr<ScopeSampleRecordMap> m_scopeSampleMap; 140 206 }; 141 207 142 // SCOPENODE_ / MACHINE_ macros for use from within member methods on ScopeNode / Machine respectively.143 #if ENABLE(SAMPLING_TOOL)144 #define SCOPENODE_SAMPLING_notifyOfScope(sampler) sampler->notifyOfScope(this)145 #define MACHINE_SAMPLING_sample(codeBlock, vPC) m_sampler->sample(codeBlock, vPC)146 #define MACHINE_SAMPLING_privateExecuteReturned() m_sampler->privateExecuteReturned()147 #define MACHINE_SAMPLING_callingHostFunction() m_sampler->callingHostFunction()148 #define CTI_MACHINE_SAMPLING_callingHostFunction() ARG_globalData->machine->m_sampler->callingHostFunction()149 #else150 #define SCOPENODE_SAMPLING_notifyOfScope(sampler)151 #define MACHINE_SAMPLING_sample(codeBlock, vPC)152 #define MACHINE_SAMPLING_privateExecuteReturned()153 #define MACHINE_SAMPLING_callingHostFunction()154 #define CTI_MACHINE_SAMPLING_callingHostFunction()155 #endif156 157 208 } // namespace JSC 158 209
Note:
See TracChangeset
for help on using the changeset viewer.