Ignore:
Timestamp:
Dec 28, 2008, 12:52:06 AM (16 years ago)
Author:
[email protected]
Message:

2008-12-28 Cameron Zwarich <[email protected]>

Reviewed by Oliver Hunt.

Bug 22840: REGRESSION (r38349): Gmail doesn't load with profiling enabled
<https://bugs.webkit.org/show_bug.cgi?id=22840>
<rdar://problem/6468077>

JavaScriptCore:

  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitNewArray): Add an assertion that the range of registers passed to op_new_array is sequential. (JSC::BytecodeGenerator::emitCall): Correct the relocation of registers when emitting profiler hooks so that registers aren't leaked. Also, add an assertion that the 'this' register is always ref'd (because it is), remove the needless protection of the 'this' register when relocating, and add an assertion that the range of registers passed to op_call for function call arguments is sequential. (JSC::BytecodeGenerator::emitConstruct): Correct the relocation of registers when emitting profiler hooks so that registers aren't leaked. Also, add an assertion that the range of registers passed to op_construct for function call arguments is sequential.

LayoutTests:

  • fast/profiler/call-register-leak-expected.txt: Added.
  • fast/profiler/call-register-leak.html: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r39366 r39488  
    11891189            break;
    11901190        argv.append(newTemporary());
     1191        // op_new_array requires the initial values to be a sequential range of registers
     1192        ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
    11911193        emitNode(argv.last().get(), n->value());
    11921194    }
     
    12371239    ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
    12381240    ASSERT(func->refCount());
    1239 
     1241    ASSERT(thisRegister->refCount());
     1242
     1243    RegisterID* originalFunc = func;
    12401244    if (m_shouldEmitProfileHooks) {
    12411245        // If codegen decided to recycle func as this call's destination register,
     
    12431247        // for the sake of op_profile_did_call.
    12441248        if (dst == func) {
    1245             RefPtr<RegisterID> protect = thisRegister;
    12461249            RefPtr<RegisterID> movedThisRegister = emitMove(newTemporary(), thisRegister);
    12471250            RefPtr<RegisterID> movedFunc = emitMove(thisRegister, func);
     
    12571260    for (ArgumentListNode* n = argumentsNode->m_listNode.get(); n; n = n->m_next.get()) {
    12581261        argv.append(newTemporary());
     1262        // op_call requires the arguments to be a sequential range of registers
     1263        ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
    12591264        emitNode(argv.last().get(), n);
    12601265    }
     
    12911296        instructions().append(func->index());
    12921297
    1293         if (dst == func) {
     1298        if (dst == originalFunc) {
    12941299            thisRegister->deref();
    12951300            func->deref();
     
    13221327    ASSERT(func->refCount());
    13231328
     1329    RegisterID* originalFunc = func;
    13241330    if (m_shouldEmitProfileHooks) {
    13251331        // If codegen decided to recycle func as this call's destination register,
     
    13391345    for (ArgumentListNode* n = argumentsNode ? argumentsNode->m_listNode.get() : 0; n; n = n->m_next.get()) {
    13401346        argv.append(newTemporary());
     1347        // op_construct requires the arguments to be a sequential range of registers
     1348        ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
    13411349        emitNode(argv.last().get(), n);
    13421350    }
     
    13791387        instructions().append(func->index());
    13801388       
    1381         if (dst == func)
     1389        if (dst == originalFunc)
    13821390            func->deref();
    13831391    }
Note: See TracChangeset for help on using the changeset viewer.