diff options
Diffstat (limited to 'Source/JavaScriptCore/runtime/Executable.h')
-rw-r--r-- | Source/JavaScriptCore/runtime/Executable.h | 205 |
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 |