Add ability to symbolically set and dump JSC VM options.

See comments in runtime/Options.h for details on how the options work.
https://bugs.webkit.org/show_bug.cgi?id=90420

Patch by Mark Lam <mark.lam@apple.com> on 2012-07-03
Reviewed by Filip Pizlo.

* assembler/LinkBuffer.cpp:
(JSC::LinkBuffer::finalizeCodeWithDisassembly):
* assembler/LinkBuffer.h:
(JSC):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::shouldOptimizeNow):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::likelyToTakeSlowCase):
(JSC::CodeBlock::couldTakeSlowCase):
(JSC::CodeBlock::likelyToTakeSpecialFastCase):
(JSC::CodeBlock::likelyToTakeDeepestSlowCase):
(JSC::CodeBlock::likelyToTakeAnySlowCase):
(JSC::CodeBlock::jitAfterWarmUp):
(JSC::CodeBlock::jitSoon):
(JSC::CodeBlock::reoptimizationRetryCounter):
(JSC::CodeBlock::countReoptimization):
(JSC::CodeBlock::counterValueForOptimizeAfterWarmUp):
(JSC::CodeBlock::counterValueForOptimizeAfterLongWarmUp):
(JSC::CodeBlock::optimizeSoon):
(JSC::CodeBlock::exitCountThresholdForReoptimization):
(JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop):
* bytecode/ExecutionCounter.h:
(JSC::ExecutionCounter::clippedThreshold):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleInlining):
* dfg/DFGCapabilities.h:
(JSC::DFG::mightCompileEval):
(JSC::DFG::mightCompileProgram):
(JSC::DFG::mightCompileFunctionForCall):
(JSC::DFG::mightCompileFunctionForConstruct):
(JSC::DFG::mightInlineFunctionForCall):
(JSC::DFG::mightInlineFunctionForConstruct):
* dfg/DFGCommon.h:
(JSC::DFG::shouldShowDisassembly):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow):
* dfg/DFGVariableAccessData.h:
(JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
* heap/MarkStack.cpp:
(JSC::MarkStackSegmentAllocator::allocate):
(JSC::MarkStackSegmentAllocator::shrinkReserve):
(JSC::MarkStackArray::MarkStackArray):
(JSC::MarkStackThreadSharedData::MarkStackThreadSharedData):
(JSC::SlotVisitor::donateKnownParallel):
(JSC::SlotVisitor::drain):
(JSC::SlotVisitor::drainFromShared):
* heap/MarkStack.h:
(JSC::MarkStack::mergeOpaqueRootsIfProfitable):
(JSC::MarkStack::addOpaqueRoot):
* heap/SlotVisitor.h:
(JSC::SlotVisitor::donate):
* jit/JIT.cpp:
(JSC::JIT::emitOptimizationCheck):
* jsc.cpp:
(printUsageStatement):
(parseArguments):
* runtime/InitializeThreading.cpp:
(JSC::initializeThreadingOnce):
* runtime/JSGlobalData.cpp:
(JSC::enableAssembler):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
* runtime/Options.cpp:
(JSC):
(JSC::overrideOptionWithHeuristic):
(JSC::Options::initialize):
(JSC::Options::setOption):
(JSC::Options::dumpAllOptions):
(JSC::Options::dumpOption):
* runtime/Options.h:
(JSC):
(Options):
(EntryInfo):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@121798 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 2fcd5d2f
2012-07-03 Mark Lam <mark.lam@apple.com>
Add ability to symbolically set and dump JSC VM options.
See comments in runtime/Options.h for details on how the options work.
https://bugs.webkit.org/show_bug.cgi?id=90420
Reviewed by Filip Pizlo.
* assembler/LinkBuffer.cpp:
(JSC::LinkBuffer::finalizeCodeWithDisassembly):
* assembler/LinkBuffer.h:
(JSC):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::shouldOptimizeNow):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::likelyToTakeSlowCase):
(JSC::CodeBlock::couldTakeSlowCase):
(JSC::CodeBlock::likelyToTakeSpecialFastCase):
(JSC::CodeBlock::likelyToTakeDeepestSlowCase):
(JSC::CodeBlock::likelyToTakeAnySlowCase):
(JSC::CodeBlock::jitAfterWarmUp):
(JSC::CodeBlock::jitSoon):
(JSC::CodeBlock::reoptimizationRetryCounter):
(JSC::CodeBlock::countReoptimization):
(JSC::CodeBlock::counterValueForOptimizeAfterWarmUp):
(JSC::CodeBlock::counterValueForOptimizeAfterLongWarmUp):
(JSC::CodeBlock::optimizeSoon):
(JSC::CodeBlock::exitCountThresholdForReoptimization):
(JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop):
* bytecode/ExecutionCounter.h:
(JSC::ExecutionCounter::clippedThreshold):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleInlining):
* dfg/DFGCapabilities.h:
(JSC::DFG::mightCompileEval):
(JSC::DFG::mightCompileProgram):
(JSC::DFG::mightCompileFunctionForCall):
(JSC::DFG::mightCompileFunctionForConstruct):
(JSC::DFG::mightInlineFunctionForCall):
(JSC::DFG::mightInlineFunctionForConstruct):
* dfg/DFGCommon.h:
(JSC::DFG::shouldShowDisassembly):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow):
* dfg/DFGVariableAccessData.h:
(JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
* heap/MarkStack.cpp:
(JSC::MarkStackSegmentAllocator::allocate):
(JSC::MarkStackSegmentAllocator::shrinkReserve):
(JSC::MarkStackArray::MarkStackArray):
(JSC::MarkStackThreadSharedData::MarkStackThreadSharedData):
(JSC::SlotVisitor::donateKnownParallel):
(JSC::SlotVisitor::drain):
(JSC::SlotVisitor::drainFromShared):
* heap/MarkStack.h:
(JSC::MarkStack::mergeOpaqueRootsIfProfitable):
(JSC::MarkStack::addOpaqueRoot):
* heap/SlotVisitor.h:
(JSC::SlotVisitor::donate):
* jit/JIT.cpp:
(JSC::JIT::emitOptimizationCheck):
* jsc.cpp:
(printUsageStatement):
(parseArguments):
* runtime/InitializeThreading.cpp:
(JSC::initializeThreadingOnce):
* runtime/JSGlobalData.cpp:
(JSC::enableAssembler):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
* runtime/Options.cpp:
(JSC):
(JSC::overrideOptionWithHeuristic):
(JSC::Options::initialize):
(JSC::Options::setOption):
(JSC::Options::dumpAllOptions):
(JSC::Options::dumpOption):
* runtime/Options.h:
(JSC):
(Options):
(EntryInfo):
2012-07-03 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> Joel Dillon <joel.dillon@codethink.co.uk>
[Qt][Win] Fix broken QtWebKit5.lib linking
......
......@@ -159,6 +159,7 @@ EXPORTS
?deleteAllCompiledCode@Heap@JSC@@QAEXXZ
?displayName@JSFunction@JSC@@QAE?BVUString@2@PAVExecState@2@@Z
?dtoa@WTF@@YAXQADNAA_NAAHAAI@Z
?dumpAllOptions@Options@JSC@@SAXPAU_iobuf@@@Z
?dumpSampleData@JSGlobalData@JSC@@QAEXPAVExecState@2@@Z
?empty@StringImpl@WTF@@SAPAV12@XZ
?enumerable@PropertyDescriptor@JSC@@QBE_NXZ
......@@ -305,6 +306,7 @@ EXPORTS
?setGetter@PropertyDescriptor@JSC@@QAEXVJSValue@2@@Z
?setLoc@StatementNode@JSC@@QAEXHH@Z
?setMainThreadCallbacksPaused@WTF@@YAX_N@Z
?setOption@Options@JSC@@SA_NPBD@Z
?setOrderLowerFirst@Collator@WTF@@QAEX_N@Z
?setPrototype@JSObject@JSC@@QAEXAAVJSGlobalData@2@VJSValue@2@@Z
?setSetter@PropertyDescriptor@JSC@@QAEXVJSValue@2@@Z
......
......@@ -41,7 +41,7 @@ LinkBuffer::CodeRef LinkBuffer::finalizeCodeWithoutDisassembly()
LinkBuffer::CodeRef LinkBuffer::finalizeCodeWithDisassembly(const char* format, ...)
{
ASSERT(Options::showDisassembly || Options::showDFGDisassembly);
ASSERT(Options::showDisassembly() || Options::showDFGDisassembly());
CodeRef result = finalizeCodeWithoutDisassembly();
......
......@@ -279,7 +279,7 @@ private:
// is true, so you can hide expensive disassembly-only computations inside there.
#define FINALIZE_CODE(linkBufferReference, dataLogArgumentsForHeading) \
FINALIZE_CODE_IF(Options::showDisassembly, linkBufferReference, dataLogArgumentsForHeading)
FINALIZE_CODE_IF(Options::showDisassembly(), linkBufferReference, dataLogArgumentsForHeading)
} // namespace JSC
......
......@@ -2773,7 +2773,7 @@ bool CodeBlock::shouldOptimizeNow()
dumpValueProfiles();
#endif
if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay)
if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay())
return true;
unsigned numberOfLiveNonArgumentValueProfiles;
......@@ -2784,9 +2784,9 @@ bool CodeBlock::shouldOptimizeNow()
dataLog("Profile hotness: %lf, %lf\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(), (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles());
#endif
if ((!numberOfValueProfiles() || (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles() >= Options::desiredProfileLivenessRate)
&& (!totalNumberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / totalNumberOfValueProfiles() >= Options::desiredProfileFullnessRate)
&& static_cast<unsigned>(m_optimizationDelayCounter) + 1 >= Options::minimumOptimizationDelay)
if ((!numberOfValueProfiles() || (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles() >= Options::desiredProfileLivenessRate())
&& (!totalNumberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / totalNumberOfValueProfiles() >= Options::desiredProfileFullnessRate())
&& static_cast<unsigned>(m_optimizationDelayCounter) + 1 >= Options::minimumOptimizationDelay())
return true;
ASSERT(m_optimizationDelayCounter < std::numeric_limits<uint8_t>::max());
......
......@@ -685,7 +685,7 @@ namespace JSC {
if (!numberOfRareCaseProfiles())
return false;
unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
return value >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
return value >= Options::likelyToTakeSlowCaseMinimumCount() && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold();
}
bool couldTakeSlowCase(int bytecodeOffset)
......@@ -693,7 +693,7 @@ namespace JSC {
if (!numberOfRareCaseProfiles())
return false;
unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
return value >= Options::couldTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::couldTakeSlowCaseThreshold;
return value >= Options::couldTakeSlowCaseMinimumCount() && static_cast<double>(value) / m_executionEntryCount >= Options::couldTakeSlowCaseThreshold();
}
RareCaseProfile* addSpecialFastCaseProfile(int bytecodeOffset)
......@@ -713,7 +713,7 @@ namespace JSC {
if (!numberOfRareCaseProfiles())
return false;
unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
return specialFastCaseCount >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(specialFastCaseCount) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
return specialFastCaseCount >= Options::likelyToTakeSlowCaseMinimumCount() && static_cast<double>(specialFastCaseCount) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold();
}
bool likelyToTakeDeepestSlowCase(int bytecodeOffset)
......@@ -723,7 +723,7 @@ namespace JSC {
unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
unsigned value = slowCaseCount - specialFastCaseCount;
return value >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
return value >= Options::likelyToTakeSlowCaseMinimumCount() && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold();
}
bool likelyToTakeAnySlowCase(int bytecodeOffset)
......@@ -733,7 +733,7 @@ namespace JSC {
unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
unsigned value = slowCaseCount + specialFastCaseCount;
return value >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
return value >= Options::likelyToTakeSlowCaseMinimumCount() && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold();
}
unsigned executionEntryCount() const { return m_executionEntryCount; }
......@@ -955,12 +955,12 @@ namespace JSC {
void jitAfterWarmUp()
{
m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITAfterWarmUp, this);
m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITAfterWarmUp(), this);
}
void jitSoon()
{
m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITSoon, this);
m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITSoon(), this);
}
const ExecutionCounter& llintExecuteCounter() const
......@@ -991,25 +991,25 @@ namespace JSC {
// to avoid thrashing.
unsigned reoptimizationRetryCounter() const
{
ASSERT(m_reoptimizationRetryCounter <= Options::reoptimizationRetryCounterMax);
ASSERT(m_reoptimizationRetryCounter <= Options::reoptimizationRetryCounterMax());
return m_reoptimizationRetryCounter;
}
void countReoptimization()
{
m_reoptimizationRetryCounter++;
if (m_reoptimizationRetryCounter > Options::reoptimizationRetryCounterMax)
m_reoptimizationRetryCounter = Options::reoptimizationRetryCounterMax;
if (m_reoptimizationRetryCounter > Options::reoptimizationRetryCounterMax())
m_reoptimizationRetryCounter = Options::reoptimizationRetryCounterMax();
}
int32_t counterValueForOptimizeAfterWarmUp()
{
return Options::thresholdForOptimizeAfterWarmUp << reoptimizationRetryCounter();
return Options::thresholdForOptimizeAfterWarmUp() << reoptimizationRetryCounter();
}
int32_t counterValueForOptimizeAfterLongWarmUp()
{
return Options::thresholdForOptimizeAfterLongWarmUp << reoptimizationRetryCounter();
return Options::thresholdForOptimizeAfterLongWarmUp() << reoptimizationRetryCounter();
}
int32_t* addressOfJITExecuteCounter()
......@@ -1089,7 +1089,7 @@ namespace JSC {
// in the baseline code.
void optimizeSoon()
{
m_jitExecuteCounter.setNewThreshold(Options::thresholdForOptimizeSoon << reoptimizationRetryCounter(), this);
m_jitExecuteCounter.setNewThreshold(Options::thresholdForOptimizeSoon() << reoptimizationRetryCounter(), this);
}
uint32_t osrExitCounter() const { return m_osrExitCounter; }
......@@ -1118,12 +1118,12 @@ namespace JSC {
uint32_t exitCountThresholdForReoptimization()
{
return adjustedExitCountThreshold(Options::osrExitCountForReoptimization);
return adjustedExitCountThreshold(Options::osrExitCountForReoptimization());
}
uint32_t exitCountThresholdForReoptimizationFromLoop()
{
return adjustedExitCountThreshold(Options::osrExitCountForReoptimizationFromLoop);
return adjustedExitCountThreshold(Options::osrExitCountForReoptimizationFromLoop());
}
bool shouldReoptimizeNow()
......
......@@ -48,10 +48,10 @@ public:
static T clippedThreshold(JSGlobalObject* globalObject, T threshold)
{
int32_t maxThreshold;
if (Options::randomizeExecutionCountsBetweenCheckpoints)
maxThreshold = globalObject->weakRandomInteger() % Options::maximumExecutionCountsBetweenCheckpoints;
if (Options::randomizeExecutionCountsBetweenCheckpoints())
maxThreshold = globalObject->weakRandomInteger() % Options::maximumExecutionCountsBetweenCheckpoints();
else
maxThreshold = Options::maximumExecutionCountsBetweenCheckpoints;
maxThreshold = Options::maximumExecutionCountsBetweenCheckpoints();
if (threshold > maxThreshold)
threshold = maxThreshold;
return threshold;
......
......@@ -1273,7 +1273,7 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c
unsigned depth = 0;
for (InlineStackEntry* entry = m_inlineStackTop; entry; entry = entry->m_caller) {
++depth;
if (depth >= Options::maximumInliningDepth)
if (depth >= Options::maximumInliningDepth())
return false; // Depth exceeded.
if (entry->executable() == executable)
......
......@@ -41,29 +41,29 @@ namespace JSC { namespace DFG {
// check opcodes.
inline bool mightCompileEval(CodeBlock* codeBlock)
{
return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
}
inline bool mightCompileProgram(CodeBlock* codeBlock)
{
return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
}
inline bool mightCompileFunctionForCall(CodeBlock* codeBlock)
{
return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
}
inline bool mightCompileFunctionForConstruct(CodeBlock* codeBlock)
{
return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
}
inline bool mightInlineFunctionForCall(CodeBlock* codeBlock)
{
return codeBlock->instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount
return codeBlock->instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount()
&& !codeBlock->ownerExecutable()->needsActivation();
}
inline bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
{
return codeBlock->instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount
return codeBlock->instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount()
&& !codeBlock->ownerExecutable()->needsActivation();
}
......
......@@ -136,7 +136,7 @@ enum OptimizationFixpointState { FixpointConverged, FixpointNotConverged };
inline bool shouldShowDisassembly()
{
return Options::showDisassembly || Options::showDFGDisassembly;
return Options::showDisassembly() || Options::showDFGDisassembly();
}
} } // namespace JSC::DFG
......
......@@ -40,6 +40,7 @@
#include "DFGRedundantPhiEliminationPhase.h"
#include "DFGValidate.h"
#include "DFGVirtualRegisterAllocationPhase.h"
#include "Options.h"
namespace JSC { namespace DFG {
......@@ -60,7 +61,10 @@ inline bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlo
ASSERT(codeBlock);
ASSERT(codeBlock->alternative());
ASSERT(codeBlock->alternative()->getJITType() == JITCode::BaselineJIT);
if (!Options::useDFGJIT())
return false;
#if DFG_ENABLE(DEBUG_VERBOSE)
dataLog("DFG compiling code block %p(%p) for executable %p, number of instructions = %u.\n", codeBlock, codeBlock->alternative(), codeBlock->ownerExecutable(), codeBlock->instructionCount());
#endif
......
......@@ -52,7 +52,7 @@ OSRExit::OSRExit(ExitKind kind, JSValueSource jsValueSource, MethodOfGettingAVal
bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
{
if (static_cast<double>(m_count) / dfgCodeBlock->osrExitCounter() <= Options::osrExitProminenceForFrequentExitSite)
if (static_cast<double>(m_count) / dfgCodeBlock->osrExitCounter() <= Options::osrExitProminenceForFrequentExitSite())
return false;
FrequentExitSite exitSite;
......
......@@ -176,7 +176,7 @@ public:
// If the variable has been voted to become a double, then make it a
// double.
if (doubleVoteRatio() >= Options::doubleVoteRatioForDoubleFormat)
if (doubleVoteRatio() >= Options::doubleVoteRatioForDoubleFormat())
return true;
return false;
......
......@@ -65,7 +65,7 @@ MarkStackSegment* MarkStackSegmentAllocator::allocate()
}
}
return static_cast<MarkStackSegment*>(OSAllocator::reserveAndCommit(Options::gcMarkStackSegmentSize));
return static_cast<MarkStackSegment*>(OSAllocator::reserveAndCommit(Options::gcMarkStackSegmentSize()));
}
void MarkStackSegmentAllocator::release(MarkStackSegment* segment)
......@@ -86,13 +86,13 @@ void MarkStackSegmentAllocator::shrinkReserve()
while (segments) {
MarkStackSegment* toFree = segments;
segments = segments->m_previous;
OSAllocator::decommitAndRelease(toFree, Options::gcMarkStackSegmentSize);
OSAllocator::decommitAndRelease(toFree, Options::gcMarkStackSegmentSize());
}
}
MarkStackArray::MarkStackArray(MarkStackSegmentAllocator& allocator)
: m_allocator(allocator)
, m_segmentCapacity(MarkStackSegment::capacityFromSize(Options::gcMarkStackSegmentSize))
, m_segmentCapacity(MarkStackSegment::capacityFromSize(Options::gcMarkStackSegmentSize()))
, m_top(0)
, m_numberOfPreviousSegments(0)
{
......@@ -262,7 +262,7 @@ MarkStackThreadSharedData::MarkStackThreadSharedData(JSGlobalData* globalData)
, m_parallelMarkersShouldExit(false)
{
#if ENABLE(PARALLEL_GC)
for (unsigned i = 1; i < Options::numberOfGCMarkers; ++i) {
for (unsigned i = 1; i < Options::numberOfGCMarkers(); ++i) {
SlotVisitor* slotVisitor = new SlotVisitor(*this);
m_markingThreadsMarkStack.append(slotVisitor);
m_markingThreads.append(createThread(markingThreadStartFunc, slotVisitor, "JavaScriptCore::Marking"));
......@@ -368,7 +368,7 @@ void SlotVisitor::donateKnownParallel()
// Otherwise, assume that a thread will go idle soon, and donate.
m_stack.donateSomeCellsTo(m_shared.m_sharedMarkStack);
if (m_shared.m_numberOfActiveParallelMarkers < Options::numberOfGCMarkers)
if (m_shared.m_numberOfActiveParallelMarkers < Options::numberOfGCMarkers())
m_shared.m_markingCondition.broadcast();
}
......@@ -377,10 +377,10 @@ void SlotVisitor::drain()
ASSERT(m_isInParallelMode);
#if ENABLE(PARALLEL_GC)
if (Options::numberOfGCMarkers > 1) {
if (Options::numberOfGCMarkers() > 1) {
while (!m_stack.isEmpty()) {
m_stack.refill();
for (unsigned countdown = Options::minimumNumberOfScansBetweenRebalance; m_stack.canRemoveLast() && countdown--;)
for (unsigned countdown = Options::minimumNumberOfScansBetweenRebalance(); m_stack.canRemoveLast() && countdown--;)
visitChildren(*this, m_stack.removeLast());
donateKnownParallel();
}
......@@ -401,14 +401,14 @@ void SlotVisitor::drainFromShared(SharedDrainMode sharedDrainMode)
{
ASSERT(m_isInParallelMode);
ASSERT(Options::numberOfGCMarkers);
ASSERT(Options::numberOfGCMarkers());
bool shouldBeParallel;
#if ENABLE(PARALLEL_GC)
shouldBeParallel = Options::numberOfGCMarkers > 1;
shouldBeParallel = Options::numberOfGCMarkers() > 1;
#else
ASSERT(Options::numberOfGCMarkers == 1);
ASSERT(Options::numberOfGCMarkers() == 1);
shouldBeParallel = false;
#endif
......@@ -469,7 +469,7 @@ void SlotVisitor::drainFromShared(SharedDrainMode sharedDrainMode)
}
}
size_t idleThreadCount = Options::numberOfGCMarkers - m_shared.m_numberOfActiveParallelMarkers;
size_t idleThreadCount = Options::numberOfGCMarkers() - m_shared.m_numberOfActiveParallelMarkers;
m_stack.stealSomeCellsFrom(m_shared.m_sharedMarkStack, idleThreadCount);
m_shared.m_numberOfActiveParallelMarkers++;
}
......
......@@ -304,7 +304,7 @@ namespace JSC {
void mergeOpaqueRootsIfProfitable()
{
if (static_cast<unsigned>(m_opaqueRoots.size()) < Options::opaqueRootMergeThreshold)
if (static_cast<unsigned>(m_opaqueRoots.size()) < Options::opaqueRootMergeThreshold())
return;
mergeOpaqueRoots();
}
......@@ -350,7 +350,7 @@ namespace JSC {
inline void MarkStack::addOpaqueRoot(void* root)
{
#if ENABLE(PARALLEL_GC)
if (Options::numberOfGCMarkers == 1) {
if (Options::numberOfGCMarkers() == 1) {
// Put directly into the shared HashSet.
m_shared.m_opaqueRoots.add(root);
return;
......
......@@ -41,7 +41,7 @@ public:
void donate()
{
ASSERT(m_isInParallelMode);
if (Options::numberOfGCMarkers == 1)
if (Options::numberOfGCMarkers() == 1)
return;
donateKnownParallel();
......
......@@ -99,7 +99,7 @@ void JIT::emitOptimizationCheck(OptimizationCheckKind kind)
if (!canBeOptimized())
return;
Jump skipOptimize = branchAdd32(Signed, TrustedImm32(kind == LoopOptimizationCheck ? Options::executionCounterIncrementForLoop : Options::executionCounterIncrementForReturn), AbsoluteAddress(m_codeBlock->addressOfJITExecuteCounter()));
Jump skipOptimize = branchAdd32(Signed, TrustedImm32(kind == LoopOptimizationCheck ? Options::executionCounterIncrementForLoop() : Options::executionCounterIncrementForReturn()), AbsoluteAddress(m_codeBlock->addressOfJITExecuteCounter()));
JITStubCall stubCall(this, cti_optimize);
stubCall.addArgument(TrustedImm32(m_bytecodeOffset));
if (kind == EnterOptimizationCheck)
......
......@@ -614,6 +614,11 @@ static NO_RETURN void printUsageStatement(bool help = false)
fprintf(stderr, " -s Installs signal handlers that exit on a crash (Unix platforms only)\n");
#endif
fprintf(stderr, " -x Output exit code before terminating\n");
fprintf(stderr, "\n");
fprintf(stderr, " --options Dumps all JSC VM options and exits\n");
fprintf(stderr, " --dumpOptions Dumps all JSC VM options before continuing\n");
fprintf(stderr, " --<jsc VM option>=<value> Sets the specified JSC VM option\n");
fprintf(stderr, "\n");
exit(help ? EXIT_SUCCESS : EXIT_FAILURE);
}
......@@ -621,6 +626,9 @@ static NO_RETURN void printUsageStatement(bool help = false)
static void parseArguments(int argc, char** argv, CommandLine& options)
{
int i = 1;
bool needToDumpOptions = false;
bool needToExit = false;
for (; i < argc; ++i) {
const char* arg = argv[i];
if (!strcmp(arg, "-f")) {
......@@ -662,6 +670,26 @@ static void parseArguments(int argc, char** argv, CommandLine& options)
}
if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
printUsageStatement(true);
if (!strcmp(arg, "--options")) {
needToDumpOptions = true;
needToExit = true;
continue;
}
if (!strcmp(arg, "--dumpOptions")) {
needToDumpOptions = true;
continue;
}
// See if the -- option is a JSC VM option.
// NOTE: At this point, we know that the arg starts with "--". Skip it.
if (JSC::Options::setOption(&arg[2])) {
// The arg was recognized as a VM option and has been parsed.
continue; // Just continue with the next arg.
}
// This arg is not recognized by the VM nor by jsc. Pass it on to the
// script.
options.scripts.append(Script(true, argv[i]));
}
......@@ -670,6 +698,11 @@ static void parseArguments(int argc, char** argv, CommandLine& options)
for (; i < argc; ++i)
options.arguments.append(argv[i]);
if (needToDumpOptions)
JSC::Options::dumpAllOptions(stderr);
if (needToExit)
exit(EXIT_SUCCESS);
}
int jscmain(int argc, char** argv)
......
......@@ -53,7 +53,7 @@ static void initializeThreadingOnce()
{
WTF::double_conversion::initialize();
WTF::initializeThreading();
Options::initializeOptions();
Options::initialize();
#if ENABLE(WRITE_BARRIER_PROFILING)
WriteBarrierCounters::initialize();
#endif
......
......@@ -99,7 +99,7 @@ extern const HashTable stringConstructorTable;
#if ENABLE(ASSEMBLER) && (ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT))
static bool enableAssembler(ExecutableAllocator& executableAllocator)
{
if (!executableAllocator.isValid() || !Options::useJIT)
if (!executableAllocator.isValid() || !Options::useJIT())
return false;
#if USE(CF)
......
......@@ -115,7 +115,7 @@ template <typename T> static inline void visitIfNeeded(SlotVisitor& visitor, Wri
JSGlobalObject::JSGlobalObject(JSGlobalData& globalData, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable)
: JSSegmentedVariableObject(globalData, structure, &m_symbolTable)
, m_globalScopeChain()
, m_weakRandom(Options::forceWeakRandomSeed ? Options::forcedWeakRandomSeed : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
, m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
, m_evalEnabled(true)
, m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable)
{
......
......@@ -27,8 +27,13 @@
#include "Options.h"
#include <limits>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wtf/NumberOfCores.h>
#include <wtf/PageBlock.h>
#include <wtf/StdLibExtras.h>
#include <wtf/StringExtras.h>
#if OS(DARWIN) && ENABLE(PARALLEL_GC)
#include <sys/sysctl.h>
......@@ -37,67 +42,9 @@
// Set to 1 to control the heuristics using environment variables.
#define ENABLE_RUN_TIME_HEURISTICS 0
#if ENABLE(RUN_TIME_HEURISTICS)
#include <stdio.h>
#include <stdlib.h>
#include <wtf/StdLibExtras.h>
#endif
namespace JSC { namespace Options {
bool useJIT;
bool showDisassembly;
bool showDFGDisassembly;
unsigned maximumOptimizationCandidateInstructionCount;
unsigned maximumFunctionForCallInlineCandidateInstructionCount;
unsigned maximumFunctionForConstructInlineCandidateInstructionCount;
unsigned maximumInliningDepth;
int32_t thresholdForJITAfterWarmUp;
int32_t thresholdForJITSoon;
namespace JSC {