Changeset 29425 in webkit


Ignore:
Timestamp:
Jan 11, 2008 6:08:50 PM (16 years ago)
Author:
mjs@apple.com
Message:

JavaScriptCore:

Reviewed by Maciej.

Optimized ActivationImp allocation, so that activation records are now
first allocated on an explicitly managed stack and only heap allocated
when necessary. Roughly a 5% improvement on SunSpider, and a larger
improvement on benchmarks that use more function calls.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • kjs/Activation.h: Added. (KJS::ActivationImp::ActivationData::ActivationData): (KJS::ActivationImp::ActivationImp): (KJS::ActivationImp::classInfo): (KJS::ActivationImp::isActivationObject): (KJS::ActivationImp::isOnStack): (KJS::ActivationImp::d): (KJS::StackActivation::StackActivation):
  • kjs/ExecState.cpp: (KJS::ExecState::ExecState): (KJS::ExecState::~ExecState):
  • kjs/ExecState.h: (KJS::ExecState::replaceScopeChainTop): (KJS::ExecState::setActivationObject): (KJS::ExecState::setLocalStorage):
  • kjs/JSGlobalObject.cpp: (KJS::JSGlobalObject::reset): (KJS::JSGlobalObject::pushActivation): (KJS::JSGlobalObject::checkActivationCount): (KJS::JSGlobalObject::popActivationHelper): (KJS::JSGlobalObject::popActivation): (KJS::JSGlobalObject::tearOffActivation):
  • kjs/JSGlobalObject.h:
  • kjs/JSVariableObject.h: (KJS::JSVariableObject::JSVariableObjectData::JSVariableObjectData): (KJS::JSVariableObject::JSVariableObject):
  • kjs/function.cpp: (KJS::FunctionImp::argumentsGetter): (KJS::ActivationImp::ActivationImp): (KJS::ActivationImp::~ActivationImp): (KJS::ActivationImp::init): (KJS::ActivationImp::getOwnPropertySlot): (KJS::ActivationImp::markHelper): (KJS::ActivationImp::mark): (KJS::ActivationImp::ActivationData::ActivationData): (KJS::GlobalFuncImp::callAsFunction):
  • kjs/function.h:
  • kjs/nodes.cpp: (KJS::PostIncResolveNode::evaluate): (KJS::PostDecResolveNode::evaluate): (KJS::PreIncResolveNode::evaluate): (KJS::PreDecResolveNode::evaluate): (KJS::ReadModifyResolveNode::evaluate): (KJS::AssignResolveNode::evaluate): (KJS::WithNode::execute): (KJS::TryNode::execute): (KJS::FunctionBodyNode::processDeclarations): (KJS::FuncExprNode::evaluate):
  • kjs/object.h:
  • kjs/scope_chain.h: (KJS::ScopeChain::replace):
  • kjs/scope_chain_mark.h: Added. (KJS::ScopeChain::mark):

WebCore:

Reviewed by Maciej.

Added a new forwarding header, because Activation.h has been separated
from function.h

  • ForwardingHeaders/kjs/Activation.h: Added.

LayoutTests:

Reviewed by Maciej.

Added a test case that came up when developing the ActivationImp tear-off.

  • fast/js/resources/vardecl-preserve-arguments.js:
  • fast/js/vardecl-preserve-arguments-expected.txt:
