⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 243364 in webkit


Ignore:
Timestamp:
Mar 21, 2019, 11:45:20 PM (7 years ago)
Author:
ysuzuki@apple.com
Message:

[JSC] Shrink sizeof(RegExpObject)
https://bugs.webkit.org/show_bug.cgi?id=196130

Reviewed by Saam Barati.

sizeof(RegExpObject) is 48B due to one bool flag. We should compress this flag into lower bit of RegExp* field so that we can make RegExpObject 32B.
It saves memory footprint 1.3% in RAMification's regexp.

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileNewRegexp):
(JSC::DFG::SpeculativeJIT::compileSetRegExpObjectLastIndex):

  • ftl/FTLAbstractHeapRepository.h:
  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileNewRegexp):
(JSC::FTL::DFG::LowerDFGToB3::compileSetRegExpObjectLastIndex):

  • runtime/RegExpObject.cpp:

(JSC::RegExpObject::RegExpObject):
(JSC::RegExpObject::visitChildren):
(JSC::RegExpObject::getOwnPropertySlot):
(JSC::RegExpObject::defineOwnProperty):

  • runtime/RegExpObject.h:
Location:
trunk/Source/JavaScriptCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r243363 r243364  
     12019-03-21  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Shrink sizeof(RegExpObject)
     4        https://bugs.webkit.org/show_bug.cgi?id=196130
     5
     6        Reviewed by Saam Barati.
     7
     8        sizeof(RegExpObject) is 48B due to one bool flag. We should compress this flag into lower bit of RegExp* field so that we can make RegExpObject 32B.
     9        It saves memory footprint 1.3% in RAMification's regexp.
     10
     11        * dfg/DFGSpeculativeJIT.cpp:
     12        (JSC::DFG::SpeculativeJIT::compileNewRegexp):
     13        (JSC::DFG::SpeculativeJIT::compileSetRegExpObjectLastIndex):
     14        * ftl/FTLAbstractHeapRepository.h:
     15        * ftl/FTLLowerDFGToB3.cpp:
     16        (JSC::FTL::DFG::LowerDFGToB3::compileNewRegexp):
     17        (JSC::FTL::DFG::LowerDFGToB3::compileSetRegExpObjectLastIndex):
     18        * runtime/RegExpObject.cpp:
     19        (JSC::RegExpObject::RegExpObject):
     20        (JSC::RegExpObject::visitChildren):
     21        (JSC::RegExpObject::getOwnPropertySlot):
     22        (JSC::RegExpObject::defineOwnProperty):
     23        * runtime/RegExpObject.h:
     24
    1252019-03-21  Tomas Popela  <tpopela@redhat.com>
    226
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r243280 r243364  
    97919791    m_jit.storePtr(
    97929792        TrustedImmPtr(node->cellOperand()),
    9793         CCallHelpers::Address(resultGPR, RegExpObject::offsetOfRegExp()));
     9793        CCallHelpers::Address(resultGPR, RegExpObject::offsetOfRegExpAndLastIndexIsNotWritableFlag()));
    97949794    m_jit.storeValue(lastIndexRegs, CCallHelpers::Address(resultGPR, RegExpObject::offsetOfLastIndex()));
    9795     m_jit.store8(TrustedImm32(true), CCallHelpers::Address(resultGPR, RegExpObject::offsetOfLastIndexIsWritable()));
    97969795    m_jit.mutatorFence(*m_jit.vm());
    97979796
     
    1113111130        speculationCheck(
    1113211131            ExoticObjectMode, JSValueRegs(), nullptr,
    11133             m_jit.branchTest8(
    11134                 JITCompiler::Zero,
    11135                 JITCompiler::Address(regExpGPR, RegExpObject::offsetOfLastIndexIsWritable())));
     11132            m_jit.branchTestPtr(
     11133                JITCompiler::NonZero,
     11134                JITCompiler::Address(regExpGPR, RegExpObject::offsetOfRegExpAndLastIndexIsNotWritableFlag()),
     11135                JITCompiler::TrustedImm32(RegExpObject::lastIndexIsNotWritableFlag)));
    1113611136    }
    1113711137
  • trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h

    r242397 r243364  
    9797    macro(JSSymbolTableObject_symbolTable, JSSymbolTableObject::offsetOfSymbolTable()) \
    9898    macro(JSWrapperObject_internalValue, JSWrapperObject::internalValueOffset()) \
    99     macro(RegExpObject_regExp, RegExpObject::offsetOfRegExp()) \
     99    macro(RegExpObject_regExpAndLastIndexIsNotWritableFlag, RegExpObject::offsetOfRegExpAndLastIndexIsNotWritableFlag()) \
    100100    macro(RegExpObject_lastIndex, RegExpObject::offsetOfLastIndex()) \
    101     macro(RegExpObject_lastIndexIsWritable, RegExpObject::offsetOfLastIndexIsWritable()) \
    102101    macro(ShadowChicken_Packet_callee, OBJECT_OFFSETOF(ShadowChicken::Packet, callee)) \
    103102    macro(ShadowChicken_Packet_frame, OBJECT_OFFSETOF(ShadowChicken::Packet, frame)) \
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r243280 r243364  
    1129111291        auto structure = m_graph.registerStructure(m_graph.globalObjectFor(m_node->origin.semantic)->regExpStructure());
    1129211292        LValue fastResultValue = allocateObject<RegExpObject>(structure, m_out.intPtrZero, slowCase);
    11293         m_out.storePtr(frozenPointer(regexp), fastResultValue, m_heaps.RegExpObject_regExp);
     11293        m_out.storePtr(frozenPointer(regexp), fastResultValue, m_heaps.RegExpObject_regExpAndLastIndexIsNotWritableFlag);
    1129411294        m_out.store64(lastIndex, fastResultValue, m_heaps.RegExpObject_lastIndex);
    11295         m_out.store32As8(m_out.constInt32(true), m_out.address(fastResultValue, m_heaps.RegExpObject_lastIndexIsWritable));
    1129611295        mutatorFence();
    1129711296        ValueFromBlock fastResult = m_out.anchor(fastResultValue);
     
    1137911378            speculate(
    1138011379                ExoticObjectMode, noValue(), nullptr,
    11381                 m_out.isZero32(m_out.load8ZeroExt32(regExp, m_heaps.RegExpObject_lastIndexIsWritable)));
     11380                m_out.testNonZeroPtr(
     11381                    m_out.loadPtr(regExp, m_heaps.RegExpObject_regExpAndLastIndexIsNotWritableFlag),
     11382                    m_out.constIntPtr(RegExpObject::lastIndexIsNotWritableFlag)));
    1138211383
    1138311384            m_out.store64(value, regExp, m_heaps.RegExpObject_lastIndex);
  • trunk/Source/JavaScriptCore/runtime/RegExpObject.cpp

    r240593 r243364  
    3939RegExpObject::RegExpObject(VM& vm, Structure* structure, RegExp* regExp)
    4040    : JSNonFinalObject(vm, structure)
    41     , m_regExp(vm, this, regExp)
    42     , m_lastIndexIsWritable(true)
     41    , m_regExpAndLastIndexIsNotWritableFlag(bitwise_cast<uintptr_t>(regExp)) // lastIndexIsNotWritableFlag is not set.
    4342{
    4443    m_lastIndex.setWithoutWriteBarrier(jsNumber(0));
     
    5756    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    5857    Base::visitChildren(thisObject, visitor);
    59     visitor.append(thisObject->m_regExp);
     58    visitor.appendUnbarriered(thisObject->regExp());
    6059    visitor.append(thisObject->m_lastIndex);
    6160}
     
    6665    if (propertyName == vm.propertyNames->lastIndex) {
    6766        RegExpObject* regExp = jsCast<RegExpObject*>(object);
    68         unsigned attributes = regExp->m_lastIndexIsWritable ? PropertyAttribute::DontDelete | PropertyAttribute::DontEnum : PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly;
     67        unsigned attributes = regExp->lastIndexIsWritable() ? PropertyAttribute::DontDelete | PropertyAttribute::DontEnum : PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly;
    6968        slot.setValue(regExp, attributes, regExp->getLastIndex());
    7069        return true;
     
    118117        if (descriptor.isAccessorDescriptor())
    119118            return typeError(exec, scope, shouldThrow, UnconfigurablePropertyChangeAccessMechanismError);
    120         if (!regExp->m_lastIndexIsWritable) {
     119        if (!regExp->lastIndexIsWritable()) {
    121120            if (descriptor.writablePresent() && descriptor.writable())
    122121                return typeError(exec, scope, shouldThrow, UnconfigurablePropertyChangeWritabilityError);
     
    130129        }
    131130        if (descriptor.writablePresent() && !descriptor.writable())
    132             regExp->m_lastIndexIsWritable = false;
     131            regExp->setLastIndexIsNotWritable();
    133132        return true;
    134133    }
  • trunk/Source/JavaScriptCore/runtime/RegExpObject.h

    r233122 r243364  
    3333    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
    3434
     35    static constexpr uintptr_t lastIndexIsNotWritableFlag = 1;
     36
    3537    static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp)
    3638    {
     
    4749    }
    4850
    49     void setRegExp(VM& vm, RegExp* r) { m_regExp.set(vm, this, r); }
    50     RegExp* regExp() const { return m_regExp.get(); }
     51    void setRegExp(VM& vm, RegExp* regExp)
     52    {
     53        uintptr_t result = (m_regExpAndLastIndexIsNotWritableFlag & lastIndexIsNotWritableFlag) | bitwise_cast<uintptr_t>(regExp);
     54        m_regExpAndLastIndexIsNotWritableFlag = result;
     55        vm.heap.writeBarrier(this, regExp);
     56    }
     57
     58    RegExp* regExp() const
     59    {
     60        return bitwise_cast<RegExp*>(m_regExpAndLastIndexIsNotWritableFlag & (~lastIndexIsNotWritableFlag));
     61    }
    5162
    5263    bool setLastIndex(ExecState* exec, size_t lastIndex)
     
    5566        auto scope = DECLARE_THROW_SCOPE(vm);
    5667
    57         if (LIKELY(m_lastIndexIsWritable)) {
     68        if (LIKELY(lastIndexIsWritable())) {
    5869            m_lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
    5970            return true;
     
    6778        auto scope = DECLARE_THROW_SCOPE(vm);
    6879
    69         if (LIKELY(m_lastIndexIsWritable)) {
     80        if (LIKELY(lastIndexIsWritable())) {
    7081            m_lastIndex.set(vm, this, lastIndex);
    7182            return true;
    7283        }
    73 
    7484        return typeError(exec, scope, shouldThrow, ReadonlyPropertyWriteError);
    7585    }
     
    96106    }
    97107
    98     static ptrdiff_t offsetOfRegExp()
     108    static ptrdiff_t offsetOfRegExpAndLastIndexIsNotWritableFlag()
    99109    {
    100         return OBJECT_OFFSETOF(RegExpObject, m_regExp);
     110        return OBJECT_OFFSETOF(RegExpObject, m_regExpAndLastIndexIsNotWritableFlag);
    101111    }
    102112
     
    104114    {
    105115        return OBJECT_OFFSETOF(RegExpObject, m_lastIndex);
    106     }
    107 
    108     static ptrdiff_t offsetOfLastIndexIsWritable()
    109     {
    110         return OBJECT_OFFSETOF(RegExpObject, m_lastIndexIsWritable);
    111116    }
    112117
     
    123128    static void visitChildren(JSCell*, SlotVisitor&);
    124129
     130    bool lastIndexIsWritable() const
     131    {
     132        return !(m_regExpAndLastIndexIsNotWritableFlag & lastIndexIsNotWritableFlag);
     133    }
     134
     135    void setLastIndexIsNotWritable()
     136    {
     137        m_regExpAndLastIndexIsNotWritableFlag = (m_regExpAndLastIndexIsNotWritableFlag | lastIndexIsNotWritableFlag);
     138    }
     139
    125140    JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
    126141    JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     
    132147    MatchResult matchInline(ExecState*, JSGlobalObject*, JSString*);
    133148
    134     WriteBarrier<RegExp> m_regExp;
     149    uintptr_t m_regExpAndLastIndexIsNotWritableFlag { 0 };
    135150    WriteBarrier<Unknown> m_lastIndex;
    136     uint8_t m_lastIndexIsWritable;
    137151};
    138152
Note: See TracChangeset for help on using the changeset viewer.