Changeset 108908 in webkit


Ignore:
Timestamp:
Feb 25, 2012, 3:05:38 PM (14 years ago)
Author:
fpizlo@apple.com
Message:

DFG should support activations and nested functions
https://bugs.webkit.org/show_bug.cgi?id=79554

Reviewed by Oliver Hunt.

Wrote the simplest possible implementation of activations. Big speed-up on
code that uses activations, no speed-up on major benchmarks (SunSpider, V8,
Kraken) because they do not appear to have sufficient coverage over code
that uses activations.

  • bytecode/PredictedType.cpp:

(JSC::predictionToString):
(JSC::predictionFromValue):

  • bytecode/PredictedType.h:

(JSC):
(JSC::isEmptyPrediction):

  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::execute):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::ByteCodeParser):
(ByteCodeParser):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::buildOperandMapsIfNecessary):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
(JSC::DFG::ByteCodeParser::parse):

  • dfg/DFGCapabilities.h:

(JSC::DFG::canCompileOpcode):
(JSC::DFG::canInlineOpcode):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::needsActivation):

  • dfg/DFGNode.h:

(DFG):
(JSC::DFG::Node::storageAccessDataIndex):
(Node):
(JSC::DFG::Node::hasFunctionDeclIndex):
(JSC::DFG::Node::functionDeclIndex):
(JSC::DFG::Node::hasFunctionExprIndex):
(JSC::DFG::Node::functionExprIndex):

  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck):
(DFG):
(JSC::DFG::SpeculativeJIT::compileNewFunctionExpression):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::callOperation):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

