summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/Executable.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime/Executable.h')
-rw-r--r--Source/JavaScriptCore/runtime/Executable.h73
1 files changed, 48 insertions, 25 deletions
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index e999d3a08..e5f6de438 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -54,7 +54,8 @@ namespace JSC {
return false;
}
- class ExecutableBase : public JSCell {
+ class ExecutableBase : public JSCell, public DoublyLinkedListNode<ExecutableBase> {
+ friend class WTF::DoublyLinkedListNode<ExecutableBase>;
friend class JIT;
protected:
@@ -80,6 +81,11 @@ namespace JSC {
static void destroy(JSCell*);
#endif
+ bool isFunctionExecutable()
+ {
+ return structure()->typeInfo().type() == FunctionExecutableType;
+ }
+
bool isHostFunction() const
{
ASSERT((m_numParametersForCall == NUM_PARAMETERS_IS_HOST) == (m_numParametersForConstruct == NUM_PARAMETERS_IS_HOST));
@@ -88,6 +94,8 @@ namespace JSC {
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(CompoundType, StructureFlags), &s_info); }
+ void clearCode();
+
static JS_EXPORTDATA const ClassInfo s_info;
protected:
@@ -95,8 +103,10 @@ namespace JSC {
int m_numParametersForCall;
int m_numParametersForConstruct;
-#if ENABLE(JIT)
public:
+ static void clearCodeVirtual(ExecutableBase*);
+
+#if ENABLE(JIT)
JITCode& generatedJITCodeForCall()
{
ASSERT(m_jitCodeForCall);
@@ -166,14 +176,18 @@ namespace JSC {
return intrinsic();
return NoIntrinsic;
}
+#endif
protected:
+ ExecutableBase* m_prev;
+ ExecutableBase* m_next;
+
+#if ENABLE(JIT)
JITCode m_jitCodeForCall;
JITCode m_jitCodeForConstruct;
MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck;
MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheck;
#endif
- void clearCode();
};
class NativeExecutable : public ExecutableBase {
@@ -194,7 +208,6 @@ namespace JSC {
executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
executable->finishCreation(globalData, JITCode::HostFunction(callThunk), JITCode::HostFunction(constructThunk), intrinsic);
}
- globalData.heap.addFinalizer(executable, &finalize);
return executable;
}
#endif
@@ -205,7 +218,6 @@ namespace JSC {
ASSERT(!globalData.canUseJIT());
NativeExecutable* executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
executable->finishCreation(globalData);
- globalData.heap.addFinalizer(executable, &finalize);
return executable;
}
#endif
@@ -246,8 +258,6 @@ namespace JSC {
}
#endif
- static void finalize(JSCell*);
-
private:
NativeExecutable(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
: ExecutableBase(globalData, globalData.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
@@ -303,6 +313,8 @@ namespace JSC {
void finishCreation(JSGlobalData& globalData)
{
Base::finishCreation(globalData);
+ globalData.heap.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode().
+
#if ENABLE(CODEBLOCK_SAMPLING)
if (SamplingTool* sampler = globalData.interpreter->sampler())
sampler->notifyOfScope(globalData, this);
@@ -358,7 +370,6 @@ namespace JSC {
{
EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, source, isInStrictContext);
executable->finishCreation(exec->globalData());
- exec->globalData().heap.addFinalizer(executable, &finalize);
return executable;
}
@@ -377,9 +388,7 @@ namespace JSC {
void unlinkCalls();
- protected:
void clearCode();
- static void finalize(JSCell*);
private:
static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
@@ -400,7 +409,6 @@ namespace JSC {
{
ProgramExecutable* executable = new (NotNull, allocateCell<ProgramExecutable>(*exec->heap())) ProgramExecutable(exec, source);
executable->finishCreation(exec->globalData());
- exec->globalData().heap.addFinalizer(executable, &finalize);
return executable;
}
@@ -447,9 +455,7 @@ namespace JSC {
void unlinkCalls();
- protected:
void clearCode();
- static void finalize(JSCell*);
private:
static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
@@ -461,10 +467,9 @@ namespace JSC {
OwnPtr<ProgramCodeBlock> m_programCodeBlock;
};
- class FunctionExecutable : public ScriptExecutable, public DoublyLinkedListNode<FunctionExecutable> {
+ class FunctionExecutable : public ScriptExecutable {
friend class JIT;
friend class LLIntOffsetsExtractor;
- friend class WTF::DoublyLinkedListNode<FunctionExecutable>;
public:
typedef ScriptExecutable Base;
@@ -472,8 +477,6 @@ namespace JSC {
{
FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(*exec->heap())) FunctionExecutable(exec, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
executable->finishCreation(exec->globalData(), name, firstLine, lastLine);
- exec->globalData().heap.addFunctionExecutable(executable);
- exec->globalData().heap.addFinalizer(executable, &finalize);
return executable;
}
@@ -481,8 +484,6 @@ namespace JSC {
{
FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
executable->finishCreation(globalData, name, firstLine, lastLine);
- globalData.heap.addFunctionExecutable(executable);
- globalData.heap.addFinalizer(executable, &finalize);
return executable;
}
@@ -639,7 +640,7 @@ namespace JSC {
UString paramString() const;
SharedSymbolTable* symbolTable() const { return m_symbolTable; }
- void discardCode();
+ void clearCodeIfNotCompiling();
static void visitChildren(JSCell*, SlotVisitor&);
static FunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
@@ -651,10 +652,9 @@ namespace JSC {
void unlinkCalls();
- protected:
void clearCode();
- static void finalize(JSCell*);
+ protected:
void finishCreation(JSGlobalData& globalData, const Identifier& name, int firstLine, int lastLine)
{
Base::finishCreation(globalData);
@@ -677,7 +677,18 @@ namespace JSC {
ASSERT(kind == CodeForConstruct);
return m_codeBlockForConstruct;
}
-
+
+ bool isCompiling()
+ {
+#if ENABLE(JIT)
+ if (!m_jitCodeForCall && m_codeBlockForCall)
+ return true;
+ if (!m_jitCodeForConstruct && m_codeBlockForConstruct)
+ return true;
+#endif
+ return false;
+ }
+
static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
unsigned m_numCapturedVariables : 31;
bool m_forceUsesArguments : 1;
@@ -689,8 +700,6 @@ namespace JSC {
Identifier m_inferredName;
WriteBarrier<JSString> m_nameValue;
SharedSymbolTable* m_symbolTable;
- FunctionExecutable* m_next;
- FunctionExecutable* m_prev;
};
inline FunctionExecutable* JSFunction::jsExecutable() const
@@ -725,6 +734,20 @@ namespace JSC {
return function->nativeFunction() == nativeFunction;
}
+ inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable)
+ {
+ switch (executable->structure()->typeInfo().type()) {
+ case EvalExecutableType:
+ return jsCast<EvalExecutable*>(executable)->clearCode();
+ case ProgramExecutableType:
+ return jsCast<ProgramExecutable*>(executable)->clearCode();
+ case FunctionExecutableType:
+ return jsCast<FunctionExecutable*>(executable)->clearCode();
+ default:
+ return jsCast<NativeExecutable*>(executable)->clearCode();
+ }
+ }
+
inline void ScriptExecutable::unlinkCalls()
{
switch (structure()->typeInfo().type()) {