| Differences between
and this patch
- Source/JavaScriptCore/bytecode/CodeBlock.cpp -20 / +4 lines
Lines 2616-2647 void CodeBlock::propagateTransitions(Slo Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec1
2616
2616
2617
#if ENABLE(JIT)
2617
#if ENABLE(JIT)
2618
    if (JITCode::isJIT(jitType())) {
2618
    if (JITCode::isJIT(jitType())) {
2619
        for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) {
2619
        for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter)
2620
            StructureStubInfo& stubInfo = **iter;
2620
            allAreMarkedSoFar &= (*iter)->propagateTransitions(visitor);
2621
            if (stubInfo.cacheType != CacheType::Stub)
2622
                continue;
2623
            PolymorphicAccess* list = stubInfo.u.stub;
2624
            JSCell* origin = stubInfo.codeOrigin.codeOriginOwner();
2625
            if (origin && !Heap::isMarked(origin)) {
2626
                allAreMarkedSoFar = false;
2627
                continue;
2628
            }
2629
            for (unsigned j = list->size(); j--;) {
2630
                const AccessCase& access = list->at(j);
2631
                if (access.type() != AccessCase::Transition)
2632
                    continue;
2633
                if (Heap::isMarked(access.structure()))
2634
                    visitor.appendUnbarrieredReadOnlyPointer(access.newStructure());
2635
                else
2636
                    allAreMarkedSoFar = false;
2637
            }
2638
        }
2639
    }
2621
    }
2640
#endif // ENABLE(JIT)
2622
#endif // ENABLE(JIT)
2641
    
2623
    
