Changeset 37891 in webkit for trunk/JavaScriptCore
- Timestamp:
- Oct 25, 2008, 12:59:47 PM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r37888 r37891 1 2008-10-25 Geoffrey Garen <[email protected]> 2 3 Reviewed by Sam Weinig, with Gavin Barraclough's help. 4 5 Fixed Sampling Tool: 6 - Made CodeBlock sampling work with CTI 7 - Improved accuracy by unifying most sampling data into a single 8 32bit word, which can be written / read atomically. 9 - Split out three different #ifdefs for modularity: OPCODE_SAMPLING; 10 CODEBLOCK_SAMPLING; OPCODE_STATS. 11 - Improved reporting clarity 12 - Refactored for code clarity 13 14 * JavaScriptCore.exp: Exported another symbol. 15 16 * VM/CTI.cpp: 17 (JSC::CTI::emitCTICall): 18 (JSC::CTI::compileOpCall): 19 (JSC::CTI::emitSlowScriptCheck): 20 (JSC::CTI::compileBinaryArithOpSlowCase): 21 (JSC::CTI::privateCompileMainPass): 22 (JSC::CTI::privateCompileSlowCases): 23 (JSC::CTI::privateCompile): 24 * VM/CTI.h: Updated CTI codegen to use the unified SamplingTool interface 25 for encoding samples. (This required passing the current vPC to a lot 26 more functions, since the unified interface samples the current vPC.) 27 Added hooks for writing the current CodeBlock* on function entry and 28 after a function call, for the sake of the CodeBlock sampler. Removed 29 obsolete hook for clearing the current sample inside op_end. Also removed 30 the custom enum used to differentiate flavors of op_call, since the 31 OpcodeID enum works just as well. (This was important in an earlier 32 version of the patch, but now it's just cleanup.) 33 34 * VM/CodeBlock.cpp: 35 (JSC::CodeBlock::lineNumberForVPC): 36 * VM/CodeBlock.h: Upated for refactored #ifdefs. Changed lineNumberForVPC 37 to be robust against vPCs not recorded for exception handling, since 38 the Sampler may ask for an arbitrary vPC. 39 40 * VM/Machine.cpp: 41 (JSC::Machine::execute): 42 (JSC::Machine::privateExecute): 43 (JSC::Machine::cti_op_call_NotJSFunction): 44 (JSC::Machine::cti_op_construct_NotJSConstruct): 45 * VM/Machine.h: 46 (JSC::Machine::setSampler): 47 (JSC::Machine::sampler): 48 (JSC::Machine::jitCodeBuffer): Upated for refactored #ifdefs. Changed 49 Machine to use SamplingTool helper objects to record movement in and 50 out of host code. This makes samples a bit more precise. 51 52 * VM/Opcode.cpp: 53 (JSC::OpcodeStats::~OpcodeStats): 54 * VM/Opcode.h: Upated for refactored #ifdefs. Added a little more padding, 55 to accomodate our more verbose opcode names. 56 57 * VM/SamplingTool.cpp: 58 (JSC::ScopeSampleRecord::sample): Only count a sample toward our total 59 if we actually record it. This solves cases where a CodeBlock will 60 claim to have been sampled many times, with reported samples that don't 61 match. 62 63 (JSC::SamplingTool::run): Read the current sample into a Sample helper 64 object, to ensure that the data doesn't change while we're analyzing it, 65 and to help decode the data. Only access the CodeBlock sampling hash 66 table if CodeBlock sampling has been enabled, so non-CodeBlock sampling 67 runs can operate with even less overhead. 68 69 (JSC::SamplingTool::dump): I reorganized this code a lot to print the 70 most important info at the top, print as a table, annotate and document 71 the stuff I didn't understand when I started, etc. 72 73 * VM/SamplingTool.h: New helper classes, described above. 74 75 * kjs/Parser.h: 76 * kjs/Shell.cpp: 77 (runWithScripts): 78 * kjs/nodes.cpp: 79 (JSC::ScopeNode::ScopeNode): Updated for new sampling APIs. 80 81 * wtf/Platform.h: Moved sampling #defines here, since our custom is to 82 put ENABLE #defines into Platform.h. Made explicit the fact that 83 CODEBLOCK_SAMPLING depends on OPCODE_SAMPLING. 84 1 85 2008-10-25 Jan Michael Alonzo <[email protected]> 2 86 -
trunk/JavaScriptCore/JavaScriptCore.exp
r37812 r37891 125 125 __ZN3JSC12JSGlobalData6createEv 126 126 __ZN3JSC12JSGlobalDataD1Ev 127 __ZN3JSC12SamplingTool13notifyOfScopeEPNS_9ScopeNodeE 127 128 __ZN3JSC12SamplingTool4dumpEPNS_9ExecStateE 128 129 __ZN3JSC12SamplingTool4stopEv -
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 -
trunk/JavaScriptCore/kjs/Parser.h
r37622 r37891 24 24 #define Parser_h 25 25 26 #include "SourceProvider.h" 26 27 #include "debugger.h" 27 #include "SourceProvider.h"28 28 #include "nodes.h" 29 29 #include <wtf/Forward.h> -
trunk/JavaScriptCore/kjs/Shell.cpp
r37845 r37891 323 323 CodeGenerator::setDumpsGeneratedCode(true); 324 324 325 #if ENABLE( SAMPLING_TOOL)325 #if ENABLE(OPCODE_SAMPLING) 326 326 Machine* machine = globalObject->globalData()->machine; 327 machine->m_sampler = new SamplingTool(); 328 machine->m_sampler->start(); 327 machine->setSampler(new SamplingTool(machine)); 329 328 #endif 330 329 … … 339 338 prettyPrintScript(globalObject->globalExec(), fileName, script); 340 339 else { 340 #if ENABLE(OPCODE_SAMPLING) 341 machine->sampler()->start(); 342 #endif 341 343 Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName)); 342 344 success = success && completion.complType() != Throw; … … 349 351 350 352 globalObject->globalExec()->clearException(); 351 } 352 } 353 354 #if ENABLE(SAMPLING_TOOL) 355 machine->m_sampler->stop(); 356 machine->m_sampler->dump(globalObject->globalExec()); 357 delete machine->m_sampler; 353 354 #if ENABLE(OPCODE_SAMPLING) 355 machine->sampler()->stop(); 356 #endif 357 } 358 } 359 360 #if ENABLE(OPCODE_SAMPLING) 361 machine->sampler()->dump(globalObject->globalExec()); 362 delete machine->sampler(); 358 363 #endif 359 364 return success; -
trunk/JavaScriptCore/kjs/nodes.cpp
r37859 r37891 34 34 #include "PropertyNameArray.h" 35 35 #include "RegExpObject.h" 36 #include "SamplingTool.h" 36 37 #include "debugger.h" 37 38 #include "lexer.h" 38 39 #include "operations.h" 39 #include "SamplingTool.h"40 40 #include <math.h> 41 41 #include <wtf/Assertions.h> … … 1699 1699 if (funcStack) 1700 1700 m_functionStack = *funcStack; 1701 1702 SCOPENODE_SAMPLING_notifyOfScope(globalData->machine->m_sampler); 1701 #if ENABLE(OPCODE_SAMPLING) 1702 globalData->machine->sampler()->notifyOfScope(this); 1703 #endif 1703 1704 } 1704 1705 -
trunk/JavaScriptCore/wtf/Platform.h
r37854 r37891 348 348 #endif 349 349 350 #if !defined(ENABLE_SAMPLING_TOOL) 351 #define ENABLE_SAMPLING_TOOL 0 350 #if !defined(ENABLE_OPCODE_STATS) 351 #define ENABLE_OPCODE_STATS 0 352 #endif 353 354 #if !defined(ENABLE_CODEBLOCK_SAMPLING) 355 #define ENABLE_CODEBLOCK_SAMPLING 0 356 #endif 357 358 #if ENABLE(CODEBLOCK_SAMPLING) && !defined(ENABLE_OPCODE_SAMPLING) 359 #define ENABLE_OPCODE_SAMPLING 1 360 #endif 361 362 #if !defined(ENABLE_OPCODE_SAMPLING) 363 #define ENABLE_OPCODE_SAMPLING 0 352 364 #endif 353 365
Note:
See TracChangeset
for help on using the changeset viewer.