LLInt C loop backend.

https://bugs.webkit.org/show_bug.cgi?id=91052.

Patch by Mark Lam <mark.lam@apple.com> on 2012-09-01
Reviewed by Filip Pizlo.

Source/JavaScriptCore:

* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dump):
(JSC::CodeBlock::bytecodeOffset):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC):
* interpreter/Interpreter.h:
* jit/JITStubs.h:
(JITStackFrame):
(JSC):
* llint/LLIntCLoop.cpp: Added.
(JSC):
(LLInt):
(JSC::LLInt::CLoop::initialize):
(JSC::LLInt::CLoop::catchRoutineFor):
(JSC::LLInt::CLoop::hostCodeEntryFor):
(JSC::LLInt::CLoop::jsCodeEntryWithArityCheckFor):
(JSC::LLInt::CLoop::jsCodeEntryFor):
* llint/LLIntCLoop.h: Added.
(JSC):
(LLInt):
(CLoop):
* llint/LLIntData.cpp:
(JSC::LLInt::initialize):
* llint/LLIntData.h:
(JSC):
* llint/LLIntOfflineAsmConfig.h:
* llint/LLIntOpcode.h:
* llint/LLIntThunks.cpp:
(LLInt):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter.cpp:
(LLInt):
(JSC::LLInt::Ints2Double):
(JSC):
(JSC::CLoop::execute):
* llint/LowLevelInterpreter.h:
(JSC):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/asm.rb:
* offlineasm/backends.rb:
* offlineasm/cloop.rb: Added.
* offlineasm/instructions.rb:
* runtime/Executable.h:
(ExecutableBase):
(JSC::ExecutableBase::hostCodeEntryFor):
(JSC::ExecutableBase::jsCodeEntryFor):
(JSC::ExecutableBase::jsCodeWithArityCheckEntryFor):
(JSC::ExecutableBase::catchRoutineFor):
(NativeExecutable):
* runtime/JSValue.h:
(JSC):
(LLInt):
(JSValue):
* runtime/JSValueInlineMethods.h:
(JSC):
(JSC::JSValue::JSValue):
* runtime/Options.cpp:
(JSC::Options::initialize):

Source/WTF:

Added configs for the llint C loop backend.

