Changeset 139145 in webkit


Ignore:
Timestamp:
Jan 8, 2013 6:37:29 PM (11 years ago)
Author:
oliver@apple.com
Message:

Support op_typeof in the DFG
https://bugs.webkit.org/show_bug.cgi?id=98898

Reviewed by Filip Pizlo.

Adds a TypeOf node to the DFG to support op_typeof.

To avoid adding too much GC horror, this also makes the
common strings portion of the SmallString cache strongly
referenced.

  • dfg/DFGAbstractState.cpp:

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

We try to determine the result early here, and substitute in a constant.
Otherwise we leave the node intact, and set the result type to SpecString.

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

Parse op_typeof

  • dfg/DFGCSEPhase.cpp:

(JSC::DFG::CSEPhase::performNodeCSE):

TypeOf nodes can be subjected to pure CSE

  • dfg/DFGCapabilities.h:

(JSC::DFG::canCompileOpcode):

We can handle typeof.

  • dfg/DFGNodeType.h:

(DFG):

Define the node.

  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h: Add operationTypeOf to support the non-trivial cases.
  • dfg/DFGPredictionPropagationPhase.cpp:

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

  • dfg/DFGSpeculativeJIT32_64.cpp:

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

  • dfg/DFGSpeculativeJIT64.cpp:

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

Actual codegen

  • runtime/Operations.cpp:

(JSC::jsTypeStringForValue):
(JSC):

  • runtime/Operations.h:

(JSC):

Some refactoring to allow us to get the type string for an
object without needing a callframe.

