diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h')
-rw-r--r-- | Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h | 536 |
1 files changed, 163 insertions, 373 deletions
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h index b9dae2d5c..f0574976c 100644 --- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h +++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved. + * Copyright (C) 2012-2016 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,41 +23,42 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef UnlinkedCodeBlock_h -#define UnlinkedCodeBlock_h +#pragma once #include "BytecodeConventions.h" #include "CodeSpecializationKind.h" #include "CodeType.h" +#include "ConstructAbility.h" #include "ExpressionRangeInfo.h" +#include "HandlerInfo.h" #include "Identifier.h" #include "JSCell.h" #include "JSString.h" +#include "LockDuringMarking.h" #include "ParserModes.h" #include "RegExp.h" #include "SpecialPointer.h" -#include "SymbolTable.h" +#include "UnlinkedFunctionExecutable.h" +#include "VariableEnvironment.h" #include "VirtualRegister.h" - -#include <wtf/Compression.h> -#include <wtf/RefCountedArray.h> +#include <wtf/BitVector.h> +#include <wtf/TriState.h> #include <wtf/Vector.h> namespace JSC { +class BytecodeRewriter; class Debugger; -class FunctionBodyNode; class FunctionExecutable; -class FunctionParameters; -class JSScope; -struct ParserError; +class ParserError; class ScriptExecutable; class SourceCode; class SourceProvider; -class SymbolTable; class UnlinkedCodeBlock; class UnlinkedFunctionCodeBlock; +class UnlinkedFunctionExecutable; class UnlinkedInstructionStream; +struct ExecutableInfo; typedef unsigned UnlinkedValueProfile; typedef unsigned UnlinkedArrayProfile; @@ -65,134 +66,12 @@ typedef unsigned UnlinkedArrayAllocationProfile; typedef unsigned UnlinkedObjectAllocationProfile; typedef unsigned UnlinkedLLIntCallLinkInfo; -struct ExecutableInfo { - ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor) - : m_needsActivation(needsActivation) - , m_usesEval(usesEval) - , m_isStrictMode(isStrictMode) - , m_isConstructor(isConstructor) - { - } - bool m_needsActivation; - bool m_usesEval; - bool m_isStrictMode; - bool m_isConstructor; -}; - -class UnlinkedFunctionExecutable : public JSCell { -public: - friend class CodeCache; - typedef JSCell Base; - static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, bool isFromGlobalCode = false) - { - UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node, isFromGlobalCode); - instance->finishCreation(*vm); - return instance; - } - - const Identifier& name() const { return m_name; } - const Identifier& inferredName() const { return m_inferredName; } - JSString* nameValue() const { return m_nameValue.get(); } - SymbolTable* symbolTable(CodeSpecializationKind kind) - { - return (kind == CodeForCall) ? m_symbolTableForCall.get() : m_symbolTableForConstruct.get(); - } - size_t parameterCount() const; - bool isInStrictContext() const { return m_isInStrictContext; } - FunctionNameIsInScopeToggle functionNameIsInScopeToggle() const { return m_functionNameIsInScopeToggle; } - - unsigned firstLineOffset() const { return m_firstLineOffset; } - unsigned lineCount() const { return m_lineCount; } - unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart; } - unsigned unlinkedBodyStartColumn() const { return m_unlinkedBodyStartColumn; } - unsigned unlinkedBodyEndColumn() const { return m_unlinkedBodyEndColumn; } - unsigned startOffset() const { return m_startOffset; } - unsigned sourceLength() { return m_sourceLength; } - - String paramString() const; - - UnlinkedFunctionCodeBlock* codeBlockFor(VM&, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, ParserError&); - - static UnlinkedFunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception); - - FunctionExecutable* link(VM&, const SourceCode&, size_t lineOffset, size_t sourceOffset); - - void clearCodeForRecompilation() - { - m_symbolTableForCall.clear(); - m_symbolTableForConstruct.clear(); - m_codeBlockForCall.clear(); - m_codeBlockForConstruct.clear(); - } - - FunctionParameters* parameters() { return m_parameters.get(); } - - void recordParse(CodeFeatures features, bool hasCapturedVariables) - { - m_features = features; - m_hasCapturedVariables = hasCapturedVariables; - } - - bool forceUsesArguments() const { return m_forceUsesArguments; } - - CodeFeatures features() const { return m_features; } - bool hasCapturedVariables() const { return m_hasCapturedVariables; } - - static const bool needsDestruction = true; - static const bool hasImmortalStructure = true; - static void destroy(JSCell*); - -private: - UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*, bool isFromGlobalCode); - WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall; - WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct; - - unsigned m_numCapturedVariables : 29; - bool m_forceUsesArguments : 1; - bool m_isInStrictContext : 1; - bool m_hasCapturedVariables : 1; - bool m_isFromGlobalCode : 1; - - Identifier m_name; - Identifier m_inferredName; - WriteBarrier<JSString> m_nameValue; - WriteBarrier<SymbolTable> m_symbolTableForCall; - WriteBarrier<SymbolTable> m_symbolTableForConstruct; - RefPtr<FunctionParameters> m_parameters; - unsigned m_firstLineOffset; - unsigned m_lineCount; - unsigned m_unlinkedFunctionNameStart; - unsigned m_unlinkedBodyStartColumn; - unsigned m_unlinkedBodyEndColumn; - unsigned m_startOffset; - unsigned m_sourceLength; - - CodeFeatures m_features; - - FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle; - -protected: - void finishCreation(VM& vm) - { - Base::finishCreation(vm); - m_nameValue.set(vm, this, jsString(&vm, name().string())); - } - - static void visitChildren(JSCell*, SlotVisitor&); - -public: - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) - { - return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), info()); - } - - static const unsigned StructureFlags = OverridesVisitChildren | JSCell::StructureFlags; - - DECLARE_EXPORT_INFO; -}; - struct UnlinkedStringJumpTable { - typedef HashMap<RefPtr<StringImpl>, int32_t> StringOffsetTable; + struct OffsetLocation { + int32_t branchOffset; + }; + + typedef HashMap<RefPtr<StringImpl>, OffsetLocation> StringOffsetTable; StringOffsetTable offsetTable; inline int32_t offsetForValue(StringImpl* value, int32_t defaultOffset) @@ -201,7 +80,7 @@ struct UnlinkedStringJumpTable { StringOffsetTable::const_iterator loc = offsetTable.find(value); if (loc == end) return defaultOffset; - return loc->value; + return loc->value.branchOffset; } }; @@ -218,13 +97,6 @@ struct UnlinkedSimpleJumpTable { } }; -struct UnlinkedHandlerInfo { - uint32_t start; - uint32_t end; - uint32_t target; - uint32_t scopeDepth; -}; - struct UnlinkedInstruction { UnlinkedInstruction() { u.operand = 0; } UnlinkedInstruction(OpcodeID opcode) { u.opcode = opcode; } @@ -239,31 +111,36 @@ struct UnlinkedInstruction { class UnlinkedCodeBlock : public JSCell { public: typedef JSCell Base; + static const unsigned StructureFlags = Base::StructureFlags; + static const bool needsDestruction = true; - static const bool hasImmortalStructure = true; enum { CallFunction, ApplyFunction }; + typedef UnlinkedInstruction Instruction; + typedef Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow> UnpackedInstructions; + bool isConstructor() const { return m_isConstructor; } bool isStrictMode() const { return m_isStrictMode; } bool usesEval() const { return m_usesEval; } - - bool needsFullScopeChain() const { return m_needsFullScopeChain; } - void setNeedsFullScopeChain(bool needsFullScopeChain) { m_needsFullScopeChain = needsFullScopeChain; } + SourceParseMode parseMode() const { return m_parseMode; } + bool isArrowFunction() const { return isArrowFunctionParseMode(parseMode()); } + DerivedContextType derivedContextType() const { return static_cast<DerivedContextType>(m_derivedContextType); } + EvalContextType evalContextType() const { return static_cast<EvalContextType>(m_evalContextType); } + bool isArrowFunctionContext() const { return m_isArrowFunctionContext; } + bool isClassContext() const { return m_isClassContext; } void addExpressionInfo(unsigned instructionOffset, int divot, int startOffset, int endOffset, unsigned line, unsigned column); + void addTypeProfilerExpressionInfo(unsigned instructionOffset, unsigned startDivot, unsigned endDivot); + bool hasExpressionInfo() { return m_expressionInfo.size(); } + const Vector<ExpressionRangeInfo>& expressionInfo() { return m_expressionInfo; } // Special registers void setThisRegister(VirtualRegister thisRegister) { m_thisRegister = thisRegister; } - void setActivationRegister(VirtualRegister activationRegister) { m_activationRegister = activationRegister; } - - void setArgumentsRegister(VirtualRegister argumentsRegister) { m_argumentsRegister = argumentsRegister; } - bool usesArguments() const { return m_argumentsRegister.isValid(); } - VirtualRegister argumentsRegister() const { return m_argumentsRegister; } - + void setScopeRegister(VirtualRegister scopeRegister) { m_scopeRegister = scopeRegister; } bool usesGlobalObject() const { return m_globalObjectRegister.isValid(); } void setGlobalObjectRegister(VirtualRegister globalObjectRegister) { m_globalObjectRegister = globalObjectRegister; } @@ -277,8 +154,10 @@ public: unsigned addRegExp(RegExp* r) { createRareDataIfNecessary(); + VM& vm = *this->vm(); + auto locker = lockDuringMarking(vm.heap, *this); unsigned size = m_rareData->m_regexps.size(); - m_rareData->m_regexps.append(WriteBarrier<RegExp>(*m_vm, this, r)); + m_rareData->m_regexps.append(WriteBarrier<RegExp>(vm, this, r)); return size; } unsigned numberOfRegExps() const @@ -296,19 +175,47 @@ public: const Identifier& identifier(int index) const { return m_identifiers[index]; } const Vector<Identifier>& identifiers() const { return m_identifiers; } - size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); } - unsigned addConstant(JSValue v) + const Vector<BitVector>& bitVectors() const { return m_bitVectors; } + BitVector& bitVector(size_t i) { return m_bitVectors[i]; } + unsigned addBitVector(BitVector&& bitVector) + { + m_bitVectors.append(WTFMove(bitVector)); + return m_bitVectors.size() - 1; + } + + unsigned addConstant(JSValue v, SourceCodeRepresentation sourceCodeRepresentation = SourceCodeRepresentation::Other) + { + VM& vm = *this->vm(); + auto locker = lockDuringMarking(vm.heap, *this); + unsigned result = m_constantRegisters.size(); + m_constantRegisters.append(WriteBarrier<Unknown>()); + m_constantRegisters.last().set(vm, this, v); + m_constantsSourceCodeRepresentation.append(sourceCodeRepresentation); + return result; + } + unsigned addConstant(LinkTimeConstant type) { + VM& vm = *this->vm(); + auto locker = lockDuringMarking(vm.heap, *this); unsigned result = m_constantRegisters.size(); + ASSERT(result); + unsigned index = static_cast<unsigned>(type); + ASSERT(index < LinkTimeConstantCount); + m_linkTimeConstants[index] = result; m_constantRegisters.append(WriteBarrier<Unknown>()); - m_constantRegisters.last().set(*m_vm, this, v); + m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other); return result; } - unsigned addOrFindConstant(JSValue); + unsigned registerIndexForLinkTimeConstant(LinkTimeConstant type) + { + unsigned index = static_cast<unsigned>(type); + ASSERT(index < LinkTimeConstantCount); + return m_linkTimeConstants[index]; + } const Vector<WriteBarrier<Unknown>>& constantRegisters() { return m_constantRegisters; } const WriteBarrier<Unknown>& constantRegister(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex]; } ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; } - ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); } + const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation() { return m_constantsSourceCodeRepresentation; } // Jumps size_t numberOfJumpTargets() const { return m_jumpTargets.size(); } @@ -316,38 +223,25 @@ public: unsigned jumpTarget(int index) const { return m_jumpTargets[index]; } unsigned lastJumpTarget() const { return m_jumpTargets.last(); } - void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; } - bool isNumericCompareFunction() const { return m_isNumericCompareFunction; } + UnlinkedHandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset, RequiredHandler = RequiredHandler::AnyHandler); + UnlinkedHandlerInfo* handlerForIndex(unsigned, RequiredHandler = RequiredHandler::AnyHandler); - void shrinkToFit() - { - m_jumpTargets.shrinkToFit(); - m_identifiers.shrinkToFit(); - m_constantRegisters.shrinkToFit(); - m_functionDecls.shrinkToFit(); - m_functionExprs.shrinkToFit(); - m_propertyAccessInstructions.shrinkToFit(); - m_expressionInfo.shrinkToFit(); - -#if ENABLE(BYTECODE_COMMENTS) - m_bytecodeComments.shrinkToFit(); -#endif - if (m_rareData) { - m_rareData->m_exceptionHandlers.shrinkToFit(); - m_rareData->m_regexps.shrinkToFit(); - m_rareData->m_constantBuffers.shrinkToFit(); - m_rareData->m_switchJumpTables.shrinkToFit(); - m_rareData->m_stringSwitchJumpTables.shrinkToFit(); - m_rareData->m_expressionInfoFatPositions.shrinkToFit(); - } - } + bool isBuiltinFunction() const { return m_isBuiltinFunction; } + + ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); } + SuperBinding superBinding() const { return static_cast<SuperBinding>(m_superBinding); } + JSParserScriptMode scriptMode() const { return static_cast<JSParserScriptMode>(m_scriptMode); } + + void shrinkToFit(); void setInstructions(std::unique_ptr<UnlinkedInstructionStream>); const UnlinkedInstructionStream& instructions() const; + int numCalleeLocals() const { return m_numCalleeLocals; } + int m_numVars; int m_numCapturedVars; - int m_numCalleeRegisters; + int m_numCalleeLocals; // Jump Tables @@ -361,18 +255,22 @@ public: unsigned addFunctionDecl(UnlinkedFunctionExecutable* n) { + VM& vm = *this->vm(); + auto locker = lockDuringMarking(vm.heap, *this); unsigned size = m_functionDecls.size(); m_functionDecls.append(WriteBarrier<UnlinkedFunctionExecutable>()); - m_functionDecls.last().set(*m_vm, this, n); + m_functionDecls.last().set(vm, this, n); return size; } UnlinkedFunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); } size_t numberOfFunctionDecls() { return m_functionDecls.size(); } unsigned addFunctionExpr(UnlinkedFunctionExecutable* n) { + VM& vm = *this->vm(); + auto locker = lockDuringMarking(vm.heap, *this); unsigned size = m_functionExprs.size(); m_functionExprs.append(WriteBarrier<UnlinkedFunctionExecutable>()); - m_functionExprs.last().set(*m_vm, this, n); + m_functionExprs.last().set(vm, this, n); return size; } UnlinkedFunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); } @@ -380,13 +278,9 @@ public: // Exception handling support size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; } - void addExceptionHandler(const UnlinkedHandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); } + void addExceptionHandler(const UnlinkedHandlerInfo& handler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(handler); } UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; } - SymbolTable* symbolTable() const { return m_symbolTable.get(); } - - VM* vm() const { return m_vm; } - UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; } unsigned numberOfArrayProfiles() { return m_arrayProfileCount; } UnlinkedArrayAllocationProfile addArrayAllocationProfile() { return m_arrayAllocationProfileCount++; } @@ -402,8 +296,7 @@ public: CodeType codeType() const { return m_codeType; } VirtualRegister thisRegister() const { return m_thisRegister; } - VirtualRegister activationRegister() const { return m_activationRegister; } - + VirtualRegister scopeRegister() const { return m_scopeRegister; } void addPropertyAccessInstruction(unsigned propertyAccessInstruction) { @@ -436,94 +329,125 @@ public: return m_rareData->m_constantBuffers[index]; } - bool hasRareData() const { return m_rareData; } + bool hasRareData() const { return m_rareData.get(); } int lineNumberForBytecodeOffset(unsigned bytecodeOffset); void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, - int& startOffset, int& endOffset, unsigned& line, unsigned& column); + int& startOffset, int& endOffset, unsigned& line, unsigned& column) const; + + bool typeProfilerExpressionInfoForBytecodeOffset(unsigned bytecodeOffset, unsigned& startDivot, unsigned& endDivot); - void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount, unsigned endColumn) + void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned lineCount, unsigned endColumn) { m_features = features; m_hasCapturedVariables = hasCapturedVariables; - m_firstLine = firstLine; m_lineCount = lineCount; // For the UnlinkedCodeBlock, startColumn is always 0. m_endColumn = endColumn; } + const String& sourceURLDirective() const { return m_sourceURLDirective; } + const String& sourceMappingURLDirective() const { return m_sourceMappingURLDirective; } + void setSourceURLDirective(const String& sourceURL) { m_sourceURLDirective = sourceURL; } + void setSourceMappingURLDirective(const String& sourceMappingURL) { m_sourceMappingURLDirective = sourceMappingURL; } + CodeFeatures codeFeatures() const { return m_features; } bool hasCapturedVariables() const { return m_hasCapturedVariables; } - unsigned firstLine() const { return m_firstLine; } unsigned lineCount() const { return m_lineCount; } ALWAYS_INLINE unsigned startColumn() const { return 0; } unsigned endColumn() const { return m_endColumn; } + void addOpProfileControlFlowBytecodeOffset(size_t offset) + { + createRareDataIfNecessary(); + m_rareData->m_opProfileControlFlowBytecodeOffsets.append(offset); + } + const Vector<size_t>& opProfileControlFlowBytecodeOffsets() const + { + ASSERT(m_rareData); + return m_rareData->m_opProfileControlFlowBytecodeOffsets; + } + bool hasOpProfileControlFlowBytecodeOffsets() const + { + return m_rareData && !m_rareData->m_opProfileControlFlowBytecodeOffsets.isEmpty(); + } + void dumpExpressionRangeInfo(); // For debugging purpose only. + bool wasCompiledWithDebuggingOpcodes() const { return m_wasCompiledWithDebuggingOpcodes; } + + TriState didOptimize() const { return m_didOptimize; } + void setDidOptimize(TriState didOptimize) { m_didOptimize = didOptimize; } + protected: - UnlinkedCodeBlock(VM*, Structure*, CodeType, const ExecutableInfo&); + UnlinkedCodeBlock(VM*, Structure*, CodeType, const ExecutableInfo&, DebuggerMode); ~UnlinkedCodeBlock(); void finishCreation(VM& vm) { Base::finishCreation(vm); - if (codeType() == GlobalCode) - return; - m_symbolTable.set(vm, this, SymbolTable::create(vm)); } private: + friend class BytecodeRewriter; + void applyModification(BytecodeRewriter&); void createRareDataIfNecessary() { - if (!m_rareData) - m_rareData = adoptPtr(new RareData); + if (!m_rareData) { + auto locker = lockDuringMarking(*heap(), *this); + m_rareData = std::make_unique<RareData>(); + } } - void getLineAndColumn(ExpressionRangeInfo&, unsigned& line, unsigned& column); - - std::unique_ptr<UnlinkedInstructionStream> m_unlinkedInstructions; + void getLineAndColumn(const ExpressionRangeInfo&, unsigned& line, unsigned& column) const; int m_numParameters; - VM* m_vm; + + std::unique_ptr<UnlinkedInstructionStream> m_unlinkedInstructions; VirtualRegister m_thisRegister; - VirtualRegister m_argumentsRegister; - VirtualRegister m_activationRegister; + VirtualRegister m_scopeRegister; VirtualRegister m_globalObjectRegister; - bool m_needsFullScopeChain : 1; - bool m_usesEval : 1; - bool m_isNumericCompareFunction : 1; - bool m_isStrictMode : 1; - bool m_isConstructor : 1; - bool m_hasCapturedVariables : 1; - unsigned m_firstLine; + String m_sourceURLDirective; + String m_sourceMappingURLDirective; + + unsigned m_usesEval : 1; + unsigned m_isStrictMode : 1; + unsigned m_isConstructor : 1; + unsigned m_hasCapturedVariables : 1; + unsigned m_isBuiltinFunction : 1; + unsigned m_superBinding : 1; + unsigned m_scriptMode: 1; + unsigned m_isArrowFunctionContext : 1; + unsigned m_isClassContext : 1; + unsigned m_wasCompiledWithDebuggingOpcodes : 1; + unsigned m_constructorKind : 2; + unsigned m_derivedContextType : 2; + unsigned m_evalContextType : 2; unsigned m_lineCount; unsigned m_endColumn; + TriState m_didOptimize; + SourceParseMode m_parseMode; CodeFeatures m_features; CodeType m_codeType; Vector<unsigned> m_jumpTargets; + Vector<unsigned> m_propertyAccessInstructions; + // Constant Pools Vector<Identifier> m_identifiers; + Vector<BitVector> m_bitVectors; Vector<WriteBarrier<Unknown>> m_constantRegisters; + Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation; typedef Vector<WriteBarrier<UnlinkedFunctionExecutable>> FunctionExpressionVector; FunctionExpressionVector m_functionDecls; FunctionExpressionVector m_functionExprs; - - WriteBarrier<SymbolTable> m_symbolTable; - - Vector<unsigned> m_propertyAccessInstructions; - -#if ENABLE(BYTECODE_COMMENTS) - Vector<Comment> m_bytecodeComments; - size_t m_bytecodeCommentIterator; -#endif + std::array<unsigned, LinkTimeConstantCount> m_linkTimeConstants; unsigned m_arrayProfileCount; unsigned m_arrayAllocationProfileCount; @@ -548,159 +472,25 @@ public: Vector<UnlinkedStringJumpTable> m_stringSwitchJumpTables; Vector<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions; + + struct TypeProfilerExpressionRange { + unsigned m_startDivot; + unsigned m_endDivot; + }; + HashMap<unsigned, TypeProfilerExpressionRange> m_typeProfilerInfoMap; + Vector<size_t> m_opProfileControlFlowBytecodeOffsets; }; private: - OwnPtr<RareData> m_rareData; + std::unique_ptr<RareData> m_rareData; Vector<ExpressionRangeInfo> m_expressionInfo; protected: - - static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; static void visitChildren(JSCell*, SlotVisitor&); + static size_t estimatedSize(JSCell*); public: DECLARE_INFO; }; -class UnlinkedGlobalCodeBlock : public UnlinkedCodeBlock { -public: - typedef UnlinkedCodeBlock Base; - -protected: - UnlinkedGlobalCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info) - : Base(vm, structure, codeType, info) - { - } - - static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; - - DECLARE_INFO; -}; - -class UnlinkedProgramCodeBlock : public UnlinkedGlobalCodeBlock { -private: - friend class CodeCache; - static UnlinkedProgramCodeBlock* create(VM* vm, const ExecutableInfo& info) - { - UnlinkedProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedProgramCodeBlock>(vm->heap)) UnlinkedProgramCodeBlock(vm, vm->unlinkedProgramCodeBlockStructure.get(), info); - instance->finishCreation(*vm); - return instance; - } - -public: - typedef UnlinkedGlobalCodeBlock Base; - static void destroy(JSCell*); - - void addFunctionDeclaration(VM& vm, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable) - { - m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(vm, this, functionExecutable))); - } - - void addVariableDeclaration(const Identifier& name, bool isConstant) - { - m_varDeclarations.append(std::make_pair(name, isConstant)); - } - - typedef Vector<std::pair<Identifier, bool>> VariableDeclations; - typedef Vector<std::pair<Identifier, WriteBarrier<UnlinkedFunctionExecutable>> > FunctionDeclations; - - const VariableDeclations& variableDeclarations() const { return m_varDeclarations; } - const FunctionDeclations& functionDeclarations() const { return m_functionDeclarations; } - - static void visitChildren(JSCell*, SlotVisitor&); - -private: - UnlinkedProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info) - : Base(vm, structure, GlobalCode, info) - { - } - - VariableDeclations m_varDeclarations; - FunctionDeclations m_functionDeclarations; - -public: - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) - { - return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), info()); - } - - static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; - - DECLARE_INFO; -}; - -class UnlinkedEvalCodeBlock : public UnlinkedGlobalCodeBlock { -private: - friend class CodeCache; - - static UnlinkedEvalCodeBlock* create(VM* vm, const ExecutableInfo& info) - { - UnlinkedEvalCodeBlock* instance = new (NotNull, allocateCell<UnlinkedEvalCodeBlock>(vm->heap)) UnlinkedEvalCodeBlock(vm, vm->unlinkedEvalCodeBlockStructure.get(), info); - instance->finishCreation(*vm); - return instance; - } - -public: - typedef UnlinkedGlobalCodeBlock Base; - static void destroy(JSCell*); - - const Identifier& variable(unsigned index) { return m_variables[index]; } - unsigned numVariables() { return m_variables.size(); } - void adoptVariables(Vector<Identifier, 0, UnsafeVectorOverflow>& variables) - { - ASSERT(m_variables.isEmpty()); - m_variables.swap(variables); - } - -private: - UnlinkedEvalCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info) - : Base(vm, structure, EvalCode, info) - { - } - - Vector<Identifier, 0, UnsafeVectorOverflow> m_variables; - -public: - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) - { - return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedEvalCodeBlockType, StructureFlags), info()); - } - - static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; - - DECLARE_INFO; -}; - -class UnlinkedFunctionCodeBlock : public UnlinkedCodeBlock { -public: - static UnlinkedFunctionCodeBlock* create(VM* vm, CodeType codeType, const ExecutableInfo& info) - { - UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(vm->heap)) UnlinkedFunctionCodeBlock(vm, vm->unlinkedFunctionCodeBlockStructure.get(), codeType, info); - instance->finishCreation(*vm); - return instance; - } - - typedef UnlinkedCodeBlock Base; - static void destroy(JSCell*); - -private: - UnlinkedFunctionCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info) - : Base(vm, structure, codeType, info) - { - } - -public: - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) - { - return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), info()); - } - - static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; - - DECLARE_INFO; -}; - } - -#endif // UnlinkedCodeBlock_h |