Location:
trunk/Source/JavaScriptCore
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r108907 r108908  
     12012-02-25  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG should support activations and nested functions
     4        https://bugs.webkit.org/show_bug.cgi?id=79554
     5
     6        Reviewed by Oliver Hunt.
     7       
     8        Wrote the simplest possible implementation of activations. Big speed-up on
     9        code that uses activations, no speed-up on major benchmarks (SunSpider, V8,
     10        Kraken) because they do not appear to have sufficient coverage over code
     11        that uses activations.
     12
     13        * bytecode/PredictedType.cpp:
     14        (JSC::predictionToString):
     15        (JSC::predictionFromValue):
     16        * bytecode/PredictedType.h:
     17        (JSC):
     18        (JSC::isEmptyPrediction):
     19        * dfg/DFGAbstractState.cpp:
     20        (JSC::DFG::AbstractState::execute):
     21        * dfg/DFGByteCodeParser.cpp:
     22        (JSC::DFG::ByteCodeParser::ByteCodeParser):
     23        (ByteCodeParser):
     24        (JSC::DFG::ByteCodeParser::parseBlock):
     25        (JSC::DFG::ByteCodeParser::buildOperandMapsIfNecessary):
     26        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
     27        (JSC::DFG::ByteCodeParser::parse):
     28        * dfg/DFGCapabilities.h:
     29        (JSC::DFG::canCompileOpcode):
     30        (JSC::DFG::canInlineOpcode):
     31        * dfg/DFGGraph.h:
     32        (JSC::DFG::Graph::needsActivation):
     33        * dfg/DFGNode.h:
     34        (DFG):
     35        (JSC::DFG::Node::storageAccessDataIndex):
     36        (Node):
     37        (JSC::DFG::Node::hasFunctionDeclIndex):
     38        (JSC::DFG::Node::functionDeclIndex):
     39        (JSC::DFG::Node::hasFunctionExprIndex):
     40        (JSC::DFG::Node::functionExprIndex):
     41        * dfg/DFGOperations.cpp:
     42        * dfg/DFGOperations.h:
     43        * dfg/DFGPredictionPropagationPhase.cpp:
     44        (JSC::DFG::PredictionPropagationPhase::propagate):
     45        * dfg/DFGSpeculativeJIT.cpp:
     46        (JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck):
     47        (DFG):
     48        (JSC::DFG::SpeculativeJIT::compileNewFunctionExpression):
     49        * dfg/DFGSpeculativeJIT.h:
     50        (JSC::DFG::SpeculativeJIT::callOperation):
     51        * dfg/DFGSpeculativeJIT32_64.cpp:
     52        (JSC::DFG::SpeculativeJIT::compile):
     53        * dfg/DFGSpeculativeJIT64.cpp:
     54        (JSC::DFG::SpeculativeJIT::compile):
     55
    1562012-02-25  Benjamin Poulain  <benjamin@webkit.org>
    257
  • trunk/Source/JavaScriptCore/bytecode/PredictedType.cpp

    r108677 r108908  
    154154        isTop = false;
    155155   
    156     if (isTop)
    157         return "Top";
     156    if (isTop) {
     157        ptr = description;
     158        ptr.strcat("Top");
     159    }
     160   
     161    if (value & PredictEmpty)
     162        ptr.strcat("Empty");
    158163   
    159164    *ptr++ = 0;
     
    222227PredictedType predictionFromValue(JSValue value)
    223228{
     229    if (value.isEmpty())
     230        return PredictEmpty;
    224231    if (value.isInt32())
    225232        return PredictInt32;
  • trunk/Source/JavaScriptCore/bytecode/PredictedType.h

    r106590 r108908  
    6262static const PredictedType PredictNumber            = 0x00070000; // It's either an Int32 or a Double.
    6363static const PredictedType PredictBoolean           = 0x00080000; // It's definitely a Boolean.
    64 static const PredictedType PredictOther             = 0x40000000; // It's definitely none of the above.
    65 static const PredictedType PredictTop               = 0x7fffffff; // It can be any of the above.
     64static const PredictedType PredictOther             = 0x08000000; // It's definitely none of the above.
     65static const PredictedType PredictTop               = 0x0fffffff; // It can be any of the above.
     66static const PredictedType PredictEmpty             = 0x10000000; // It's definitely an empty value marker.
     67static const PredictedType PredictEmptyOrTop        = 0x1fffffff; // It can be any of the above.
    6668static const PredictedType FixedIndexedStorageMask = PredictByteArray | PredictInt8Array | PredictInt16Array | PredictInt32Array | PredictUint8Array | PredictUint8ClampedArray | PredictUint16Array | PredictUint32Array | PredictFloat32Array | PredictFloat64Array;
    6769
     
    218220}
    219221
     222inline bool isEmptyPrediction(PredictedType value)
     223{
     224    return value == PredictEmpty;
     225}
     226
    220227const char* predictionToString(PredictedType value);
    221228
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp

    r108842 r108908  
    724724           
    725725    case NewObject:
    726         forNode(nodeIndex).set(m_codeBlock->globalObject()->emptyObjectStructure());
     726        forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->emptyObjectStructure());
    727727        m_haveStructures = true;
    728728        break;
    729            
     729       
     730    case CreateActivation:
     731        forNode(nodeIndex).set(m_graph.m_globalData.activationStructure.get());
     732        m_haveStructures = true;
     733        break;
     734       
     735    case TearOffActivation:
     736        // Does nothing that is user-visible.
     737        break;
     738       
     739    case NewFunction:
     740    case NewFunctionExpression:
     741    case NewFunctionNoCheck:
     742        forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->functionStructure());
     743        break;
     744       
    730745    case GetCallee:
    731746        forNode(nodeIndex).set(PredictFunction);
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r108842 r108908  
    6767        , m_inlineStackTop(0)
    6868        , m_haveBuiltOperandMaps(false)
     69        , m_emptyJSValueIndex(UINT_MAX)
    6970    {
    7071        ASSERT(m_profiledBlock);
     
    948949    // Mapping between values and constant numbers.
    949950    JSValueMap m_jsValueMap;
     951    // Index of the empty value, or UINT_MAX if there is no mapping. This is a horrible
     952    // work-around for the fact that JSValueMap can't handle "empty" values.
     953    unsigned m_emptyJSValueIndex;
    950954   
    951955    // Cache of code blocks that we've generated bytecode for.
     
    22232227            NEXT_OPCODE(op_loop_hint);
    22242228        }
     2229           
     2230        case op_init_lazy_reg: {
     2231            set(currentInstruction[1].u.operand, getJSConstantForValue(JSValue()));
     2232            NEXT_OPCODE(op_init_lazy_reg);
     2233        }
     2234           
     2235        case op_create_activation: {
     2236            set(currentInstruction[1].u.operand, addToGraph(CreateActivation, get(currentInstruction[1].u.operand)));
     2237            NEXT_OPCODE(op_create_activation);
     2238        }
     2239           
     2240        case op_tear_off_activation: {
     2241            // This currently ignores arguments because we don't support them yet.
     2242            addToGraph(TearOffActivation, get(currentInstruction[1].u.operand));
     2243            NEXT_OPCODE(op_tear_off_activation);
     2244        }
     2245           
     2246        case op_new_func: {
     2247            if (!currentInstruction[3].u.operand) {
     2248                set(currentInstruction[1].u.operand,
     2249                    addToGraph(NewFunctionNoCheck, OpInfo(currentInstruction[2].u.operand)));
     2250            } else {
     2251                set(currentInstruction[1].u.operand,
     2252                    addToGraph(
     2253                        NewFunction,
     2254                        OpInfo(currentInstruction[2].u.operand),
     2255                        get(currentInstruction[1].u.operand)));
     2256            }
     2257            NEXT_OPCODE(op_new_func);
     2258        }
     2259           
     2260        case op_new_func_exp: {
     2261            set(currentInstruction[1].u.operand,
     2262                addToGraph(NewFunctionExpression, OpInfo(currentInstruction[2].u.operand)));
     2263            NEXT_OPCODE(op_new_func_exp);
     2264        }
    22252265
    22262266        default:
     
    24752515    for (size_t i = 0; i < m_codeBlock->numberOfIdentifiers(); ++i)
    24762516        m_identifierMap.add(m_codeBlock->identifier(i).impl(), i);
    2477     for (size_t i = 0; i < m_codeBlock->numberOfConstantRegisters(); ++i)
    2478         m_jsValueMap.add(JSValue::encode(m_codeBlock->getConstant(i + FirstConstantRegisterIndex)), i + FirstConstantRegisterIndex);
     2517    for (size_t i = 0; i < m_codeBlock->numberOfConstantRegisters(); ++i) {
     2518        JSValue value = m_codeBlock->getConstant(i + FirstConstantRegisterIndex);
     2519        if (!value)
     2520            m_emptyJSValueIndex = i + FirstConstantRegisterIndex;
     2521        else
     2522            m_jsValueMap.add(JSValue::encode(value), i + FirstConstantRegisterIndex);
     2523    }
    24792524   
    24802525    m_haveBuiltOperandMaps = true;
     
    25262571        for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i) {
    25272572            JSValue value = codeBlock->getConstant(i + FirstConstantRegisterIndex);
     2573            if (!value) {
     2574                if (byteCodeParser->m_emptyJSValueIndex == UINT_MAX) {
     2575                    byteCodeParser->m_emptyJSValueIndex = byteCodeParser->m_codeBlock->numberOfConstantRegisters() + FirstConstantRegisterIndex;
     2576                    byteCodeParser->m_codeBlock->addConstant(JSValue());
     2577                    byteCodeParser->m_constants.append(ConstantRecord());
     2578                }
     2579                m_constantRemap[i] = byteCodeParser->m_emptyJSValueIndex;
     2580                continue;
     2581            }
    25282582            pair<JSValueMap::iterator, bool> result = byteCodeParser->m_jsValueMap.add(JSValue::encode(value), byteCodeParser->m_codeBlock->numberOfConstantRegisters() + FirstConstantRegisterIndex);
    25292583            if (result.second) {
     
    26532707    // We should be pretending that the code has an activation.
    26542708    ASSERT(m_graph.needsActivation());
    2655 #else
    2656     // For now we should never see code that needs activations.
    2657     ASSERT(!m_graph.needsActivation());
    26582709#endif
    26592710   
  • trunk/Source/JavaScriptCore/dfg/DFGCapabilities.h

    r108866 r108908  
    155155    case op_construct:
    156156    case op_new_regexp:
     157    case op_init_lazy_reg:
     158    case op_create_activation:
     159    case op_tear_off_activation:
     160    case op_new_func:
     161    case op_new_func_exp:
    157162        return true;
    158163       
     
    180185    // Inlining doesn't correctly remap regular expression operands.
    181186    case op_new_regexp:
     187        return false;
     188       
     189    // We don't support inlining code that creates activations or has nested functions.
     190    case op_init_lazy_reg:
     191    case op_create_activation:
     192    case op_tear_off_activation:
     193    case op_new_func:
     194    case op_new_func_exp:
    182195        return false;
    183196       
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r108842 r108908  
    311311        return true;
    312312#else
    313         return m_codeBlock->ownerExecutable()->needsActivation() && m_codeBlock->codeType() != GlobalCode;
     313        return m_codeBlock->needsFullScopeChain() && m_codeBlock->codeType() != GlobalCode;
    314314#endif
    315315    }
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r108842 r108908  
    292292    macro(StrCat, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
    293293    \
     294    /* Nodes used for activations. Activation support works by having it anchored at */\
     295    /* epilgoues via TearOffActivation, and all CreateActivation nodes kept alive by */\
     296    /* being threaded with each other. */\
     297    macro(CreateActivation, NodeResultJS) \
     298    macro(TearOffActivation, NodeMustGenerate) \
     299    \
     300    /* Nodes for creating functions. */\
     301    macro(NewFunctionNoCheck, NodeResultJS) \
     302    macro(NewFunction, NodeResultJS) \
     303    macro(NewFunctionExpression, NodeResultJS) \
     304    \
    294305    /* Block terminals. */\
    295306    macro(Jump, NodeMustGenerate | NodeIsTerminal | NodeIsJump) \
     
    776787    unsigned storageAccessDataIndex()
    777788    {
     789        ASSERT(hasStorageAccessData());
     790        return m_opInfo;
     791    }
     792   
     793    bool hasFunctionDeclIndex()
     794    {
     795        return op == NewFunction
     796            || op == NewFunctionNoCheck;
     797    }
     798   
     799    unsigned functionDeclIndex()
     800    {
     801        ASSERT(hasFunctionDeclIndex());
     802        return m_opInfo;
     803    }
     804   
     805    bool hasFunctionExprIndex()
     806    {
     807        return op == NewFunctionExpression;
     808    }
     809   
     810    unsigned functionExprIndex()
     811    {
     812        ASSERT(hasFunctionExprIndex());
    778813        return m_opInfo;
    779814    }
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r108444 r108908  
    3434#include "InlineASM.h"
    3535#include "Interpreter.h"
     36#include "JSActivation.h"
    3637#include "JSByteArray.h"
    3738#include "JSGlobalData.h"
     39#include "JSStaticScopeObject.h"
    3840#include "Operations.h"
    3941
     
    973975   
    974976    return JSValue::encode(RegExpObject::create(exec->globalData(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp));
     977}
     978
     979JSCell* DFG_OPERATION operationCreateActivation(ExecState* exec)
     980{
     981    JSGlobalData& globalData = exec->globalData();
     982    JSActivation* activation = JSActivation::create(
     983        globalData, exec, static_cast<FunctionExecutable*>(exec->codeBlock()->ownerExecutable()));
     984    exec->setScopeChain(exec->scopeChain()->push(activation));
     985    return activation;
     986}
     987
     988void DFG_OPERATION operationTearOffActivation(ExecState* exec, JSCell* activation)
     989{
     990    ASSERT(activation);
     991    ASSERT(activation->inherits(&JSActivation::s_info));
     992    static_cast<JSActivation*>(activation)->tearOff(exec->globalData());
     993}
     994
     995JSCell* DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable)
     996{
     997    ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info));
     998    return static_cast<FunctionExecutable*>(functionExecutable)->make(exec, exec->scopeChain());
     999}
     1000
     1001JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* functionExecutableAsCell)
     1002{
     1003    ASSERT(functionExecutableAsCell->inherits(&FunctionExecutable::s_info));
     1004    FunctionExecutable* functionExecutable =
     1005        static_cast<FunctionExecutable*>(functionExecutableAsCell);
     1006    JSFunction *function = functionExecutable->make(exec, exec->scopeChain());
     1007    if (!functionExecutable->name().isNull()) {
     1008        JSStaticScopeObject* functionScopeObject =
     1009            JSStaticScopeObject::create(
     1010                exec, functionExecutable->name(), function, ReadOnly | DontDelete);
     1011        function->setScope(exec->globalData(), function->scope()->push(functionScopeObject));
     1012    }
     1013    return function;
    9751014}
    9761015
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r107485 r108908  
    9090typedef double DFG_OPERATION (*D_DFGOperation_EJ)(ExecState*, EncodedJSValue);
    9191typedef void* DFG_OPERATION (*P_DFGOperation_E)(ExecState*);
     92typedef void DFG_OPERATION (V_DFGOperation_EC)(ExecState*, JSCell*);
    9293
    9394// These routines are provide callbacks out to C++ implementations of operations too complex to JIT.
     
    146147void* DFG_OPERATION operationVirtualConstruct(ExecState*);
    147148void* DFG_OPERATION operationLinkConstruct(ExecState*);
     149JSCell* DFG_OPERATION operationCreateActivation(ExecState*);
     150void DFG_OPERATION operationTearOffActivation(ExecState*, JSCell*);
     151JSCell* DFG_OPERATION operationNewFunction(ExecState*, JSCell*);
     152JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState*, JSCell*);
    148153
    149154// This method is used to lookup an exception hander, keyed by faultLocation, which is
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r108842 r108908  
    398398        }
    399399           
     400        case CreateActivation: {
     401            changed |= setPrediction(PredictObjectOther);
     402            break;
     403        }
     404           
     405        case NewFunction:
     406        case NewFunctionNoCheck:
     407        case NewFunctionExpression: {
     408            changed |= setPrediction(PredictFunction);
     409            break;
     410        }
     411           
    400412        case GetArrayLength:
    401413        case GetByteArrayLength:
     
    440452        case PutStructure:
    441453        case PutByOffset:
     454        case TearOffActivation:
    442455            break;
    443456           
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r108842 r108908  
    26902690}
    26912691
     2692void SpeculativeJIT::compileNewFunctionNoCheck(Node& node)
     2693{
     2694    GPRResult result(this);
     2695    GPRReg resultGPR = result.gpr();
     2696    flushRegisters();
     2697    callOperation(
     2698        operationNewFunction, resultGPR, m_jit.codeBlock()->functionDecl(node.functionDeclIndex()));
     2699    cellResult(resultGPR, m_compileIndex);
     2700}
     2701
     2702void SpeculativeJIT::compileNewFunctionExpression(Node& node)
     2703{
     2704    GPRResult result(this);
     2705    GPRReg resultGPR = result.gpr();
     2706    flushRegisters();
     2707    callOperation(
     2708        operationNewFunctionExpression,
     2709        resultGPR,
     2710        m_jit.codeBlock()->functionExpr(node.functionExprIndex()));
     2711    cellResult(resultGPR, m_compileIndex);
     2712}
     2713
    26922714} } // namespace JSC::DFG
    26932715
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r108842 r108908  
    11611161        return appendCallWithExceptionCheckSetResult(operation, result);
    11621162    }
     1163    JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, JSCell* cell)
     1164    {
     1165        m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
     1166        return appendCallWithExceptionCheckSetResult(operation, result);
     1167    }
    11631168    JITCompiler::Call callOperation(C_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell)
    11641169    {
     
    11951200        m_jit.setupArgumentsWithExecState(arg1, arg2);
    11961201        return appendCallWithExceptionCheckSetResult(operation, result);
     1202    }
     1203    JITCompiler::Call callOperation(V_DFGOperation_EC operation, GPRReg arg1)
     1204    {
     1205        m_jit.setupArgumentsWithExecState(arg1);
     1206        return appendCallWithExceptionCheck(operation);
    11971207    }
    11981208    JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1, GPRReg arg2, void* pointer)
     
    13291339        return appendCallWithExceptionCheckSetResult(operation, result);
    13301340    }
     1341    JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, JSCell* cell)
     1342    {
     1343        m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
     1344        return appendCallWithExceptionCheckSetResult(operation, result);
     1345    }
    13311346    JITCompiler::Call callOperation(C_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell)
    13321347    {
     
    13631378        m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
    13641379        return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
     1380    }
     1381    JITCompiler::Call callOperation(V_DFGOperation_EC operation, GPRReg arg1)
     1382    {
     1383        m_jit.setupArgumentsWithExecState(arg1);
     1384        return appendCallWithExceptionCheck(operation);
    13651385    }
    13661386    JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer)
     
    17141734    void compileGetByValOnFloatTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize, TypedArraySpeculationRequirements);
    17151735    void compilePutByValForFloatTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArraySpeculationRequirements);
     1736    void compileNewFunctionNoCheck(Node& node);
     1737    void compileNewFunctionExpression(Node& node);
    17161738   
    17171739    // It is acceptable to have structure be equal to scratch, so long as you're fine
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r108842 r108908  
    34893489    }
    34903490
     3491    case CreateActivation: {
     3492        JSValueOperand value(this, node.child1());
     3493        GPRTemporary result(this, value);
     3494       
     3495        GPRReg valueTagGPR = value.tagGPR();
     3496        GPRReg valuePayloadGPR = value.payloadGPR();
     3497        GPRReg resultGPR = result.gpr();
     3498       
     3499        m_jit.move(valuePayloadGPR, resultGPR);
     3500       
     3501        JITCompiler::Jump alreadyCreated = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
     3502       
     3503        silentSpillAllRegisters(resultGPR);
     3504        callOperation(operationCreateActivation, resultGPR);
     3505        silentFillAllRegisters(resultGPR);
     3506       
     3507        alreadyCreated.link(&m_jit);
     3508       
     3509        cellResult(resultGPR, m_compileIndex);
     3510        break;
     3511    }
     3512       
     3513    case TearOffActivation: {
     3514        JSValueOperand value(this, node.child1());
     3515        GPRTemporary result(this, value);
     3516       
     3517        GPRReg valueTagGPR = value.tagGPR();
     3518        GPRReg valuePayloadGPR = value.payloadGPR();
     3519       
     3520        JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
     3521       
     3522        silentSpillAllRegisters(InvalidGPRReg);
     3523        callOperation(operationTearOffActivation, valuePayloadGPR);
     3524        silentFillAllRegisters(InvalidGPRReg);
     3525       
     3526        notCreated.link(&m_jit);
     3527       
     3528        noResult(m_compileIndex);
     3529        break;
     3530    }
     3531       
     3532    case NewFunctionNoCheck:
     3533        compileNewFunctionNoCheck(node);
     3534        break;
     3535       
     3536    case NewFunction: {
     3537        JSValueOperand value(this, node.child1());
     3538        GPRTemporary result(this, value);
     3539       
     3540        GPRReg valueTagGPR = value.tagGPR();
     3541        GPRReg valuePayloadGPR = value.payloadGPR();
     3542        GPRReg resultGPR = result.gpr();
     3543       
     3544        m_jit.move(valuePayloadGPR, resultGPR);
     3545       
     3546        JITCompiler::Jump alreadyCreated = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
     3547       
     3548        silentSpillAllRegisters(resultGPR);
     3549        callOperation(
     3550            operationNewFunction, resultGPR, m_jit.codeBlock()->functionDecl(node.functionDeclIndex()));
     3551        silentFillAllRegisters(resultGPR);
     3552       
     3553        alreadyCreated.link(&m_jit);
     3554       
     3555        cellResult(resultGPR, m_compileIndex);
     3556        break;
     3557    }
     3558       
     3559    case NewFunctionExpression:
     3560        compileNewFunctionExpression(node);
     3561        break;
     3562
    34913563    case ForceOSRExit: {
    34923564        terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r108842 r108908  
    34523452        break;
    34533453    }
     3454       
     3455    case CreateActivation: {
     3456        JSValueOperand value(this, node.child1());
     3457        GPRTemporary result(this, value);
     3458       
     3459        GPRReg valueGPR = value.gpr();
     3460        GPRReg resultGPR = result.gpr();
     3461       
     3462        m_jit.move(valueGPR, resultGPR);
     3463       
     3464        JITCompiler::Jump alreadyCreated = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR);
     3465       
     3466        silentSpillAllRegisters(resultGPR);
     3467        callOperation(operationCreateActivation, resultGPR);
     3468        silentFillAllRegisters(resultGPR);
     3469       
     3470        alreadyCreated.link(&m_jit);
     3471       
     3472        cellResult(resultGPR, m_compileIndex);
     3473        break;
     3474    }
     3475       
     3476    case TearOffActivation: {
     3477        JSValueOperand value(this, node.child1());
     3478        GPRReg valueGPR = value.gpr();
     3479       
     3480        JITCompiler::Jump notCreated = m_jit.branchTestPtr(JITCompiler::Zero, valueGPR);
     3481       
     3482        silentSpillAllRegisters(InvalidGPRReg);
     3483        callOperation(operationTearOffActivation, valueGPR);
     3484        silentFillAllRegisters(InvalidGPRReg);
     3485       
     3486        notCreated.link(&m_jit);
     3487       
     3488        noResult(m_compileIndex);
     3489        break;
     3490    }
     3491       
     3492    case NewFunctionNoCheck:
     3493        compileNewFunctionNoCheck(node);
     3494        break;
     3495       
     3496    case NewFunction: {
     3497        JSValueOperand value(this, node.child1());
     3498        GPRTemporary result(this, value);
     3499       
     3500        GPRReg valueGPR = value.gpr();
     3501        GPRReg resultGPR = result.gpr();
     3502       
     3503        m_jit.move(valueGPR, resultGPR);
     3504       
     3505        JITCompiler::Jump alreadyCreated = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR);
     3506       
     3507        silentSpillAllRegisters(resultGPR);
     3508        callOperation(
     3509            operationNewFunction, resultGPR, m_jit.codeBlock()->functionDecl(node.functionDeclIndex()));
     3510        silentFillAllRegisters(resultGPR);
     3511       
     3512        alreadyCreated.link(&m_jit);
     3513       
     3514        cellResult(resultGPR, m_compileIndex);
     3515        break;
     3516    }
     3517       
     3518    case NewFunctionExpression:
     3519        compileNewFunctionExpression(node);
     3520        break;
    34543521
    34553522    case ForceOSRExit: {
Note: See TracChangeset for help on using the changeset viewer.