Ignore:
Timestamp:
Nov 22, 2002, 1:04:55 AM (23 years ago)
Author:
darin
Message:

JavaScriptCore:

  • change ScopeChain to be a singly linked list shares tails, gives 11% gain on iBench
  • kjs/context.h: (ContextImp::pushScope): Make inline, use push instead of prepend, and pass imp pointer. (ContextImp::popScope): Make inline, use pop instead of removeFirst.
  • kjs/function.cpp: (DeclaredFunctionImp::DeclaredFunctionImp): No need to copy.
  • kjs/function_object.cpp: (FunctionObjectImp::construct): Use push instead of prepend, and pass imp pointer.
  • kjs/internal.cpp: (ContextImp::ContextImp): Use clear, push instead of prepend, and pass imp pointers.
  • kjs/nodes.cpp: (ResolveNode::evaluateReference): Use isEmpty, pop, and top instead of ScopeChainIterator.
  • kjs/object.h: Change _scope to be a NoRefScopeChain.
  • kjs/object.cpp: No need to initialize _scope any more, since it's not a NoRefScopeChain.
  • kjs/scope_chain.h: Rewrite, different implementation and interface.
  • kjs/scope_chain.cpp: More of the same.

WebCore:

  • khtml/ecma/kjs_dom.cpp: (DOMNode::pushEventHandlerScope): Change to push handlers on an existing scope chain rather than returning one. Name change too.
  • khtml/ecma/kjs_dom.h: More of the same.
  • khtml/ecma/kjs_html.cpp: (KJS::HTMLElement::pushEventHandlerScope): And here.
  • khtml/ecma/kjs_html.h: And here.
  • khtml/ecma/kjs_events.cpp: (JSEventListener::handleEvent): Use the pushEventHandlerScope function, and also don't worry about optimizing the "no change" case, because that already works pretty efficiently.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/scope_chain.cpp

    r2821 r2824  
    1 // -*- c-basic-offset: 2 -*-
    21/*
    32 *  This file is part of the KDE libraries
    4  *  Copyright (C) 1999-2001 Harri Porten ([email protected])
    5  *  Copyright (C) 2001 Peter Kelly ([email protected])
     3 *  Copyright (C) 2002 Apple Computer, Inc.
    64 *
    75 *  This library is free software; you can redistribute it and/or
     
    2422#include "scope_chain.h"
    2523
     24#include "object.h"
     25
    2626namespace KJS {
    2727
    28   struct ScopeChainNode {
    29     ScopeChainNode(const Value &val, ScopeChainNode *p, ScopeChainNode *n)
    30       : member(val.imp()), prev(p), next(n) { }
    31     ScopeChainNode(ValueImp *val, ScopeChainNode *p, ScopeChainNode *n)
    32       : member(val), prev(p), next(n) { }
    33     ValueImp *member;
    34     ScopeChainNode *prev, *next;
    35   };
    36 
    37   struct ScopeChainHookNode : public ScopeChainNode {
    38     ScopeChainHookNode(bool needsMarking) : ScopeChainNode(Value(), this, this),
    39         listRefCount(1), nodesRefCount(needsMarking ? 0 : 1) { }
    40     int listRefCount;
    41     int nodesRefCount;
    42   };
    43 
    44 // ------------------------------ ScopeChainIterator ---------------------------------
    45 
    46 ValueImp* ScopeChainIterator::operator->() const
     28ScopeChainNode::ScopeChainNode(ScopeChainNode *n, ObjectImp *o)
     29    : next(n), object(o), nodeAndObjectRefCount(1), nodeOnlyRefCount(0)
    4730{
    48   return node->member;
     31    o->ref();
    4932}
    5033
    51 Value ScopeChainIterator::operator*() const
     34inline void ScopeChain::ref() const
    5235{
    53   return Value(node->member);
     36    for (ScopeChainNode *n = _node; n; n = n->next) {
     37        if (n->nodeAndObjectRefCount++ != 0)
     38            break;
     39        n->object->ref();
     40    }
    5441}
    5542
    56 Value ScopeChainIterator::operator++()
     43ScopeChain::ScopeChain(const NoRefScopeChain &c)
     44    : _node(c._node)
    5745{
    58   node = node->next;
    59   return Value(node->member);
     46    ref();
    6047}
    6148
    62 Value ScopeChainIterator::operator++(int)
     49ScopeChain &ScopeChain::operator=(const ScopeChain &c)
    6350{
    64   const ScopeChainNode *n = node;
    65   ++*this;
    66   return Value(n->member);
     51    c.ref();
     52    deref();
     53    _node = c._node;
     54    return *this;
    6755}
    6856
    69 // ------------------------------ ScopeChain -----------------------------------------
    70 
    71 ScopeChain::ScopeChain(bool needsMarking) : hook(new ScopeChainHookNode(needsMarking)), m_needsMarking(needsMarking)
     57void ScopeChain::push(ObjectImp *o)
    7258{
     59    _node = new ScopeChainNode(_node, o);
    7360}
    7461
    75 ScopeChain::ScopeChain(const ScopeChain& l) : hook(l.hook), m_needsMarking(false)
     62void ScopeChain::pop()
    7663{
    77   ++hook->listRefCount;
    78   if (hook->nodesRefCount++ == 0)
    79     refAll();
     64    ScopeChainNode *oldNode = _node;
     65    assert(oldNode);
     66    ScopeChainNode *newNode = oldNode->next;
     67    _node = newNode;
     68   
     69    // Three cases:
     70    //   1) This was not the last reference of the old node.
     71    //      In this case we move our ref from the old to the new node.
     72    //   2) This was the last reference of the old node, but there are garbage collected references.
     73    //      In this case, the new node doesn't get any new ref, and the object is deref'd.
     74    //   3) This was the last reference of the old node.
     75    //      In this case the object is deref'd and the entire node goes.
     76    if (--oldNode->nodeAndObjectRefCount != 0) {
     77        if (newNode)
     78            ++newNode->nodeAndObjectRefCount;
     79    } else {
     80        oldNode->object->deref();
     81        if (oldNode->nodeOnlyRefCount == 0)
     82            delete oldNode;
     83    }
    8084}
    8185
    82 ScopeChain& ScopeChain::operator=(const ScopeChain& l)
     86void ScopeChain::release()
    8387{
    84   ScopeChain(l).swap(*this);
    85   return *this;
     88    ScopeChainNode *n = _node;
     89    do {
     90        ScopeChainNode *next = n->next;
     91        n->object->deref();
     92        if (n->nodeOnlyRefCount == 0)
     93            delete n;
     94        n = next;
     95    } while (n && --n->nodeAndObjectRefCount == 0);
    8696}
    8797
    88 ScopeChain::~ScopeChain()
     98inline void NoRefScopeChain::ref() const
    8999{
    90   if (!m_needsMarking)
    91     if (--hook->nodesRefCount == 0)
    92       derefAll();
    93  
    94   if (--hook->listRefCount == 0) {
    95     assert(hook->nodesRefCount == 0);
    96     clearInternal();
    97     delete hook;
    98   }
     100    for (ScopeChainNode *n = _node; n; n = n->next)
     101        if (n->nodeOnlyRefCount++ != 0)
     102            break;
    99103}
    100104
    101 void ScopeChain::mark() const
     105NoRefScopeChain &NoRefScopeChain::operator=(const ScopeChain &c)
    102106{
    103   ScopeChainNode *n = hook->next;
    104   while (n != hook) {
    105     if (!n->member->marked())
    106       n->member->mark();
    107     n = n->next;
    108   }
     107    c.ref();
     108    deref();
     109    _node = c._node;
     110    return *this;
    109111}
    110112
    111 void ScopeChain::append(const Value& val)
     113void NoRefScopeChain::mark()
    112114{
    113   ScopeChainNode *n = new ScopeChainNode(val, hook->prev, hook);
    114   if (hook->nodesRefCount)
    115     n->member->ref();
    116   hook->prev->next = n;
    117   hook->prev = n;
     115    for (ScopeChainNode *n = _node; n; n = n->next) {
     116        ObjectImp *o = n->object;
     117        if (!o->marked())
     118            o->mark();
     119    }
    118120}
    119121
    120 void ScopeChain::prepend(const Value& val)
     122void NoRefScopeChain::release()
    121123{
    122   ScopeChainNode *n = new ScopeChainNode(val, hook, hook->next);
    123   if (hook->nodesRefCount)
    124     n->member->ref();
    125   hook->next->prev = n;
    126   hook->next = n;
    127 }
    128 
    129 void ScopeChain::prepend(ValueImp *val)
    130 {
    131   ScopeChainNode *n = new ScopeChainNode(val, hook, hook->next);
    132   if (hook->nodesRefCount)
    133     n->member->ref();
    134   hook->next->prev = n;
    135   hook->next = n;
    136 }
    137 
    138 void ScopeChain::prependList(const ScopeChain& lst)
    139 {
    140   ScopeChainNode *otherHook = lst.hook;
    141   ScopeChainNode *n = otherHook->prev;
    142   while (n != otherHook) {
    143     prepend(n->member);
    144     n = n->prev;
    145   }
    146 }
    147 
    148 void ScopeChain::removeFirst()
    149 {
    150   erase(hook->next);
    151 }
    152 
    153 void ScopeChain::clearInternal()
    154 {
    155   ScopeChainNode *n = hook->next;
    156   while (n != hook) {
    157     n = n->next;
    158     delete n->prev;
    159   }
    160 
    161   hook->next = hook;
    162   hook->prev = hook;
    163 }
    164 
    165 ScopeChain ScopeChain::copy() const
    166 {
    167   ScopeChain newScopeChain;
    168   newScopeChain.prependList(*this);
    169   return newScopeChain;
    170 }
    171 
    172 ScopeChainIterator ScopeChain::begin() const
    173 {
    174   return ScopeChainIterator(hook->next);
    175 }
    176 
    177 ScopeChainIterator ScopeChain::end() const
    178 {
    179   return ScopeChainIterator(hook);
    180 }
    181 
    182 void ScopeChain::erase(ScopeChainNode *n)
    183 {
    184   if (n != hook) {
    185     if (hook->nodesRefCount)
    186       n->member->deref();
    187     n->next->prev = n->prev;
    188     n->prev->next = n->next;
    189     delete n;
    190   }
    191 }
    192 
    193 void ScopeChain::refAll() const
    194 {
    195   for (ScopeChainNode *n = hook->next; n != hook; n = n->next)
    196     n->member->ref();
    197 }
    198 
    199 void ScopeChain::derefAll() const
    200 {
    201   for (ScopeChainNode *n = hook->next; n != hook; n = n->next)
    202     n->member->deref();
    203 }
    204 
    205 void ScopeChain::swap(ScopeChain &other)
    206 {
    207   if (!m_needsMarking)
    208     if (other.hook->nodesRefCount++ == 0)
    209       other.refAll();
    210   if (!other.m_needsMarking)
    211     if (hook->nodesRefCount++ == 0)
    212       refAll();
    213 
    214   if (!m_needsMarking)
    215     if (--hook->nodesRefCount == 0)
    216       derefAll();
    217   if (!other.m_needsMarking)
    218     if (--other.hook->nodesRefCount == 0)
    219       other.derefAll();
    220 
    221   ScopeChainHookNode *tmp = hook;
    222   hook = other.hook;
    223   other.hook = tmp;
    224 }
    225 
    226 bool ScopeChain::isEmpty() const
    227 {
    228     return hook->next == hook;
     124    ScopeChainNode *n = _node;
     125    do {
     126        ScopeChainNode *next = n->next;
     127        if (n->nodeAndObjectRefCount == 0)
     128            delete n;
     129        n = next;
     130    } while (n && --n->nodeOnlyRefCount == 0);
    229131}
    230132
Note: See TracChangeset for help on using the changeset viewer.