Location:
trunk
Files:
3 added
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r29402 r29425  
     12008-01-11  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
     2
     3        Reviewed by Maciej.
     4
     5        Optimized ActivationImp allocation, so that activation records are now
     6        first allocated on an explicitly managed stack and only heap allocated
     7        when necessary. Roughly a 5% improvement on SunSpider, and a larger
     8        improvement on benchmarks that use more function calls.
     9
     10        * JavaScriptCore.xcodeproj/project.pbxproj:
     11        * kjs/Activation.h: Added.
     12        (KJS::ActivationImp::ActivationData::ActivationData):
     13        (KJS::ActivationImp::ActivationImp):
     14        (KJS::ActivationImp::classInfo):
     15        (KJS::ActivationImp::isActivationObject):
     16        (KJS::ActivationImp::isOnStack):
     17        (KJS::ActivationImp::d):
     18        (KJS::StackActivation::StackActivation):
     19        * kjs/ExecState.cpp:
     20        (KJS::ExecState::ExecState):
     21        (KJS::ExecState::~ExecState):
     22        * kjs/ExecState.h:
     23        (KJS::ExecState::replaceScopeChainTop):
     24        (KJS::ExecState::setActivationObject):
     25        (KJS::ExecState::setLocalStorage):
     26        * kjs/JSGlobalObject.cpp:
     27        (KJS::JSGlobalObject::reset):
     28        (KJS::JSGlobalObject::pushActivation):
     29        (KJS::JSGlobalObject::checkActivationCount):
     30        (KJS::JSGlobalObject::popActivationHelper):
     31        (KJS::JSGlobalObject::popActivation):
     32        (KJS::JSGlobalObject::tearOffActivation):
     33        * kjs/JSGlobalObject.h:
     34        * kjs/JSVariableObject.h:
     35        (KJS::JSVariableObject::JSVariableObjectData::JSVariableObjectData):
     36        (KJS::JSVariableObject::JSVariableObject):
     37        * kjs/function.cpp:
     38        (KJS::FunctionImp::argumentsGetter):
     39        (KJS::ActivationImp::ActivationImp):
     40        (KJS::ActivationImp::~ActivationImp):
     41        (KJS::ActivationImp::init):
     42        (KJS::ActivationImp::getOwnPropertySlot):
     43        (KJS::ActivationImp::markHelper):
     44        (KJS::ActivationImp::mark):
     45        (KJS::ActivationImp::ActivationData::ActivationData):
     46        (KJS::GlobalFuncImp::callAsFunction):
     47        * kjs/function.h:
     48        * kjs/nodes.cpp:
     49        (KJS::PostIncResolveNode::evaluate):
     50        (KJS::PostDecResolveNode::evaluate):
     51        (KJS::PreIncResolveNode::evaluate):
     52        (KJS::PreDecResolveNode::evaluate):
     53        (KJS::ReadModifyResolveNode::evaluate):
     54        (KJS::AssignResolveNode::evaluate):
     55        (KJS::WithNode::execute):
     56        (KJS::TryNode::execute):
     57        (KJS::FunctionBodyNode::processDeclarations):
     58        (KJS::FuncExprNode::evaluate):
     59        * kjs/object.h:
     60        * kjs/scope_chain.h:
     61        (KJS::ScopeChain::replace):
     62        * kjs/scope_chain_mark.h: Added.
     63        (KJS::ScopeChain::mark):
     64
    1652008-01-11  Simon Hausmann  <hausmann@webkit.org>
    266
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r29381 r29425  
    532532                70B16A260569A10900DB756D /* runtime_object.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; name = runtime_object.cpp; path = bindings/runtime_object.cpp; sourceTree = "<group>"; tabWidth = 8; };
    533533                70B16A270569A10900DB756D /* runtime_object.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = runtime_object.h; path = bindings/runtime_object.h; sourceTree = "<group>"; tabWidth = 8; };
     534                7E2C6C950D31C6AB002D44E2 /* Activation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Activation.h; path = kjs/Activation.h; sourceTree = "<group>"; };
     535                7E2C6C980D31C6B6002D44E2 /* scope_chain_mark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = scope_chain_mark.h; path = kjs/scope_chain_mark.h; sourceTree = "<group>"; };
    534536                84ABF1DE070B628C00A3AC05 /* npruntime_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = npruntime_impl.h; path = bindings/npruntime_impl.h; sourceTree = "<group>"; tabWidth = 8; };
    535537                9303F567099118FA00AD71B8 /* OwnPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnPtr.h; sourceTree = "<group>"; };
     
    689691                        isa = PBXGroup;
    690692                        children = (
     693                                7E2C6C980D31C6B6002D44E2 /* scope_chain_mark.h */,
     694                                7E2C6C950D31C6AB002D44E2 /* Activation.h */,
    691695                                937B63CC09E766D200A671DD /* DerivedSources.make */,
    692696                                14B8ECA60A5653980062BE54 /* JavaScriptCore.exp */,
  • trunk/JavaScriptCore/kjs/ExecState.cpp

    r29067 r29425  
    2626#include "ExecState.h"
    2727
     28#include "Activation.h"
    2829#include "JSGlobalObject.h"
    2930#include "function.h"
    3031#include "internal.h"
     32#include "scope_chain_mark.h"
    3133
    3234namespace KJS {
     
    106108    , m_codeType(FunctionCode)
    107109{
    108     ActivationImp* activation = new ActivationImp(this);
     110    ActivationImp* activation = globalObject->pushActivation(this);
    109111    m_activation = activation;
    110112    m_localStorage = &activation->localStorage();
     
    116118ExecState::~ExecState()
    117119{
     120    if (m_codeType == FunctionCode && m_activation->needsPop())
     121        m_globalObject->popActivation();
     122   
    118123    m_globalObject->setCurrentExec(m_savedExec);
    119124}
  • trunk/JavaScriptCore/kjs/ExecState.h

    r29067 r29425  
    7878       
    7979        const ScopeChain& scopeChain() const { return m_scopeChain; }
     80        void replaceScopeChainTop(JSObject* o) { m_scopeChain.replaceTop(o); }
    8081       
    8182        JSVariableObject* variableObject() const { return m_variableObject; }
     
    8889       
    8990        ActivationImp* activationObject() { return m_activation; }
     91        void setActivationObject(ActivationImp* a) { m_activation = a; }
    9092        CodeType codeType() { return m_codeType; }
    9193        ScopeNode* scopeNode() { return m_scopeNode; }
     
    113115
    114116        LocalStorage& localStorage() { return *m_localStorage; }
     117        void setLocalStorage(LocalStorage* s) { m_localStorage = s; }
    115118
    116119        // These are only valid right after calling execute().
  • trunk/JavaScriptCore/kjs/JSGlobalObject.cpp

    r29091 r29425  
    11/*
    22 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
     3 * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca)
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    3031#include "JSGlobalObject.h"
    3132
    32 #include "SavedBuiltins.h"
     33#include "Activation.h"
    3334#include "array_object.h"
    3435#include "bool_object.h"
     
    4142#include "object_object.h"
    4243#include "regexp_object.h"
     44#include "SavedBuiltins.h"
    4345#include "string_object.h"
    4446
     
    201203    ExecState* exec = &d()->globalExec;
    202204
     205    d()->activations = new ActivationStackNode;
     206    d()->activationCount = 0;
     207
    203208    // Prototypes
    204209    d()->functionPrototype = new FunctionPrototype(exec);
     
    495500}
    496501
     502ActivationImp* JSGlobalObject::pushActivation(ExecState* exec)
     503{
     504    if (d()->activationCount == activationStackNodeSize) {
     505        ActivationStackNode* newNode = new ActivationStackNode;
     506        newNode->prev = d()->activations;
     507        d()->activations = newNode;
     508        d()->activationCount = 0;
     509    }
     510   
     511    StackActivation* stackEntry = &d()->activations->data[d()->activationCount++];
     512    stackEntry->activationStorage.init(exec);
     513   
     514    return &(stackEntry->activationStorage);
     515}
     516
     517inline void JSGlobalObject::checkActivationCount()
     518{
     519    if (!d()->activationCount) {
     520        ActivationStackNode* prev = d()->activations->prev;
     521        delete d()->activations;
     522        d()->activations = prev;
     523        d()->activationCount = activationStackNodeSize;
     524    }
     525}
     526
     527void JSGlobalObject::popActivation()
     528{
     529    checkActivationCount();
     530    d()->activations->data[--d()->activationCount].activationDataStorage.localStorage.shrink(0);   
     531}
     532
     533void JSGlobalObject::tearOffActivation(ExecState* exec, bool leaveRelic)
     534{
     535    if (exec->codeType() == FunctionCode && static_cast<ActivationImp*>(exec->activationObject())->isOnStack()) {
     536        ActivationImp* oldActivation = static_cast<ActivationImp*>(exec->activationObject());
     537        ActivationImp* newActivation = new ActivationImp(*oldActivation->d(), leaveRelic);
     538       
     539        if (!leaveRelic) {
     540            checkActivationCount();
     541            d()->activationCount--;
     542        }
     543       
     544        oldActivation->d()->localStorage.shrink(0);
     545       
     546        exec->setActivationObject(newActivation);
     547        exec->setVariableObject(newActivation);
     548        exec->setLocalStorage(&(newActivation->localStorage()));
     549        exec->replaceScopeChainTop(newActivation);
     550    }
     551}
     552
    497553} // namespace KJS
  • trunk/JavaScriptCore/kjs/JSGlobalObject.h

    r28884 r29425  
    2828namespace KJS {
    2929
     30    class ActivationImp;
     31    class ActivationStackNode;
    3032    class ArrayObjectImp;
    3133    class ArrayPrototype;
     
    129131
    130132            SymbolTable inlineSymbolTable;
     133
     134            ActivationStackNode* activations;
     135            size_t activationCount;
    131136        };
    132137
     
    228233        virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
    229234
     235        ActivationImp* pushActivation(ExecState*);
     236        void popActivation();
     237        void tearOffActivation(ExecState*, bool markAsRelic = false);
     238
    230239    private:
    231240        void init();
     
    236245        void resetTimeoutCheck();
    237246
     247        void checkActivationCount();
     248
    238249        static JSGlobalObject* s_head;
    239250    };
  • trunk/JavaScriptCore/kjs/JSVariableObject.h

    r28884 r29425  
    5757        // size of a JSCell).
    5858        struct JSVariableObjectData {
     59            JSVariableObjectData() { }
     60
    5961            JSVariableObjectData(SymbolTable* s)
    6062                : symbolTable(s) // Subclass owns this pointer.
     
    6668
    6769        };
     70
     71        JSVariableObject() { }
    6872
    6973        JSVariableObject(JSVariableObjectData* data)
  • trunk/JavaScriptCore/kjs/function.cpp

    r29067 r29425  
    2727#include "function.h"
    2828
     29#include "Activation.h"
    2930#include "ExecState.h"
    3031#include "JSGlobalObject.h"
     
    8586{
    8687  FunctionImp* thisObj = static_cast<FunctionImp*>(slot.slotBase());
    87   ExecState* e = exec;
    88   while (e) {
    89     if (e->function() == thisObj)
     88 
     89  for (ExecState* e = exec; e; e = e->callingExecState())
     90    if (e->function() == thisObj) {
     91      e->dynamicGlobalObject()->tearOffActivation(e, e == exec);
    9092      return e->activationObject()->get(exec, propertyName);
    91     e = e->callingExecState();
    92   }
     93    }
     94 
    9395  return jsNull();
    9496}
     
    341343const ClassInfo ActivationImp::info = { "Activation", 0, 0 };
    342344
     345ActivationImp::ActivationImp(const ActivationData& oldData, bool leaveRelic)
     346{
     347    JSVariableObject::d = new ActivationData(oldData);
     348    d()->leftRelic = leaveRelic;
     349}
     350
     351ActivationImp::~ActivationImp()
     352{
     353    if (!d()->isOnStack)
     354        delete d();
     355}
     356
     357void ActivationImp::init(ExecState* exec)
     358{
     359    d()->symbolTable = &exec->function()->body->symbolTable();
     360    d()->exec = exec;
     361    d()->function = exec->function();
     362    d()->argumentsObject = 0;
     363}
     364
    343365JSValue* ActivationImp::argumentsGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot& slot)
    344366{
     
    368390    // Only return the built-in arguments object if it wasn't overridden above.
    369391    if (propertyName == exec->propertyNames().arguments) {
     392        for (ExecState* e = exec; e; e = e->callingExecState())
     393            if (e->function() == d()->function) {
     394                e->dynamicGlobalObject()->tearOffActivation(e, e == exec);
     395                ActivationImp* newActivation = e->activationObject();
     396                slot.setCustom(newActivation, newActivation->getArgumentsGetter());
     397                return true;
     398            }
     399       
    370400        slot.setCustom(this, getArgumentsGetter());
    371401        return true;
     
    399429}
    400430
    401 void ActivationImp::mark()
    402 {
    403     JSVariableObject::mark();
     431void ActivationImp::markChildren()
     432{
     433    LocalStorage& localStorage = d()->localStorage;
     434    size_t size = localStorage.size();
     435   
     436    for (size_t i = 0; i < size; ++i) {
     437        JSValue* value = localStorage[i].value;
     438       
     439        if (!value->marked())
     440            value->mark();
     441    }
    404442   
    405443    if (!d()->function->marked())
    406444        d()->function->mark();
    407 
     445   
    408446    if (d()->argumentsObject && !d()->argumentsObject->marked())
    409         d()->argumentsObject->mark();
     447        d()->argumentsObject->mark();   
     448}
     449
     450void ActivationImp::mark()
     451{
     452    JSObject::mark();
     453    markChildren();
    410454}
    411455
     
    416460    // call instead of storing the list ourselves.
    417461    d()->argumentsObject = new Arguments(exec, d()->exec->function(), *d()->exec->arguments(), this);
     462}
     463
     464ActivationImp::ActivationData::ActivationData(const ActivationData& old)
     465    : JSVariableObjectData(old)
     466    , exec(old.exec)
     467    , function(old.function)
     468    , argumentsObject(old.argumentsObject)
     469    , isOnStack(false)
     470{
    418471}
    419472
     
    697750
    698751        // enter a new execution context
     752        if (!switchGlobal)
     753            exec->dynamicGlobalObject()->tearOffActivation(exec);
     754       
    699755        JSGlobalObject* globalObject = switchGlobal ? static_cast<JSGlobalObject*>(thisObj) : exec->dynamicGlobalObject();
    700756        ExecState newExec(globalObject, evalNode.get(), exec);
  • trunk/JavaScriptCore/kjs/function.h

    r28907 r29425  
    3737  class FunctionBodyNode;
    3838  class FunctionPrototype;
     39  class JSGlobalObject;
    3940
    4041  class InternalFunctionImp : public JSObject {
     
    138139  };
    139140
    140   class ActivationImp : public JSVariableObject {
    141   private:
    142     using JSVariableObject::JSVariableObjectData;
    143 
    144     struct ActivationImpData : public JSVariableObjectData {
    145         ActivationImpData(ExecState* e)
    146             : JSVariableObjectData(&e->function()->body->symbolTable())
    147             , exec(e)
    148             , function(e->function()) // Store this pointer for marking, to keep our symbol table / scope alive after exec has gone out of scope.
    149             , argumentsObject(0)
    150         {
    151         }
    152 
    153         ExecState* exec;
    154         FunctionImp* function;
    155         Arguments* argumentsObject;
    156     };
    157 
    158   public:
    159     ActivationImp(ExecState* exec)
    160         : JSVariableObject(new ActivationImpData(exec))
    161     {
    162     }
    163 
    164     virtual ~ActivationImp()
    165     {
    166         delete d();
    167     }
    168 
    169     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    170     virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, int attr = None);
    171     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    172 
    173     virtual const ClassInfo* classInfo() const { return &info; }
    174     static const ClassInfo info;
    175 
    176     virtual void mark();
    177 
    178     virtual bool isActivationObject() { return true; }
    179 
    180   private:
    181     static PropertySlot::GetValueFunc getArgumentsGetter();
    182     static JSValue* argumentsGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot);
    183     void createArgumentsObject(ExecState*);
    184     ActivationImpData* d() { return static_cast<ActivationImpData*>(JSVariableObject::d); }
    185   };
    186 
    187141  class GlobalFuncImp : public InternalFunctionImp {
    188142  public:
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r29109 r29425  
    12821282
    12831283  PropertySlot slot;
    1284   JSObject *base;
    12851284  do {
    1286     base = *iter;
    1287     if (base->getPropertySlot(exec, m_ident, slot)) {
     1285    if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
     1286        // See the comment in PostIncResolveNode::evaluate().
     1287       
     1288        JSObject* base = *iter;
    12881289        JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
    12891290        base->put(exec, m_ident, jsNumber(v->toNumber(exec) + 1));
     
    13391340
    13401341  PropertySlot slot;
    1341   JSObject *base;
    13421342  do {
    1343     base = *iter;
    1344     if (base->getPropertySlot(exec, m_ident, slot)) {
     1343    if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
     1344        // See the comment in PostIncResolveNode::evaluate().
     1345       
     1346        JSObject* base = *iter;
    13451347        JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
    13461348        base->put(exec, m_ident, jsNumber(v->toNumber(exec) - 1));
     
    17521754
    17531755  PropertySlot slot;
    1754   JSObject *base;
    17551756  do {
    1756     base = *iter;
    1757     if (base->getPropertySlot(exec, m_ident, slot)) {
     1757    if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
     1758        // See the comment in PostIncResolveNode::evaluate().
     1759       
     1760        JSObject* base = *iter;
    17581761        JSValue *v = slot.getValue(exec, base, m_ident);
    17591762
     
    17991802
    18001803  PropertySlot slot;
    1801   JSObject *base;
    18021804  do {
    1803     base = *iter;
    1804     if (base->getPropertySlot(exec, m_ident, slot)) {
     1805    if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
     1806        // See the comment in PostIncResolveNode::evaluate().
     1807       
     1808        JSObject* base = *iter;
    18051809        JSValue *v = slot.getValue(exec, base, m_ident);
    18061810
     
    32293233  do {
    32303234    base = *iter;
    3231     if (base->getPropertySlot(exec, m_ident, slot))
     3235    if (base->getPropertySlot(exec, m_ident, slot)) {
     3236      // See the comment in PostIncResolveNode::evaluate().
     3237     
     3238      base = *iter;
    32323239      goto found;
     3240    }
    32333241
    32343242    ++iter;
     
    32663274  do {
    32673275    base = *iter;
    3268     if (base->getPropertySlot(exec, m_ident, slot))
     3276    if (base->getPropertySlot(exec, m_ident, slot)) {
     3277      // See the comment in PostIncResolveNode::evaluate().
     3278     
     3279      base = *iter;
    32693280      goto found;
     3281    }
    32703282
    32713283    ++iter;
     
    39984010  JSObject *o = v->toObject(exec);
    39994011  KJS_CHECKEXCEPTION
     4012  exec->dynamicGlobalObject()->tearOffActivation(exec);
    40004013  exec->pushScope(o);
    40014014  JSValue* value = statement->execute(exec);
     
    41964209    JSObject* obj = new JSObject;
    41974210    obj->put(exec, exceptionIdent, result, DontDelete);
     4211    exec->dynamicGlobalObject()->tearOffActivation(exec);
    41984212    exec->pushScope(obj);
    41994213    result = catchBlock->execute(exec);
     
    43584372    }
    43594373
     4374    if (m_functionStack.size() != 0)
     4375      exec->dynamicGlobalObject()->tearOffActivation(exec);
     4376
    43604377    LocalStorage& localStorage = exec->variableObject()->localStorage();
    43614378   
     
    45704587JSValue *FuncExprNode::evaluate(ExecState *exec)
    45714588{
     4589  exec->dynamicGlobalObject()->tearOffActivation(exec);
     4590 
    45724591  bool named = !ident.isNull();
    45734592  JSObject *functionScopeObject = 0;
  • trunk/JavaScriptCore/kjs/object.h

    r29068 r29425  
    581581}
    582582
    583 
    584 // FIXME: Put this function in a separate file named something like scope_chain_mark.h -- can't put it in scope_chain.h since it depends on JSObject.
    585 
    586 inline void ScopeChain::mark()
    587 {
    588     for (ScopeChainNode *n = _node; n; n = n->next) {
    589         JSObject *o = n->object;
    590         if (!o->marked())
    591             o->mark();
    592     }
    593 }
    594 
    595583inline void ScopeChain::release()
    596584{
  • trunk/JavaScriptCore/kjs/scope_chain.h

    r29068 r29425  
    8181        void push(JSObject *);
    8282        void push(const ScopeChain &);
     83        void replaceTop(JSObject*);
    8384        void pop();
    8485       
     
    130131}
    131132
     133inline void ScopeChain::replaceTop(JSObject* o)
     134{
     135    ASSERT(o);
     136    _node->object = o;
     137}
     138
    132139inline void ScopeChain::pop()
    133140{
  • trunk/LayoutTests/ChangeLog

    r29424 r29425  
     12008-01-11  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
     2
     3        Reviewed by Maciej.
     4
     5        Added a test case that came up when developing the ActivationImp tear-off.
     6
     7        * fast/js/resources/vardecl-preserve-arguments.js:
     8        * fast/js/vardecl-preserve-arguments-expected.txt:
     9
    1102008-01-11  Justin Garcia  <justin.garcia@apple.com>
    211
  • trunk/LayoutTests/fast/js/resources/vardecl-preserve-arguments.js

    r24287 r29425  
    112112}
    113113
     114function argumentsTearOff1()
     115{
     116    return argumentsTearOff2(2);
     117}
     118
     119function argumentsTearOff2(b)
     120{
     121    var v = b;
     122    var w = argumentsTearOff1.arguments;
     123    argumentsTearOff3(3);
     124    return v;
     125}
     126
     127function argumentsTearOff3(c)
     128{
     129    var v = c;
     130}
     131
    114132shouldBe("argumentsLength()", "0");
    115133shouldBe("argumentsLength(1)", "1");
     
    143161shouldBe("argumentsLengthOverrideInnerBlock3('a','b')", "2");
    144162
     163shouldBe("argumentsTearOff1()", "2");
     164
    145165// this tests that behaviour should persists for
    146166// the program source elements also
  • trunk/LayoutTests/fast/js/vardecl-preserve-arguments-expected.txt

    r24287 r29425  
    6060PASS 7 is 7
    6161PASS argumentsLengthOverrideInnerBlock3('a','b') is 2
     62PASS argumentsTearOff1() is 2
    6263PASS typeof undefined is 'undefined'
    6364PASS 'undefined' is 'undefined'
  • trunk/WebCore/ChangeLog

    r29423 r29425  
     12008-01-11  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
     2
     3        Reviewed by Maciej.
     4
     5        Added a new forwarding header, because Activation.h has been separated
     6        from function.h
     7
     8        * ForwardingHeaders/kjs/Activation.h: Added.
     9
    1102008-01-11  Luca Bruno  <lethalman88@gmail.com>
    211
Note: See TracChangeset for help on using the changeset viewer.