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.h205
1 files changed, 103 insertions, 102 deletions
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index 83eb602c4..28e823ca4 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010, 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
@@ -32,10 +32,11 @@
#include "HandlerInfo.h"
#include "JSFunction.h"
#include "Interpreter.h"
+#include "JITCode.h"
#include "JSGlobalObject.h"
#include "LLIntCLoop.h"
-#include "Nodes.h"
#include "SamplingTool.h"
+#include "SourceCode.h"
#include "UnlinkedCodeBlock.h"
#include <wtf/PassOwnPtr.h>
@@ -67,16 +68,16 @@ namespace JSC {
static const int NUM_PARAMETERS_IS_HOST = 0;
static const int NUM_PARAMETERS_NOT_COMPILED = -1;
- ExecutableBase(JSGlobalData& globalData, Structure* structure, int numParameters)
- : JSCell(globalData, structure)
+ ExecutableBase(VM& vm, Structure* structure, int numParameters)
+ : JSCell(vm, structure)
, m_numParametersForCall(numParameters)
, m_numParametersForConstruct(numParameters)
{
}
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
}
public:
@@ -101,7 +102,7 @@ namespace JSC {
return m_numParametersForCall == NUM_PARAMETERS_IS_HOST;
}
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(CompoundType, StructureFlags), &s_info); }
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CompoundType, StructureFlags), &s_info); }
void clearCode();
@@ -176,16 +177,6 @@ namespace JSC {
return hasJITCodeForConstruct();
}
- // Intrinsics are only for calls, currently.
- Intrinsic intrinsic() const;
-
- Intrinsic intrinsicFor(CodeSpecializationKind kind) const
- {
- if (isCall(kind))
- return intrinsic();
- return NoIntrinsic;
- }
-
static ptrdiff_t offsetOfJITCodeFor(CodeSpecializationKind kind)
{
if (kind == CodeForCall)
@@ -211,6 +202,16 @@ namespace JSC {
}
#endif // ENABLE(JIT)
+ // Intrinsics are only for calls, currently.
+ Intrinsic intrinsic() const;
+
+ Intrinsic intrinsicFor(CodeSpecializationKind kind) const
+ {
+ if (isCall(kind))
+ return intrinsic();
+ return NoIntrinsic;
+ }
+
#if ENABLE(JIT) || ENABLE(LLINT_C_LOOP)
MacroAssemblerCodePtr hostCodeEntryFor(CodeSpecializationKind kind)
{
@@ -270,26 +271,26 @@ namespace JSC {
typedef ExecutableBase Base;
#if ENABLE(JIT)
- static NativeExecutable* create(JSGlobalData& globalData, MacroAssemblerCodeRef callThunk, NativeFunction function, MacroAssemblerCodeRef constructThunk, NativeFunction constructor, Intrinsic intrinsic)
+ static NativeExecutable* create(VM& vm, MacroAssemblerCodeRef callThunk, NativeFunction function, MacroAssemblerCodeRef constructThunk, NativeFunction constructor, Intrinsic intrinsic)
{
NativeExecutable* executable;
if (!callThunk) {
- executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
- executable->finishCreation(globalData, JITCode(), JITCode(), intrinsic);
+ executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor);
+ executable->finishCreation(vm, JITCode(), JITCode(), intrinsic);
} else {
- executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
- executable->finishCreation(globalData, JITCode::HostFunction(callThunk), JITCode::HostFunction(constructThunk), intrinsic);
+ executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor);
+ executable->finishCreation(vm, JITCode::HostFunction(callThunk), JITCode::HostFunction(constructThunk), intrinsic);
}
return executable;
}
#endif
#if ENABLE(LLINT_C_LOOP)
- static NativeExecutable* create(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
+ static NativeExecutable* create(VM& vm, NativeFunction function, NativeFunction constructor)
{
- ASSERT(!globalData.canUseJIT());
- NativeExecutable* executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
- executable->finishCreation(globalData);
+ ASSERT(!vm.canUseJIT());
+ NativeExecutable* executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor);
+ executable->finishCreation(vm);
return executable;
}
#endif
@@ -302,8 +303,24 @@ namespace JSC {
NativeFunction function() { return m_function; }
NativeFunction constructor() { return m_constructor; }
+
+ NativeFunction nativeFunctionFor(CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return function();
+ ASSERT(kind == CodeForConstruct);
+ return constructor();
+ }
+
+ static ptrdiff_t offsetOfNativeFunctionFor(CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return OBJECT_OFFSETOF(NativeExecutable, m_function);
+ ASSERT(kind == CodeForConstruct);
+ return OBJECT_OFFSETOF(NativeExecutable, m_constructor);
+ }
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(LeafType, StructureFlags), &s_info); }
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(LeafType, StructureFlags), &s_info); }
static const ClassInfo s_info;
@@ -311,9 +328,9 @@ namespace JSC {
protected:
#if ENABLE(JIT)
- void finishCreation(JSGlobalData& globalData, JITCode callThunk, JITCode constructThunk, Intrinsic intrinsic)
+ void finishCreation(VM& vm, JITCode callThunk, JITCode constructThunk, Intrinsic intrinsic)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
m_jitCodeForCall = callThunk;
m_jitCodeForConstruct = constructThunk;
m_jitCodeForCallWithArityCheck = callThunk.addressForCall();
@@ -323,8 +340,8 @@ namespace JSC {
#endif
private:
- NativeExecutable(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
- : ExecutableBase(globalData, globalData.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
+ NativeExecutable(VM& vm, NativeFunction function, NativeFunction constructor)
+ : ExecutableBase(vm, vm.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
, m_function(function)
, m_constructor(constructor)
{
@@ -340,17 +357,19 @@ namespace JSC {
public:
typedef ExecutableBase Base;
- ScriptExecutable(Structure* structure, JSGlobalData& globalData, const SourceCode& source, bool isInStrictContext)
- : ExecutableBase(globalData, structure, NUM_PARAMETERS_NOT_COMPILED)
+ ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext)
+ : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
, m_features(isInStrictContext ? StrictModeFeature : 0)
+ , m_neverInline(false)
{
}
ScriptExecutable(Structure* structure, ExecState* exec, const SourceCode& source, bool isInStrictContext)
- : ExecutableBase(exec->globalData(), structure, NUM_PARAMETERS_NOT_COMPILED)
+ : ExecutableBase(exec->vm(), structure, NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
, m_features(isInStrictContext ? StrictModeFeature : 0)
+ , m_neverInline(false)
{
}
@@ -365,11 +384,16 @@ namespace JSC {
const String& sourceURL() const { return m_source.provider()->url(); }
int lineNo() const { return m_firstLine; }
int lastLine() const { return m_lastLine; }
+ unsigned startColumn() const { return m_startColumn; }
bool usesEval() const { return m_features & EvalFeature; }
bool usesArguments() const { return m_features & ArgumentsFeature; }
bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); }
bool isStrictMode() const { return m_features & StrictModeFeature; }
+
+ void setNeverInline(bool value) { m_neverInline = value; }
+ bool neverInline() const { return m_neverInline; }
+ bool isInliningCandidate() const { return !neverInline(); }
void unlinkCalls();
@@ -377,31 +401,34 @@ namespace JSC {
static const ClassInfo s_info;
- void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
+ void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine, unsigned startColumn)
{
m_features = features;
m_hasCapturedVariables = hasCapturedVariables;
m_firstLine = firstLine;
m_lastLine = lastLine;
+ m_startColumn = startColumn;
}
protected:
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
- globalData.heap.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode().
+ Base::finishCreation(vm);
+ vm.heap.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode().
#if ENABLE(CODEBLOCK_SAMPLING)
- if (SamplingTool* sampler = globalData.interpreter->sampler())
- sampler->notifyOfScope(globalData, this);
+ if (SamplingTool* sampler = vm.interpreter->sampler())
+ sampler->notifyOfScope(vm, this);
#endif
}
SourceCode m_source;
CodeFeatures m_features;
bool m_hasCapturedVariables;
+ bool m_neverInline;
int m_firstLine;
int m_lastLine;
+ unsigned m_startColumn;
};
class EvalExecutable : public ScriptExecutable {
@@ -413,7 +440,7 @@ namespace JSC {
JSObject* compile(ExecState* exec, JSScope* scope)
{
- ASSERT(exec->globalData().dynamicGlobalObject);
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
JSObject* error = 0;
if (!m_evalCodeBlock)
error = compileInternal(exec, scope, JITCode::bottomTierJIT());
@@ -424,7 +451,7 @@ namespace JSC {
JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
#if ENABLE(JIT)
- void jettisonOptimizedCode(JSGlobalData&);
+ void jettisonOptimizedCode(VM&);
bool jitCompile(ExecState*);
#endif
@@ -434,10 +461,10 @@ namespace JSC {
return *m_evalCodeBlock;
}
- static EvalExecutable* create(ExecState* exec, const SourceCode& source, bool isInStrictContext)
+ static EvalExecutable* create(ExecState* exec, PassRefPtr<CodeCache> cache, const SourceCode& source, bool isInStrictContext)
{
- EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, source, isInStrictContext);
- executable->finishCreation(exec->globalData());
+ EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, cache, source, isInStrictContext);
+ executable->finishCreation(exec->vm());
return executable;
}
@@ -447,9 +474,9 @@ namespace JSC {
return generatedJITCodeForCall();
}
#endif
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(EvalExecutableType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(EvalExecutableType, StructureFlags), &s_info);
}
static const ClassInfo s_info;
@@ -462,13 +489,14 @@ namespace JSC {
private:
static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
- EvalExecutable(ExecState*, const SourceCode&, bool);
+ EvalExecutable(ExecState*, PassRefPtr<CodeCache>, const SourceCode&, bool);
JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
static void visitChildren(JSCell*, SlotVisitor&);
OwnPtr<EvalCodeBlock> m_evalCodeBlock;
WriteBarrier<UnlinkedEvalCodeBlock> m_unlinkedEvalCodeBlock;
+ RefPtr<CodeCache> m_codeCache;
};
class ProgramExecutable : public ScriptExecutable {
@@ -479,18 +507,18 @@ namespace JSC {
static ProgramExecutable* create(ExecState* exec, const SourceCode& source)
{
ProgramExecutable* executable = new (NotNull, allocateCell<ProgramExecutable>(*exec->heap())) ProgramExecutable(exec, source);
- executable->finishCreation(exec->globalData());
+ executable->finishCreation(exec->vm());
return executable;
}
- JSObject* initalizeGlobalProperties(JSGlobalData&, CallFrame*, JSScope*);
+ JSObject* initializeGlobalProperties(VM&, CallFrame*, JSScope*);
static void destroy(JSCell*);
JSObject* compile(ExecState* exec, JSScope* scope)
{
- ASSERT(exec->globalData().dynamicGlobalObject);
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
JSObject* error = 0;
if (!m_programCodeBlock)
error = compileInternal(exec, scope, JITCode::bottomTierJIT());
@@ -501,7 +529,7 @@ namespace JSC {
JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
#if ENABLE(JIT)
- void jettisonOptimizedCode(JSGlobalData&);
+ void jettisonOptimizedCode(VM&);
bool jitCompile(ExecState*);
#endif
@@ -520,9 +548,9 @@ namespace JSC {
}
#endif
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(ProgramExecutableType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ProgramExecutableType, StructureFlags), &s_info);
}
static const ClassInfo s_info;
@@ -555,15 +583,20 @@ namespace JSC {
public:
typedef ScriptExecutable Base;
- static FunctionExecutable* create(JSGlobalData& globalData, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine)
+ static FunctionExecutable* create(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn)
{
- FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, source, unlinkedExecutable, firstLine, lastLine);
- executable->finishCreation(globalData);
+ FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(vm.heap)) FunctionExecutable(vm, source, unlinkedExecutable, firstLine, lastLine, startColumn);
+ executable->finishCreation(vm);
return executable;
}
static FunctionExecutable* fromGlobalCode(const Identifier& name, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
static void destroy(JSCell*);
+
+ UnlinkedFunctionExecutable* unlinkedExecutable()
+ {
+ return m_unlinkedExecutable.get();
+ }
// Returns either call or construct bytecode. This can be appropriate
// for answering questions that that don't vary between call and construct --
@@ -576,13 +609,11 @@ namespace JSC {
return *m_codeBlockForConstruct;
}
- FunctionCodeBlock* codeBlockWithBytecodeFor(CodeSpecializationKind);
-
PassOwnPtr<FunctionCodeBlock> produceCodeBlockFor(JSScope*, CodeSpecializationKind, JSObject*& exception);
JSObject* compileForCall(ExecState* exec, JSScope* scope)
{
- ASSERT(exec->globalData().dynamicGlobalObject);
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
JSObject* error = 0;
if (!m_codeBlockForCall)
error = compileForCallInternal(exec, scope, JITCode::bottomTierJIT());
@@ -593,7 +624,7 @@ namespace JSC {
JSObject* compileOptimizedForCall(ExecState*, JSScope*, unsigned bytecodeIndex);
#if ENABLE(JIT)
- void jettisonOptimizedCodeForCall(JSGlobalData&);
+ void jettisonOptimizedCodeForCall(VM&);
bool jitCompileForCall(ExecState*);
#endif
@@ -610,7 +641,7 @@ namespace JSC {
JSObject* compileForConstruct(ExecState* exec, JSScope* scope)
{
- ASSERT(exec->globalData().dynamicGlobalObject);
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
JSObject* error = 0;
if (!m_codeBlockForConstruct)
error = compileForConstructInternal(exec, scope, JITCode::bottomTierJIT());
@@ -621,7 +652,7 @@ namespace JSC {
JSObject* compileOptimizedForConstruct(ExecState*, JSScope*, unsigned bytecodeIndex);
#if ENABLE(JIT)
- void jettisonOptimizedCodeForConstruct(JSGlobalData&);
+ void jettisonOptimizedCodeForConstruct(VM&);
bool jitCompileForConstruct(ExecState*);
#endif
@@ -661,13 +692,13 @@ namespace JSC {
}
#if ENABLE(JIT)
- void jettisonOptimizedCodeFor(JSGlobalData& globalData, CodeSpecializationKind kind)
+ void jettisonOptimizedCodeFor(VM& vm, CodeSpecializationKind kind)
{
if (kind == CodeForCall)
- jettisonOptimizedCodeForCall(globalData);
+ jettisonOptimizedCodeForCall(vm);
else {
ASSERT(kind == CodeForConstruct);
- jettisonOptimizedCodeForConstruct(globalData);
+ jettisonOptimizedCodeForConstruct(vm);
}
}
@@ -713,9 +744,9 @@ namespace JSC {
void clearCodeIfNotCompiling();
void clearUnlinkedCodeForRecompilationIfNotCompiling();
static void visitChildren(JSCell*, SlotVisitor&);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), &s_info);
}
static const ClassInfo s_info;
@@ -725,7 +756,7 @@ namespace JSC {
void clearCode();
private:
- FunctionExecutable(JSGlobalData&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine);
+ FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine, unsigned startColumn);
JSObject* compileForCallInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
JSObject* compileForConstructInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
@@ -755,38 +786,6 @@ namespace JSC {
OwnPtr<FunctionCodeBlock> m_codeBlockForConstruct;
};
- inline JSFunction::JSFunction(JSGlobalData& globalData, FunctionExecutable* executable, JSScope* scope)
- : Base(globalData, scope->globalObject()->functionStructure())
- , m_executable(globalData, this, executable)
- , m_scope(globalData, this, scope)
- , m_inheritorIDWatchpoint(InitializedBlind) // See comment in JSFunction.cpp concerning the reason for using InitializedBlind as opposed to InitializedWatching.
- {
- }
-
- inline FunctionExecutable* JSFunction::jsExecutable() const
- {
- ASSERT(!isHostFunctionNonInline());
- return static_cast<FunctionExecutable*>(m_executable.get());
- }
-
- inline bool JSFunction::isHostFunction() const
- {
- ASSERT(m_executable);
- return m_executable->isHostFunction();
- }
-
- inline NativeFunction JSFunction::nativeFunction()
- {
- ASSERT(isHostFunction());
- return static_cast<NativeExecutable*>(m_executable.get())->function();
- }
-
- inline NativeFunction JSFunction::nativeConstructor()
- {
- ASSERT(isHostFunction());
- return static_cast<NativeExecutable*>(m_executable.get())->constructor();
- }
-
inline bool isHostFunction(JSValue value, NativeFunction nativeFunction)
{
JSFunction* function = jsCast<JSFunction*>(getJSFunction(value));
@@ -819,10 +818,12 @@ namespace JSC {
case FunctionExecutableType:
return jsCast<FunctionExecutable*>(this)->unlinkCalls();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
}
+#include "JSFunctionInlines.h"
+
#endif