source: webkit/trunk/JavaScriptCore/kjs/ExecState.cpp@ 29425

Last change on this file since 29425 was 29425, checked in by [email protected], 17 years ago

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:
  • Property svn:eol-style set to native
File size: 4.5 KB
Line 
1// -*- mode: c++; c-basic-offset: 4 -*-
2/*
3 * 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])
6 * Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25#include "config.h"
26#include "ExecState.h"
27
28#include "Activation.h"
29#include "JSGlobalObject.h"
30#include "function.h"
31#include "internal.h"
32#include "scope_chain_mark.h"
33
34namespace KJS {
35
36static inline List* globalEmptyList()
37{
38 static List staticEmptyList;
39 return &staticEmptyList;
40}
41
42// ECMA 10.2
43
44ExecState::ExecState(JSGlobalObject* globalObject, JSObject* /*thisObject*/, ProgramNode* programNode)
45 : m_globalObject(globalObject)
46 , m_exception(0)
47 , m_propertyNames(CommonIdentifiers::shared())
48 , m_emptyList(globalEmptyList())
49 , m_callingExec(0)
50 , m_savedExec(0)
51 , m_scopeNode(programNode)
52 , m_function(0)
53 , m_arguments(0)
54 , m_activation(0)
55 , m_localStorage(&globalObject->localStorage())
56 , m_variableObject(globalObject)
57 , m_thisVal(globalObject)
58 , m_iterationDepth(0)
59 , m_switchDepth(0)
60 , m_codeType(GlobalCode)
61{
62 // FIXME: This function ignores the "thisObject" parameter, which means that the API for evaluating
63 // a script with a this object that's not the same as the global object is broken, and probably
64 // has been for some time.
65 m_scopeChain.push(globalObject);
66 if (programNode)
67 globalObject->setCurrentExec(this);
68}
69
70ExecState::ExecState(JSGlobalObject* globalObject, EvalNode* evalNode, ExecState* callingExec)
71 : m_globalObject(globalObject)
72 , m_exception(0)
73 , m_propertyNames(callingExec->m_propertyNames)
74 , m_emptyList(callingExec->m_emptyList)
75 , m_callingExec(callingExec)
76 , m_savedExec(globalObject->currentExec())
77 , m_scopeNode(evalNode)
78 , m_function(0)
79 , m_arguments(0)
80 , m_activation(0)
81 , m_localStorage(callingExec->m_localStorage)
82 , m_scopeChain(callingExec->m_scopeChain)
83 , m_variableObject(callingExec->m_variableObject)
84 , m_thisVal(callingExec->m_thisVal)
85 , m_iterationDepth(0)
86 , m_switchDepth(0)
87 , m_codeType(EvalCode)
88{
89 globalObject->setCurrentExec(this);
90}
91
92ExecState::ExecState(JSGlobalObject* globalObject, JSObject* thisObject,
93 FunctionBodyNode* functionBodyNode, ExecState* callingExec,
94 FunctionImp* func, const List& args)
95 : m_globalObject(globalObject)
96 , m_exception(0)
97 , m_propertyNames(callingExec->m_propertyNames)
98 , m_emptyList(callingExec->m_emptyList)
99 , m_callingExec(callingExec)
100 , m_savedExec(globalObject->currentExec())
101 , m_scopeNode(functionBodyNode)
102 , m_function(func)
103 , m_arguments(&args)
104 , m_scopeChain(func->scope())
105 , m_thisVal(thisObject)
106 , m_iterationDepth(0)
107 , m_switchDepth(0)
108 , m_codeType(FunctionCode)
109{
110 ActivationImp* activation = globalObject->pushActivation(this);
111 m_activation = activation;
112 m_localStorage = &activation->localStorage();
113 m_variableObject = activation;
114 m_scopeChain.push(activation);
115 globalObject->setCurrentExec(this);
116}
117
118ExecState::~ExecState()
119{
120 if (m_codeType == FunctionCode && m_activation->needsPop())
121 m_globalObject->popActivation();
122
123 m_globalObject->setCurrentExec(m_savedExec);
124}
125
126void ExecState::mark()
127{
128 for (ExecState* exec = this; exec; exec = exec->m_callingExec)
129 exec->m_scopeChain.mark();
130}
131
132JSGlobalObject* ExecState::lexicalGlobalObject() const
133{
134 if (scopeChain().isEmpty())
135 return dynamicGlobalObject();
136
137 JSObject* object = scopeChain().bottom();
138 if (object && object->isGlobalObject())
139 return static_cast<JSGlobalObject*>(object);
140
141 return dynamicGlobalObject();
142}
143
144} // namespace KJS
Note: See TracBrowser for help on using the repository browser.