2642
#if ENABLE(DFG_JIT)
2624
#if ENABLE(DFG_JIT)
2643
    if (JITCode::isOptimizingJIT(jitType())) {
2625
    if (JITCode::isOptimizingJIT(jitType())) {
2644
        DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
2626
        DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
2627
        for (auto& weakReference : dfgCommon->weakStructureReferences)
2628
            allAreMarkedSoFar &= weakReference->markIfCheap(visitor);
2645
        
2629
        
2646
        for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) {
2630
        for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) {
2647
            if (shouldMarkTransition(dfgCommon->transitions[i])) {
2631
            if (shouldMarkTransition(dfgCommon->transitions[i])) {
- Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp +29 lines
Lines 554-559 bool AccessCase::visitWeak(VM& vm) const Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp_sec1
554
    return true;
554
    return true;
555
}
555
}
556
556
557
bool AccessCase::propagateTransitions(SlotVisitor& visitor) const
558
{
559
    bool result = true;
560
    
561
    if (m_structure)
562
        result &= m_structure->markIfCheap(visitor);
563
    
564
    switch (m_type) {
565
    case Transition:
566
        if (Heap::isMarked(m_structure->previousID()))
567
            visitor.appendUnbarrieredReadOnlyPointer(m_structure.get());
568
        else
569
            result = false;
570
        break;
571
    default:
572
        break;
573
    }
574
    
575
    return result;
576
}
577
557
void AccessCase::generateWithGuard(
578
void AccessCase::generateWithGuard(
558
    AccessGenerationState& state, CCallHelpers::JumpList& fallThrough)
579
    AccessGenerationState& state, CCallHelpers::JumpList& fallThrough)
559
{
580
{
Lines 1487-1492 bool PolymorphicAccess::visitWeak(VM& vm Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp_sec2
1487
    return true;
1508
    return true;
1488
}
1509
}
1489
1510
1511
bool PolymorphicAccess::propagateTransitions(SlotVisitor& visitor) const
1512
{
1513
    bool result = true;
1514
    for (unsigned i = 0; i < size(); ++i)
1515
        result &= at(i).propagateTransitions(visitor);
1516
    return result;
1517
}
1518
1490
void PolymorphicAccess::dump(PrintStream& out) const
1519
void PolymorphicAccess::dump(PrintStream& out) const
1491
{
1520
{
1492
    out.print(RawPointer(this), ":[");
1521
    out.print(RawPointer(this), ":[");
- Source/JavaScriptCore/bytecode/PolymorphicAccess.h +5 lines
Lines 248-253 private: Source/JavaScriptCore/bytecode/PolymorphicAccess.h_sec1
248
    AccessCase();
248
    AccessCase();
249
249
250
    bool visitWeak(VM&) const;
250
    bool visitWeak(VM&) const;
251
    bool propagateTransitions(SlotVisitor&) const;
251
    
252
    
252
    // FIXME: This only exists because of how AccessCase puts post-generation things into itself.
253
    // FIXME: This only exists because of how AccessCase puts post-generation things into itself.
253
    // https://bugs.webkit.org/show_bug.cgi?id=156456
254
    // https://bugs.webkit.org/show_bug.cgi?id=156456
Lines 396-401 public: Source/JavaScriptCore/bytecode/PolymorphicAccess.h_sec2
396
397
397
    // If this returns false then we are requesting a reset of the owning StructureStubInfo.
398
    // If this returns false then we are requesting a reset of the owning StructureStubInfo.
398
    bool visitWeak(VM&) const;
399
    bool visitWeak(VM&) const;
400
    
401
    // This returns true if it has marked everything it will ever marked. This can be used as an
402
    // optimization to then avoid calling this method again during the fixpoint.
403
    bool propagateTransitions(SlotVisitor&) const;
399
404
400
    void aboutToDie();
405
    void aboutToDie();
401
406
- Source/JavaScriptCore/bytecode/StructureStubInfo.cpp -1 / +20 lines
Lines 230-236 void StructureStubInfo::visitWeakReferen Source/JavaScriptCore/bytecode/StructureStubInfo.cpp_sec1
230
{
230
{
231
    VM& vm = *codeBlock->vm();
231
    VM& vm = *codeBlock->vm();
232
    
232
    
233
    bufferedStructures.clear();
233
    bufferedStructures.genericFilter(
234
        [&] (Structure* structure) -> bool {
235
            return Heap::isMarked(structure);
236
        });
234
237
235
    switch (cacheType) {
238
    switch (cacheType) {
236
    case CacheType::GetByIdSelf:
239
    case CacheType::GetByIdSelf:
Lines 250-255 void StructureStubInfo::visitWeakReferen Source/JavaScriptCore/bytecode/StructureStubInfo.cpp_sec2
250
    resetByGC = true;
253
    resetByGC = true;
251
}
254
}
252
255
256
bool StructureStubInfo::propagateTransitions(SlotVisitor& visitor)
257
{
258
    switch (cacheType) {
259
    case CacheType::Unset:
260
        return true;
261
    case CacheType::GetByIdSelf:
262
    case CacheType::PutByIdReplace:
263
        return u.byIdSelf.baseObjectStructure->markIfCheap(visitor);
264
    case CacheType::Stub:
265
        return u.stub->propagateTransitions(visitor);
266
    }
267
    
268
    RELEASE_ASSERT_NOT_REACHED();
269
    return true;
270
}
271
253
bool StructureStubInfo::containsPC(void* pc) const
272
bool StructureStubInfo::containsPC(void* pc) const
254
{
273
{
255
    if (cacheType != CacheType::Stub)
274
    if (cacheType != CacheType::Stub)
- Source/JavaScriptCore/bytecode/StructureStubInfo.h +3 lines
Lines 81-86 public: Source/JavaScriptCore/bytecode/StructureStubInfo.h_sec1
81
    // Check if the stub has weak references that are dead. If it does, then it resets itself,
81
    // Check if the stub has weak references that are dead. If it does, then it resets itself,
82
    // either entirely or just enough to ensure that those dead pointers don't get used anymore.
82
    // either entirely or just enough to ensure that those dead pointers don't get used anymore.
83
    void visitWeakReferences(CodeBlock*);
83
    void visitWeakReferences(CodeBlock*);
84
    
85
    // This returns true if it has marked everything that it will ever mark.
86
    bool propagateTransitions(SlotVisitor&);
84
        
87
        
85
    ALWAYS_INLINE bool considerCaching(Structure* structure)
88
    ALWAYS_INLINE bool considerCaching(Structure* structure)
86
    {
89
    {
- Source/JavaScriptCore/runtime/Structure.cpp +15 lines
Lines 1135-1140 void Structure::visitChildren(JSCell* ce Source/JavaScriptCore/runtime/Structure.cpp_sec1
1135
    visitor.append(&thisObject->m_inferredTypeTable);
1135
    visitor.append(&thisObject->m_inferredTypeTable);
1136
}
1136
}
1137
1137
1138
bool Structure::isCheapDuringGC()
1139
{
1140
    return (!m_globalObject || Heap::isMarked(m_globalObject.get()))
1141
        && (!storedPrototypeObject() || Heap::isMarked(storedPrototypeObject()));
1142
}
1143
1144
bool Structure::markIfCheap(SlotVisitor& visitor)
1145
{
1146
    if (!isCheapDuringGC())
1147
        return Heap::isMarked(this);
1148
    
1149
    visitor.appendUnbarrieredReadOnlyPointer(this);
1150
    return true;
1151
}
1152
1138
bool Structure::prototypeChainMayInterceptStoreTo(VM& vm, PropertyName propertyName)
1153
bool Structure::prototypeChainMayInterceptStoreTo(VM& vm, PropertyName propertyName)
1139
{
1154
{
1140
    if (parseIndex(propertyName))
1155
    if (parseIndex(propertyName))
- Source/JavaScriptCore/runtime/Structure.h +5 lines
Lines 260-265 public: Source/JavaScriptCore/runtime/Structure.h_sec1
260
    StructureChain* prototypeChain(VM&, JSGlobalObject*) const;
260
    StructureChain* prototypeChain(VM&, JSGlobalObject*) const;
261
    StructureChain* prototypeChain(ExecState*) const;
261
    StructureChain* prototypeChain(ExecState*) const;
262
    static void visitChildren(JSCell*, SlotVisitor&);
262
    static void visitChildren(JSCell*, SlotVisitor&);
263
    
264
    bool isCheapDuringGC();
265
    
266
    // Returns true if this structure is now marked.
267
    bool markIfCheap(SlotVisitor&);
263
        
268
        
264
    // Will just the prototype chain intercept this property access?
269
    // Will just the prototype chain intercept this property access?
265
    JS_EXPORT_PRIVATE bool prototypeChainMayInterceptStoreTo(VM&, PropertyName);
270
    JS_EXPORT_PRIVATE bool prototypeChainMayInterceptStoreTo(VM&, PropertyName);

Return to Bug 157324