* wtf/Platform.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@127374 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 570cd740
2012-09-01 Mark Lam <mark.lam@apple.com>
LLInt C loop backend.
https://bugs.webkit.org/show_bug.cgi?id=91052.
Reviewed by Filip Pizlo.
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dump):
(JSC::CodeBlock::bytecodeOffset):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC):
* interpreter/Interpreter.h:
* jit/JITStubs.h:
(JITStackFrame):
(JSC):
* llint/LLIntCLoop.cpp: Added.
(JSC):
(LLInt):
(JSC::LLInt::CLoop::initialize):
(JSC::LLInt::CLoop::catchRoutineFor):
(JSC::LLInt::CLoop::hostCodeEntryFor):
(JSC::LLInt::CLoop::jsCodeEntryWithArityCheckFor):
(JSC::LLInt::CLoop::jsCodeEntryFor):
* llint/LLIntCLoop.h: Added.
(JSC):
(LLInt):
(CLoop):
* llint/LLIntData.cpp:
(JSC::LLInt::initialize):
* llint/LLIntData.h:
(JSC):
* llint/LLIntOfflineAsmConfig.h:
* llint/LLIntOpcode.h:
* llint/LLIntThunks.cpp:
(LLInt):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter.cpp:
(LLInt):
(JSC::LLInt::Ints2Double):
(JSC):
(JSC::CLoop::execute):
* llint/LowLevelInterpreter.h:
(JSC):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/asm.rb:
* offlineasm/backends.rb:
* offlineasm/cloop.rb: Added.
* offlineasm/instructions.rb:
* runtime/Executable.h:
(ExecutableBase):
(JSC::ExecutableBase::hostCodeEntryFor):
(JSC::ExecutableBase::jsCodeEntryFor):
(JSC::ExecutableBase::jsCodeWithArityCheckEntryFor):
(JSC::ExecutableBase::catchRoutineFor):
(NativeExecutable):
* runtime/JSValue.h:
(JSC):
(LLInt):
(JSValue):
* runtime/JSValueInlineMethods.h:
(JSC):
(JSC::JSValue::JSValue):
* runtime/Options.cpp:
(JSC::Options::initialize):
2012-09-01 Geoffrey Garen <ggaren@apple.com>
Rolled back in a piece of <http://trac.webkit.org/changeset/127293>.
......
......@@ -715,6 +715,8 @@
E49DC16B12EF293E00184A1F /* SourceProviderCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E49DC15512EF277200184A1F /* SourceProviderCache.cpp */; };
E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E49DC15112EF272200184A1F /* SourceProviderCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */ = {isa = PBXBuildFile; fileRef = E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */; };
FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE4A331F15BD2E07006F54F3 /* VMInspector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */; };
FE4A332015BD2E07006F54F3 /* VMInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4A331E15BD2E07006F54F3 /* VMInspector.h */; };
FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = FED287B115EC9A5700DA8161 /* LLIntOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -1509,6 +1511,8 @@
F692A87D0255597D01FF60F7 /* RegExp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExp.cpp; sourceTree = "<group>"; tabWidth = 8; };
F692A87E0255597D01FF60F7 /* RegExp.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = RegExp.h; sourceTree = "<group>"; tabWidth = 8; };
F692A8870255597D01FF60F7 /* JSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSValue.cpp; sourceTree = "<group>"; tabWidth = 8; };
FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntCLoop.cpp; path = llint/LLIntCLoop.cpp; sourceTree = "<group>"; };
FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCLoop.h; path = llint/LLIntCLoop.h; sourceTree = "<group>"; };
FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMInspector.cpp; sourceTree = "<group>"; };
FE4A331E15BD2E07006F54F3 /* VMInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMInspector.h; sourceTree = "<group>"; };
FEB63AA2159B9DA3008932A6 /* Comment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Comment.h; sourceTree = "<group>"; };
......@@ -1646,6 +1650,8 @@
isa = PBXGroup;
children = (
FED287B115EC9A5700DA8161 /* LLIntOpcode.h */,
FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */,
FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */,
5DDDF44614FEE72200B4FB4D /* LLIntDesiredOffsets.h */,
0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */,
0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */,
......@@ -2519,6 +2525,7 @@
86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */,
C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */,
C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */,
FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */,
C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */,
C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */,
C21122E315DD9AB300790E3A /* MarkStackInlineMethods.h in Headers */,
......@@ -3495,6 +3502,7 @@
14874AE315EBDE4A002E3587 /* JSNameScope.cpp in Sources */,
14874AE515EBDE4A002E3587 /* JSScope.cpp in Sources */,
1442566115EDE98D0066A49B /* JSWithScope.cpp in Sources */,
FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -1550,6 +1550,10 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
dumpBytecodeCommentAndNewLine(location);
break;
}
#if ENABLE(LLINT_C_LOOP)
default:
ASSERT(false); // We should never get here.
#endif
}
}
......@@ -2638,8 +2642,21 @@ unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddre
UNUSED_PARAM(exec);
UNUSED_PARAM(returnAddress);
#if ENABLE(LLINT)
#if !ENABLE(LLINT_C_LOOP)
// When using the JIT, we could have addresses that are not bytecode
// addresses. We check if the return address is in the LLint glue and
// opcode handlers range here to ensure that we are looking at bytecode
// before attempting to convert the return address into a bytecode offset.
//
// In the case of the C Loop LLInt, the JIT is disabled, and the only
// valid return addresses should be bytecode PCs. So, we can and need to
// forego this check because when we do not ENABLE(COMPUTED_GOTO_OPCODES),
// then the bytecode "PC"s are actually the opcodeIDs and are not bounded
// by llint_begin and llint_end.
if (returnAddress.value() >= LLInt::getCodePtr(llint_begin)
&& returnAddress.value() <= LLInt::getCodePtr(llint_end)) {
&& returnAddress.value() <= LLInt::getCodePtr(llint_end))
#endif
{
ASSERT(exec->codeBlock());
ASSERT(exec->codeBlock() == this);
ASSERT(JITCode::isBaselineCode(getJITType()));
......
......@@ -50,6 +50,7 @@
#include "JSPropertyNameIterator.h"
#include "JSString.h"
#include "JSWithScope.h"
#include "LLIntCLoop.h"
#include "LiteralParser.h"
#include "NameInstance.h"
#include "ObjectPrototype.h"
......@@ -983,12 +984,16 @@ failedJSONP:
SamplingTool::CallRecord callRecord(m_sampler.get());
m_reentryDepth++;
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_program_prologue);
#else // !ENABLE(LLINT_C_LOOP)
#if ENABLE(JIT)
if (!classicEnabled())
result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scope->globalData());
else
#endif // ENABLE(JIT)
result = privateExecute(Normal, &m_registerFile, newCallFrame);
#endif // !ENABLE(LLINT_C_LOOP)
m_reentryDepth--;
}
......@@ -1055,12 +1060,17 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
SamplingTool::CallRecord callRecord(m_sampler.get());
m_reentryDepth++;
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_function_for_call_prologue);
#else // ENABLE(LLINT_C_LOOP)
#if ENABLE(JIT)
if (!classicEnabled())
result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScope->globalData());
else
#endif // ENABLE(JIT)
result = privateExecute(Normal, &m_registerFile, newCallFrame);
#endif // !ENABLE(LLINT_C_LOOP)
m_reentryDepth--;
}
......@@ -1149,12 +1159,16 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
SamplingTool::CallRecord callRecord(m_sampler.get());
m_reentryDepth++;
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_function_for_construct_prologue);
#else // !ENABLE(LLINT_C_LOOP)
#if ENABLE(JIT)
if (!classicEnabled())
result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScope->globalData());
else
#endif // ENABLE(JIT)
result = privateExecute(Normal, &m_registerFile, newCallFrame);
#endif // !ENABLE(LLINT_C_LOOP)
m_reentryDepth--;
}
......@@ -1252,6 +1266,9 @@ JSValue Interpreter::execute(CallFrameClosure& closure)
SamplingTool::CallRecord callRecord(m_sampler.get());
m_reentryDepth++;
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(closure.newCallFrame, llint_function_for_call_prologue);
#else // !ENABLE(LLINT_C_LOOP)
#if ENABLE(JIT)
#if ENABLE(CLASSIC_INTERPRETER)
if (closure.newCallFrame->globalData().canUseJIT())
......@@ -1264,6 +1281,8 @@ JSValue Interpreter::execute(CallFrameClosure& closure)
#if ENABLE(CLASSIC_INTERPRETER)
result = privateExecute(Normal, &m_registerFile, closure.newCallFrame);
#endif
#endif // !ENABLE(LLINT_C_LOOP)
m_reentryDepth--;
}
......@@ -1352,6 +1371,9 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
m_reentryDepth++;
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_eval_prologue);
#else // !ENABLE(LLINT_C_LOOP)
#if ENABLE(JIT)
#if ENABLE(CLASSIC_INTERPRETER)
if (callFrame->globalData().canUseJIT())
......@@ -1364,6 +1386,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
#if ENABLE(CLASSIC_INTERPRETER)
result = privateExecute(Normal, &m_registerFile, newCallFrame);
#endif
#endif // !ENABLE(LLINT_C_LOOP)
m_reentryDepth--;
}
......@@ -1636,6 +1659,8 @@ NEVER_INLINE void Interpreter::uncacheGetByID(CodeBlock*, Instruction* vPC)
#endif // ENABLE(CLASSIC_INTERPRETER)
#if !ENABLE(LLINT_C_LOOP)
JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame)
{
// One-time initialization of our address tables. We have to put this code
......@@ -5092,6 +5117,9 @@ skip_id_custom_self:
#endif // ENABLE(CLASSIC_INTERPRETER)
}
#endif // !ENABLE(LLINT_C_LOOP)
JSValue Interpreter::retrieveArgumentsFromVMCode(CallFrame* callFrame, JSFunction* function) const
{
CallFrame* functionCallFrame = findFunctionCallFrameFromVMCode(callFrame, function);
......
......@@ -275,7 +275,9 @@ namespace JSC {
static CallFrame* findFunctionCallFrameFromVMCode(CallFrame*, JSFunction*);
#if !ENABLE(LLINT_C_LOOP)
JSValue privateExecute(ExecutionFlag, RegisterFile*, CallFrame*);
#endif
void dumpRegisters(CallFrame*);
......
......@@ -468,7 +468,13 @@ extern "C" {
void* JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION) REFERENCED_FROM_ASM WTF_INTERNAL;
} // extern "C"
#endif // ENABLE(JIT)
#elif ENABLE(LLINT_C_LOOP)
struct JITStackFrame {
JSGlobalData* globalData;
};
#endif // ENABLE(LLINT_C_LOOP)
} // namespace JSC
......
/*
* Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "LLIntCLoop.h"
#include "Instruction.h"
namespace JSC {
namespace LLInt {
#if ENABLE(LLINT_C_LOOP)
void CLoop::initialize()
{
execute(0, llint_unused, true);
}
void* CLoop::catchRoutineFor(Instruction* catchPCForInterpreter)
{
return reinterpret_cast<Instruction*>(catchPCForInterpreter->u.opcode);
}
MacroAssemblerCodePtr CLoop::hostCodeEntryFor(CodeSpecializationKind kind)
{
MacroAssemblerCodePtr codePtr;
codePtr = (kind == CodeForCall) ?
MacroAssemblerCodePtr::createLLIntCodePtr(llint_native_call_trampoline) :
MacroAssemblerCodePtr::createLLIntCodePtr(llint_native_construct_trampoline);
return codePtr;
}
MacroAssemblerCodePtr CLoop::jsCodeEntryWithArityCheckFor(CodeSpecializationKind kind)
{
MacroAssemblerCodePtr codePtr;
codePtr = (kind == CodeForCall) ?
MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_arity_check) :
MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_construct_arity_check);
return codePtr;
}
MacroAssemblerCodePtr CLoop::jsCodeEntryFor(CodeSpecializationKind kind)
{
MacroAssemblerCodePtr codePtr;
codePtr = (kind == CodeForCall) ?
MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_prologue) :
MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_construct_prologue);
return codePtr;
}
#endif // ENABLE(LLINT_C_LOOP)
} } // namespace JSC::LLInt
/*
* Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LLIntCLoop_h
#define LLIntCLoop_h
#if ENABLE(LLINT_C_LOOP)
#include "CodeSpecializationKind.h"
#include "JSValue.h"
#include "MacroAssemblerCodeRef.h"
#include "Opcode.h"
#include "Register.h"
namespace JSC {
namespace LLInt {
const OpcodeID llint_unused = llint_end;
class CLoop {
public:
static void initialize();
static JSValue execute(CallFrame*, OpcodeID bootstrapOpcodeId = llint_unused, bool isInitializationPass = false);
static void* catchRoutineFor(Instruction* catchPCForInterpreter);
static MacroAssemblerCodePtr hostCodeEntryFor(CodeSpecializationKind);
static MacroAssemblerCodePtr jsCodeEntryWithArityCheckFor(CodeSpecializationKind);
static MacroAssemblerCodePtr jsCodeEntryFor(CodeSpecializationKind);
};
} } // namespace JSC::LLInt
#endif // ENABLE(LLINT_C_LOOP)
#endif // LLIntCLoop_h
......@@ -31,6 +31,7 @@
#include "BytecodeConventions.h"
#include "CodeType.h"
#include "Instruction.h"
#include "LLIntCLoop.h"
#include "Opcode.h"
namespace JSC { namespace LLInt {
......@@ -43,13 +44,18 @@ void initialize()
Data::s_exceptionInstructions = new Instruction[maxOpcodeLength + 1];
Data::s_opcodeMap = new Opcode[numOpcodeIDs];
#if ENABLE(LLINT_C_LOOP)
CLoop::initialize();
#else // !ENABLE(LLINT_C_LOOP)
for (int i = 0; i < maxOpcodeLength + 1; ++i)
Data::s_exceptionInstructions[i].u.pointer =
LLInt::getCodePtr(llint_throw_from_slow_path_trampoline);
#define OPCODE_ENTRY(opcode, length) \
#define OPCODE_ENTRY(opcode, length) \
Data::s_opcodeMap[opcode] = LLInt::getCodePtr(llint_##opcode);
FOR_EACH_OPCODE_ID(OPCODE_ENTRY);
#undef OPCODE_ENTRY
#endif // !ENABLE(LLINT_C_LOOP)
}
#if COMPILER(CLANG)
......
......@@ -35,7 +35,11 @@ namespace JSC {
class JSGlobalData;
struct Instruction;
#if ENABLE(LLINT_C_LOOP)
typedef OpcodeID LLIntCode;
#else
typedef void (*LLIntCode)();
#endif
namespace LLInt {
......
......@@ -31,6 +31,17 @@
#include <wtf/InlineASM.h>
#include <wtf/Platform.h>
#if ENABLE(LLINT_C_LOOP)
#define OFFLINE_ASM_C_LOOP 1
#define OFFLINE_ASM_X86 0
#define OFFLINE_ASM_ARMv7 0
#define OFFLINE_ASM_X86_64 0
#else // !ENABLE(LLINT_C_LOOP)
#define OFFLINE_ASM_C_LOOP 0
#if CPU(X86)
#define OFFLINE_ASM_X86 1
#else
......@@ -49,6 +60,8 @@
#define OFFLINE_ASM_X86_64 0
#endif
#endif // !ENABLE(LLINT_C_LOOP)
#if USE(JSVALUE64)
#define OFFLINE_ASM_JSVALUE64 1
#else
......
......@@ -30,9 +30,19 @@
#if ENABLE(LLINT)
#if ENABLE(LLINT_C_LOOP)
#define FOR_EACH_LLINT_NOJIT_NATIVE_HELPER(macro) \
macro(getHostCallReturnValue, 1) \
macro(ctiOpThrowNotCaught, 1)
#else // !ENABLE(LLINT_C_LOOP)
#define FOR_EACH_LLINT_NOJIT_NATIVE_HELPER(macro) \
// Nothing to do here. Use the JIT impl instead.
#endif // !ENABLE(LLINT_C_LOOP)
#define FOR_EACH_LLINT_NATIVE_HELPER(macro) \
FOR_EACH_LLINT_NOJIT_NATIVE_HELPER(macro) \
......@@ -56,7 +66,11 @@
macro(llint_end, 1)
#if ENABLE(LLINT_C_LOOP)
#define FOR_EACH_LLINT_OPCODE_EXTENSION(macro) FOR_EACH_LLINT_NATIVE_HELPER(macro)
#else
#define FOR_EACH_LLINT_OPCODE_EXTENSION(macro) // Nothing to add.
#endif
#else // !ENABLE(LLINT)
......
......@@ -36,6 +36,8 @@
namespace JSC { namespace LLInt {
#if !ENABLE(LLINT_C_LOOP)
static MacroAssemblerCodeRef generateThunkWithJumpTo(JSGlobalData* globalData, void (*target)(), const char *thunkKind)
{
JSInterfaceJIT jit;
......@@ -78,6 +80,8 @@ MacroAssemblerCodeRef programEntryThunkGenerator(JSGlobalData* globalData)
return generateThunkWithJumpTo(globalData, llint_program_prologue, "program");
}
#endif // !ENABLE(LLINT_C_LOOP)
} } // namespace JSC::LLInt
#endif // ENABLE(LLINT)
......@@ -110,9 +110,13 @@ end
# Some common utilities.
macro crash()
storei t0, 0xbbadbeef[]
move 0, t0
call t0
if C_LOOP
cloopCrash
else
storei t0, 0xbbadbeef[]
move 0, t0
call t0
end
end
macro assert(assertion)
......@@ -124,7 +128,10 @@ macro assert(assertion)
end
macro preserveReturnAddressAfterCall(destinationRegister)
if ARMv7
if C_LOOP
# In our case, we're only preserving the bytecode vPC.
move lr, destinationRegister
elsif ARMv7
move lr, destinationRegister
elsif X86 or X86_64
pop destinationRegister
......@@ -134,7 +141,10 @@ macro preserveReturnAddressAfterCall(destinationRegister)
end
macro restoreReturnAddressBeforeReturn(sourceRegister)
if ARMv7
if C_LOOP
# In our case, we're only restoring the bytecode vPC.
move sourceRegister, lr
elsif ARMv7
move sourceRegister, lr
elsif X86 or X86_64
push sourceRegister
......@@ -150,8 +160,12 @@ macro traceExecution()
end
macro callTargetFunction(callLinkInfo)
call LLIntCallLinkInfo::machineCodeTarget[callLinkInfo]
dispatchAfterCall()
if C_LOOP
cloopCallJSFunction LLIntCallLinkInfo::machineCodeTarget[callLinkInfo]
else
call LLIntCallLinkInfo::machineCodeTarget[callLinkInfo]
dispatchAfterCall()
end
end
macro slowPathForCall(advance, slowPath)
......@@ -159,7 +173,11 @@ macro slowPathForCall(advance, slowPath)
advance,
slowPath,
macro (callee)
call callee
if C_LOOP
cloopCallJSFunction callee
else
call callee
end
dispatchAfterCall()
end)
end
......
......@@ -32,6 +32,48 @@
#include "Opcode.h"
#if ENABLE(LLINT_C_LOOP)
namespace JSC {
// The following is a minimal set of alias for the opcode names. This is needed
// because there is code (e.g. in GetByIdStatus.cpp and PutByIdStatus.cpp)
// which refers to the opcodes expecting them to be prefixed with "llint_".
// In the CLoop implementation, the 2 are equivalent. Hence, we set up this
// alias here.
//
// Note: we don't just do this for all opcodes because we only need a few,
// and currently, FOR_EACH_OPCODE_ID() includes the llint and JIT opcode
// extensions which we definitely don't want to add an alias for. With some
// minor refactoring, we can use FOR_EACH_OPCODE_ID() to automatically
// generate a llint_ alias for all opcodes, but that is not needed at this
// time.
const OpcodeID llint_op_call = op_call;
const OpcodeID llint_op_call_eval = op_call_eval;
const OpcodeID llint_op_call_varargs = op_call_varargs;
const OpcodeID llint_op_construct = op_construct;
const OpcodeID llint_op_catch = op_catch;
const OpcodeID llint_op_get_by_id = op_get_by_id;
const OpcodeID llint_op_get_by_id_out_of_line = op_get_by_id_out_of_line;
const OpcodeID llint_op_put_by_id = op_put_by_id;
const OpcodeID llint_op_put_by_id_out_of_line = op_put_by_id_out_of_line;
const OpcodeID llint_op_put_by_id_transition_direct =
op_put_by_id_transition_direct;
const OpcodeID llint_op_put_by_id_transition_direct_out_of_line =
op_put_by_id_transition_direct_out_of_line;
const OpcodeID llint_op_put_by_id_transition_normal =
op_put_by_id_transition_normal;
const OpcodeID llint_op_put_by_id_transition_normal_out_of_line =
op_put_by_id_transition_normal_out_of_line;
const OpcodeID llint_op_method_check = op_method_check;
} // namespace JSC
#else // !ENABLE(LLINT_C_LOOP)
#define LLINT_INSTRUCTION_DECL(opcode, length) extern "C" void llint_##opcode();
FOR_EACH_OPCODE_ID(LLINT_INSTRUCTION_DECL);
#undef LLINT_INSTRUCTION_DECL
......@@ -40,6 +82,7 @@
FOR_EACH_LLINT_NATIVE_HELPER(DECLARE_LLINT_NATIVE_HELPER)
#undef DECLARE_LLINT_NATIVE_HELPER
#endif // !ENABLE(LLINT_C_LOOP)