diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h')
-rw-r--r-- | Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h | 402 |
1 files changed, 224 insertions, 178 deletions
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h index f5b2b44a9..b9dae2d5c 100644 --- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h +++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2015 Apple Inc. All Rights Reserved. + * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,37 +29,35 @@ #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 "ParserModes.h" #include "RegExp.h" #include "SpecialPointer.h" -#include "UnlinkedFunctionExecutable.h" -#include "VariableEnvironment.h" +#include "SymbolTable.h" #include "VirtualRegister.h" -#include <wtf/FastBitVector.h> + +#include <wtf/Compression.h> #include <wtf/RefCountedArray.h> #include <wtf/Vector.h> namespace JSC { class Debugger; -class FunctionMetadataNode; +class FunctionBodyNode; class FunctionExecutable; +class FunctionParameters; class JSScope; -class ParserError; +struct 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; @@ -67,6 +65,132 @@ 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; StringOffsetTable offsetTable; @@ -94,6 +218,13 @@ 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; } @@ -108,32 +239,31 @@ 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 }; bool isConstructor() const { return m_isConstructor; } bool isStrictMode() const { return m_isStrictMode; } bool usesEval() const { return m_usesEval; } - SourceParseMode parseMode() const { return m_parseMode; } - bool isArrowFunction() const { return m_parseMode == SourceParseMode::ArrowFunctionMode; } - DerivedContextType derivedContextType() const { return static_cast<DerivedContextType>(m_derivedContextType); } - bool isArrowFunctionContext() const { return m_isArrowFunctionContext; } - bool isClassContext() const { return m_isClassContext; } + + bool needsFullScopeChain() const { return m_needsFullScopeChain; } + void setNeedsFullScopeChain(bool needsFullScopeChain) { m_needsFullScopeChain = needsFullScopeChain; } 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 setScopeRegister(VirtualRegister scopeRegister) { m_scopeRegister = scopeRegister; } + 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; } + bool usesGlobalObject() const { return m_globalObjectRegister.isValid(); } void setGlobalObjectRegister(VirtualRegister globalObjectRegister) { m_globalObjectRegister = globalObjectRegister; } @@ -148,7 +278,7 @@ public: { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); - m_rareData->m_regexps.append(WriteBarrier<RegExp>(*vm(), this, r)); + m_rareData->m_regexps.append(WriteBarrier<RegExp>(*m_vm, this, r)); return size; } unsigned numberOfRegExps() const @@ -166,35 +296,19 @@ public: const Identifier& identifier(int index) const { return m_identifiers[index]; } const Vector<Identifier>& identifiers() const { return m_identifiers; } - unsigned addConstant(JSValue v, SourceCodeRepresentation sourceCodeRepresentation = SourceCodeRepresentation::Other) - { - 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) + size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); } + unsigned addConstant(JSValue v) { 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_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other); + m_constantRegisters.last().set(*m_vm, this, v); return result; } - unsigned registerIndexForLinkTimeConstant(LinkTimeConstant type) - { - unsigned index = static_cast<unsigned>(type); - ASSERT(index < LinkTimeConstantCount); - return m_linkTimeConstants[index]; - } + unsigned addOrFindConstant(JSValue); 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; } - const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation() { return m_constantsSourceCodeRepresentation; } + ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); } // Jumps size_t numberOfJumpTargets() const { return m_jumpTargets.size(); } @@ -202,22 +316,22 @@ public: unsigned jumpTarget(int index) const { return m_jumpTargets[index]; } unsigned lastJumpTarget() const { return m_jumpTargets.last(); } - bool isBuiltinFunction() const { return m_isBuiltinFunction; } - - ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); } - SuperBinding superBinding() const { return static_cast<SuperBinding>(m_superBinding); } + void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; } + bool isNumericCompareFunction() const { return m_isNumericCompareFunction; } void shrinkToFit() { m_jumpTargets.shrinkToFit(); m_identifiers.shrinkToFit(); m_constantRegisters.shrinkToFit(); - m_constantsSourceCodeRepresentation.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(); @@ -233,7 +347,7 @@ public: int m_numVars; int m_numCapturedVars; - int m_numCalleeLocals; + int m_numCalleeRegisters; // Jump Tables @@ -249,7 +363,7 @@ public: { unsigned size = m_functionDecls.size(); m_functionDecls.append(WriteBarrier<UnlinkedFunctionExecutable>()); - m_functionDecls.last().set(*vm(), this, n); + m_functionDecls.last().set(*m_vm, this, n); return size; } UnlinkedFunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); } @@ -258,7 +372,7 @@ public: { unsigned size = m_functionExprs.size(); m_functionExprs.append(WriteBarrier<UnlinkedFunctionExecutable>()); - m_functionExprs.last().set(*vm(), this, n); + m_functionExprs.last().set(*m_vm, this, n); return size; } UnlinkedFunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); } @@ -266,10 +380,12 @@ public: // Exception handling support size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; } - void addExceptionHandler(const UnlinkedHandlerInfo& handler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(handler); } + void addExceptionHandler(const UnlinkedHandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); } UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; } - VM* vm() const; + SymbolTable* symbolTable() const { return m_symbolTable.get(); } + + VM* vm() const { return m_vm; } UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; } unsigned numberOfArrayProfiles() { return m_arrayProfileCount; } @@ -286,7 +402,8 @@ public: CodeType codeType() const { return m_codeType; } VirtualRegister thisRegister() const { return m_thisRegister; } - VirtualRegister scopeRegister() const { return m_scopeRegister; } + VirtualRegister activationRegister() const { return m_activationRegister; } + void addPropertyAccessInstruction(unsigned propertyAccessInstruction) { @@ -319,15 +436,13 @@ public: return m_rareData->m_constantBuffers[index]; } - bool hasRareData() const { return m_rareData.get(); } + bool hasRareData() const { return m_rareData; } int lineNumberForBytecodeOffset(unsigned bytecodeOffset); void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column); - bool typeProfilerExpressionInfoForBytecodeOffset(unsigned bytecodeOffset, unsigned& startDivot, unsigned& endDivot); - void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount, unsigned endColumn) { m_features = features; @@ -345,21 +460,6 @@ public: 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. protected: @@ -369,6 +469,9 @@ protected: void finishCreation(VM& vm) { Base::finishCreation(vm); + if (codeType() == GlobalCode) + return; + m_symbolTable.set(vm, this, SymbolTable::create(vm)); } private: @@ -376,49 +479,51 @@ private: void createRareDataIfNecessary() { if (!m_rareData) - m_rareData = std::make_unique<RareData>(); + m_rareData = adoptPtr(new RareData); } void getLineAndColumn(ExpressionRangeInfo&, unsigned& line, unsigned& column); - int m_numParameters; - std::unique_ptr<UnlinkedInstructionStream> m_unlinkedInstructions; + int m_numParameters; + VM* m_vm; + VirtualRegister m_thisRegister; - VirtualRegister m_scopeRegister; + VirtualRegister m_argumentsRegister; + VirtualRegister m_activationRegister; VirtualRegister m_globalObjectRegister; - unsigned m_usesEval : 1; - unsigned m_isStrictMode : 1; - unsigned m_isConstructor : 1; - unsigned m_hasCapturedVariables : 1; - unsigned m_isBuiltinFunction : 1; - unsigned m_constructorKind : 2; - unsigned m_superBinding : 1; - unsigned m_derivedContextType : 2; - unsigned m_isArrowFunctionContext : 1; - unsigned m_isClassContext : 1; + 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; unsigned m_lineCount; unsigned m_endColumn; - SourceParseMode m_parseMode; CodeFeatures m_features; CodeType m_codeType; Vector<unsigned> m_jumpTargets; - Vector<unsigned> m_propertyAccessInstructions; - // Constant Pools Vector<Identifier> m_identifiers; Vector<WriteBarrier<Unknown>> m_constantRegisters; - Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation; typedef Vector<WriteBarrier<UnlinkedFunctionExecutable>> FunctionExpressionVector; FunctionExpressionVector m_functionDecls; FunctionExpressionVector m_functionExprs; - std::array<unsigned, LinkTimeConstantCount> m_linkTimeConstants; + + WriteBarrier<SymbolTable> m_symbolTable; + + Vector<unsigned> m_propertyAccessInstructions; + +#if ENABLE(BYTECODE_COMMENTS) + Vector<Comment> m_bytecodeComments; + size_t m_bytecodeCommentIterator; +#endif unsigned m_arrayProfileCount; unsigned m_arrayAllocationProfileCount; @@ -443,22 +548,16 @@ 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: - std::unique_ptr<RareData> m_rareData; + OwnPtr<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; @@ -474,10 +573,12 @@ protected: { } + static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; + DECLARE_INFO; }; -class UnlinkedProgramCodeBlock final : public UnlinkedGlobalCodeBlock { +class UnlinkedProgramCodeBlock : public UnlinkedGlobalCodeBlock { private: friend class CodeCache; static UnlinkedProgramCodeBlock* create(VM* vm, const ExecutableInfo& info) @@ -489,102 +590,47 @@ private: public: typedef UnlinkedGlobalCodeBlock Base; - static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; - static void destroy(JSCell*); - void setVariableDeclarations(const VariableEnvironment& environment) { m_varDeclarations = environment; } - const VariableEnvironment& variableDeclarations() const { return m_varDeclarations; } - - void setLexicalDeclarations(const VariableEnvironment& environment) { m_lexicalDeclarations = environment; } - const VariableEnvironment& lexicalDeclarations() const { return m_lexicalDeclarations; } - - static void visitChildren(JSCell*, SlotVisitor&); - -private: - UnlinkedProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info) - : Base(vm, structure, GlobalCode, info) + void addFunctionDeclaration(VM& vm, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable) { + m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(vm, this, functionExecutable))); } - VariableEnvironment m_varDeclarations; - VariableEnvironment m_lexicalDeclarations; - -public: - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) - { - return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), info()); - } - - DECLARE_INFO; -}; - -class UnlinkedModuleProgramCodeBlock final : public UnlinkedGlobalCodeBlock { -private: - friend class CodeCache; - static UnlinkedModuleProgramCodeBlock* create(VM* vm, const ExecutableInfo& info) + void addVariableDeclaration(const Identifier& name, bool isConstant) { - UnlinkedModuleProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedModuleProgramCodeBlock>(vm->heap)) UnlinkedModuleProgramCodeBlock(vm, vm->unlinkedModuleProgramCodeBlockStructure.get(), info); - instance->finishCreation(*vm); - return instance; + m_varDeclarations.append(std::make_pair(name, isConstant)); } -public: - typedef UnlinkedGlobalCodeBlock Base; - static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; + typedef Vector<std::pair<Identifier, bool>> VariableDeclations; + typedef Vector<std::pair<Identifier, WriteBarrier<UnlinkedFunctionExecutable>> > FunctionDeclations; - static void destroy(JSCell*); + const VariableDeclations& variableDeclarations() const { return m_varDeclarations; } + const FunctionDeclations& functionDeclarations() const { return m_functionDeclarations; } static void visitChildren(JSCell*, SlotVisitor&); - // This offset represents the constant register offset to the stored symbol table that represents the layout of the - // module environment. This symbol table is created by the byte code generator since the module environment includes - // the top-most lexical captured variables inside the module code. This means that, once the module environment is - // allocated and instantiated from this symbol table, it is titely coupled with the specific unlinked module program - // code block and the stored symbol table. So before executing the module code, we should not clear the unlinked module - // program code block in the module executable. This requirement is met because the garbage collector only clears - // unlinked code in (1) unmarked executables and (2) function executables. - // - // Since the function code may be executed repeatedly and the environment of each function execution is different, - // the function code need to allocate and instantiate the environment in the prologue of the function code. On the - // other hand, the module code is executed only once. So we can instantiate the module environment outside the module - // code. At that time, we construct the module environment by using the symbol table that is held by the module executable. - // The symbol table held by the executable is the cloned one from one in the unlinked code block. Instantiating the module - // environment before executing and linking the module code is required to link the imported bindings between the modules. - // - // The unlinked module program code block only holds the pre-cloned symbol table in its constant register pool. It does - // not hold the instantiated module environment. So while the module environment requires the specific unlinked module - // program code block, the unlinked module code block can be used for the module environment instantiated from this - // unlinked code block. There is 1:N relation between the unlinked module code block and the module environments. So the - // unlinked module program code block can be cached. - // - // On the other hand, the linked code block for the module environment includes the resolved references to the imported - // bindings. The imported binding references the other module environment, so the linked code block is titly coupled - // with the specific set of the module environments. Thus, the linked code block should not be cached. - int moduleEnvironmentSymbolTableConstantRegisterOffset() { return m_moduleEnvironmentSymbolTableConstantRegisterOffset; } - void setModuleEnvironmentSymbolTableConstantRegisterOffset(int offset) - { - m_moduleEnvironmentSymbolTableConstantRegisterOffset = offset; - } - private: - UnlinkedModuleProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info) - : Base(vm, structure, ModuleCode, info) + UnlinkedProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info) + : Base(vm, structure, GlobalCode, info) { } - int m_moduleEnvironmentSymbolTableConstantRegisterOffset { 0 }; + VariableDeclations m_varDeclarations; + FunctionDeclations m_functionDeclarations; public: static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { - return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedModuleProgramCodeBlockType, StructureFlags), info()); + return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), info()); } + static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; + DECLARE_INFO; }; -class UnlinkedEvalCodeBlock final : public UnlinkedGlobalCodeBlock { +class UnlinkedEvalCodeBlock : public UnlinkedGlobalCodeBlock { private: friend class CodeCache; @@ -597,8 +643,6 @@ private: public: typedef UnlinkedGlobalCodeBlock Base; - static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; - static void destroy(JSCell*); const Identifier& variable(unsigned index) { return m_variables[index]; } @@ -623,14 +667,13 @@ public: return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedEvalCodeBlockType, StructureFlags), info()); } + static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; + DECLARE_INFO; }; -class UnlinkedFunctionCodeBlock final : public UnlinkedCodeBlock { +class UnlinkedFunctionCodeBlock : public UnlinkedCodeBlock { public: - typedef UnlinkedCodeBlock Base; - static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; - 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); @@ -638,6 +681,7 @@ public: return instance; } + typedef UnlinkedCodeBlock Base; static void destroy(JSCell*); private: @@ -652,6 +696,8 @@ public: return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), info()); } + static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; + DECLARE_INFO; }; |