Changeset 127374 in webkit


Ignore:
Timestamp:
Sep 1, 2012 10:36:51 AM (12 years ago)
Author:
commit-queue@webkit.org
Message:

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:

(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:
Location:
trunk/Source
Files:
2 added
25 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r127373 r127374  
     12012-09-01  Mark Lam  <mark.lam@apple.com>
     2
     3        LLInt C loop backend.
     4        https://bugs.webkit.org/show_bug.cgi?id=91052.
     5
     6        Reviewed by Filip Pizlo.
     7
     8        * JavaScriptCore.xcodeproj/project.pbxproj:
     9        * bytecode/CodeBlock.cpp:
     10        (JSC::CodeBlock::dump):
     11        (JSC::CodeBlock::bytecodeOffset):
     12        * interpreter/Interpreter.cpp:
     13        (JSC::Interpreter::execute):
     14        (JSC::Interpreter::executeCall):
     15        (JSC::Interpreter::executeConstruct):
     16        (JSC):
     17        * interpreter/Interpreter.h:
     18        * jit/JITStubs.h:
     19        (JITStackFrame):
     20        (JSC):
     21        * llint/LLIntCLoop.cpp: Added.
     22        (JSC):
     23        (LLInt):
     24        (JSC::LLInt::CLoop::initialize):
     25        (JSC::LLInt::CLoop::catchRoutineFor):
     26        (JSC::LLInt::CLoop::hostCodeEntryFor):
     27        (JSC::LLInt::CLoop::jsCodeEntryWithArityCheckFor):
     28        (JSC::LLInt::CLoop::jsCodeEntryFor):
     29        * llint/LLIntCLoop.h: Added.
     30        (JSC):
     31        (LLInt):
     32        (CLoop):
     33        * llint/LLIntData.cpp:
     34        (JSC::LLInt::initialize):
     35        * llint/LLIntData.h:
     36        (JSC):
     37        * llint/LLIntOfflineAsmConfig.h:
     38        * llint/LLIntOpcode.h:
     39        * llint/LLIntThunks.cpp:
     40        (LLInt):
     41        * llint/LowLevelInterpreter.asm:
     42        * llint/LowLevelInterpreter.cpp:
     43        (LLInt):
     44        (JSC::LLInt::Ints2Double):
     45        (JSC):
     46        (JSC::CLoop::execute):
     47        * llint/LowLevelInterpreter.h:
     48        (JSC):
     49        * llint/LowLevelInterpreter32_64.asm:
     50        * llint/LowLevelInterpreter64.asm:
     51        * offlineasm/asm.rb:
     52        * offlineasm/backends.rb:
     53        * offlineasm/cloop.rb: Added.
     54        * offlineasm/instructions.rb:
     55        * runtime/Executable.h:
     56        (ExecutableBase):
     57        (JSC::ExecutableBase::hostCodeEntryFor):
     58        (JSC::ExecutableBase::jsCodeEntryFor):
     59        (JSC::ExecutableBase::jsCodeWithArityCheckEntryFor):
     60        (JSC::ExecutableBase::catchRoutineFor):
     61        (NativeExecutable):
     62        * runtime/JSValue.h:
     63        (JSC):
     64        (LLInt):
     65        (JSValue):
     66        * runtime/JSValueInlineMethods.h:
     67        (JSC):
     68        (JSC::JSValue::JSValue):
     69        * runtime/Options.cpp:
     70        (JSC::Options::initialize):
     71
    1722012-09-01  Geoffrey Garen  <ggaren@apple.com>
    273
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r127202 r127374  
    716716                E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E49DC15112EF272200184A1F /* SourceProviderCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
    717717                E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */ = {isa = PBXBuildFile; fileRef = E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
     718                FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */; };
     719                FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */; settings = {ATTRIBUTES = (Private, ); }; };
    718720                FE4A331F15BD2E07006F54F3 /* VMInspector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */; };
    719721                FE4A332015BD2E07006F54F3 /* VMInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4A331E15BD2E07006F54F3 /* VMInspector.h */; };
     
    15101512                F692A87E0255597D01FF60F7 /* RegExp.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = RegExp.h; sourceTree = "<group>"; tabWidth = 8; };
    15111513                F692A8870255597D01FF60F7 /* JSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSValue.cpp; sourceTree = "<group>"; tabWidth = 8; };
     1514                FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntCLoop.cpp; path = llint/LLIntCLoop.cpp; sourceTree = "<group>"; };
     1515                FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCLoop.h; path = llint/LLIntCLoop.h; sourceTree = "<group>"; };
    15121516                FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMInspector.cpp; sourceTree = "<group>"; };
    15131517                FE4A331E15BD2E07006F54F3 /* VMInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMInspector.h; sourceTree = "<group>"; };
     
    16471651                        children = (
    16481652                                FED287B115EC9A5700DA8161 /* LLIntOpcode.h */,
     1653                                FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */,
     1654                                FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */,
    16491655                                5DDDF44614FEE72200B4FB4D /* LLIntDesiredOffsets.h */,
    16501656                                0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */,
     
    25202526                                C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */,
    25212527                                C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */,
     2528                                FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */,
    25222529                                C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */,
    25232530                                C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */,
     
    34963503                                14874AE515EBDE4A002E3587 /* JSScope.cpp in Sources */,
    34973504                                1442566115EDE98D0066A49B /* JSWithScope.cpp in Sources */,
     3505                                FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */,
    34983506                        );
    34993507                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r127202 r127374  
    15511551            break;
    15521552        }
     1553#if ENABLE(LLINT_C_LOOP)
     1554        default:
     1555            ASSERT(false); // We should never get here.
     1556#endif
    15531557    }
    15541558}
     
    26392643    UNUSED_PARAM(returnAddress);
    26402644#if ENABLE(LLINT)
     2645#if !ENABLE(LLINT_C_LOOP)
     2646    // When using the JIT, we could have addresses that are not bytecode
     2647    // addresses. We check if the return address is in the LLint glue and
     2648    // opcode handlers range here to ensure that we are looking at bytecode
     2649    // before attempting to convert the return address into a bytecode offset.
     2650    //
     2651    // In the case of the C Loop LLInt, the JIT is disabled, and the only
     2652    // valid return addresses should be bytecode PCs. So, we can and need to
     2653    // forego this check because when we do not ENABLE(COMPUTED_GOTO_OPCODES),
     2654    // then the bytecode "PC"s are actually the opcodeIDs and are not bounded
     2655    // by llint_begin and llint_end.
    26412656    if (returnAddress.value() >= LLInt::getCodePtr(llint_begin)
    2642         && returnAddress.value() <= LLInt::getCodePtr(llint_end)) {
     2657        && returnAddress.value() <= LLInt::getCodePtr(llint_end))
     2658#endif
     2659    {
    26432660        ASSERT(exec->codeBlock());
    26442661        ASSERT(exec->codeBlock() == this);
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r127349 r127374  
    5151#include "JSString.h"
    5252#include "JSWithScope.h"
     53#include "LLIntCLoop.h"
    5354#include "LiteralParser.h"
    5455#include "NameInstance.h"
     
    984985
    985986        m_reentryDepth++; 
     987#if ENABLE(LLINT_C_LOOP)
     988        result = LLInt::CLoop::execute(newCallFrame, llint_program_prologue);
     989#else // !ENABLE(LLINT_C_LOOP)
    986990#if ENABLE(JIT)
    987991        if (!classicEnabled())
     
    990994#endif // ENABLE(JIT)
    991995            result = privateExecute(Normal, &m_registerFile, newCallFrame);
     996#endif // !ENABLE(LLINT_C_LOOP)
    992997
    993998        m_reentryDepth--;
     
    10561061
    10571062            m_reentryDepth++; 
     1063#if ENABLE(LLINT_C_LOOP)
     1064            result = LLInt::CLoop::execute(newCallFrame, llint_function_for_call_prologue);
     1065#else // ENABLE(LLINT_C_LOOP)
    10581066#if ENABLE(JIT)
    10591067            if (!classicEnabled())
     
    10621070#endif // ENABLE(JIT)
    10631071                result = privateExecute(Normal, &m_registerFile, newCallFrame);
     1072#endif // !ENABLE(LLINT_C_LOOP)
     1073
    10641074            m_reentryDepth--;
    10651075        }
     
    11501160
    11511161            m_reentryDepth++; 
     1162#if ENABLE(LLINT_C_LOOP)
     1163            result = LLInt::CLoop::execute(newCallFrame, llint_function_for_construct_prologue);
     1164#else // !ENABLE(LLINT_C_LOOP)
    11521165#if ENABLE(JIT)
    11531166            if (!classicEnabled())
     
    11561169#endif // ENABLE(JIT)
    11571170                result = privateExecute(Normal, &m_registerFile, newCallFrame);
     1171#endif // !ENABLE(LLINT_C_LOOP)
    11581172            m_reentryDepth--;
    11591173        }
     
    12531267       
    12541268        m_reentryDepth++; 
     1269#if ENABLE(LLINT_C_LOOP)
     1270        result = LLInt::CLoop::execute(closure.newCallFrame, llint_function_for_call_prologue);
     1271#else // !ENABLE(LLINT_C_LOOP)
    12551272#if ENABLE(JIT)
    12561273#if ENABLE(CLASSIC_INTERPRETER)
     
    12651282            result = privateExecute(Normal, &m_registerFile, closure.newCallFrame);
    12661283#endif
     1284#endif // !ENABLE(LLINT_C_LOOP)
     1285
    12671286        m_reentryDepth--;
    12681287    }
     
    13531372        m_reentryDepth++;
    13541373       
     1374#if ENABLE(LLINT_C_LOOP)
     1375        result = LLInt::CLoop::execute(newCallFrame, llint_eval_prologue);
     1376#else // !ENABLE(LLINT_C_LOOP)
    13551377#if ENABLE(JIT)
    13561378#if ENABLE(CLASSIC_INTERPRETER)
     
    13651387            result = privateExecute(Normal, &m_registerFile, newCallFrame);
    13661388#endif
     1389#endif // !ENABLE(LLINT_C_LOOP)
    13671390        m_reentryDepth--;
    13681391    }
     
    16361659
    16371660#endif // ENABLE(CLASSIC_INTERPRETER)
     1661
     1662#if !ENABLE(LLINT_C_LOOP)
    16381663
    16391664JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame)
     
    50935118}
    50945119
     5120#endif // !ENABLE(LLINT_C_LOOP)
     5121
     5122
    50955123JSValue Interpreter::retrieveArgumentsFromVMCode(CallFrame* callFrame, JSFunction* function) const
    50965124{
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.h

    r127202 r127374  
    276276        static CallFrame* findFunctionCallFrameFromVMCode(CallFrame*, JSFunction*);
    277277
     278#if !ENABLE(LLINT_C_LOOP)
    278279        JSValue privateExecute(ExecutionFlag, RegisterFile*, CallFrame*);
     280#endif
    279281
    280282        void dumpRegisters(CallFrame*);
  • trunk/Source/JavaScriptCore/jit/JITStubs.h

    r121885 r127374  
    469469} // extern "C"
    470470
    471 #endif // ENABLE(JIT)
     471#elif ENABLE(LLINT_C_LOOP)
     472
     473struct JITStackFrame {
     474    JSGlobalData* globalData;
     475};
     476
     477#endif // ENABLE(LLINT_C_LOOP)
    472478
    473479} // namespace JSC
  • trunk/Source/JavaScriptCore/llint/LLIntCLoop.h

    r127373 r127374  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #ifndef LowLevelInterpreter_h
    27 #define LowLevelInterpreter_h
     26#ifndef LLIntCLoop_h
     27#define LLIntCLoop_h
    2828
    29 #include <wtf/Platform.h>
     29#if ENABLE(LLINT_C_LOOP)
    3030
    31 #if ENABLE(LLINT)
     31#include "CodeSpecializationKind.h"
     32#include "JSValue.h"
     33#include "MacroAssemblerCodeRef.h"
     34#include "Opcode.h"
     35#include "Register.h"
    3236
    33 #include "Opcode.h"
     37namespace JSC {
    3438
    35 #define LLINT_INSTRUCTION_DECL(opcode, length) extern "C" void llint_##opcode();
    36     FOR_EACH_OPCODE_ID(LLINT_INSTRUCTION_DECL);
    37 #undef LLINT_INSTRUCTION_DECL
     39namespace LLInt {
    3840
    39 #define DECLARE_LLINT_NATIVE_HELPER(name, length) extern "C" void name();
    40     FOR_EACH_LLINT_NATIVE_HELPER(DECLARE_LLINT_NATIVE_HELPER)
    41 #undef DECLARE_LLINT_NATIVE_HELPER
     41const OpcodeID llint_unused = llint_end;
    4242
     43class CLoop {
     44public:
     45    static void initialize();
     46    static JSValue execute(CallFrame*, OpcodeID bootstrapOpcodeId = llint_unused, bool isInitializationPass = false);
    4347
    44 #endif // ENABLE(LLINT)
     48    static void* catchRoutineFor(Instruction* catchPCForInterpreter);
    4549
    46 #endif // LowLevelInterpreter_h
     50    static MacroAssemblerCodePtr hostCodeEntryFor(CodeSpecializationKind);
     51    static MacroAssemblerCodePtr jsCodeEntryWithArityCheckFor(CodeSpecializationKind);
     52    static MacroAssemblerCodePtr jsCodeEntryFor(CodeSpecializationKind);
     53};
     54
     55} } // namespace JSC::LLInt
     56
     57#endif // ENABLE(LLINT_C_LOOP)
     58
     59#endif // LLIntCLoop_h
  • trunk/Source/JavaScriptCore/llint/LLIntData.cpp

    r127068 r127374  
    3232#include "CodeType.h"
    3333#include "Instruction.h"
     34#include "LLIntCLoop.h"
    3435#include "Opcode.h"
    3536
     
    4445    Data::s_opcodeMap = new Opcode[numOpcodeIDs];
    4546
     47    #if ENABLE(LLINT_C_LOOP)
     48    CLoop::initialize();
     49
     50    #else // !ENABLE(LLINT_C_LOOP)
    4651    for (int i = 0; i < maxOpcodeLength + 1; ++i)
    4752        Data::s_exceptionInstructions[i].u.pointer =
    4853            LLInt::getCodePtr(llint_throw_from_slow_path_trampoline);
    49     #define OPCODE_ENTRY(opcode, length)                                    \
     54    #define OPCODE_ENTRY(opcode, length) \
    5055        Data::s_opcodeMap[opcode] = LLInt::getCodePtr(llint_##opcode);
    5156    FOR_EACH_OPCODE_ID(OPCODE_ENTRY);
    5257    #undef OPCODE_ENTRY
     58    #endif // !ENABLE(LLINT_C_LOOP)
    5359}
    5460
  • trunk/Source/JavaScriptCore/llint/LLIntData.h

    r127199 r127374  
    3636struct Instruction;
    3737
     38#if ENABLE(LLINT_C_LOOP)
     39typedef OpcodeID LLIntCode;
     40#else
    3841typedef void (*LLIntCode)();
     42#endif
    3943
    4044namespace LLInt {
  • trunk/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h

    r127333 r127374  
    3232#include <wtf/Platform.h>
    3333
     34
     35#if ENABLE(LLINT_C_LOOP)
     36#define OFFLINE_ASM_C_LOOP 1
     37#define OFFLINE_ASM_X86 0
     38#define OFFLINE_ASM_ARMv7 0
     39#define OFFLINE_ASM_X86_64 0
     40
     41#else // !ENABLE(LLINT_C_LOOP)
     42
     43#define OFFLINE_ASM_C_LOOP 0
     44
    3445#if CPU(X86)
    3546#define OFFLINE_ASM_X86 1
     
    4960#define OFFLINE_ASM_X86_64 0
    5061#endif
     62
     63#endif // !ENABLE(LLINT_C_LOOP)
    5164
    5265#if USE(JSVALUE64)
  • trunk/Source/JavaScriptCore/llint/LLIntOpcode.h

    r126955 r127374  
    3131#if ENABLE(LLINT)
    3232
     33#if ENABLE(LLINT_C_LOOP)
     34
     35#define FOR_EACH_LLINT_NOJIT_NATIVE_HELPER(macro) \
     36    macro(getHostCallReturnValue, 1) \
     37    macro(ctiOpThrowNotCaught, 1)
     38
     39#else // !ENABLE(LLINT_C_LOOP)
     40
    3341#define FOR_EACH_LLINT_NOJIT_NATIVE_HELPER(macro) \
    3442    // Nothing to do here. Use the JIT impl instead.
     43
     44#endif // !ENABLE(LLINT_C_LOOP)
    3545
    3646
     
    5767
    5868
     69#if ENABLE(LLINT_C_LOOP)
     70#define FOR_EACH_LLINT_OPCODE_EXTENSION(macro) FOR_EACH_LLINT_NATIVE_HELPER(macro)
     71#else
    5972#define FOR_EACH_LLINT_OPCODE_EXTENSION(macro) // Nothing to add.
     73#endif
    6074
    6175#else // !ENABLE(LLINT)
  • trunk/Source/JavaScriptCore/llint/LLIntThunks.cpp

    r127202 r127374  
    3636
    3737namespace JSC { namespace LLInt {
     38
     39#if !ENABLE(LLINT_C_LOOP)
    3840
    3941static MacroAssemblerCodeRef generateThunkWithJumpTo(JSGlobalData* globalData, void (*target)(), const char *thunkKind)
     
    7981}
    8082
     83#endif // !ENABLE(LLINT_C_LOOP)
     84
    8185} } // namespace JSC::LLInt
    8286
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r127333 r127374  
    111111# Some common utilities.
    112112macro crash()
    113     storei t0, 0xbbadbeef[]
    114     move 0, t0
    115     call t0
     113    if C_LOOP
     114        cloopCrash
     115    else
     116        storei t0, 0xbbadbeef[]
     117        move 0, t0
     118        call t0
     119    end
    116120end
    117121
     
    125129
    126130macro preserveReturnAddressAfterCall(destinationRegister)
    127     if ARMv7
     131    if C_LOOP
     132        # In our case, we're only preserving the bytecode vPC.
     133        move lr, destinationRegister
     134    elsif ARMv7
    128135        move lr, destinationRegister
    129136    elsif X86 or X86_64
     
    135142
    136143macro restoreReturnAddressBeforeReturn(sourceRegister)
    137     if ARMv7
     144    if C_LOOP
     145        # In our case, we're only restoring the bytecode vPC.
     146        move sourceRegister, lr
     147    elsif ARMv7
    138148        move sourceRegister, lr
    139149    elsif X86 or X86_64
     
    151161
    152162macro callTargetFunction(callLinkInfo)
    153     call LLIntCallLinkInfo::machineCodeTarget[callLinkInfo]
    154     dispatchAfterCall()
     163    if C_LOOP
     164        cloopCallJSFunction LLIntCallLinkInfo::machineCodeTarget[callLinkInfo]
     165    else
     166        call LLIntCallLinkInfo::machineCodeTarget[callLinkInfo]
     167        dispatchAfterCall()
     168    end
    155169end
    156170
     
    160174        slowPath,
    161175        macro (callee)
    162             call callee
     176            if C_LOOP
     177                cloopCallJSFunction callee
     178            else
     179                call callee
     180            end
    163181            dispatchAfterCall()
    164182        end)
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp

    r127333 r127374  
    3232#include <wtf/InlineASM.h>
    3333
     34#if ENABLE(LLINT_C_LOOP)
     35#include "CodeBlock.h"
     36#include "LLintCLoop.h"
     37#include "LLintSlowPaths.h"
     38#include "VMInspector.h"
     39#include <wtf/MathExtras.h>
     40
     41using namespace JSC::LLInt;
     42
     43// LLInt C Loop opcodes
     44// ====================
     45// In the implementation of the C loop, the LLint trampoline glue functions
     46// (e.g. llint_program_prologue, llint_eval_prologue, etc) are addressed as
     47// if they are bytecode handlers. That means the names of the trampoline
     48// functions will be added to the OpcodeID list via the
     49// FOR_EACH_LLINT_OPCODE_EXTENSION() macro that FOR_EACH_OPCODE_ID()
     50// includes.
     51//
     52// In addition, some JIT trampoline functions which are needed by LLInt
     53// (e.g. getHostCallReturnValue, ctiOpThrowNotCaught) are also added as
     54// bytecodes, and the CLoop will provide bytecode handlers for them.
     55//
     56// In the CLoop, we can only dispatch indirectly to these bytecodes
     57// (including the LLInt and JIT extensions). All other dispatches
     58// (i.e. goto's) must be to a known label (i.e. local / global labels).
     59
     60
     61// How are the opcodes named?
     62// ==========================
     63// Here is a table to show examples of how each of the manifestation of the
     64// opcodes are named:
     65//
     66//   Type:                        Opcode            Trampoline Glue
     67//                                ======            ===============
     68//   [In the llint .asm files]
     69//   llint labels:                llint_op_enter    llint_program_prologue
     70//
     71//   OpcodeID:                    op_enter          llint_program
     72//                                [in Opcode.h]     [in LLIntOpcode.h]
     73//
     74//   When using a switch statement dispatch in the CLoop, each "opcode" is
     75//   a case statement:
     76//   Opcode:                      case op_enter:    case llint_program_prologue:
     77//
     78//   When using a computed goto dispatch in the CLoop, each opcode is a label:
     79//   Opcode:                      op_enter:         llint_program_prologue:
     80
     81
     82//============================================================================
     83// Define the opcode dispatch mechanism when using the C loop:
     84//
     85
     86// These are for building a C Loop interpreter:
     87#define OFFLINE_ASM_BEGIN
     88#define OFFLINE_ASM_END
     89
     90
     91#define OFFLINE_ASM_OPCODE_LABEL(opcode) DEFINE_OPCODE(opcode)
     92#if ENABLE(COMPUTED_GOTO_OPCODES)
     93    #define OFFLINE_ASM_GLUE_LABEL(label)  label:
     94#else
     95    #define OFFLINE_ASM_GLUE_LABEL(label)  case label: label:
     96#endif
     97
     98#define OFFLINE_ASM_LOCAL_LABEL(label)   label:
     99
     100
     101namespace JSC {
     102namespace LLInt {
     103
     104#if USE(JSVALUE32_64)
     105static double Ints2Double(uint32_t lo, uint32_t hi)
     106{
     107    union {
     108        double dval;
     109        uint64_t ival64;
     110    } u;
     111    u.ival64 = (static_cast<uint64_t>(hi) << 32) | lo;
     112    return u.dval;
     113}
     114#endif // USE(JSVALUE32_64)
     115
     116} // namespace LLint
     117
     118
     119JSValue CLoop::execute(CallFrame* callFrame, OpcodeID bootstrapOpcodeId,
     120                       bool isInitializationPass)
     121{
     122    #define CAST reinterpret_cast
     123    #define SIGN_BIT32(x) (x & 0x80000000)
     124
     125    // One-time initialization of our address tables. We have to put this code
     126    // here because our labels are only in scope inside this function. The
     127    // caller (or one of its ancestors) is responsible for ensuring that this
     128    // is only called once during the initialization of the VM before threads
     129    // are at play.
     130    if (UNLIKELY(isInitializationPass)) {
     131#if ENABLE(COMPUTED_GOTO_OPCODES)
     132        Opcode* opcodeMap = LLInt::opcodeMap();
     133        #define OPCODE_ENTRY(__opcode, length) \
     134            opcodeMap[__opcode] = bitwise_cast<void*>(&&__opcode);
     135        FOR_EACH_OPCODE_ID(OPCODE_ENTRY)
     136        #undef OPCODE_ENTRY
     137
     138        #define LLINT_OPCODE_ENTRY(__opcode, length) \
     139            opcodeMap[__opcode] = bitwise_cast<void*>(&&__opcode);
     140
     141        FOR_EACH_LLINT_NATIVE_HELPER(LLINT_OPCODE_ENTRY)
     142        #undef LLINT_OPCODE_ENTRY
     143#endif
     144        // Note: we can only set the exceptionInstructions after we have
     145        // initialized the opcodeMap above. This is because getCodePtr()
     146        // can depend on the opcodeMap.
     147        Instruction* exceptionInstructions = LLInt::exceptionInstructions();
     148        for (int i = 0; i < maxOpcodeLength + 1; ++i)
     149            exceptionInstructions[i].u.pointer =
     150                LLInt::getCodePtr(llint_throw_from_slow_path_trampoline);
     151
     152        return JSValue();
     153    }
     154
     155    ASSERT(callFrame->globalData().topCallFrame == callFrame);
     156
     157    // Define the pseudo registers used by the LLINT C Loop backend:
     158    union CLoopRegister {
     159        intptr_t i;
     160        uintptr_t u;
     161        int32_t i32;
     162        uint32_t u32;
     163        int8_t i8;
     164        uint8_t u8;
     165        int8_t* i8p;
     166        void* vp;
     167        ExecState* execState;
     168        void* instruction;
     169        NativeFunction nativeFunc;
     170#if USE(JSVALUE64)
     171        int64_t i64;
     172        EncodedJSValue encodedJSValue;
     173        double castToDouble;
     174#endif
     175        Opcode opcode;
     176    };
     177    union CLoopDoubleRegister {
     178        double d;
     179#if USE(JSVALUE64)
     180        void* castToVoidPtr;
     181#endif
     182    };
     183
     184    // The CLoop llint backend is initially based on the ARMv7 backend, and
     185    // then further enhanced with a few instructions from the x86 backend to
     186    // support building for X64 targets. Hence, the shape of the generated
     187    // code and the usage convention of registers will look a lot like the
     188    // ARMv7 backend's.
     189    //
     190    // For example, on a 32-bit build:
     191    // 1. Outgoing args will be set up as follows:
     192    //    arg1 in t0 (r0 on ARM)
     193    //    arg2 in t1 (r1 on ARM)
     194    // 2. 32 bit return values will be in t0 (r0 on ARM).
     195    // 3. 64 bit return values (e.g. doubles) will be in t0,t1 (r0,r1 on ARM).
     196    //
     197    // But instead of naming these simulator registers based on their ARM
     198    // counterparts, we'll name them based on their original llint asm names.
     199    // This will make it easier to correlate the generated code with the
     200    // original llint asm code.
     201    //
     202    // On a 64-bit build, it more like x64 in that the registers are 64 bit.
     203    // Hence:
     204    // 1. Outgoing args are still the same: arg1 in t0, arg2 in t1, etc.
     205    // 2. 32 bit result values will be in the low 32-bit of t0.
     206    // 3. 64 bit result values will be in t0.
     207
     208    CLoopRegister t0, t1, t2, t3;
     209#if USE(JSVALUE64)
     210    CLoopRegister rBasePC, tagTypeNumber, tagMask;
     211#endif
     212    CLoopRegister rRetVPC;
     213    CLoopDoubleRegister d0, d1;
     214
     215    // Instantiate the pseudo JIT stack frame used by the LLINT C Loop backend:
     216    JITStackFrame jitStackFrame;
     217
     218    // The llint expects the native stack pointer, sp, to be pointing to the
     219    // jitStackFrame (which is the simulation of the native stack frame):
     220    JITStackFrame* const sp = &jitStackFrame;
     221    sp->globalData = &callFrame->globalData();
     222
     223    // Set up an alias for the globalData ptr in the JITStackFrame:
     224    JSGlobalData* &globalData = sp->globalData;
     225
     226    CodeBlock* codeBlock = callFrame->codeBlock();
     227    Instruction* vPC;
     228
     229    // rPC is an alias for vPC. Set up the alias:
     230    CLoopRegister& rPC = *CAST<CLoopRegister*>(&vPC);
     231
     232#if USE(JSVALUE32_64)
     233    vPC = codeBlock->instructions().begin();
     234#else // USE(JSVALUE64)
     235    vPC = 0;
     236    rBasePC.vp = codeBlock->instructions().begin();
     237
     238    // For the ASM llint, JITStubs takes care of this initialization. We do
     239    // it explicitly here for the C loop:
     240    tagTypeNumber.i = 0xFFFF000000000000;
     241    tagMask.i = 0xFFFF000000000002;
     242#endif // USE(JSVALUE64)
     243
     244    // cfr is an alias for callFrame. Set up this alias:
     245    CLoopRegister& cfr = *CAST<CLoopRegister*>(&callFrame);
     246
     247    // Simulate a native return PC which should never be used:
     248    rRetVPC.i = 0xbbadbeef;
     249
     250    // Interpreter variables for value passing between opcodes and/or helpers:
     251    NativeFunction nativeFunc = 0;
     252    JSValue functionReturnValue;
     253    Opcode opcode;
     254
     255    if (bootstrapOpcodeId != llint_unused)
     256        opcode = LLInt::getOpcode(bootstrapOpcodeId);
     257
     258    #if ENABLE(OPCODE_STATS)
     259        #define RECORD_OPCODE_STATS(__opcode) \
     260            OpcodeStats::recordInstruction(__opcode)
     261    #else
     262        #define RECORD_OPCODE_STATS(__opcode)
     263    #endif
     264
     265    #if USE(JSVALUE32_64)
     266        #define FETCH_OPCODE() vPC->u.opcode
     267    #else // USE(JSVALUE64)
     268        #define FETCH_OPCODE() *bitwise_cast<Opcode*>(rBasePC.i8p + rPC.i * 8)
     269    #endif // USE(JSVALUE64)
     270
     271    #define NEXT_INSTRUCTION() \
     272        do {                         \
     273            opcode = FETCH_OPCODE(); \
     274            DISPATCH_OPCODE();       \
     275        } while (false)
     276
     277#if ENABLE(COMPUTED_GOTO_OPCODES)
     278
     279    //========================================================================
     280    // Loop dispatch mechanism using computed goto statements:
     281
     282    #define DISPATCH_OPCODE() goto *opcode
     283
     284    #define DEFINE_OPCODE(__opcode) \
     285        __opcode: \
     286            RECORD_OPCODE_STATS(__opcode);
     287
     288    // Dispatch to the current PC's bytecode:
     289    DISPATCH_OPCODE();
     290
     291#else // !ENABLE(COMPUTED_GOTO_OPCODES)
     292    //========================================================================
     293    // Loop dispatch mechanism using a C switch statement:
     294
     295    #define DISPATCH_OPCODE() goto dispatchOpcode
     296
     297    #define DEFINE_OPCODE(__opcode) \
     298        case __opcode: \
     299            RECORD_OPCODE_STATS(__opcode);
     300
     301    // Dispatch to the current PC's bytecode:
     302    dispatchOpcode:
     303    switch (opcode)
     304
     305#endif // !ENABLE(COMPUTED_GOTO_OPCODES)
     306
     307    //========================================================================
     308    // Bytecode handlers:
     309    {
     310        // This is the file generated by offlineasm, which contains all of the
     311        // bytecode handlers for the interpreter, as compiled from
     312        // LowLevelInterpreter.asm and its peers.
     313
     314        #include "LLIntAssembly.h"
     315
     316        // In the ASM llint, getHostCallReturnValue() is a piece of glue
     317        // function provided by the JIT (see dfg/DFGOperations.cpp).
     318        // We simulate it here with a pseduo-opcode handler.
     319        OFFLINE_ASM_GLUE_LABEL(getHostCallReturnValue)
     320        {
     321            // The ASM part pops the frame:
     322            callFrame = callFrame->callerFrame();
     323
     324            // The part in getHostCallReturnValueWithExecState():
     325            JSValue result = globalData->hostCallReturnValue;
     326#if USE(JSVALUE32_64)
     327            t1.i = result.tag();
     328            t0.i = result.payload();
     329#else
     330            t0.encodedJSValue = JSValue::encode(result);
     331#endif
     332            goto doReturnHelper;
     333        }
     334
     335        OFFLINE_ASM_GLUE_LABEL(ctiOpThrowNotCaught)
     336        {
     337            return globalData->exception;
     338        }
     339
     340#if !ENABLE(COMPUTED_GOTO_OPCODES)
     341    default:
     342        ASSERT(false);
     343#endif
     344
     345    } // END bytecode handler cases.
     346
     347    //========================================================================
     348    // Bytecode helpers:
     349
     350    doReturnHelper: {
     351        ASSERT(!!callFrame);
     352        if (callFrame->hasHostCallFrameFlag()) {
     353#if USE(JSVALUE32_64)
     354            return JSValue(t1.i, t0.i); // returning JSValue(tag, payload);
     355#else
     356            return JSValue::decode(t0.encodedJSValue);
     357#endif
     358        }
     359
     360        // The normal ASM llint call implementation returns to the caller as
     361        // recorded in rRetVPC, and the caller would fetch the return address
     362        // from ArgumentCount.tag() (see the dispatchAfterCall() macro used in
     363        // the callTargetFunction() macro in the llint asm files).
     364        //
     365        // For the C loop, we don't have the JIT stub to this work for us.
     366        // So, we need to implement the equivalent of dispatchAfterCall() here
     367        // before dispatching to the PC.
     368
     369        vPC = callFrame->currentVPC();
     370
     371#if USE(JSVALUE64)
     372        // Based on LowLevelInterpreter64.asm's dispatchAfterCall():
     373
     374        // When returning from a native trampoline call, unlike the assembly
     375        // LLInt, we can't simply return to the caller. In our case, we grab
     376        // the caller's VPC and resume execution there. However, the caller's
     377        // VPC returned by callFrame->currentVPC() is in the form of the real
     378        // address of the target bytecode, but the 64-bit llint expects the
     379        // VPC to be a bytecode offset. Hence, we need to map it back to a
     380        // bytecode offset before we dispatch via the usual dispatch mechanism
     381        // i.e. NEXT_INSTRUCTION():
     382
     383        codeBlock = callFrame->codeBlock();
     384        ASSERT(codeBlock);
     385        rPC.vp = callFrame->currentVPC();
     386        rPC.i = rPC.i8p - reinterpret_cast<int8_t*>(codeBlock->instructions().begin());
     387        rPC.i >>= 3;
     388
     389        rBasePC.vp = codeBlock->instructions().begin();
     390#endif // USE(JSVALUE64)
     391
     392        NEXT_INSTRUCTION();
     393
     394    } // END doReturnHelper.
     395
     396
     397    // Keep the compiler happy so that it doesn't complain about unused
     398    // labels for the LLInt trampoline glue:
     399    #define LLINT_OPCODE_ENTRY(__opcode, length) \
     400        UNUSED_PARAM(&&__opcode);
     401        FOR_EACH_LLINT_NATIVE_HELPER(LLINT_OPCODE_ENTRY)
     402    #undef LLINT_OPCODE_ENTRY
     403
     404
     405    #undef NEXT_INSTRUCTION
     406    #undef DEFINE_OPCODE
     407    #undef CHECK_FOR_TIMEOUT
     408    #undef CAST
     409    #undef SIGN_BIT32
     410
     411} // Interpreter::llintCLoopExecute()
     412
     413} // namespace JSC
     414
     415#else // !ENABLE(LLINT_C_LOOP)
     416
    34417//============================================================================
    35418// Define the opcode dispatch mechanism when using an ASM loop:
     
    63446#include "LLIntAssembly.h"
    64447
     448#endif // !ENABLE(LLINT_C_LOOP)
     449
    65450#endif // ENABLE(LLINT)
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.h

    r126955 r127374  
    3333#include "Opcode.h"
    3434
     35#if ENABLE(LLINT_C_LOOP)
     36
     37namespace JSC {
     38
     39// The following is a minimal set of alias for the opcode names. This is needed
     40// because there is code (e.g. in GetByIdStatus.cpp and PutByIdStatus.cpp)
     41// which refers to the opcodes expecting them to be prefixed with "llint_".
     42// In the CLoop implementation, the 2 are equivalent. Hence, we set up this
     43// alias here.
     44//
     45// Note: we don't just do this for all opcodes because we only need a few,
     46// and currently, FOR_EACH_OPCODE_ID() includes the llint and JIT opcode
     47// extensions which we definitely don't want to add an alias for. With some
     48// minor refactoring, we can use FOR_EACH_OPCODE_ID() to automatically
     49// generate a llint_ alias for all opcodes, but that is not needed at this
     50// time.
     51
     52const OpcodeID llint_op_call = op_call;
     53const OpcodeID llint_op_call_eval = op_call_eval;
     54const OpcodeID llint_op_call_varargs = op_call_varargs;
     55const OpcodeID llint_op_construct = op_construct;
     56const OpcodeID llint_op_catch = op_catch;
     57const OpcodeID llint_op_get_by_id = op_get_by_id;
     58const OpcodeID llint_op_get_by_id_out_of_line = op_get_by_id_out_of_line;
     59const OpcodeID llint_op_put_by_id = op_put_by_id;
     60const OpcodeID llint_op_put_by_id_out_of_line = op_put_by_id_out_of_line;
     61
     62const OpcodeID llint_op_put_by_id_transition_direct =
     63    op_put_by_id_transition_direct;
     64const OpcodeID llint_op_put_by_id_transition_direct_out_of_line =
     65    op_put_by_id_transition_direct_out_of_line;
     66const OpcodeID llint_op_put_by_id_transition_normal =
     67    op_put_by_id_transition_normal;
     68const OpcodeID llint_op_put_by_id_transition_normal_out_of_line =
     69    op_put_by_id_transition_normal_out_of_line;
     70
     71const OpcodeID llint_op_method_check = op_method_check;
     72
     73} // namespace JSC
     74
     75#else // !ENABLE(LLINT_C_LOOP)
     76
    3577#define LLINT_INSTRUCTION_DECL(opcode, length) extern "C" void llint_##opcode();
    3678    FOR_EACH_OPCODE_ID(LLINT_INSTRUCTION_DECL);
     
    4183#undef DECLARE_LLINT_NATIVE_HELPER
    4284
     85#endif // !ENABLE(LLINT_C_LOOP)
    4386
    4487#endif // ENABLE(LLINT)
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r127345 r127374  
    114114        poke arg2, 1
    115115        call function
     116    elsif C_LOOP
     117        cloopCallSlowPath function, arg1, arg2
    116118    else
    117119        error
     
    133135        poke arg4, 3
    134136        call function
     137    elsif C_LOOP
     138        error
    135139    else
    136140        error
     
    18261830        restoreReturnAddressBeforeReturn(t3)
    18271831        loadp JITStackFrame::globalData[sp], t3
     1832    elsif C_LOOP
     1833        loadp JITStackFrame::globalData[sp], t3
     1834        storep cfr, JSGlobalData::topCallFrame[t3]
     1835        move t0, t2
     1836        preserveReturnAddressAfterCall(t3)
     1837        storep t3, ReturnPC[cfr]
     1838        move cfr, t0
     1839        loadi Callee + PayloadOffset[cfr], t1
     1840        loadp JSFunction::m_executable[t1], t1
     1841        move t2, cfr
     1842        cloopCallNative executableOffsetToFunction[t1]
     1843        restoreReturnAddressBeforeReturn(t3)
     1844        loadp JITStackFrame::globalData[sp], t3
    18281845    else 
    18291846        error
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r127345 r127374  
    5656        move arg2, t4
    5757        call function
     58    elsif C_LOOP
     59        cloopCallSlowPath function, arg1, arg2
    5860    else
    5961        error
     
    6971        move arg4, t2
    7072        call function
     73    elsif C_LOOP
     74        error
    7175    else
    7276        error
     
    16571661        addp 16 - 8, sp
    16581662        loadp JITStackFrame::globalData + 8[sp], t3
     1663
     1664    elsif C_LOOP
     1665        loadp CallerFrame[cfr], t0
     1666        loadp ScopeChain[t0], t1
     1667        storep t1, ScopeChain[cfr]
     1668
     1669        loadp JITStackFrame::globalData[sp], t3
     1670        storep cfr, JSGlobalData::topCallFrame[t3]
     1671
     1672        move t0, t2
     1673        preserveReturnAddressAfterCall(t3)
     1674        storep t3, ReturnPC[cfr]
     1675        move cfr, t0
     1676        loadp Callee[cfr], t1
     1677        loadp JSFunction::m_executable[t1], t1
     1678        move t2, cfr
     1679        cloopCallNative executableOffsetToFunction[t1]
     1680
     1681        restoreReturnAddressBeforeReturn(t3)
     1682        loadp JITStackFrame::globalData[sp], t3
    16591683    else
    16601684        error
  • trunk/Source/JavaScriptCore/offlineasm/asm.rb

    r127333 r127374  
    9797    end
    9898   
     99    # Puts a C Statement in the output stream.
     100    def putc(*line)
     101        raise unless @state == :asm
     102        @outp.puts(formatDump("    " + line.join(''), lastComment))
     103    end
     104   
    99105    def formatDump(dumpStr, comment, commentColumns=$preferredCommentStartColumn)
    100106        if comment.length > 0
     
    174180    def self.localLabelReference(labelName)
    175181        "\" LOCAL_LABEL_STRING(#{labelName}) \""
     182    end
     183   
     184    def self.cLabelReference(labelName)
     185        "#{labelName}"
     186    end
     187   
     188    def self.cLocalLabelReference(labelName)
     189        "#{labelName}"
    176190    end
    177191   
  • trunk/Source/JavaScriptCore/offlineasm/backends.rb

    r122650 r127374  
    2626require "ast"
    2727require "x86"
     28require "cloop"
    2829
    2930BACKENDS =
     
    3132     "X86",
    3233     "X86_64",
    33      "ARMv7"
     34     "ARMv7",
     35     "C_LOOP"
    3436    ]
    3537
     
    4345     "X86",
    4446     "X86_64",
    45      "ARMv7"
     47     "ARMv7",
     48     "C_LOOP"
    4649    ]
    4750
     
    7780        Assembler.labelReference(name[1..-1])
    7881    end
     82    def cLabel
     83        Assembler.cLabelReference(name[1..-1])
     84    end
    7985end
    8086
     
    8288    def asmLabel
    8389        Assembler.localLabelReference("_offlineasm_"+name[1..-1])
     90    end
     91    def cLabel
     92        Assembler.cLocalLabelReference("_offlineasm_"+name[1..-1])
    8493    end
    8594end
  • trunk/Source/JavaScriptCore/offlineasm/instructions.rb

    r122650 r127374  
    228228    ]
    229229
    230 INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS + ARMv7_INSTRUCTIONS
     230CXX_INSTRUCTIONS =
     231    [
     232     "cloopCrash",           # no operands
     233     "cloopCallJSFunction",  # operands: callee
     234     "cloopCallNative",      # operands: callee
     235     "cloopCallSlowPath",    # operands: callTarget, currentFrame, currentPC
     236    ]
     237
     238INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS + ARMv7_INSTRUCTIONS + CXX_INSTRUCTIONS
    231239
    232240INSTRUCTION_PATTERN = Regexp.new('\\A((' + INSTRUCTIONS.join(')|(') + '))\\Z')
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r127333 r127374  
    3232#include "JSFunction.h"
    3333#include "Interpreter.h"
     34#include "LLIntCLoop.h"
    3435#include "Nodes.h"
    3536#include "SamplingTool.h"
     
    202203            return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct);
    203204        }
    204 #endif
    205 
     205#endif // ENABLE(JIT)
     206
     207#if ENABLE(JIT) || ENABLE(LLINT_C_LOOP)
    206208        MacroAssemblerCodePtr hostCodeEntryFor(CodeSpecializationKind kind)
    207209        {
     210            #if ENABLE(JIT)
    208211            return generatedJITCodeFor(kind).addressForCall();
     212            #else
     213            return LLInt::CLoop::hostCodeEntryFor(kind);
     214            #endif
    209215        }
    210216
    211217        MacroAssemblerCodePtr jsCodeEntryFor(CodeSpecializationKind kind)
    212218        {
     219            #if ENABLE(JIT)
    213220            return generatedJITCodeFor(kind).addressForCall();
     221            #else
     222            return LLInt::CLoop::jsCodeEntryFor(kind);
     223            #endif
    214224        }
    215225
    216226        MacroAssemblerCodePtr jsCodeWithArityCheckEntryFor(CodeSpecializationKind kind)
    217227        {
     228            #if ENABLE(JIT)
    218229            return generatedJITCodeWithArityCheckFor(kind);
     230            #else
     231            return LLInt::CLoop::jsCodeEntryWithArityCheckFor(kind);
     232            #endif
    219233        }
    220234
    221235        static void* catchRoutineFor(HandlerInfo* handler, Instruction* catchPCForInterpreter)
    222236        {
     237            #if ENABLE(JIT)
    223238            UNUSED_PARAM(catchPCForInterpreter);
    224239            return handler->nativeCode.executableAddress();
    225         }
     240            #else
     241            UNUSED_PARAM(handler);
     242            return LLInt::CLoop::catchRoutineFor(catchPCForInterpreter);
     243            #endif
     244        }
     245#endif // ENABLE(JIT || ENABLE(LLINT_C_LOOP)
    226246
    227247    protected:
     
    259279#endif
    260280
    261 #if ENABLE(CLASSIC_INTERPRETER)
     281#if ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT_C_LOOP)
    262282        static NativeExecutable* create(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
    263283        {
  • trunk/Source/JavaScriptCore/runtime/JSValue.h

    r127191 r127374  
    5555    }
    5656#endif
     57#if ENABLE(LLINT_C_LOOP)
    5758    namespace LLInt {
    58         class Data;
    59     }
     59        class CLoop;
     60    }
     61#endif
    6062
    6163    struct ClassInfo;
     
    120122        friend class DFG::OSRExitCompiler;
    121123        friend class DFG::SpeculativeJIT;
     124#endif
     125#if ENABLE(LLINT_C_LOOP)
     126        friend class LLInt::CLoop;
    122127#endif
    123128
     
    291296        uint32_t tag() const;
    292297        int32_t payload() const;
     298
     299#if ENABLE(LLINT_C_LOOP)
     300        // This should only be used by the LLInt C Loop interpreter who needs
     301        // synthesize JSValue from its "register"s holding tag and payload
     302        // values.
     303        explicit JSValue(int32_t tag, int32_t payload);
     304#endif
     305
    293306#elif USE(JSVALUE64)
    294307        /*
  • trunk/Source/JavaScriptCore/runtime/JSValueInlineMethods.h

    r127333 r127374  
    308308    }
    309309
     310#if ENABLE(LLINT_C_LOOP)
     311    inline JSValue::JSValue(int32_t tag, int32_t payload)
     312    {
     313        u.asBits.tag = tag;
     314        u.asBits.payload = payload;
     315    }
     316#endif
     317
    310318    inline bool JSValue::isNumber() const
    311319    {
  • trunk/Source/JavaScriptCore/runtime/Options.cpp

    r121925 r127374  
    139139#endif
    140140   
     141#if ENABLE(LLINT_C_LOOP)
     142    useJIT() = false;
     143    useDFGJIT() = false;
     144#endif
     145
    141146    // Do range checks where needed and make corrections to the options:
    142147    ASSERT(thresholdForOptimizeAfterLongWarmUp() >= thresholdForOptimizeAfterWarmUp());
  • trunk/Source/WTF/ChangeLog

    r127306 r127374  
     12012-09-01  Mark Lam  <mark.lam@apple.com>
     2
     3        LLInt C loop backend.
     4        https://bugs.webkit.org/show_bug.cgi?id=91052.
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Added configs for the llint C loop backend.
     9
     10        * wtf/Platform.h:
     11
    1122012-08-31  Pratik Solanki  <psolanki@apple.com>
    213
  • trunk/Source/WTF/wtf/Platform.h

    r127199 r127374  
    955955
    956956/* Ensure that either the JIT or the interpreter has been enabled. */
    957 #if !defined(ENABLE_CLASSIC_INTERPRETER) && !ENABLE(JIT)
     957#if !defined(ENABLE_CLASSIC_INTERPRETER) && !ENABLE(JIT) && !ENABLE(LLINT)
    958958#define ENABLE_CLASSIC_INTERPRETER 1
    959959#endif
    960 #if !(ENABLE(JIT) || ENABLE(CLASSIC_INTERPRETER))
     960
     961/* If the jit and classic interpreter is not available, enable the LLInt C Loop: */
     962#if !ENABLE(JIT) && !ENABLE(CLASSIC_INTERPRETER)
     963    #define ENABLE_LLINT 1
     964    #define ENABLE_LLINT_C_LOOP 1
     965    #define ENABLE_DFG_JIT 0
     966#endif
     967
     968/* Do a sanity check to make sure that we at least have one execution engine in
     969   use: */
     970#if !(ENABLE(JIT) || ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT))
    961971#error You have to have at least one execution model enabled to build JSC
     972#endif
     973/* Do a sanity check to make sure that we don't have both the classic interpreter
     974   and the llint C loop in use at the same time: */
     975#if ENABLE(CLASSIC_INTERPRETER) && ENABLE(LLINT_C_LOOP)
     976#error You cannot build both the classic interpreter and the llint C loop together
    962977#endif
    963978
     
    979994#endif
    980995
     996/* Determine if we need to enable Computed Goto Opcodes or not: */
    981997#if (HAVE(COMPUTED_GOTO) && ENABLE(LLINT)) || ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    982998#define ENABLE_COMPUTED_GOTO_OPCODES 1
     
    9871003
    9881004/* Yet Another Regex Runtime - turned on by default for JIT enabled ports. */
    989 #if !defined(ENABLE_YARR_JIT) && ENABLE(JIT) && !PLATFORM(CHROMIUM)
     1005#if !defined(ENABLE_YARR_JIT) && (ENABLE(JIT) || ENABLE(LLINT_C_LOOP)) && !PLATFORM(CHROMIUM)
    9901006#define ENABLE_YARR_JIT 1
    9911007
Note: See TracChangeset for help on using the changeset viewer.