Location:
trunk/Source/JavaScriptCore
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r139136 r139145  
     12013-01-08  Oliver Hunt  <oliver@apple.com>
     2
     3        Support op_typeof in the DFG
     4        https://bugs.webkit.org/show_bug.cgi?id=98898
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Adds a TypeOf node to the DFG to support op_typeof.
     9
     10        To avoid adding too much GC horror, this also makes the
     11        common strings portion of the SmallString cache strongly
     12        referenced.
     13
     14        * dfg/DFGAbstractState.cpp:
     15        (JSC::DFG::AbstractState::execute):
     16          We try to determine the result early here, and substitute in a constant.
     17          Otherwise we leave the node intact, and set the result type to SpecString.
     18        * dfg/DFGByteCodeParser.cpp:
     19        (JSC::DFG::ByteCodeParser::parseBlock):
     20          Parse op_typeof
     21        * dfg/DFGCSEPhase.cpp:
     22        (JSC::DFG::CSEPhase::performNodeCSE):
     23          TypeOf nodes can be subjected to pure CSE
     24        * dfg/DFGCapabilities.h:
     25        (JSC::DFG::canCompileOpcode):
     26          We can handle typeof.
     27        * dfg/DFGNodeType.h:
     28        (DFG):
     29          Define the node.
     30        * dfg/DFGOperations.cpp:
     31        * dfg/DFGOperations.h:
     32          Add operationTypeOf to support the non-trivial cases.
     33        * dfg/DFGPredictionPropagationPhase.cpp:
     34        (JSC::DFG::PredictionPropagationPhase::propagate):
     35        * dfg/DFGSpeculativeJIT32_64.cpp:
     36        (JSC::DFG::SpeculativeJIT::compile):
     37        * dfg/DFGSpeculativeJIT64.cpp:
     38        (JSC::DFG::SpeculativeJIT::compile):
     39          Actual codegen
     40        * runtime/Operations.cpp:
     41        (JSC::jsTypeStringForValue):
     42        (JSC):
     43        * runtime/Operations.h:
     44        (JSC):
     45          Some refactoring to allow us to get the type string for an
     46          object without needing a callframe.
     47
     48
    1492013-01-08  Filip Pizlo  <fpizlo@apple.com>
    250
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp

    r138921 r139145  
    3232#include "DFGBasicBlock.h"
    3333#include "GetByIdStatus.h"
     34#include "Operations.h"
    3435#include "PutByIdStatus.h"
    3536
     
    708709                constantWasSet = trySetConstant(nodeIndex, jsBoolean(isJSString(child)));
    709710                break;
     711            case IsObject:
     712                if (child.isNull() || !child.isObject()) {
     713                    constantWasSet = trySetConstant(nodeIndex, jsBoolean(child.isNull()));
     714                    break;
     715                }
    710716            default:
    711717                constantWasSet = false;
     
    717723            }
    718724        }
     725
    719726        forNode(nodeIndex).set(SpecBoolean);
     727        break;
     728    }
     729
     730    case TypeOf: {
     731        JSGlobalData* globalData = m_codeBlock->globalData();
     732        JSValue child = forNode(node.child1()).value();
     733        AbstractValue& abstractChild = forNode(node.child1());
     734        if (child) {
     735            JSValue typeString = jsTypeStringForValue(*globalData, m_codeBlock->globalObjectFor(node.codeOrigin), child);
     736            if (trySetConstant(nodeIndex, typeString)) {
     737                m_foundConstants = true;
     738                break;
     739            }
     740        } else if (isNumberSpeculation(abstractChild.m_type)) {
     741            if (trySetConstant(nodeIndex, globalData->smallStrings.numberString())) {
     742                forNode(node.child1()).filter(SpecNumber);
     743                m_foundConstants = true;
     744                break;
     745            }
     746        } else if (isStringSpeculation(abstractChild.m_type)) {
     747            if (trySetConstant(nodeIndex, globalData->smallStrings.stringString())) {
     748                forNode(node.child1()).filter(SpecString);
     749                m_foundConstants = true;
     750                break;
     751            }
     752        } else if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isArgumentsSpeculation(abstractChild.m_type)) {
     753            if (trySetConstant(nodeIndex, globalData->smallStrings.objectString())) {
     754                forNode(node.child1()).filter(SpecFinalObject | SpecArray | SpecArguments);
     755                m_foundConstants = true;
     756                break;
     757            }
     758        } else if (isFunctionSpeculation(abstractChild.m_type)) {
     759            if (trySetConstant(nodeIndex, globalData->smallStrings.functionString())) {
     760                forNode(node.child1()).filter(SpecFunction);
     761                m_foundConstants = true;
     762                break;
     763            }
     764        } else if (isBooleanSpeculation(abstractChild.m_type)) {
     765            if (trySetConstant(nodeIndex, globalData->smallStrings.booleanString())) {
     766                forNode(node.child1()).filter(SpecBoolean);
     767                m_foundConstants = true;
     768                break;
     769            }
     770        } else {
     771            Node& childNode = m_graph[node.child1()];
     772            if (isCellSpeculation(childNode.prediction())) {
     773                if (isStringSpeculation(childNode.prediction()))
     774                    forNode(node.child1()).filter(SpecString);
     775                else
     776                    forNode(node.child1()).filter(SpecCell);
     777                node.setCanExit(true);
     778            }
     779        }
     780        forNode(nodeIndex).set(SpecString);
    720781        break;
    721782    }
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r139098 r139145  
    32243224        }
    32253225
     3226        case op_typeof: {
     3227            set(currentInstruction[1].u.operand,
     3228                addToGraph(TypeOf, get(currentInstruction[2].u.operand)));
     3229            NEXT_OPCODE(op_typeof);
     3230        }
     3231
    32263232        default:
    32273233            // Parse failed! This should not happen because the capabilities checker
  • trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

    r138921 r139145  
    598598            case AllocatePropertyStorage:
    599599            case ReallocatePropertyStorage:
     600            case TypeOf:
    600601                return NoNode;
    601602               
     
    11671168        case GetScopeRegisters:
    11681169        case GetScope:
     1170        case TypeOf:
    11691171            setReplacement(pureCSE(node));
    11701172            break;
  • trunk/Source/JavaScriptCore/dfg/DFGCapabilities.h

    r138921 r139145  
    199199    case op_put_to_base_variable:
    200200    case op_put_to_base:
     201    case op_typeof:
    201202        return CanCompile;
    202203       
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r138921 r139145  
    215215    macro(IsObject, NodeResultBoolean) \
    216216    macro(IsFunction, NodeResultBoolean) \
     217    macro(TypeOf, NodeResultJS) \
    217218    macro(LogicalNot, NodeResultBoolean) \
    218219    macro(ToPrimitive, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r138970 r139145  
    14271427{
    14281428    return jsIsFunctionType(JSValue::decode(value));
     1429}
     1430
     1431JSCell* DFG_OPERATION operationTypeOf(ExecState* exec, JSCell* value)
     1432{
     1433    return jsTypeStringForValue(exec, JSValue(value)).asCell();
    14291434}
    14301435
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r138201 r139145  
    200200size_t DFG_OPERATION operationIsObject(ExecState*, EncodedJSValue) WTF_INTERNAL;
    201201size_t DFG_OPERATION operationIsFunction(EncodedJSValue) WTF_INTERNAL;
     202JSCell* DFG_OPERATION operationTypeOf(ExecState*, JSCell*) WTF_INTERNAL;
    202203void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState*, JSObject*, Structure*, PropertyOffset, EncodedJSValue) WTF_INTERNAL;
    203204char* DFG_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState*) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r139068 r139145  
    519519            break;
    520520        }
    521            
     521
     522        case TypeOf: {
     523            changed |= setPrediction(SpecString);
     524            changed |= mergeDefaultFlags(node);
     525            break;
     526        }
     527
    522528        case GetById: {
    523529            changed |= mergePrediction(node.getHeapPrediction());
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r138921 r139145  
    45854585        break;
    45864586    }
     4587    case TypeOf: {
     4588        JSValueOperand value(this, node.child1());
     4589        GPRReg tagGPR = value.tagGPR();
     4590        GPRReg payloadGPR = value.payloadGPR();
     4591        GPRTemporary temp(this);
     4592        GPRReg tempGPR = temp.gpr();
     4593        GPRResult result(this);
     4594        GPRReg resultGPR = result.gpr();
     4595        JITCompiler::JumpList doneJumps;
     4596
     4597        flushRegisters();
     4598
     4599        JITCompiler::Jump isNotCell = m_jit.branch32(JITCompiler::NotEqual, tagGPR, JITCompiler::TrustedImm32(JSValue::CellTag));
     4600        Node& child = m_jit.graph()[node.child1()];
     4601        if (child.shouldSpeculateCell())
     4602            speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node.child1(), isNotCell);
     4603
     4604        if (!child.shouldSpeculateNonStringCell()) {
     4605            m_jit.loadPtr(JITCompiler::Address(payloadGPR, JSCell::structureOffset()), tempGPR);
     4606            JITCompiler::Jump notString = m_jit.branch8(JITCompiler::NotEqual, JITCompiler::Address(tempGPR, Structure::typeInfoTypeOffset()), TrustedImm32(StringType));
     4607            if (child.shouldSpeculateString())
     4608                speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node.child1(), notString);
     4609            m_jit.move(TrustedImmPtr(m_jit.globalData()->smallStrings.stringString()), resultGPR);
     4610            doneJumps.append(m_jit.jump());
     4611            if (!child.shouldSpeculateString()) {
     4612                notString.link(&m_jit);
     4613                callOperation(operationTypeOf, resultGPR, payloadGPR);
     4614                doneJumps.append(m_jit.jump());
     4615            }
     4616        } else {
     4617            callOperation(operationTypeOf, resultGPR, payloadGPR);
     4618            doneJumps.append(m_jit.jump());
     4619        }
     4620
     4621        if (!child.shouldSpeculateCell()) {
     4622            isNotCell.link(&m_jit);
     4623
     4624            m_jit.add32(TrustedImm32(1), tagGPR, tempGPR);
     4625            JITCompiler::Jump notNumber = m_jit.branch32(JITCompiler::AboveOrEqual, tempGPR, JITCompiler::TrustedImm32(JSValue::LowestTag + 1));
     4626            m_jit.move(TrustedImmPtr(m_jit.globalData()->smallStrings.numberString()), resultGPR);
     4627            doneJumps.append(m_jit.jump());
     4628            notNumber.link(&m_jit);
     4629
     4630            JITCompiler::Jump notUndefined = m_jit.branch32(JITCompiler::NotEqual, tagGPR, TrustedImm32(JSValue::UndefinedTag));
     4631            m_jit.move(TrustedImmPtr(m_jit.globalData()->smallStrings.undefinedString()), resultGPR);
     4632            doneJumps.append(m_jit.jump());
     4633            notUndefined.link(&m_jit);
     4634
     4635            JITCompiler::Jump notNull = m_jit.branch32(JITCompiler::NotEqual, tagGPR, TrustedImm32(JSValue::NullTag));
     4636            m_jit.move(TrustedImmPtr(m_jit.globalData()->smallStrings.objectString()), resultGPR);
     4637            doneJumps.append(m_jit.jump());
     4638            notNull.link(&m_jit);
     4639
     4640            // Only boolean left
     4641            m_jit.move(TrustedImmPtr(m_jit.globalData()->smallStrings.booleanString()), resultGPR);
     4642        }
     4643        doneJumps.link(&m_jit);
     4644        cellResult(resultGPR, m_compileIndex);
     4645        break;
     4646    }
    45874647
    45884648    case Phi:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r138921 r139145  
    40894089       
    40904090        jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
    4091        
     4091
    40924092        break;
    40934093    }
     
    45094509        m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
    45104510        jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
     4511        break;
     4512    }
     4513
     4514    case TypeOf: {
     4515        JSValueOperand value(this, node.child1());
     4516        GPRReg valueGPR = value.gpr();
     4517        GPRTemporary temp(this);
     4518        GPRReg tempGPR = temp.gpr();
     4519        GPRResult result(this);
     4520        GPRReg resultGPR = result.gpr();
     4521        JITCompiler::JumpList doneJumps;
     4522
     4523        flushRegisters();
     4524
     4525        JITCompiler::Jump isNotCell = m_jit.branchTest64(JITCompiler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
     4526        Node& child = m_jit.graph()[node.child1()];
     4527        if (child.shouldSpeculateCell())
     4528            speculationCheck(BadType, JSValueSource(valueGPR), node.child1(), isNotCell);
     4529
     4530        if (!child.shouldSpeculateNonStringCell()) {
     4531            m_jit.loadPtr(JITCompiler::Address(valueGPR, JSCell::structureOffset()), tempGPR);
     4532            JITCompiler::Jump notString = m_jit.branch8(JITCompiler::NotEqual, JITCompiler::Address(tempGPR, Structure::typeInfoTypeOffset()), TrustedImm32(StringType));
     4533            if (child.shouldSpeculateString())
     4534                speculationCheck(BadType, JSValueSource(valueGPR), node.child1(), notString);
     4535            m_jit.move(TrustedImmPtr(m_jit.globalData()->smallStrings.stringString()), resultGPR);
     4536            doneJumps.append(m_jit.jump());
     4537            if (!child.shouldSpeculateString()) {
     4538                notString.link(&m_jit);
     4539                callOperation(operationTypeOf, resultGPR, valueGPR);
     4540                doneJumps.append(m_jit.jump());
     4541            }
     4542        } else {
     4543            callOperation(operationTypeOf, resultGPR, valueGPR);
     4544            doneJumps.append(m_jit.jump());
     4545        }
     4546
     4547        if (!child.shouldSpeculateCell()) {
     4548            isNotCell.link(&m_jit);
     4549            JITCompiler::Jump notNumber = m_jit.branchTest64(JITCompiler::Zero, valueGPR, GPRInfo::tagTypeNumberRegister);
     4550            m_jit.move(TrustedImmPtr(m_jit.globalData()->smallStrings.numberString()), resultGPR);
     4551            doneJumps.append(m_jit.jump());
     4552            notNumber.link(&m_jit);
     4553
     4554            JITCompiler::Jump notUndefined = m_jit.branch64(JITCompiler::NotEqual, valueGPR, JITCompiler::TrustedImm64(ValueUndefined));
     4555            m_jit.move(TrustedImmPtr(m_jit.globalData()->smallStrings.undefinedString()), resultGPR);
     4556            doneJumps.append(m_jit.jump());
     4557            notUndefined.link(&m_jit);
     4558
     4559            JITCompiler::Jump notNull = m_jit.branch64(JITCompiler::NotEqual, valueGPR, JITCompiler::TrustedImm64(ValueNull));
     4560            m_jit.move(TrustedImmPtr(m_jit.globalData()->smallStrings.objectString()), resultGPR);
     4561            doneJumps.append(m_jit.jump());
     4562            notNull.link(&m_jit);
     4563
     4564            // Only boolean left
     4565            m_jit.move(TrustedImmPtr(m_jit.globalData()->smallStrings.booleanString()), resultGPR);
     4566        }
     4567        doneJumps.link(&m_jit);
     4568        cellResult(resultGPR, m_compileIndex);
    45114569        break;
    45124570    }
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r135469 r139145  
    493493        }
    494494
     495        m_globalData->smallStrings.visitStrongReferences(visitor);
     496
    495497        {
    496498            GCPHASE(VisitMachineRoots);
  • trunk/Source/JavaScriptCore/runtime/BooleanPrototype.cpp

    r131088 r139145  
    8080    JSValue thisValue = exec->hostThisValue();
    8181    if (thisValue == jsBoolean(false))
    82         return JSValue::encode(globalData->smallStrings.falseString(globalData));
     82        return JSValue::encode(globalData->smallStrings.falseString());
    8383
    8484    if (thisValue == jsBoolean(true))
    85         return JSValue::encode(globalData->smallStrings.trueString(globalData));
     85        return JSValue::encode(globalData->smallStrings.trueString());
    8686
    8787    if (!thisValue.inherits(&BooleanObject::s_info))
     
    8989
    9090    if (asBooleanObject(thisValue)->internalValue() == jsBoolean(false))
    91         return JSValue::encode(globalData->smallStrings.falseString(globalData));
     91        return JSValue::encode(globalData->smallStrings.falseString());
    9292
    9393    ASSERT(asBooleanObject(thisValue)->internalValue() == jsBoolean(true));
    94     return JSValue::encode(globalData->smallStrings.trueString(globalData));
     94    return JSValue::encode(globalData->smallStrings.trueString());
    9595}
    9696
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.cpp

    r139004 r139145  
    231231    unlinkedEvalCodeBlockStructure.set(*this, UnlinkedEvalCodeBlock::createStructure(*this, 0, jsNull()));
    232232    unlinkedFunctionCodeBlockStructure.set(*this, UnlinkedFunctionCodeBlock::createStructure(*this, 0, jsNull()));
     233    smallStrings.initializeCommonStrings(*this);
    233234
    234235    wtfThreadData().setCurrentIdentifierTable(existingEntryIdentifierTable);
     
    246247
    247248    heap.notifyIsSafeToCollect();
    248    
     249
    249250    LLInt::Data::performAssertions(*this);
    250251   
  • trunk/Source/JavaScriptCore/runtime/JSString.h

    r130303 r139145  
    334334    inline JSString* jsEmptyString(JSGlobalData* globalData)
    335335    {
    336         return globalData->smallStrings.emptyString(globalData);
     336        return globalData->smallStrings.emptyString();
    337337    }
    338338
     
    387387        int size = s.length();
    388388        if (!size)
    389             return globalData->smallStrings.emptyString(globalData);
     389            return globalData->smallStrings.emptyString();
    390390        if (size == 1) {
    391391            UChar c = s.characterAt(0);
     
    403403        JSGlobalData* globalData = &exec->globalData();
    404404        if (!length)
    405             return globalData->smallStrings.emptyString(globalData);
     405            return globalData->smallStrings.emptyString();
    406406        return jsSubstring(globalData, s->value(exec), offset, length);
    407407    }
     
    413413        ASSERT(offset + length <= static_cast<unsigned>(s.length()));
    414414        if (!length)
    415             return globalData->smallStrings.emptyString(globalData);
     415            return globalData->smallStrings.emptyString();
    416416        if (length == 1) {
    417417            UChar c = s.characterAt(offset);
     
    428428        ASSERT(offset + length <= static_cast<unsigned>(s.length()));
    429429        if (!length)
    430             return globalData->smallStrings.emptyString(globalData);
     430            return globalData->smallStrings.emptyString();
    431431        if (length == 1) {
    432432            UChar c = s.characterAt(offset);
     
    441441        int size = s.length();
    442442        if (!size)
    443             return globalData->smallStrings.emptyString(globalData);
     443            return globalData->smallStrings.emptyString();
    444444        if (size == 1) {
    445445            UChar c = s.characterAt(0);
  • trunk/Source/JavaScriptCore/runtime/JSValue.cpp

    r138073 r139145  
    296296        return jsString(&globalData, globalData.numericStrings.add(asDouble()));
    297297    if (isTrue())
    298         return globalData.smallStrings.trueString(&globalData);
     298        return globalData.smallStrings.trueString();
    299299    if (isFalse())
    300         return globalData.smallStrings.falseString(&globalData);
     300        return globalData.smallStrings.falseString();
    301301    if (isNull())
    302         return globalData.smallStrings.nullString(&globalData);
     302        return globalData.smallStrings.nullString();
    303303    if (isUndefined())
    304         return globalData.smallStrings.undefinedString(&globalData);
     304        return globalData.smallStrings.undefinedString();
    305305
    306306    ASSERT(isCell());
  • trunk/Source/JavaScriptCore/runtime/Operations.cpp

    r137699 r139145  
    5757}
    5858
    59 JSValue jsTypeStringForValue(CallFrame* callFrame, JSValue v)
     59JSValue jsTypeStringForValue(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue v)
    6060{
    61     JSGlobalData& globalData = callFrame->globalData();
    6261    if (v.isUndefined())
    63         return globalData.smallStrings.undefinedString(&globalData);
     62        return globalData.smallStrings.undefinedString();
    6463    if (v.isBoolean())
    65         return globalData.smallStrings.booleanString(&globalData);
     64        return globalData.smallStrings.booleanString();
    6665    if (v.isNumber())
    67         return globalData.smallStrings.numberString(&globalData);
     66        return globalData.smallStrings.numberString();
    6867    if (v.isString())
    69         return globalData.smallStrings.stringString(&globalData);
     68        return globalData.smallStrings.stringString();
    7069    if (v.isObject()) {
    7170        // Return "undefined" for objects that should be treated
    7271        // as null when doing comparisons.
    73         if (asObject(v)->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()))
    74             return globalData.smallStrings.undefinedString(&globalData);
     72        if (asObject(v)->structure()->masqueradesAsUndefined(globalObject))
     73            return globalData.smallStrings.undefinedString();
    7574        CallData callData;
    7675        JSObject* object = asObject(v);
    7776        if (object->methodTable()->getCallData(object, callData) != CallTypeNone)
    78             return globalData.smallStrings.functionString(&globalData);
     77            return globalData.smallStrings.functionString();
    7978    }
    80     return globalData.smallStrings.objectString(&globalData);
     79    return globalData.smallStrings.objectString();
     80}
     81
     82JSValue jsTypeStringForValue(CallFrame* callFrame, JSValue v)
     83{
     84    return jsTypeStringForValue(callFrame->globalData(), callFrame->lexicalGlobalObject(), v);
    8185}
    8286
  • trunk/Source/JavaScriptCore/runtime/Operations.h

    r137700 r139145  
    3333    NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue);
    3434    JSValue jsTypeStringForValue(CallFrame*, JSValue);
     35    JSValue jsTypeStringForValue(JSGlobalData&, JSGlobalObject*, JSValue);
    3536    bool jsIsObjectType(CallFrame*, JSValue);
    3637    bool jsIsFunctionType(JSValue);
  • trunk/Source/JavaScriptCore/runtime/SmallStrings.cpp

    r127191 r139145  
    8181}
    8282
     83void SmallStrings::initializeCommonStrings(JSGlobalData& globalData)
     84{
     85    createEmptyString(&globalData);
     86#define JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE(name) initialize(&globalData, m_##name, #name);
     87    JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE)
     88#undef JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE
     89}
     90
     91void SmallStrings::visitStrongReferences(SlotVisitor& visitor)
     92{
     93    visitor.appendUnbarrieredPointer(&m_emptyString);
     94#define JSC_COMMON_STRINGS_ATTRIBUTE_VISIT(name) visitor.appendUnbarrieredPointer(&m_##name);
     95    JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_VISIT)
     96#undef JSC_COMMON_STRINGS_ATTRIBUTE_VISIT
     97}
     98
    8399SmallStrings::~SmallStrings()
    84100{
     
    90106    for (unsigned i = 0; i < singleCharacterStringCount; ++i)
    91107        finalize(m_singleCharacterStrings[i]);
    92 #define JSC_COMMON_STRINGS_ATTRIBUTE_FINALIZE(name) finalize(m_##name);
    93     JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_FINALIZE)
    94 #undef JSC_COMMON_STRINGS_ATTRIBUTE_FINALIZE
    95108}
    96109
  • trunk/Source/JavaScriptCore/runtime/SmallStrings.h

    r127191 r139145  
    2626#ifndef SmallStrings_h
    2727#define SmallStrings_h
     28
     29#include "WriteBarrier.h"
    2830
    2931#include <wtf/FixedArray.h>
     
    6264        ~SmallStrings();
    6365
    64         JSString* emptyString(JSGlobalData* globalData)
     66        JSString* emptyString()
    6567        {
    66             if (!m_emptyString)
    67                 createEmptyString(globalData);
    6868            return m_emptyString;
    6969        }
     
    8282        JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; }
    8383
     84        void initializeCommonStrings(JSGlobalData&);
     85        void visitStrongReferences(SlotVisitor&);
     86
    8487#define JSC_COMMON_STRINGS_ACCESSOR_DEFINITION(name) \
    85         JSString* name##String(JSGlobalData* globalData) const \
     88        JSString* name##String() const \
    8689        { \
    87             if (!m_##name) \
    88                 initialize(globalData, m_##name, #name); \
    8990            return m_##name; \
    9091        }
     
    101102
    102103        JSString* m_emptyString;
    103 #define JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION(name) mutable JSString* m_##name;
     104#define JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION(name) JSString* m_##name;
    104105        JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION)
    105106#undef JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION
Note: See TracChangeset for help on using the changeset viewer.