Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (195835 => 195836)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2016-01-29 20:35:30 UTC (rev 195835)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2016-01-29 20:37:52 UTC (rev 195836)
@@ -1740,13 +1740,18 @@
CodeBlock::CodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, CodeBlock& other)
: JSCell(*vm, structure)
, m_globalObject(other.m_globalObject)
- , m_heap(other.m_heap)
, m_numCalleeLocals(other.m_numCalleeLocals)
, m_numVars(other.m_numVars)
- , m_isConstructor(other.m_isConstructor)
, m_shouldAlwaysBeInlined(true)
+#if ENABLE(JIT)
+ , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
+#endif
, m_didFailFTLCompilation(false)
, m_hasBeenCompiledWithFTL(false)
+ , m_isConstructor(other.m_isConstructor)
+ , m_isStrictMode(other.m_isStrictMode)
+ , m_needsActivation(other.m_needsActivation)
+ , m_codeType(other.m_codeType)
, m_unlinkedCode(*other.m_vm, this, other.m_unlinkedCode.get())
, m_hasDebuggerStatement(false)
, m_steppingMode(SteppingModeDisabled)
@@ -1757,12 +1762,10 @@
, m_thisRegister(other.m_thisRegister)
, m_scopeRegister(other.m_scopeRegister)
, m_lexicalEnvironmentRegister(other.m_lexicalEnvironmentRegister)
- , m_isStrictMode(other.m_isStrictMode)
- , m_needsActivation(other.m_needsActivation)
+ , m_hash(other.m_hash)
, m_source(other.m_source)
, m_sourceOffset(other.m_sourceOffset)
, m_firstLineColumnOffset(other.m_firstLineColumnOffset)
- , m_codeType(other.m_codeType)
, m_constantRegisters(other.m_constantRegisters)
, m_constantsSourceCodeRepresentation(other.m_constantsSourceCodeRepresentation)
, m_functionDecls(other.m_functionDecls)
@@ -1771,14 +1774,10 @@
, m_optimizationDelayCounter(0)
, m_reoptimizationRetryCounter(0)
, m_creationTime(std::chrono::steady_clock::now())
- , m_hash(other.m_hash)
-#if ENABLE(JIT)
- , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
-#endif
{
m_visitWeaklyHasBeenCalled.store(false, std::memory_order_relaxed);
- ASSERT(m_heap->isDeferred());
+ ASSERT(heap()->isDeferred());
ASSERT(m_scopeRegister.isLocal());
setNumParameters(other.numParameters());
@@ -1801,20 +1800,25 @@
m_rareData->m_liveCalleeLocalsAtYield = other.m_rareData->m_liveCalleeLocalsAtYield;
}
- m_heap->m_codeBlocks.add(this);
+ heap()->m_codeBlocks.add(this);
}
CodeBlock::CodeBlock(VM* vm, Structure* structure, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock,
JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
: JSCell(*vm, structure)
, m_globalObject(scope->globalObject()->vm(), this, scope->globalObject())
- , m_heap(&m_globalObject->vm().heap)
, m_numCalleeLocals(unlinkedCodeBlock->m_numCalleeLocals)
, m_numVars(unlinkedCodeBlock->m_numVars)
- , m_isConstructor(unlinkedCodeBlock->isConstructor())
, m_shouldAlwaysBeInlined(true)
+#if ENABLE(JIT)
+ , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
+#endif
, m_didFailFTLCompilation(false)
, m_hasBeenCompiledWithFTL(false)
+ , m_isConstructor(unlinkedCodeBlock->isConstructor())
+ , m_isStrictMode(unlinkedCodeBlock->isStrictMode())
+ , m_needsActivation(unlinkedCodeBlock->hasActivationRegister() && unlinkedCodeBlock->codeType() == FunctionCode)
+ , m_codeType(unlinkedCodeBlock->codeType())
, m_unlinkedCode(m_globalObject->vm(), this, unlinkedCodeBlock)
, m_hasDebuggerStatement(false)
, m_steppingMode(SteppingModeDisabled)
@@ -1824,23 +1828,17 @@
, m_thisRegister(unlinkedCodeBlock->thisRegister())
, m_scopeRegister(unlinkedCodeBlock->scopeRegister())
, m_lexicalEnvironmentRegister(unlinkedCodeBlock->activationRegister())
- , m_isStrictMode(unlinkedCodeBlock->isStrictMode())
- , m_needsActivation(unlinkedCodeBlock->hasActivationRegister() && unlinkedCodeBlock->codeType() == FunctionCode)
, m_source(sourceProvider)
, m_sourceOffset(sourceOffset)
, m_firstLineColumnOffset(firstLineColumnOffset)
- , m_codeType(unlinkedCodeBlock->codeType())
, m_osrExitCounter(0)
, m_optimizationDelayCounter(0)
, m_reoptimizationRetryCounter(0)
, m_creationTime(std::chrono::steady_clock::now())
-#if ENABLE(JIT)
- , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
-#endif
{
m_visitWeaklyHasBeenCalled.store(false, std::memory_order_relaxed);
- ASSERT(m_heap->isDeferred());
+ ASSERT(heap()->isDeferred());
ASSERT(m_scopeRegister.isLocal());
ASSERT(m_source);
@@ -1894,7 +1892,7 @@
replaceConstant(unlinkedModuleProgramCodeBlock->moduleEnvironmentSymbolTableConstantRegisterOffset(), clonedSymbolTable);
}
- m_functionDecls.resizeToFit(unlinkedCodeBlock->numberOfFunctionDecls());
+ m_functionDecls = RefCountedArray<WriteBarrier<FunctionExecutable>>(unlinkedCodeBlock->numberOfFunctionDecls());
for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) {
UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
if (vm.typeProfiler() || vm.controlFlowProfiler())
@@ -1902,7 +1900,7 @@
m_functionDecls[i].set(*m_vm, this, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
}
- m_functionExprs.resizeToFit(unlinkedCodeBlock->numberOfFunctionExprs());
+ m_functionExprs = RefCountedArray<WriteBarrier<FunctionExecutable>>(unlinkedCodeBlock->numberOfFunctionExprs());
for (size_t count = unlinkedCodeBlock->numberOfFunctionExprs(), i = 0; i < count; ++i) {
UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i);
if (vm.typeProfiler() || vm.controlFlowProfiler())
@@ -1958,15 +1956,15 @@
// Allocate metadata buffers for the bytecode
if (size_t size = unlinkedCodeBlock->numberOfLLintCallLinkInfos())
- m_llintCallLinkInfos.resizeToFit(size);
+ m_llintCallLinkInfos = RefCountedArray<LLIntCallLinkInfo>(size);
if (size_t size = unlinkedCodeBlock->numberOfArrayProfiles())
m_arrayProfiles.grow(size);
if (size_t size = unlinkedCodeBlock->numberOfArrayAllocationProfiles())
- m_arrayAllocationProfiles.resizeToFit(size);
+ m_arrayAllocationProfiles = RefCountedArray<ArrayAllocationProfile>(size);
if (size_t size = unlinkedCodeBlock->numberOfValueProfiles())
- m_valueProfiles.resizeToFit(size);
+ m_valueProfiles = RefCountedArray<ValueProfile>(size);
if (size_t size = unlinkedCodeBlock->numberOfObjectAllocationProfiles())
- m_objectAllocationProfiles.resizeToFit(size);
+ m_objectAllocationProfiles = RefCountedArray<ObjectAllocationProfile>(size);
#if ENABLE(JIT)
setCalleeSaveRegisters(RegisterSet::llintBaselineCalleeSaveRegisters());
@@ -2318,45 +2316,44 @@
if (Options::dumpGeneratedBytecodes())
dumpBytecode();
- m_heap->m_codeBlocks.add(this);
- m_heap->reportExtraMemoryAllocated(m_instructions.size() * sizeof(Instruction));
+ heap()->m_codeBlocks.add(this);
+ heap()->reportExtraMemoryAllocated(m_instructions.size() * sizeof(Instruction));
}
#if ENABLE(WEBASSEMBLY)
CodeBlock::CodeBlock(VM* vm, Structure* structure, WebAssemblyExecutable* ownerExecutable, JSGlobalObject* globalObject)
: JSCell(*vm, structure)
, m_globalObject(globalObject->vm(), this, globalObject)
- , m_heap(&m_globalObject->vm().heap)
, m_numCalleeLocals(0)
, m_numVars(0)
- , m_isConstructor(false)
, m_shouldAlwaysBeInlined(false)
+#if ENABLE(JIT)
+ , m_capabilityLevelState(DFG::CannotCompile)
+#endif
, m_didFailFTLCompilation(false)
, m_hasBeenCompiledWithFTL(false)
+ , m_isConstructor(false)
+ , m_isStrictMode(false)
+ , m_needsActivation(false)
+ , m_codeType(FunctionCode)
, m_hasDebuggerStatement(false)
, m_steppingMode(SteppingModeDisabled)
, m_numBreakpoints(0)
, m_ownerExecutable(m_globalObject->vm(), this, ownerExecutable)
, m_vm(vm)
- , m_isStrictMode(false)
- , m_needsActivation(false)
- , m_codeType(FunctionCode)
, m_osrExitCounter(0)
, m_optimizationDelayCounter(0)
, m_reoptimizationRetryCounter(0)
, m_creationTime(std::chrono::steady_clock::now())
-#if ENABLE(JIT)
- , m_capabilityLevelState(DFG::CannotCompile)
-#endif
{
- ASSERT(m_heap->isDeferred());
+ ASSERT(heap()->isDeferred());
}
void CodeBlock::finishCreation(VM& vm, WebAssemblyExecutable*, JSGlobalObject*)
{
Base::finishCreation(vm);
- m_heap->m_codeBlocks.add(this);
+ heap()->m_codeBlocks.add(this);
}
#endif
@@ -2399,7 +2396,7 @@
{
m_numParameters = newValue;
- m_argumentValueProfiles.resizeToFit(newValue);
+ m_argumentValueProfiles = RefCountedArray<ValueProfile>(newValue);
}
void EvalCodeCache::visitAggregate(SlotVisitor& visitor)
@@ -3295,7 +3292,7 @@
}
#endif // ENABLE(DFG_JIT)
- DeferGCForAWhile deferGC(*m_heap);
+ DeferGCForAWhile deferGC(*heap());
// We want to accomplish two things here:
// 1) Make sure that if this CodeBlock is on the stack right now, then if we return to it
@@ -3421,7 +3418,7 @@
if (!DFG::mightInlineFunction(this))
return;
- if (!canInline(m_capabilityLevelState))
+ if (!canInline(capabilityLevelState()))
return;
if (!DFG::isSmallEnoughToInlineCodeInto(callerCodeBlock)) {
@@ -3470,12 +3467,12 @@
return;
}
- if (callerCodeBlock->m_capabilityLevelState == DFG::CapabilityLevelNotSet) {
+ if (callerCodeBlock->capabilityLevelState() == DFG::CapabilityLevelNotSet) {
dataLog("In call from ", *callerCodeBlock, " ", callerFrame->codeOrigin(), " to ", *this, ": caller's DFG capability level is not set.\n");
CRASH();
}
- if (canCompile(callerCodeBlock->m_capabilityLevelState))
+ if (canCompile(callerCodeBlock->capabilityLevelState()))
return;
if (Options::verboseCallLink())
@@ -4193,9 +4190,11 @@
ResultProfile* CodeBlock::resultProfileForBytecodeOffset(int bytecodeOffset)
{
- auto iterator = m_bytecodeOffsetToResultProfileIndexMap.find(bytecodeOffset);
- if (iterator == m_bytecodeOffsetToResultProfileIndexMap.end())
+ if (!m_bytecodeOffsetToResultProfileIndexMap)
return nullptr;
+ auto iterator = m_bytecodeOffsetToResultProfileIndexMap->find(bytecodeOffset);
+ if (iterator == m_bytecodeOffsetToResultProfileIndexMap->end())
+ return nullptr;
return &m_resultProfiles[iterator->value];
}
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (195835 => 195836)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2016-01-29 20:35:30 UTC (rev 195835)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2016-01-29 20:37:52 UTC (rev 195836)
@@ -122,7 +122,6 @@
#endif
WriteBarrier<JSGlobalObject> m_globalObject;
- Heap* m_heap;
public:
JS_EXPORT_PRIVATE ~CodeBlock();
@@ -296,8 +295,8 @@
void setJITCode(PassRefPtr<JITCode> code)
{
- ASSERT(m_heap->isDeferred());
- m_heap->reportExtraMemoryAllocated(code->size());
+ ASSERT(heap()->isDeferred());
+ heap()->reportExtraMemoryAllocated(code->size());
ConcurrentJITLocker locker(m_lock);
WTF::storeStoreFence(); // This is probably not needed because the lock will also do something similar, but it's good to be paranoid.
m_jitCode = code;
@@ -323,7 +322,7 @@
DFG::CapabilityLevel computeCapabilityLevel();
DFG::CapabilityLevel capabilityLevel();
- DFG::CapabilityLevel capabilityLevelState() { return m_capabilityLevelState; }
+ DFG::CapabilityLevel capabilityLevelState() { return static_cast<DFG::CapabilityLevel>(m_capabilityLevelState); }
bool hasOptimizedReplacement(JITCode::JITType typeToReplace);
bool hasOptimizedReplacement(); // the typeToReplace is my JITType
@@ -377,7 +376,7 @@
CodeType codeType() const
{
- return m_codeType;
+ return static_cast<CodeType>(m_codeType);
}
PutPropertySlot::Context putByIdContext() const
@@ -460,7 +459,9 @@
m_resultProfiles.append(ResultProfile(bytecodeOffset));
profile = ""
ASSERT(&m_resultProfiles.last() == &m_resultProfiles[m_resultProfiles.size() - 1]);
- m_bytecodeOffsetToResultProfileIndexMap.add(bytecodeOffset, m_resultProfiles.size() - 1);
+ if (!m_bytecodeOffsetToResultProfileIndexMap)
+ m_bytecodeOffsetToResultProfileIndexMap = std::make_unique<BytecodeOffsetToResultProfileIndexMap>();
+ m_bytecodeOffsetToResultProfileIndexMap->add(bytecodeOffset, m_resultProfiles.size() - 1);
}
return profile;
}
@@ -610,7 +611,7 @@
return constantBufferAsVector(index).data();
}
- Heap* heap() const { return m_heap; }
+ Heap* heap() const { return &m_vm->heap; }
JSGlobalObject* globalObject() { return m_globalObject.get(); }
JSGlobalObject* globalObjectFor(CodeOrigin);
@@ -862,10 +863,8 @@
// FIXME: Make these remaining members private.
- int m_numLocalRegistersForCalleeSaves;
int m_numCalleeLocals;
int m_numVars;
- bool m_isConstructor : 1;
// This is intentionally public; it's the responsibility of anyone doing any
// of the following to hold the lock:
@@ -884,12 +883,23 @@
// without holding any locks, because the GC is guaranteed to wait until any
// concurrent compilation threads finish what they're doing.
mutable ConcurrentJITLock m_lock;
-
+
+ Atomic<bool> m_visitWeaklyHasBeenCalled;
+
bool m_shouldAlwaysBeInlined; // Not a bitfield because the JIT wants to store to it.
+
+#if ENABLE(JIT)
+ unsigned m_capabilityLevelState : 2; // DFG::CapabilityLevel
+#endif
+
bool m_allTransitionsHaveBeenMarked : 1; // Initialized and used on every GC.
-
+
bool m_didFailFTLCompilation : 1;
bool m_hasBeenCompiledWithFTL : 1;
+ bool m_isConstructor : 1;
+ bool m_isStrictMode : 1;
+ bool m_needsActivation : 1;
+ unsigned m_codeType : 2; // CodeType
// Internal methods for use by validation code. It would be private if it wasn't
// for the fact that we use it from anonymous namespaces.
@@ -1030,18 +1040,13 @@
VirtualRegister m_thisRegister;
VirtualRegister m_scopeRegister;
VirtualRegister m_lexicalEnvironmentRegister;
+ mutable CodeBlockHash m_hash;
- bool m_isStrictMode;
- bool m_needsActivation;
-
- Atomic<bool> m_visitWeaklyHasBeenCalled;
-
RefPtr<SourceProvider> m_source;
unsigned m_sourceOffset;
unsigned m_firstLineColumnOffset;
- CodeType m_codeType;
- Vector<LLIntCallLinkInfo> m_llintCallLinkInfos;
+ RefCountedArray<LLIntCallLinkInfo> m_llintCallLinkInfos;
SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo>> m_incomingLLIntCalls;
RefPtr<JITCode> m_jitCode;
#if ENABLE(JIT)
@@ -1059,14 +1064,15 @@
DFG::ExitProfile m_exitProfile;
CompressedLazyOperandValueProfileHolder m_lazyOperandValueProfiles;
#endif
- Vector<ValueProfile> m_argumentValueProfiles;
- Vector<ValueProfile> m_valueProfiles;
+ RefCountedArray<ValueProfile> m_argumentValueProfiles;
+ RefCountedArray<ValueProfile> m_valueProfiles;
SegmentedVector<RareCaseProfile, 8> m_rareCaseProfiles;
SegmentedVector<ResultProfile, 8> m_resultProfiles;
- HashMap<unsigned, unsigned, IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> m_bytecodeOffsetToResultProfileIndexMap;
- Vector<ArrayAllocationProfile> m_arrayAllocationProfiles;
+ typedef HashMap<unsigned, unsigned, IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> BytecodeOffsetToResultProfileIndexMap;
+ std::unique_ptr<BytecodeOffsetToResultProfileIndexMap> m_bytecodeOffsetToResultProfileIndexMap;
+ RefCountedArray<ArrayAllocationProfile> m_arrayAllocationProfiles;
ArrayProfileVector m_arrayProfiles;
- Vector<ObjectAllocationProfile> m_objectAllocationProfiles;
+ RefCountedArray<ObjectAllocationProfile> m_objectAllocationProfiles;
// Constant Pool
COMPILE_ASSERT(sizeof(Register) == sizeof(WriteBarrier<Unknown>), Register_must_be_same_size_as_WriteBarrier_Unknown);
@@ -1074,29 +1080,23 @@
// it, so we're stuck with it for now.
Vector<WriteBarrier<Unknown>> m_constantRegisters;
Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation;
- Vector<WriteBarrier<FunctionExecutable>> m_functionDecls;
- Vector<WriteBarrier<FunctionExecutable>> m_functionExprs;
+ RefCountedArray<WriteBarrier<FunctionExecutable>> m_functionDecls;
+ RefCountedArray<WriteBarrier<FunctionExecutable>> m_functionExprs;
WriteBarrier<CodeBlock> m_alternative;
BaselineExecutionCounter m_llintExecuteCounter;
BaselineExecutionCounter m_jitExecuteCounter;
- int32_t m_totalJITExecutions;
uint32_t m_osrExitCounter;
uint16_t m_optimizationDelayCounter;
uint16_t m_reoptimizationRetryCounter;
std::chrono::steady_clock::time_point m_creationTime;
- mutable CodeBlockHash m_hash;
-
std::unique_ptr<BytecodeLivenessAnalysis> m_livenessAnalysis;
std::unique_ptr<RareData> m_rareData;
-#if ENABLE(JIT)
- DFG::CapabilityLevel m_capabilityLevelState;
-#endif
UnconditionalFinalizer m_unconditionalFinalizer;
WeakReferenceHarvester m_weakReferenceHarvester;