Ignore:
Timestamp:
Oct 31, 2008, 12:59:08 PM (17 years ago)
Author:
[email protected]
Message:

2008-10-30 Geoffrey Garen <[email protected]>

Reviewed by Oliver Hunt.


Fixed a small bit of https://bugs.webkit.org/show_bug.cgi?id=21962
AST uses way too much memory


Removed a word from StatementNode by nixing LabelStack and turning it
into a compile-time data structure managed by CodeGenerator.


v8 tests and SunSpider, run by Gavin, report no change.


  • VM/CodeGenerator.cpp: (JSC::CodeGenerator::CodeGenerator): (JSC::CodeGenerator::newLabelScope): (JSC::CodeGenerator::breakTarget): (JSC::CodeGenerator::continueTarget):
  • VM/CodeGenerator.h: Nixed the JumpContext system because it depended on a LabelStack in the AST, and it was a little cumbersome on the client side. Replaced with LabelScope, which tracks all break / continue information in the CodeGenerator, just like we track LabelIDs and other stacks of compile-time data.
  • kjs/LabelScope.h: Added. (JSC::LabelScope::): (JSC::LabelScope::LabelScope): (JSC::LabelScope::ref): (JSC::LabelScope::deref): (JSC::LabelScope::refCount): (JSC::LabelScope::breakTarget): (JSC::LabelScope::continueTarget): (JSC::LabelScope::type): (JSC::LabelScope::name): (JSC::LabelScope::scopeDepth): Simple abstraction for holding everything you might want to know about a break-able / continue-able scope.
  • kjs/LabelStack.cpp: Removed.
  • kjs/LabelStack.h: Removed.
  • kjs/grammar.y: No need to push labels at parse time -- we don't store LabelStacks in the AST anymore.
  • kjs/nodes.cpp: (JSC::DoWhileNode::emitCode): (JSC::WhileNode::emitCode): (JSC::ForNode::emitCode): (JSC::ForInNode::emitCode): (JSC::ContinueNode::emitCode): (JSC::BreakNode::emitCode): (JSC::SwitchNode::emitCode): (JSC::LabelNode::emitCode):
  • kjs/nodes.h: (JSC::StatementNode::): (JSC::LabelNode::): Use LabelScope where we used to use JumpContext. Simplified a bunch of code. Touched up label-related error messages a bit.
  • kjs/nodes2string.cpp: (JSC::LabelNode::streamTo): Updated for rename.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/VM/CodeGenerator.cpp

    r37991 r38047  
    205205    , m_dynamicScopeDepth(0)
    206206    , m_codeType(GlobalCode)
    207     , m_continueDepth(0)
    208207    , m_nextGlobal(-1)
    209208    , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
     
    283282    , m_dynamicScopeDepth(0)
    284283    , m_codeType(FunctionCode)
    285     , m_continueDepth(0)
    286284    , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
    287285    , m_lastOpcodeID(op_end)
     
    354352    , m_dynamicScopeDepth(0)
    355353    , m_codeType(EvalCode)
    356     , m_continueDepth(0)
    357354    , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
    358355    , m_lastOpcodeID(op_end)
     
    450447        newRegister();
    451448    return &m_calleeRegisters.last();
     449}
     450
     451PassRefPtr<LabelScope> CodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
     452{
     453    // Reclaim free label scopes.
     454    while (m_labelScopes.size() && !m_labelScopes.last().refCount())
     455        m_labelScopes.removeLast();
     456
     457    // Allocate new label scope.
     458    LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : 0); // Only loops have continue targets.
     459    m_labelScopes.append(scope);
     460    return &m_labelScopes.last();
    452461}
    453462
     
    13571366}
    13581367
    1359 void CodeGenerator::pushJumpContext(LabelStack* labels, LabelID* continueTarget, LabelID* breakTarget, bool isValidUnlabeledBreakTarget)
    1360 {
    1361     JumpContext context = { labels, continueTarget, breakTarget, scopeDepth(), isValidUnlabeledBreakTarget };
    1362     m_jumpContextStack.append(context);
    1363     if (continueTarget)
    1364         m_continueDepth++;
    1365 }
    1366 
    1367 void CodeGenerator::popJumpContext()
    1368 {
    1369     ASSERT(m_jumpContextStack.size());
    1370     if (m_jumpContextStack.last().continueTarget)
    1371         m_continueDepth--;
    1372     m_jumpContextStack.removeLast();
    1373 }
    1374 
    1375 JumpContext* CodeGenerator::jumpContextForContinue(const Identifier& label)
    1376 {
    1377     if(!m_jumpContextStack.size())
     1368LabelScope* CodeGenerator::breakTarget(const Identifier& name)
     1369{
     1370    // Reclaim free label scopes.
     1371    while (m_labelScopes.size() && !m_labelScopes.last().refCount())
     1372        m_labelScopes.removeLast();
     1373
     1374    if (!m_labelScopes.size())
    13781375        return 0;
    13791376
    1380     if (label.isEmpty()) {
    1381         for (int i = m_jumpContextStack.size() - 1; i >= 0; i--) {
    1382             JumpContext* scope = &m_jumpContextStack[i];
    1383             if (scope->continueTarget)
     1377    // We special-case the following, which is a syntax error in Firefox:
     1378    // label:
     1379    //     break;
     1380    if (name.isEmpty()) {
     1381        for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
     1382            LabelScope* scope = &m_labelScopes[i];
     1383            if (scope->type() != LabelScope::NamedLabel) {
     1384                ASSERT(scope->breakTarget());
    13841385                return scope;
     1386            }
    13851387        }
    13861388        return 0;
    13871389    }
    13881390
    1389     for (int i = m_jumpContextStack.size() - 1; i >= 0; i--) {
    1390         JumpContext* scope = &m_jumpContextStack[i];
    1391         if (scope->labels->contains(label))
     1391    for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
     1392        LabelScope* scope = &m_labelScopes[i];
     1393        if (scope->name() && *scope->name() == name) {
     1394            ASSERT(scope->breakTarget());
    13921395            return scope;
     1396        }
    13931397    }
    13941398    return 0;
    13951399}
    13961400
    1397 JumpContext* CodeGenerator::jumpContextForBreak(const Identifier& label)
    1398 {
    1399     if(!m_jumpContextStack.size())
     1401LabelScope* CodeGenerator::continueTarget(const Identifier& name)
     1402{
     1403    // Reclaim free label scopes.
     1404    while (m_labelScopes.size() && !m_labelScopes.last().refCount())
     1405        m_labelScopes.removeLast();
     1406
     1407    if (!m_labelScopes.size())
    14001408        return 0;
    14011409
    1402     if (label.isEmpty()) {
    1403         for (int i = m_jumpContextStack.size() - 1; i >= 0; i--) {
    1404             JumpContext* scope = &m_jumpContextStack[i];
    1405             if (scope->isValidUnlabeledBreakTarget)
     1410    if (name.isEmpty()) {
     1411        for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
     1412            LabelScope* scope = &m_labelScopes[i];
     1413            if (scope->type() == LabelScope::Loop) {
     1414                ASSERT(scope->continueTarget());
    14061415                return scope;
     1416            }
    14071417        }
    14081418        return 0;
    14091419    }
    14101420
    1411     for (int i = m_jumpContextStack.size() - 1; i >= 0; i--) {
    1412         JumpContext* scope = &m_jumpContextStack[i];
    1413         if (scope->labels->contains(label))
    1414             return scope;
     1421    // Continue to the loop nested nearest to the label scope that matches
     1422    // 'name'.
     1423    LabelScope* result = 0;
     1424    for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
     1425        LabelScope* scope = &m_labelScopes[i];
     1426        if (scope->type() == LabelScope::Loop) {
     1427            ASSERT(scope->continueTarget());
     1428            result = scope;
     1429        }
     1430        if (scope->name() && *scope->name() == name)
     1431            return result; // may be 0
    14151432    }
    14161433    return 0;
Note: See TracChangeset for help on using the changeset viewer.