Changeset 211194 in webkit for trunk/Source/JavaScriptCore/jsc.cpp
- Timestamp:
- Jan 25, 2017, 6:34:30 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/jsc.cpp
r211070 r211194 64 64 #include "ProfilerDatabase.h" 65 65 #include "ProtoCallFrame.h" 66 #include "ReleaseHeapAccessScope.h" 66 67 #include "SamplingProfiler.h" 67 68 #include "ShadowChicken.h" … … 908 909 909 910 static bool fillBufferWithContentsOfFile(const String& fileName, Vector<char>& buffer); 911 912 class CommandLine; 913 class GlobalObject; 914 class Workers; 915 916 template<typename Func> 917 int runJSC(CommandLine, const Func&); 918 static void checkException(GlobalObject*, bool isLastFile, bool hasException, JSValue, const String& uncaughtExceptionName, bool alwaysDumpUncaughtException, bool dump, bool& success); 919 920 class Message : public ThreadSafeRefCounted<Message> { 921 public: 922 Message(ArrayBufferContents&&, int32_t); 923 ~Message(); 924 925 ArrayBufferContents&& releaseContents() { return WTFMove(m_contents); } 926 int32_t index() const { return m_index; } 927 928 private: 929 ArrayBufferContents m_contents; 930 int32_t m_index { 0 }; 931 }; 932 933 class Worker : public BasicRawSentinelNode<Worker> { 934 public: 935 Worker(Workers&); 936 ~Worker(); 937 938 void enqueue(const AbstractLocker&, RefPtr<Message>); 939 RefPtr<Message> dequeue(); 940 941 static Worker& current(); 942 943 private: 944 static ThreadSpecific<Worker*>& currentWorker(); 945 946 Workers& m_workers; 947 Deque<RefPtr<Message>> m_messages; 948 }; 949 950 class Workers { 951 public: 952 Workers(); 953 ~Workers(); 954 955 template<typename Func> 956 void broadcast(const Func&); 957 958 void report(String); 959 String tryGetReport(); 960 String getReport(); 961 962 static Workers& singleton(); 963 964 private: 965 friend class Worker; 966 967 Lock m_lock; 968 Condition m_condition; 969 SentinelLinkedList<Worker, BasicRawSentinelNode<Worker>> m_workers; 970 Deque<String> m_reports; 971 }; 910 972 911 973 static EncodedJSValue JSC_HOST_CALL functionCreateProxy(ExecState*); … … 1013 1075 static EncodedJSValue JSC_HOST_CALL functionCallerSourceOrigin(ExecState*); 1014 1076 static EncodedJSValue JSC_HOST_CALL functionGlobalObjectForObject(ExecState*); 1077 static EncodedJSValue JSC_HOST_CALL functionDollarCreateRealm(ExecState*); 1078 static EncodedJSValue JSC_HOST_CALL functionDollarDetachArrayBuffer(ExecState*); 1079 static EncodedJSValue JSC_HOST_CALL functionDollarEvalScript(ExecState*); 1080 static EncodedJSValue JSC_HOST_CALL functionDollarAgentStart(ExecState*); 1081 static EncodedJSValue JSC_HOST_CALL functionDollarAgentReceiveBroadcast(ExecState*); 1082 static EncodedJSValue JSC_HOST_CALL functionDollarAgentReport(ExecState*); 1083 static EncodedJSValue JSC_HOST_CALL functionDollarAgentSleep(ExecState*); 1084 static EncodedJSValue JSC_HOST_CALL functionDollarAgentBroadcast(ExecState*); 1085 static EncodedJSValue JSC_HOST_CALL functionDollarAgentGetReport(ExecState*); 1086 static EncodedJSValue JSC_HOST_CALL functionDollarAgentLeaving(ExecState*); 1087 static EncodedJSValue JSC_HOST_CALL functionWaitForReport(ExecState*); 1015 1088 1016 1089 struct Script { … … 1267 1340 1268 1341 putDirect(vm, Identifier::fromString(globalExec(), "console"), jsUndefined()); 1342 1343 Structure* plainObjectStructure = JSFinalObject::createStructure(vm, this, objectPrototype(), 0); 1344 1345 JSObject* dollar = JSFinalObject::create(vm, plainObjectStructure); 1346 putDirect(vm, Identifier::fromString(globalExec(), "$"), dollar); 1347 1348 addFunction(vm, dollar, "createRealm", functionDollarCreateRealm, 0); 1349 addFunction(vm, dollar, "detachArrayBuffer", functionDollarDetachArrayBuffer, 1); 1350 addFunction(vm, dollar, "evalScript", functionDollarEvalScript, 1); 1351 1352 dollar->putDirect(vm, Identifier::fromString(globalExec(), "global"), this); 1353 1354 JSObject* agent = JSFinalObject::create(vm, plainObjectStructure); 1355 dollar->putDirect(vm, Identifier::fromString(globalExec(), "agent"), agent); 1356 1357 // The test262 INTERPRETING.md document says that some of these functions are just in the main 1358 // thread and some are in the other threads. We just put them in all threads. 1359 addFunction(vm, agent, "start", functionDollarAgentStart, 1); 1360 addFunction(vm, agent, "receiveBroadcast", functionDollarAgentReceiveBroadcast, 1); 1361 addFunction(vm, agent, "report", functionDollarAgentReport, 1); 1362 addFunction(vm, agent, "sleep", functionDollarAgentSleep, 1); 1363 addFunction(vm, agent, "broadcast", functionDollarAgentBroadcast, 1); 1364 addFunction(vm, agent, "getReport", functionDollarAgentGetReport, 0); 1365 addFunction(vm, agent, "leaving", functionDollarAgentLeaving, 0); 1366 1367 addFunction(vm, "waitForReport", functionWaitForReport, 0); 1368 } 1369 1370 void addFunction(VM& vm, JSObject* object, const char* name, NativeFunction function, unsigned arguments) 1371 { 1372 Identifier identifier = Identifier::fromString(&vm, name); 1373 object->putDirect(vm, identifier, JSFunction::create(vm, this, arguments, identifier.string(), function)); 1269 1374 } 1270 1375 1271 1376 void addFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments) 1272 1377 { 1273 Identifier identifier = Identifier::fromString(&vm, name); 1274 putDirect(vm, identifier, JSFunction::create(vm, this, arguments, identifier.string(), function)); 1378 addFunction(vm, this, name, function, arguments); 1275 1379 } 1276 1380 … … 1663 1767 EncodedJSValue JSC_HOST_CALL functionSleepSeconds(ExecState* exec) 1664 1768 { 1665 if (exec->argumentCount() >= 1) 1666 sleep(exec->argument(0).toNumber(exec)); 1769 VM& vm = exec->vm(); 1770 auto scope = DECLARE_THROW_SCOPE(vm); 1771 1772 if (exec->argumentCount() >= 1) { 1773 Seconds seconds = Seconds(exec->argument(0).toNumber(exec)); 1774 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 1775 sleep(seconds); 1776 } 1777 1667 1778 return JSValue::encode(jsUndefined()); 1668 1779 } … … 2220 2331 { 2221 2332 return JSValue::encode(numberOfDFGCompiles(exec)); 2333 } 2334 2335 Message::Message(ArrayBufferContents&& contents, int32_t index) 2336 : m_contents(WTFMove(contents)) 2337 , m_index(index) 2338 { 2339 } 2340 2341 Message::~Message() 2342 { 2343 } 2344 2345 Worker::Worker(Workers& workers) 2346 : m_workers(workers) 2347 { 2348 auto locker = holdLock(m_workers.m_lock); 2349 m_workers.m_workers.append(this); 2350 2351 *currentWorker() = this; 2352 } 2353 2354 Worker::~Worker() 2355 { 2356 auto locker = holdLock(m_workers.m_lock); 2357 RELEASE_ASSERT(isOnList()); 2358 remove(); 2359 } 2360 2361 void Worker::enqueue(const AbstractLocker&, RefPtr<Message> message) 2362 { 2363 m_messages.append(message); 2364 } 2365 2366 RefPtr<Message> Worker::dequeue() 2367 { 2368 auto locker = holdLock(m_workers.m_lock); 2369 while (m_messages.isEmpty()) 2370 m_workers.m_condition.wait(m_workers.m_lock); 2371 return m_messages.takeFirst(); 2372 } 2373 2374 Worker& Worker::current() 2375 { 2376 return **currentWorker(); 2377 } 2378 2379 ThreadSpecific<Worker*>& Worker::currentWorker() 2380 { 2381 static ThreadSpecific<Worker*>* result; 2382 static std::once_flag flag; 2383 std::call_once( 2384 flag, 2385 [] () { 2386 result = new ThreadSpecific<Worker*>(); 2387 }); 2388 return *result; 2389 } 2390 2391 Workers::Workers() 2392 { 2393 } 2394 2395 Workers::~Workers() 2396 { 2397 UNREACHABLE_FOR_PLATFORM(); 2398 } 2399 2400 template<typename Func> 2401 void Workers::broadcast(const Func& func) 2402 { 2403 auto locker = holdLock(m_lock); 2404 for (Worker* worker = m_workers.begin(); worker != m_workers.end(); worker = worker->next()) { 2405 if (worker != &Worker::current()) 2406 func(locker, *worker); 2407 } 2408 m_condition.notifyAll(); 2409 } 2410 2411 void Workers::report(String string) 2412 { 2413 auto locker = holdLock(m_lock); 2414 m_reports.append(string.isolatedCopy()); 2415 m_condition.notifyAll(); 2416 } 2417 2418 String Workers::tryGetReport() 2419 { 2420 auto locker = holdLock(m_lock); 2421 if (m_reports.isEmpty()) 2422 return String(); 2423 return m_reports.takeFirst(); 2424 } 2425 2426 String Workers::getReport() 2427 { 2428 auto locker = holdLock(m_lock); 2429 while (m_reports.isEmpty()) 2430 m_condition.wait(m_lock); 2431 return m_reports.takeFirst(); 2432 } 2433 2434 Workers& Workers::singleton() 2435 { 2436 static Workers* result; 2437 static std::once_flag flag; 2438 std::call_once( 2439 flag, 2440 [] { 2441 result = new Workers(); 2442 }); 2443 return *result; 2444 } 2445 2446 EncodedJSValue JSC_HOST_CALL functionDollarCreateRealm(ExecState* exec) 2447 { 2448 VM& vm = exec->vm(); 2449 GlobalObject* result = GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), Vector<String>()); 2450 return JSValue::encode(result->getDirect(vm, Identifier::fromString(exec, "$"))); 2451 } 2452 2453 EncodedJSValue JSC_HOST_CALL functionDollarDetachArrayBuffer(ExecState* exec) 2454 { 2455 return functionTransferArrayBuffer(exec); 2456 } 2457 2458 EncodedJSValue JSC_HOST_CALL functionDollarEvalScript(ExecState* exec) 2459 { 2460 VM& vm = exec->vm(); 2461 auto scope = DECLARE_THROW_SCOPE(vm); 2462 2463 String sourceCode = exec->argument(0).toWTFString(exec); 2464 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 2465 2466 GlobalObject* globalObject = jsDynamicCast<GlobalObject*>( 2467 exec->thisValue().get(exec, Identifier::fromString(exec, "global"))); 2468 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 2469 if (!globalObject) 2470 return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Expected global to point to a global object")))); 2471 2472 NakedPtr<Exception> evaluationException; 2473 JSValue result = evaluate(globalObject->globalExec(), makeSource(sourceCode, exec->callerSourceOrigin()), JSValue(), evaluationException); 2474 if (evaluationException) 2475 throwException(exec, scope, evaluationException); 2476 return JSValue::encode(result); 2477 } 2478 2479 EncodedJSValue JSC_HOST_CALL functionDollarAgentStart(ExecState* exec) 2480 { 2481 VM& vm = exec->vm(); 2482 auto scope = DECLARE_THROW_SCOPE(vm); 2483 2484 String sourceCode = exec->argument(0).toWTFString(exec).isolatedCopy(); 2485 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 2486 2487 Lock didStartLock; 2488 Condition didStartCondition; 2489 bool didStart = false; 2490 2491 ThreadIdentifier thread = createThread( 2492 "JSC Agent", 2493 [sourceCode, &didStartLock, &didStartCondition, &didStart] () { 2494 CommandLine commandLine(0, nullptr); 2495 commandLine.m_interactive = false; 2496 runJSC( 2497 commandLine, 2498 [&] (VM&, GlobalObject* globalObject) { 2499 // Notify the thread that started us that we have registered a worker. 2500 { 2501 auto locker = holdLock(didStartLock); 2502 didStart = true; 2503 didStartCondition.notifyOne(); 2504 } 2505 2506 NakedPtr<Exception> evaluationException; 2507 bool success = true; 2508 JSValue result; 2509 result = evaluate(globalObject->globalExec(), makeSource(sourceCode, SourceOrigin(ASCIILiteral("worker"))), JSValue(), evaluationException); 2510 if (evaluationException) 2511 result = evaluationException->value(); 2512 checkException(globalObject, true, evaluationException, result, String(), false, false, success); 2513 if (!success) 2514 exit(1); 2515 return success; 2516 }); 2517 }); 2518 detachThread(thread); 2519 2520 { 2521 auto locker = holdLock(didStartLock); 2522 while (!didStart) 2523 didStartCondition.wait(didStartLock); 2524 } 2525 2526 return JSValue::encode(jsUndefined()); 2527 } 2528 2529 EncodedJSValue JSC_HOST_CALL functionDollarAgentReceiveBroadcast(ExecState* exec) 2530 { 2531 VM& vm = exec->vm(); 2532 auto scope = DECLARE_THROW_SCOPE(vm); 2533 2534 JSValue callback = exec->argument(0); 2535 CallData callData; 2536 CallType callType = getCallData(callback, callData); 2537 if (callType == CallType::None) 2538 return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Expected callback")))); 2539 2540 RefPtr<Message> message; 2541 { 2542 ReleaseHeapAccessScope releaseAccess(vm.heap); 2543 message = Worker::current().dequeue(); 2544 } 2545 2546 RefPtr<ArrayBuffer> nativeBuffer = ArrayBuffer::create(message->releaseContents()); 2547 JSArrayBuffer* jsBuffer = JSArrayBuffer::create(vm, exec->lexicalGlobalObject()->arrayBufferStructure(nativeBuffer->sharingMode()), nativeBuffer); 2548 2549 MarkedArgumentBuffer args; 2550 args.append(jsBuffer); 2551 args.append(jsNumber(message->index())); 2552 return JSValue::encode(call(exec, callback, callType, callData, jsNull(), args)); 2553 } 2554 2555 EncodedJSValue JSC_HOST_CALL functionDollarAgentReport(ExecState* exec) 2556 { 2557 VM& vm = exec->vm(); 2558 auto scope = DECLARE_THROW_SCOPE(vm); 2559 2560 String report = exec->argument(0).toWTFString(exec); 2561 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 2562 2563 Workers::singleton().report(report); 2564 2565 return JSValue::encode(jsUndefined()); 2566 } 2567 2568 EncodedJSValue JSC_HOST_CALL functionDollarAgentSleep(ExecState* exec) 2569 { 2570 VM& vm = exec->vm(); 2571 auto scope = DECLARE_THROW_SCOPE(vm); 2572 2573 if (exec->argumentCount() >= 1) { 2574 Seconds seconds = Seconds::fromMilliseconds(exec->argument(0).toNumber(exec)); 2575 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 2576 sleep(seconds); 2577 } 2578 return JSValue::encode(jsUndefined()); 2579 } 2580 2581 EncodedJSValue JSC_HOST_CALL functionDollarAgentBroadcast(ExecState* exec) 2582 { 2583 VM& vm = exec->vm(); 2584 auto scope = DECLARE_THROW_SCOPE(vm); 2585 2586 JSArrayBuffer* jsBuffer = jsDynamicCast<JSArrayBuffer*>(exec->argument(0)); 2587 if (!jsBuffer || !jsBuffer->isShared()) 2588 return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Expected SharedArrayBuffer")))); 2589 2590 int32_t index = exec->argument(1).toInt32(exec); 2591 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 2592 2593 Workers::singleton().broadcast( 2594 [&] (const AbstractLocker& locker, Worker& worker) { 2595 ArrayBuffer* nativeBuffer = jsBuffer->impl(); 2596 ArrayBufferContents contents; 2597 nativeBuffer->transferTo(contents); // "transferTo" means "share" if the buffer is shared. 2598 RefPtr<Message> message = adoptRef(new Message(WTFMove(contents), index)); 2599 worker.enqueue(locker, message); 2600 }); 2601 2602 return JSValue::encode(jsUndefined()); 2603 } 2604 2605 EncodedJSValue JSC_HOST_CALL functionDollarAgentGetReport(ExecState* exec) 2606 { 2607 VM& vm = exec->vm(); 2608 2609 String string = Workers::singleton().tryGetReport(); 2610 if (!string) 2611 return JSValue::encode(jsNull()); 2612 2613 return JSValue::encode(jsString(&vm, string)); 2614 } 2615 2616 EncodedJSValue JSC_HOST_CALL functionDollarAgentLeaving(ExecState*) 2617 { 2618 return JSValue::encode(jsUndefined()); 2619 } 2620 2621 EncodedJSValue JSC_HOST_CALL functionWaitForReport(ExecState* exec) 2622 { 2623 VM& vm = exec->vm(); 2624 2625 String string; 2626 { 2627 ReleaseHeapAccessScope releaseAccess(vm.heap); 2628 string = Workers::singleton().getReport(); 2629 } 2630 if (!string) 2631 return JSValue::encode(jsNull()); 2632 2633 return JSValue::encode(jsString(&vm, string)); 2222 2634 } 2223 2635 … … 2905 3317 } 2906 3318 3319 static void checkException(GlobalObject* globalObject, bool isLastFile, bool hasException, JSValue value, const String& uncaughtExceptionName, bool alwaysDumpUncaughtException, bool dump, bool& success) 3320 { 3321 VM& vm = globalObject->vm(); 3322 if (!uncaughtExceptionName || !isLastFile) { 3323 success = success && !hasException; 3324 if (dump && !hasException) 3325 printf("End: %s\n", value.toWTFString(globalObject->globalExec()).utf8().data()); 3326 if (hasException) 3327 dumpException(globalObject, value); 3328 } else 3329 success = success && checkUncaughtException(vm, globalObject, (hasException) ? value : JSValue(), uncaughtExceptionName, alwaysDumpUncaughtException); 3330 } 3331 2907 3332 static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scripts, const String& uncaughtExceptionName, bool alwaysDumpUncaughtException, bool dump, bool module) 2908 3333 { … … 2916 3341 auto scope = DECLARE_CATCH_SCOPE(vm); 2917 3342 bool success = true; 2918 2919 auto checkException = [&] (bool isLastFile, bool hasException, JSValue value) {2920 if (!uncaughtExceptionName || !isLastFile) {2921 success = success && !hasException;2922 if (dump && !hasException)2923 printf("End: %s\n", value.toWTFString(globalObject->globalExec()).utf8().data());2924 if (hasException)2925 dumpException(globalObject, value);2926 } else2927 success = success && checkUncaughtException(vm, globalObject, (hasException) ? value : JSValue(), uncaughtExceptionName, alwaysDumpUncaughtException);2928 };2929 3343 2930 3344 #if ENABLE(SAMPLING_FLAGS) … … 2960 3374 2961 3375 JSFunction* fulfillHandler = JSNativeStdFunction::create(vm, globalObject, 1, String(), [&, isLastFile](ExecState* exec) { 2962 checkException( isLastFile, false, exec->argument(0));3376 checkException(globalObject, isLastFile, false, exec->argument(0), uncaughtExceptionName, alwaysDumpUncaughtException, dump, success); 2963 3377 return JSValue::encode(jsUndefined()); 2964 3378 }); 2965 3379 2966 3380 JSFunction* rejectHandler = JSNativeStdFunction::create(vm, globalObject, 1, String(), [&, isLastFile](ExecState* exec) { 2967 checkException( isLastFile, true, exec->argument(0));3381 checkException(globalObject, isLastFile, true, exec->argument(0), uncaughtExceptionName, alwaysDumpUncaughtException, dump, success); 2968 3382 return JSValue::encode(jsUndefined()); 2969 3383 }); … … 2977 3391 if (evaluationException) 2978 3392 returnValue = evaluationException->value(); 2979 checkException( isLastFile, evaluationException, returnValue);3393 checkException(globalObject, isLastFile, evaluationException, returnValue, uncaughtExceptionName, alwaysDumpUncaughtException, dump, success); 2980 3394 } 2981 3395 … … 3242 3656 } 3243 3657 3244 // We make this function no inline so that globalObject won't be on the stack if we do a GC in jscmain. 3245 static int NEVER_INLINE runJSC(VM* vm, CommandLine options) 3246 { 3247 JSLockHolder locker(vm); 3658 template<typename Func> 3659 int runJSC(CommandLine options, const Func& func) 3660 { 3661 Worker worker(Workers::singleton()); 3662 3663 VM& vm = VM::create(LargeHeap).leakRef(); 3664 JSLockHolder locker(&vm); 3248 3665 3249 3666 int result; 3250 if (options.m_profile && !vm ->m_perBytecodeProfiler)3251 vm ->m_perBytecodeProfiler = std::make_unique<Profiler::Database>(*vm);3252 3253 GlobalObject* globalObject = GlobalObject::create( *vm, GlobalObject::createStructure(*vm, jsNull()), options.m_arguments);3667 if (options.m_profile && !vm.m_perBytecodeProfiler) 3668 vm.m_perBytecodeProfiler = std::make_unique<Profiler::Database>(vm); 3669 3670 GlobalObject* globalObject = GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), options.m_arguments); 3254 3671 globalObject->setRemoteDebuggingEnabled(options.m_enableRemoteDebugging); 3255 bool success = runWithScripts(globalObject, options.m_scripts, options.m_uncaughtExceptionName, options.m_alwaysDumpUncaughtException, options.m_dump, options.m_module);3672 bool success = func(vm, globalObject); 3256 3673 if (options.m_interactive && success) 3257 3674 runInteractive(globalObject); 3258 3675 3259 vm ->drainMicrotasks();3676 vm.drainMicrotasks(); 3260 3677 result = success && (test262AsyncTest == test262AsyncPassed) ? 0 : 3; 3261 3678 … … 3264 3681 3265 3682 if (options.m_profile) { 3266 if (!vm ->m_perBytecodeProfiler->save(options.m_profilerOutput.utf8().data()))3683 if (!vm.m_perBytecodeProfiler->save(options.m_profilerOutput.utf8().data())) 3267 3684 fprintf(stderr, "could not save profiler output.\n"); 3268 3685 } … … 3289 3706 #endif 3290 3707 3708 if (Options::gcAtEnd()) { 3709 // We need to hold the API lock to do a GC. 3710 JSLockHolder locker(&vm); 3711 vm.heap.collectAllGarbage(); 3712 } 3713 3714 if (options.m_dumpSamplingProfilerData) { 3715 #if ENABLE(SAMPLING_PROFILER) 3716 JSLockHolder locker(&vm); 3717 vm.samplingProfiler()->reportTopFunctions(); 3718 vm.samplingProfiler()->reportTopBytecodes(); 3719 #else 3720 dataLog("Sampling profiler is not enabled on this platform\n"); 3721 #endif 3722 } 3723 3291 3724 return result; 3292 3725 } … … 3306 3739 startTimeoutThreadIfNeeded(); 3307 3740 3308 VM* vm = &VM::create(LargeHeap).leakRef();3309 3741 int result; 3310 result = runJSC(vm, options); 3311 3312 if (Options::gcAtEnd()) { 3313 // We need to hold the API lock to do a GC. 3314 JSLockHolder locker(vm); 3315 vm->heap.collectAllGarbage(); 3316 } 3317 3318 if (options.m_dumpSamplingProfilerData) { 3319 #if ENABLE(SAMPLING_PROFILER) 3320 JSLockHolder locker(vm); 3321 vm->samplingProfiler()->reportTopFunctions(); 3322 vm->samplingProfiler()->reportTopBytecodes(); 3323 #else 3324 dataLog("Sampling profiler is not enabled on this platform\n"); 3325 #endif 3326 } 3742 result = runJSC( 3743 options, 3744 [&] (VM&, GlobalObject* globalObject) { 3745 return runWithScripts(globalObject, options.m_scripts, options.m_uncaughtExceptionName, options.m_alwaysDumpUncaughtException, options.m_dump, options.m_module); 3746 }); 3327 3747 3328 3748 printSuperSamplerState();
Note:
See TracChangeset
for help on using the changeset viewer.