summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2015-05-20 09:56:07 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2015-05-20 09:56:07 +0000
commit41386e9cb918eed93b3f13648cbef387e371e451 (patch)
treea97f9d7bd1d9d091833286085f72da9d83fd0606 /Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
parente15dd966d523731101f70ccf768bba12435a0208 (diff)
downloadWebKitGtk-tarball-41386e9cb918eed93b3f13648cbef387e371e451.tar.gz
webkitgtk-2.4.9webkitgtk-2.4.9
Diffstat (limited to 'Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h')
-rw-r--r--Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h282
1 files changed, 200 insertions, 82 deletions
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
index 552ed84a2..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,9 +29,7 @@
#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"
@@ -39,28 +37,27 @@
#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/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;
@@ -68,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;
@@ -95,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; }
@@ -109,9 +239,8 @@ 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 };
@@ -120,18 +249,21 @@ public:
bool usesEval() const { return m_usesEval; }
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(); }
// Special registers
void setThisRegister(VirtualRegister thisRegister) { m_thisRegister = thisRegister; }
- void setScopeRegister(VirtualRegister scopeRegister) { m_scopeRegister = scopeRegister; }
- void setActivationRegister(VirtualRegister activationRegister) { m_lexicalEnvironmentRegister = activationRegister; }
+ 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; }
@@ -164,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)
+ size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
+ unsigned addConstant(JSValue v)
{
unsigned result = m_constantRegisters.size();
m_constantRegisters.append(WriteBarrier<Unknown>());
m_constantRegisters.last().set(*m_vm, this, v);
- m_constantsSourceCodeRepresentation.append(sourceCodeRepresentation);
- return result;
- }
- unsigned addConstant(LinkTimeConstant type)
- {
- 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);
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(); }
@@ -200,16 +316,14 @@ 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); }
+ 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();
@@ -266,9 +380,11 @@ 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]; }
+ SymbolTable* symbolTable() const { return m_symbolTable.get(); }
+
VM* vm() const { return m_vm; }
UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; }
@@ -286,9 +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_lexicalEnvironmentRegister; }
- bool hasActivationRegister() const { return m_lexicalEnvironmentRegister.isValid(); }
+ VirtualRegister activationRegister() const { return m_activationRegister; }
+
void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
{
@@ -321,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;
@@ -347,9 +460,6 @@ public:
ALWAYS_INLINE unsigned startColumn() const { return 0; }
unsigned endColumn() const { return m_endColumn; }
- void addOpProfileControlFlowBytecodeOffset(size_t offset) { m_opProfileControlFlowBytecodeOffsets.append(offset); }
- const Vector<size_t>& opProfileControlFlowBytecodeOffsets() const { return m_opProfileControlFlowBytecodeOffsets; }
-
void dumpExpressionRangeInfo(); // For debugging purpose only.
protected:
@@ -369,7 +479,7 @@ private:
void createRareDataIfNecessary()
{
if (!m_rareData)
- m_rareData = std::make_unique<RareData>();
+ m_rareData = adoptPtr(new RareData);
}
void getLineAndColumn(ExpressionRangeInfo&, unsigned& line, unsigned& column);
@@ -380,18 +490,16 @@ private:
VM* m_vm;
VirtualRegister m_thisRegister;
- VirtualRegister m_scopeRegister;
- VirtualRegister m_lexicalEnvironmentRegister;
+ VirtualRegister m_argumentsRegister;
+ VirtualRegister m_activationRegister;
VirtualRegister m_globalObjectRegister;
- unsigned m_needsFullScopeChain : 1;
- unsigned m_usesEval : 1;
- unsigned m_isStrictMode : 1;
- unsigned m_isConstructor : 1;
- unsigned m_hasCapturedVariables : 1;
- unsigned m_isBuiltinFunction : 1;
- unsigned m_constructorKind : 2;
-
+ 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;
@@ -404,8 +512,6 @@ private:
// Constant Pools
Vector<Identifier> m_identifiers;
Vector<WriteBarrier<Unknown>> m_constantRegisters;
- Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation;
- std::array<unsigned, LinkTimeConstantCount> m_linkTimeConstants;
typedef Vector<WriteBarrier<UnlinkedFunctionExecutable>> FunctionExpressionVector;
FunctionExpressionVector m_functionDecls;
FunctionExpressionVector m_functionExprs;
@@ -445,16 +551,12 @@ public:
};
private:
- std::unique_ptr<RareData> m_rareData;
+ OwnPtr<RareData> m_rareData;
Vector<ExpressionRangeInfo> m_expressionInfo;
- struct TypeProfilerExpressionRange {
- unsigned m_startDivot;
- unsigned m_endDivot;
- };
- HashMap<unsigned, TypeProfilerExpressionRange> m_typeProfilerInfoMap;
- Vector<size_t> m_opProfileControlFlowBytecodeOffsets;
protected:
+
+ static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
static void visitChildren(JSCell*, SlotVisitor&);
public:
@@ -471,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)
@@ -486,12 +590,23 @@ 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 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&);
@@ -501,7 +616,8 @@ private:
{
}
- VariableEnvironment m_varDeclarations;
+ VariableDeclations m_varDeclarations;
+ FunctionDeclations m_functionDeclarations;
public:
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
@@ -509,10 +625,12 @@ public:
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;
@@ -525,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]; }
@@ -551,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);
@@ -566,6 +681,7 @@ public:
return instance;
}
+ typedef UnlinkedCodeBlock Base;
static void destroy(JSCell*);
private:
@@ -580,6 +696,8 @@ public:
return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), info());
}
+ static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
+
DECLARE_INFO;
};