Changeset 43642 in webkit for trunk/JavaScriptCore/parser


Ignore:
Timestamp:
May 13, 2009, 11:14:48 AM (16 years ago)
Author:
Darin Adler
Message:

JavaScriptCore:

2009-05-13 Darin Adler <Darin Adler>

Reviewed by Cameron Zwarich.

Bug 25674: syntax tree nodes should use arena allocation
https://bugs.webkit.org/show_bug.cgi?id=25674

Step 3: Add some actual arena allocation. About 1% SunSpider speedup.

  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::BytecodeGenerator): Updated since VarStack contains const Identifier* now. (JSC::BytecodeGenerator::emitPushNewScope): Updated to take a const Identifier&.
  • bytecompiler/BytecodeGenerator.h: Ditto
  • bytecompiler/SegmentedVector.h: Added isEmpty.
  • debugger/Debugger.cpp: (JSC::Debugger::recompileAllJSFunctions): Moved this function here from WebCore so WebCore doesn't need the details of FunctionBodyNode.
  • debugger/Debugger.h: Ditto.
  • interpreter/Interpreter.cpp: (JSC::Interpreter::execute): Updated since VarStack contains const Identifier* now.
  • jit/JITStubs.cpp: (JSC::JITStubs::cti_vm_lazyLinkCall): Call isHostFunction on the body rather than on the function object, since we can't easily have inlined access to the FunctionBodyNode in JSFunction.h since WebCore needs access to that header. (JSC::JITStubs::cti_op_construct_JSConstruct): Ditto.
  • profiler/Profiler.cpp: (JSC::Profiler::createCallIdentifier): Ditto.
  • parser/Grammar.y: Use JSGlobalData* to pass the global data pointer around whenever possible instead of using void*. Changed SET_EXCEPTION_LOCATION from a macro to an inline function. Marked the structure-creating functions inline. Changed the VarStack to use identifier pointers instead of actual identifiers. This takes advantage of the fact that all identifier pointers come from the arena and avoids referenc count churn. Changed Identifier* to const Identifier* to make sure we don't modify any by accident. Used identifiers for regular expression strings too, using the new scanRegExp that has out parameters instead of the old one that relied on side effects in the Lexer. Move the creation of numeric identifiers out of this file and into the PropertyNode constructor.
  • parser/Lexer.cpp: (JSC::Lexer::setCode): Pass in ParserArena, used for identifiers. (JSC::Lexer::makeIdentifier): Changed return type to const Identifier* and changed to call ParserArena. (JSC::Lexer::scanRegExp): Added out arguments that are const Identifier* as well as a prefix character argument so we can handle the /= case without a string append. (JSC::Lexer::skipRegExp): Added. Skips a regular expression without allocating Identifier objects. (JSC::Lexer::clear): Removed the code to manage m_identifiers, m_pattern, and m_flags, and added code to set m_arena to 0.
  • parser/Lexer.h: Updated for changes above.
  • parser/NodeConstructors.h: (JSC::ParserArenaFreeable::operator new): Added. Calls allocateFreeable on the arena. (JSC::ParserArenaDeletable::operator new): Changed to call the allocateDeletable function on the arena instead of deleteWithArena. (JSC::RegExpNode::RegExpNode): Changed arguments to Identifier instead of UString since these come from the parser which makes identifiers. (JSC::PropertyNode::PropertyNode): Added new constructor that makes numeric identifiers. Some day we might want to optimize this for integers so it doesn't create a string for each one. (JSC::ContinueNode::ContinueNode): Initialize m_ident to nullIdentifier since it's now a const Identifier& so it can't be left uninitialized. (JSC::BreakNode::BreakNode): Ditto. (JSC::CaseClauseNode::CaseClauseNode): Updated to use SourceElements* to keep track of the statements rather than a separate statement vector. (JSC::BlockNode::BlockNode): Ditto. (JSC::ForInNode::ForInNode): Initialize m_ident to nullIdentifier.
  • parser/Nodes.cpp: Moved the comment explaining emitBytecode in here. It seemed strangely out of place in the header. (JSC::ThrowableExpressionData::emitThrowError): Added an overload for UString as well as Identifier. (JSC::SourceElements::singleStatement): Added. (JSC::SourceElements::lastStatement): Added. (JSC::RegExpNode::emitBytecode): Updated since the pattern and flags are now Identifier instead of UString. Also changed the throwError code to use the substitution mechanism instead of doing a string append. (JSC::SourceElements::emitBytecode): Added. Replaces the old statementListEmitCode function, since we now keep the SourceElements objects around. (JSC::BlockNode::lastStatement): Added. (JSC::BlockNode::emitBytecode): Changed to use emitBytecode instead of statementListEmitCode. (JSC::CaseClauseNode::emitBytecode): Added. (JSC::CaseBlockNode::emitBytecodeForBlock): Changed to use emitBytecode instead of statementListEmitCode. (JSC::ScopeNodeData::ScopeNodeData): Changed to store the SourceElements* instead of using releaseContentsIntoVector. (JSC::ScopeNode::emitStatementsBytecode): Added. (JSC::ScopeNode::singleStatement): Added. (JSC::ProgramNode::emitBytecode): Call emitStatementsBytecode instead of statementListEmitCode. (JSC::EvalNode::emitBytecode): Ditto. (JSC::EvalNode::generateBytecode): Removed code to clear the children vector. This optimization is no longer possible since everything is in a single arena. (JSC::FunctionBodyNode::emitBytecode): Call emitStatementsBytecode insetad of statementListEmitCode and check for the return node using the new functions.
  • parser/Nodes.h: Changed VarStack to store const Identifier* instead of Identifier and rely on the arena to control lifetime. Added a new ParserArenaFreeable class. Made ParserArenaDeletable inherit from FastAllocBase instead of having its own operator new. Base the Node class on ParserArenaFreeable. Changed the various Node classes to use const Identifier& instead of Identifier to avoid the need to call their destructors and allow them to function as "freeable" in the arena. Removed extraneous JSC_FAST_CALL on definitions of inline functions. Changed ElementNode, PropertyNode, ArgumentsNode, ParameterNode, CaseClauseNode, ClauseListNode, and CaseBlockNode to use ParserArenaFreeable as a base class since they do not descend from Node. Eliminated the StatementVector type and instead have various classes use SourceElements* instead of StatementVector. This prevents those classes from having th use ParserArenaDeletable to make sure the vector destructor is called.
  • parser/Parser.cpp: (JSC::Parser::parse): Pass the arena to the lexer.
  • parser/Parser.h: Added an include of ParserArena.h, which is no longer included by Nodes.h.
  • parser/ParserArena.cpp: (JSC::ParserArena::ParserArena): Added. Initializes the new members, m_freeableMemory, m_freeablePoolEnd, and m_identifiers. (JSC::ParserArena::freeablePool): Added. Computes the pool pointer, since we store only the current pointer and the end of pool pointer. (JSC::ParserArena::deallocateObjects): Added. Contains the common memory-deallocation logic used by both the destructor and the reset function. (JSC::ParserArena::~ParserArena): Changed to call deallocateObjects. (JSC::ParserArena::reset): Ditto. Also added code to zero out the new structures, and switched to use clear() instead of shrink(0) since we don't really reuse arenas. (JSC::ParserArena::makeNumericIdentifier): Added. (JSC::ParserArena::allocateFreeablePool): Added. Used when the pool is empty. (JSC::ParserArena::isEmpty): Added. No longer inline, which is fine since this is used only for assertions at the moment.
  • parser/ParserArena.h: Added an actual arena of "freeable" objects, ones that don't need destructors to be called. Also added the segmented vector of identifiers that used to be in the Lexer.
  • runtime/FunctionConstructor.cpp: (JSC::extractFunctionBody): Use singleStatement function rather than getting at a StatementVector.
  • runtime/FunctionPrototype.cpp: (JSC::functionProtoFuncToString): Call isHostFunction on the body rather than the function object.
  • runtime/JSFunction.cpp: (JSC::JSFunction::JSFunction): Moved the structure version of this in here from the header. It's not hot enough that it needs to be inlined. (JSC::JSFunction::isHostFunction): Moved this in here from the header. It's now a helper to be used only within the class. (JSC::JSFunction::setBody): Moved this in here. It's not hot enough that it needs to be inlined, and we want to be able to compile the header without the definition of FunctionBodyNode.
  • runtime/JSFunction.h: Eliminated the include of "Nodes.h". This was exposing too much JavaScriptCore dependency to WebCore. Because of this change and some changes made to WebCore, we could now export a lot fewer headers from JavaScriptCore, but I have not done that yet in this check-in. Made a couple functions non-inline. Removes some isHostFunction() assertions.


  • wtf/FastAllocBase.h: Added the conventional using statements we use in WTF so we can use identifiers from the WTF namespace without explicit namespace qualification or namespace directive. This is the usual WTF style, although it's unconventional in the C++ world. We use the namespace primarily for link-time disambiguation, not compile-time.
  • wtf/FastMalloc.cpp: Fixed an incorrect comment.

WebCore:

2009-05-13 Darin Adler <Darin Adler>

Reviewed by Cameron Zwarich.

Bug 25674: syntax tree nodes should use arena allocation
https://bugs.webkit.org/show_bug.cgi?id=25674

  • bindings/js/JSDOMBinding.h: Removed include of JSFunction.h. We don't want the entire DOM binding to depend on that file.
  • bindings/js/JSAudioConstructor.cpp: Added include of Error.h. Before we inherited this automatically because JDDOMBinding.h included JSFunction.h, but that was excessive.
  • bindings/js/JSDOMWindowCustom.cpp: Ditto.
  • bindings/js/JSHTMLInputElementCustom.cpp: Ditto.
  • bindings/js/JSImageConstructor.cpp: Ditto.
  • bindings/js/JSLazyEventListener.cpp: Ditto, but for JSFunction.h.
  • bindings/js/JSMessageChannelConstructor.cpp: Ditto.
  • bindings/js/JSOptionConstructor.cpp: Ditto.
  • bindings/js/JSWorkerConstructor.cpp: Ditto.
  • bindings/js/JSXMLHttpRequestConstructor.cpp: Ditto.
  • bridge/jni/jni_jsobject.mm: Ditto, but for SourceCode.h.
  • inspector/InspectorController.cpp: Ditto.
  • inspector/JavaScriptDebugServer.cpp: (WebCore::JavaScriptDebugServer::recompileAllJSFunctions): Moved mose of this function into the base class in JavaScriptCore, so the details of compilation don't have to be exposed.

WebKit/mac:

2009-05-13 Darin Adler <Darin Adler>

Reviewed by Cameron Zwarich.

Bug 25674: syntax tree nodes should use arena allocation
https://bugs.webkit.org/show_bug.cgi?id=25674

  • Plugins/Hosted/NetscapePluginInstanceProxy.mm: Updated includes. New ones needed due to reducing includes of JSDOMBinding.h.
  • WebView/WebScriptDebugger.mm: Ditto.
Location:
trunk/JavaScriptCore/parser
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/parser/Grammar.y

    r43479 r43642  
    2626#include "config.h"
    2727
    28 #include <string.h>
    29 #include <stdlib.h>
     28#include "CommonIdentifiers.h"
     29#include "JSGlobalData.h"
     30#include "JSObject.h"
     31#include "JSString.h"
    3032#include "JSValue.h"
    31 #include "JSObject.h"
     33#include "Lexer.h"
    3234#include "NodeConstructors.h"
    33 #include "Lexer.h"
    34 #include "JSString.h"
    35 #include "JSGlobalData.h"
    36 #include "CommonIdentifiers.h"
    3735#include "NodeInfo.h"
    3836#include "Parser.h"
     37#include <stdlib.h>
     38#include <string.h>
    3939#include <wtf/MathExtras.h>
    4040
     
    5252int jscyylex(void* lvalp, void* llocp, void* globalPtr);
    5353int jscyyerror(const char*);
     54
    5455static inline bool allowAutomaticSemicolon(JSC::Lexer&, int);
    5556
     
    5859
    5960#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon(*LEXER, yychar)) YYABORT; } while (0)
    60 #define SET_EXCEPTION_LOCATION(node, start, divot, end) node->setExceptionSourceCode((divot), (divot) - (start), (end) - (divot))
    6161#define DBG(l, s, e) (l)->setLoc((s).first_line, (e).last_line)
    6262
     
    6464using namespace std;
    6565
    66 static ExpressionNode* makeAssignNode(void*, ExpressionNode* loc, Operator, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end);
    67 static ExpressionNode* makePrefixNode(void*, ExpressionNode* expr, Operator, int start, int divot, int end);
    68 static ExpressionNode* makePostfixNode(void*, ExpressionNode* expr, Operator, int start, int divot, int end);
    69 static PropertyNode* makeGetterOrSetterPropertyNode(void*, const Identifier &getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*, const SourceCode&);
    70 static ExpressionNodeInfo makeFunctionCallNode(void*, ExpressionNodeInfo func, ArgumentsNodeInfo, int start, int divot, int end);
    71 static ExpressionNode* makeTypeOfNode(void*, ExpressionNode*);
    72 static ExpressionNode* makeDeleteNode(void*, ExpressionNode*, int start, int divot, int end);
    73 static ExpressionNode* makeNegateNode(void*, ExpressionNode*);
    74 static NumberNode* makeNumberNode(void*, double);
    75 static ExpressionNode* makeBitwiseNotNode(void*, ExpressionNode*);
    76 static ExpressionNode* makeMultNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
    77 static ExpressionNode* makeDivNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
    78 static ExpressionNode* makeAddNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
    79 static ExpressionNode* makeSubNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
    80 static ExpressionNode* makeLeftShiftNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
    81 static ExpressionNode* makeRightShiftNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
    82 static StatementNode* makeVarStatementNode(void*, ExpressionNode*);
    83 static ExpressionNode* combineVarInitializers(void*, ExpressionNode* list, AssignResolveNode* init);
     66static ExpressionNode* makeAssignNode(JSGlobalData*, ExpressionNode* loc, Operator, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end);
     67static ExpressionNode* makePrefixNode(JSGlobalData*, ExpressionNode* expr, Operator, int start, int divot, int end);
     68static ExpressionNode* makePostfixNode(JSGlobalData*, ExpressionNode* expr, Operator, int start, int divot, int end);
     69static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData*, const Identifier& getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*, const SourceCode&);
     70static ExpressionNodeInfo makeFunctionCallNode(JSGlobalData*, ExpressionNodeInfo func, ArgumentsNodeInfo, int start, int divot, int end);
     71static ExpressionNode* makeTypeOfNode(JSGlobalData*, ExpressionNode*);
     72static ExpressionNode* makeDeleteNode(JSGlobalData*, ExpressionNode*, int start, int divot, int end);
     73static ExpressionNode* makeNegateNode(JSGlobalData*, ExpressionNode*);
     74static NumberNode* makeNumberNode(JSGlobalData*, double);
     75static ExpressionNode* makeBitwiseNotNode(JSGlobalData*, ExpressionNode*);
     76static ExpressionNode* makeMultNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
     77static ExpressionNode* makeDivNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
     78static ExpressionNode* makeAddNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
     79static ExpressionNode* makeSubNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
     80static ExpressionNode* makeLeftShiftNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
     81static ExpressionNode* makeRightShiftNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
     82static StatementNode* makeVarStatementNode(JSGlobalData*, ExpressionNode*);
     83static ExpressionNode* combineVarInitializers(JSGlobalData*, ExpressionNode* list, AssignResolveNode* init);
     84
     85// FIXME: This used to be a macro and is still named like one. It should be renamed.
     86static inline void SET_EXCEPTION_LOCATION(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end)
     87{
     88    node->setExceptionSourceCode(divot, divot - start, end - divot);
     89}
    8490
    8591#if COMPILER(MSVC)
     
    100106#define YYLEX_PARAM globalPtr
    101107
    102 template <typename T> NodeDeclarationInfo<T> createNodeDeclarationInfo(T node, ParserArenaData<DeclarationStacks::VarStack>* varDecls,
    103                                                                        ParserArenaData<DeclarationStacks::FunctionStack>* funcDecls,
    104                                                                        CodeFeatures info,
    105                                                                       int numConstants)
     108template <typename T> inline NodeDeclarationInfo<T> createNodeDeclarationInfo(T node,
     109    ParserArenaData<DeclarationStacks::VarStack>* varDecls,
     110    ParserArenaData<DeclarationStacks::FunctionStack>* funcDecls,
     111    CodeFeatures info, int numConstants)
    106112{
    107113    ASSERT((info & ~AllFeatures) == 0);
     
    110116}
    111117
    112 template <typename T> NodeInfo<T> createNodeInfo(T node, CodeFeatures info, int numConstants)
     118template <typename T> NodeInfo<T> inline createNodeInfo(T node, CodeFeatures info, int numConstants)
    113119{
    114120    ASSERT((info & ~AllFeatures) == 0);
     
    136142}
    137143
    138 static void appendToVarDeclarationList(void* globalPtr, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs)
     144static void appendToVarDeclarationList(JSGlobalData* globalData, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs)
    139145{
    140146    if (!varDecls)
    141         varDecls = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>;
    142 
    143     varDecls->data.append(make_pair(ident, attrs));
    144 
    145 }
    146 
    147 static inline void appendToVarDeclarationList(void* globalPtr, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl)
     147        varDecls = new (globalData) ParserArenaData<DeclarationStacks::VarStack>;
     148
     149    varDecls->data.append(make_pair(&ident, attrs));
     150}
     151
     152static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl)
    148153{
    149154    unsigned attrs = DeclarationStacks::IsConstant;
    150155    if (decl->hasInitializer())
    151156        attrs |= DeclarationStacks::HasInitializer;       
    152     appendToVarDeclarationList(globalPtr, varDecls, decl->ident(), attrs);
     157    appendToVarDeclarationList(globalData, varDecls, decl->ident(), attrs);
    153158}
    154159
     
    158163    int                 intValue;
    159164    double              doubleValue;
    160     Identifier*         ident;
     165    const Identifier*   ident;
    161166
    162167    // expression subtrees
     
    294299  | STRING                              { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StringNode(GLOBAL_DATA, *$1), 0, 1); }
    295300  | '/' /* regexp */                    {
    296                                             Lexer& l = *LEXER;
    297                                             if (!l.scanRegExp())
     301                                            const Identifier* pattern;
     302                                            const Identifier* flags;
     303                                            if (!LEXER->scanRegExp(pattern, flags))
    298304                                                YYABORT;
    299                                             RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, l.pattern(), l.flags());
    300                                             int size = l.pattern().size() + 2; // + 2 for the two /'s
     305                                            RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, *pattern, *flags);
     306                                            int size = pattern->size() + 2; // + 2 for the two /'s
    301307                                            SET_EXCEPTION_LOCATION(node, @1.first_column, @1.first_column + size, @1.first_column + size);
    302308                                            $$ = createNodeInfo<ExpressionNode*>(node, 0, 0);
    303309                                        }
    304310  | DIVEQUAL /* regexp with /= */       {
    305                                             Lexer& l = *LEXER;
    306                                             if (!l.scanRegExp())
     311                                            const Identifier* pattern;
     312                                            const Identifier* flags;
     313                                            if (!LEXER->scanRegExp(pattern, flags, '='))
    307314                                                YYABORT;
    308                                             RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, "=" + l.pattern(), l.flags());
    309                                             int size = l.pattern().size() + 2; // + 2 for the two /'s
     315                                            RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, *pattern, *flags);
     316                                            int size = pattern->size() + 2; // + 2 for the two /'s
    310317                                            SET_EXCEPTION_LOCATION(node, @1.first_column, @1.first_column + size, @1.first_column + size);
    311318                                            $$ = createNodeInfo<ExpressionNode*>(node, 0, 0);
     
    316323    IDENT ':' AssignmentExpr            { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *$1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); }
    317324  | STRING ':' AssignmentExpr           { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *$1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); }
    318   | NUMBER ':' AssignmentExpr           { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, Identifier(GLOBAL_DATA, UString::from($1)), $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); }
    319   | IDENT IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE    { $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(globalPtr, *$1, *$2, 0, $6, LEXER->sourceCode($5, $7, @5.first_line)), ClosureFeature, 0); DBG($6, @5, @7); if (!$$.m_node) YYABORT; }
     325  | NUMBER ':' AssignmentExpr           { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, $1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); }
     326  | IDENT IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE    { $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(GLOBAL_DATA, *$1, *$2, 0, $6, LEXER->sourceCode($5, $7, @5.first_line)), ClosureFeature, 0); DBG($6, @5, @7); if (!$$.m_node) YYABORT; }
    320327  | IDENT IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE
    321328                                                             {
    322                                                                  $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(globalPtr, *$1, *$2, $4.m_node.head, $7, LEXER->sourceCode($6, $8, @6.first_line)), $4.m_features | ClosureFeature, 0);
     329                                                                 $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(GLOBAL_DATA, *$1, *$2, $4.m_node.head, $7, LEXER->sourceCode($6, $8, @6.first_line)), $4.m_features | ClosureFeature, 0);
    323330                                                                 if ($4.m_features & ArgumentsFeature)
    324331                                                                     $7->setUsesArguments();
     
    434441
    435442CallExpr:
    436     MemberExpr Arguments                { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); }
    437   | CallExpr Arguments                  { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); }
     443    MemberExpr Arguments                { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); }
     444  | CallExpr Arguments                  { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); }
    438445  | CallExpr '[' Expr ']'               { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
    439446                                          SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column);
     
    446453
    447454CallExprNoBF:
    448     MemberExprNoBF Arguments            { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); }
    449   | CallExprNoBF Arguments              { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); }
     455    MemberExprNoBF Arguments            { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); }
     456  | CallExprNoBF Arguments              { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); }
    450457  | CallExprNoBF '[' Expr ']'           { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
    451458                                          SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column);
     
    813820
    814821Block:
    815     OPENBRACE CLOSEBRACE                             { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0);
     822    OPENBRACE CLOSEBRACE                { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0);
    816823                                          DBG($$.m_node, @1, @2); }
    817   | OPENBRACE SourceElements CLOSEBRACE              { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants);
     824  | OPENBRACE SourceElements CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants);
    818825                                          DBG($$.m_node, @1, @3); }
    819826;
     
    12421249  | TRUETOKEN
    12431250  | FALSETOKEN
    1244   | NUMBER { }
    1245   | STRING { }
    1246   | '/' /* regexp */ { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; }
    1247   | DIVEQUAL /* regexp with /= */ { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; }
     1251  | NUMBER
     1252  | STRING
     1253  | '/' /* regexp */ { if (!LEXER->skipRegExp()) YYABORT; }
     1254  | DIVEQUAL /* regexp with /= */ { if (!LEXER->skipRegExp()) YYABORT; }
    12481255;
    12491256
    12501257Property_NoNode:
    1251     IDENT ':' AssignmentExpr_NoNode { }
    1252   | STRING ':' AssignmentExpr_NoNode { }
    1253   | NUMBER ':' AssignmentExpr_NoNode { }
     1258    IDENT ':' AssignmentExpr_NoNode
     1259  | STRING ':' AssignmentExpr_NoNode
     1260  | NUMBER ':' AssignmentExpr_NoNode
    12541261  | IDENT IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE { if (*$1 != "get" && *$1 != "set") YYABORT; }
    12551262  | IDENT IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE { if (*$1 != "get" && *$1 != "set") YYABORT; }
     
    12631270PrimaryExpr_NoNode:
    12641271    PrimaryExprNoBrace_NoNode
    1265   | OPENBRACE CLOSEBRACE { }
    1266   | OPENBRACE PropertyList_NoNode CLOSEBRACE { }
     1272  | OPENBRACE CLOSEBRACE
     1273  | OPENBRACE PropertyList_NoNode CLOSEBRACE
    12671274  /* allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 */
    1268   | OPENBRACE PropertyList_NoNode ',' CLOSEBRACE { }
     1275  | OPENBRACE PropertyList_NoNode ',' CLOSEBRACE
    12691276;
    12701277
     
    12731280  | Literal_NoNode
    12741281  | ArrayLiteral_NoNode
    1275   | IDENT { }
     1282  | IDENT
    12761283  | '(' Expr_NoNode ')'
    12771284;
     
    16411648
    16421649Block_NoNode:
    1643     OPENBRACE CLOSEBRACE { }
    1644   | OPENBRACE SourceElements_NoNode CLOSEBRACE { }
     1650    OPENBRACE CLOSEBRACE
     1651  | OPENBRACE SourceElements_NoNode CLOSEBRACE
    16451652;
    16461653
     
    16511658
    16521659VariableDeclarationList_NoNode:
    1653     IDENT { }
    1654   | IDENT Initializer_NoNode { }
     1660    IDENT
     1661  | IDENT Initializer_NoNode
    16551662  | VariableDeclarationList_NoNode ',' IDENT
    16561663  | VariableDeclarationList_NoNode ',' IDENT Initializer_NoNode
     
    16581665
    16591666VariableDeclarationListNoIn_NoNode:
    1660     IDENT { }
    1661   | IDENT InitializerNoIn_NoNode { }
     1667    IDENT
     1668  | IDENT InitializerNoIn_NoNode
    16621669  | VariableDeclarationListNoIn_NoNode ',' IDENT
    16631670  | VariableDeclarationListNoIn_NoNode ',' IDENT InitializerNoIn_NoNode
     
    16751682
    16761683ConstDeclaration_NoNode:
    1677     IDENT { }
    1678   | IDENT Initializer_NoNode { }
     1684    IDENT
     1685  | IDENT Initializer_NoNode
    16791686;
    16801687
     
    17521759
    17531760CaseBlock_NoNode:
    1754     OPENBRACE CaseClausesOpt_NoNode CLOSEBRACE { }
    1755   | OPENBRACE CaseClausesOpt_NoNode DefaultClause_NoNode CaseClausesOpt_NoNode CLOSEBRACE { }
     1761    OPENBRACE CaseClausesOpt_NoNode CLOSEBRACE
     1762  | OPENBRACE CaseClausesOpt_NoNode DefaultClause_NoNode CaseClausesOpt_NoNode CLOSEBRACE
    17561763;
    17571764
     
    17771784
    17781785LabelledStatement_NoNode:
    1779     IDENT ':' Statement_NoNode { }
     1786    IDENT ':' Statement_NoNode
    17801787;
    17811788
     
    18091816
    18101817FormalParameterList_NoNode:
    1811     IDENT { }
     1818    IDENT
    18121819  | FormalParameterList_NoNode ',' IDENT
    18131820;
     
    18271834%%
    18281835
    1829 static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end)
     1836#undef GLOBAL_DATA
     1837
     1838static ExpressionNode* makeAssignNode(JSGlobalData* globalData, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end)
    18301839{
    18311840    if (!loc->isLocation())
    1832         return new (GLOBAL_DATA) AssignErrorNode(GLOBAL_DATA, loc, op, expr, divot, divot - start, end - divot);
     1841        return new (globalData) AssignErrorNode(globalData, loc, op, expr, divot, divot - start, end - divot);
    18331842
    18341843    if (loc->isResolveNode()) {
    18351844        ResolveNode* resolve = static_cast<ResolveNode*>(loc);
    18361845        if (op == OpEqual) {
    1837             AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, resolve->identifier(), expr, exprHasAssignments);
     1846            AssignResolveNode* node = new (globalData) AssignResolveNode(globalData, resolve->identifier(), expr, exprHasAssignments);
    18381847            SET_EXCEPTION_LOCATION(node, start, divot, end);
    18391848            return node;
    18401849        } else
    1841             return new (GLOBAL_DATA) ReadModifyResolveNode(GLOBAL_DATA, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
     1850            return new (globalData) ReadModifyResolveNode(globalData, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
    18421851    }
    18431852    if (loc->isBracketAccessorNode()) {
    18441853        BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc);
    18451854        if (op == OpEqual)
    1846             return new (GLOBAL_DATA) AssignBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot());
     1855            return new (globalData) AssignBracketNode(globalData, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot());
    18471856        else {
    1848             ReadModifyBracketNode* node = new (GLOBAL_DATA) ReadModifyBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot);
     1857            ReadModifyBracketNode* node = new (globalData) ReadModifyBracketNode(globalData, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot);
    18491858            node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
    18501859            return node;
     
    18541863    DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc);
    18551864    if (op == OpEqual)
    1856         return new (GLOBAL_DATA) AssignDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot());
    1857 
    1858     ReadModifyDotNode* node = new (GLOBAL_DATA) ReadModifyDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
     1865        return new (globalData) AssignDotNode(globalData, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot());
     1866
     1867    ReadModifyDotNode* node = new (globalData) ReadModifyDotNode(globalData, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
    18591868    node->setSubexpressionInfo(dot->divot(), dot->endOffset());
    18601869    return node;
    18611870}
    18621871
    1863 static ExpressionNode* makePrefixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end)
     1872static ExpressionNode* makePrefixNode(JSGlobalData* globalData, ExpressionNode* expr, Operator op, int start, int divot, int end)
    18641873{
    18651874    if (!expr->isLocation())
    1866         return new (GLOBAL_DATA) PrefixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot);
     1875        return new (globalData) PrefixErrorNode(globalData, expr, op, divot, divot - start, end - divot);
    18671876   
    18681877    if (expr->isResolveNode()) {
    18691878        ResolveNode* resolve = static_cast<ResolveNode*>(expr);
    1870         return new (GLOBAL_DATA) PrefixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot);
     1879        return new (globalData) PrefixResolveNode(globalData, resolve->identifier(), op, divot, divot - start, end - divot);
    18711880    }
    18721881    if (expr->isBracketAccessorNode()) {
    18731882        BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
    1874         PrefixBracketNode* node = new (GLOBAL_DATA) PrefixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
     1883        PrefixBracketNode* node = new (globalData) PrefixBracketNode(globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
    18751884        node->setSubexpressionInfo(bracket->divot(), bracket->startOffset());
    18761885        return node;
     
    18781887    ASSERT(expr->isDotAccessorNode());
    18791888    DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
    1880     PrefixDotNode* node = new (GLOBAL_DATA) PrefixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
     1889    PrefixDotNode* node = new (globalData) PrefixDotNode(globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
    18811890    node->setSubexpressionInfo(dot->divot(), dot->startOffset());
    18821891    return node;
    18831892}
    18841893
    1885 static ExpressionNode* makePostfixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end)
     1894static ExpressionNode* makePostfixNode(JSGlobalData* globalData, ExpressionNode* expr, Operator op, int start, int divot, int end)
    18861895{
    18871896    if (!expr->isLocation())
    1888         return new (GLOBAL_DATA) PostfixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot);
     1897        return new (globalData) PostfixErrorNode(globalData, expr, op, divot, divot - start, end - divot);
    18891898   
    18901899    if (expr->isResolveNode()) {
    18911900        ResolveNode* resolve = static_cast<ResolveNode*>(expr);
    1892         return new (GLOBAL_DATA) PostfixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot);
     1901        return new (globalData) PostfixResolveNode(globalData, resolve->identifier(), op, divot, divot - start, end - divot);
    18931902    }
    18941903    if (expr->isBracketAccessorNode()) {
    18951904        BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
    1896         PostfixBracketNode* node = new (GLOBAL_DATA) PostfixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
     1905        PostfixBracketNode* node = new (globalData) PostfixBracketNode(globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
    18971906        node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
    18981907        return node;
     
    19011910    ASSERT(expr->isDotAccessorNode());
    19021911    DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
    1903     PostfixDotNode* node = new (GLOBAL_DATA) PostfixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
     1912    PostfixDotNode* node = new (globalData) PostfixDotNode(globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
    19041913    node->setSubexpressionInfo(dot->divot(), dot->endOffset());
    19051914    return node;
    19061915}
    19071916
    1908 static ExpressionNodeInfo makeFunctionCallNode(void* globalPtr, ExpressionNodeInfo func, ArgumentsNodeInfo args, int start, int divot, int end)
     1917static ExpressionNodeInfo makeFunctionCallNode(JSGlobalData* globalData, ExpressionNodeInfo func, ArgumentsNodeInfo args, int start, int divot, int end)
    19091918{
    19101919    CodeFeatures features = func.m_features | args.m_features;
    19111920    int numConstants = func.m_numConstants + args.m_numConstants;
    19121921    if (!func.m_node->isLocation())
    1913         return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) FunctionCallValueNode(GLOBAL_DATA, func.m_node, args.m_node, divot, divot - start, end - divot), features, numConstants);
     1922        return createNodeInfo<ExpressionNode*>(new (globalData) FunctionCallValueNode(globalData, func.m_node, args.m_node, divot, divot - start, end - divot), features, numConstants);
    19141923    if (func.m_node->isResolveNode()) {
    19151924        ResolveNode* resolve = static_cast<ResolveNode*>(func.m_node);
    19161925        const Identifier& identifier = resolve->identifier();
    1917         if (identifier == GLOBAL_DATA->propertyNames->eval)
    1918             return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EvalFunctionCallNode(GLOBAL_DATA, args.m_node, divot, divot - start, end - divot), EvalFeature | features, numConstants);
    1919         return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) FunctionCallResolveNode(GLOBAL_DATA, identifier, args.m_node, divot, divot - start, end - divot), features, numConstants);
     1926        if (identifier == globalData->propertyNames->eval)
     1927            return createNodeInfo<ExpressionNode*>(new (globalData) EvalFunctionCallNode(globalData, args.m_node, divot, divot - start, end - divot), EvalFeature | features, numConstants);
     1928        return createNodeInfo<ExpressionNode*>(new (globalData) FunctionCallResolveNode(globalData, identifier, args.m_node, divot, divot - start, end - divot), features, numConstants);
    19201929    }
    19211930    if (func.m_node->isBracketAccessorNode()) {
    19221931        BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func.m_node);
    1923         FunctionCallBracketNode* node = new (GLOBAL_DATA) FunctionCallBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), args.m_node, divot, divot - start, end - divot);
     1932        FunctionCallBracketNode* node = new (globalData) FunctionCallBracketNode(globalData, bracket->base(), bracket->subscript(), args.m_node, divot, divot - start, end - divot);
    19241933        node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
    19251934        return createNodeInfo<ExpressionNode*>(node, features, numConstants);
     
    19281937    DotAccessorNode* dot = static_cast<DotAccessorNode*>(func.m_node);
    19291938    FunctionCallDotNode* node;
    1930     if (dot->identifier() == GLOBAL_DATA->propertyNames->call)
    1931         node = new (GLOBAL_DATA) CallFunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot);
    1932     else if (dot->identifier() == GLOBAL_DATA->propertyNames->apply)
    1933         node = new (GLOBAL_DATA) ApplyFunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot);
     1939    if (dot->identifier() == globalData->propertyNames->call)
     1940        node = new (globalData) CallFunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot);
     1941    else if (dot->identifier() == globalData->propertyNames->apply)
     1942        node = new (globalData) ApplyFunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot);
    19341943    else
    1935         node = new (GLOBAL_DATA) FunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot);
     1944        node = new (globalData) FunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot);
    19361945    node->setSubexpressionInfo(dot->divot(), dot->endOffset());
    19371946    return createNodeInfo<ExpressionNode*>(node, features, numConstants);
    19381947}
    19391948
    1940 static ExpressionNode* makeTypeOfNode(void* globalPtr, ExpressionNode* expr)
     1949static ExpressionNode* makeTypeOfNode(JSGlobalData* globalData, ExpressionNode* expr)
    19411950{
    19421951    if (expr->isResolveNode()) {
    19431952        ResolveNode* resolve = static_cast<ResolveNode*>(expr);
    1944         return new (GLOBAL_DATA) TypeOfResolveNode(GLOBAL_DATA, resolve->identifier());
     1953        return new (globalData) TypeOfResolveNode(globalData, resolve->identifier());
    19451954    }
    1946     return new (GLOBAL_DATA) TypeOfValueNode(GLOBAL_DATA, expr);
    1947 }
    1948 
    1949 static ExpressionNode* makeDeleteNode(void* globalPtr, ExpressionNode* expr, int start, int divot, int end)
     1955    return new (globalData) TypeOfValueNode(globalData, expr);
     1956}
     1957
     1958static ExpressionNode* makeDeleteNode(JSGlobalData* globalData, ExpressionNode* expr, int start, int divot, int end)
    19501959{
    19511960    if (!expr->isLocation())
    1952         return new (GLOBAL_DATA) DeleteValueNode(GLOBAL_DATA, expr);
     1961        return new (globalData) DeleteValueNode(globalData, expr);
    19531962    if (expr->isResolveNode()) {
    19541963        ResolveNode* resolve = static_cast<ResolveNode*>(expr);
    1955         return new (GLOBAL_DATA) DeleteResolveNode(GLOBAL_DATA, resolve->identifier(), divot, divot - start, end - divot);
     1964        return new (globalData) DeleteResolveNode(globalData, resolve->identifier(), divot, divot - start, end - divot);
    19561965    }
    19571966    if (expr->isBracketAccessorNode()) {
    19581967        BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
    1959         return new (GLOBAL_DATA) DeleteBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), divot, divot - start, end - divot);
     1968        return new (globalData) DeleteBracketNode(globalData, bracket->base(), bracket->subscript(), divot, divot - start, end - divot);
    19601969    }
    19611970    ASSERT(expr->isDotAccessorNode());
    19621971    DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
    1963     return new (GLOBAL_DATA) DeleteDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), divot, divot - start, end - divot);
    1964 }
    1965 
    1966 static PropertyNode* makeGetterOrSetterPropertyNode(void* globalPtr, const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceCode& source)
     1972    return new (globalData) DeleteDotNode(globalData, dot->base(), dot->identifier(), divot, divot - start, end - divot);
     1973}
     1974
     1975static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData* globalData, const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceCode& source)
    19671976{
    19681977    PropertyNode::Type type;
     
    19731982    else
    19741983        return 0;
    1975     return new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, name, new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, body, source, params), type);
    1976 }
    1977 
    1978 static ExpressionNode* makeNegateNode(void* globalPtr, ExpressionNode* n)
     1984    return new (globalData) PropertyNode(globalData, name, new FuncExprNode(globalData, globalData->propertyNames->nullIdentifier, body, source, params), type);
     1985}
     1986
     1987static ExpressionNode* makeNegateNode(JSGlobalData* globalData, ExpressionNode* n)
    19791988{
    19801989    if (n->isNumber()) {
     
    19871996    }
    19881997
    1989     return new (GLOBAL_DATA) NegateNode(GLOBAL_DATA, n);
    1990 }
    1991 
    1992 static NumberNode* makeNumberNode(void* globalPtr, double d)
    1993 {
    1994     return new (GLOBAL_DATA) NumberNode(GLOBAL_DATA, d);
    1995 }
    1996 
    1997 static ExpressionNode* makeBitwiseNotNode(void* globalPtr, ExpressionNode* expr)
     1998    return new (globalData) NegateNode(globalData, n);
     1999}
     2000
     2001static NumberNode* makeNumberNode(JSGlobalData* globalData, double d)
     2002{
     2003    return new (globalData) NumberNode(globalData, d);
     2004}
     2005
     2006static ExpressionNode* makeBitwiseNotNode(JSGlobalData* globalData, ExpressionNode* expr)
    19982007{
    19992008    if (expr->isNumber())
    2000         return makeNumberNode(globalPtr, ~toInt32(static_cast<NumberNode*>(expr)->value()));
    2001     return new (GLOBAL_DATA) BitwiseNotNode(GLOBAL_DATA, expr);
    2002 }
    2003 
    2004 static ExpressionNode* makeMultNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
     2009        return makeNumberNode(globalData, ~toInt32(static_cast<NumberNode*>(expr)->value()));
     2010    return new (globalData) BitwiseNotNode(globalData, expr);
     2011}
     2012
     2013static ExpressionNode* makeMultNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
    20052014{
    20062015    expr1 = expr1->stripUnaryPlus();
     
    20082017
    20092018    if (expr1->isNumber() && expr2->isNumber())
    2010         return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value());
     2019        return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value());
    20112020
    20122021    if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1)
    2013         return new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, expr2);
     2022        return new (globalData) UnaryPlusNode(globalData, expr2);
    20142023
    20152024    if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1)
    2016         return new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, expr1);
    2017 
    2018     return new (GLOBAL_DATA) MultNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
    2019 }
    2020 
    2021 static ExpressionNode* makeDivNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
     2025        return new (globalData) UnaryPlusNode(globalData, expr1);
     2026
     2027    return new (globalData) MultNode(globalData, expr1, expr2, rightHasAssignments);
     2028}
     2029
     2030static ExpressionNode* makeDivNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
    20222031{
    20232032    expr1 = expr1->stripUnaryPlus();
     
    20252034
    20262035    if (expr1->isNumber() && expr2->isNumber())
    2027         return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value());
    2028     return new (GLOBAL_DATA) DivNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
    2029 }
    2030 
    2031 static ExpressionNode* makeAddNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
     2036        return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value());
     2037    return new (globalData) DivNode(globalData, expr1, expr2, rightHasAssignments);
     2038}
     2039
     2040static ExpressionNode* makeAddNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
    20322041{
    20332042    if (expr1->isNumber() && expr2->isNumber())
    2034         return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value());
    2035     return new (GLOBAL_DATA) AddNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
    2036 }
    2037 
    2038 static ExpressionNode* makeSubNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
     2043        return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value());
     2044    return new (globalData) AddNode(globalData, expr1, expr2, rightHasAssignments);
     2045}
     2046
     2047static ExpressionNode* makeSubNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
    20392048{
    20402049    expr1 = expr1->stripUnaryPlus();
     
    20422051
    20432052    if (expr1->isNumber() && expr2->isNumber())
    2044         return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value());
    2045     return new (GLOBAL_DATA) SubNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
    2046 }
    2047 
    2048 static ExpressionNode* makeLeftShiftNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
     2053        return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value());
     2054    return new (globalData) SubNode(globalData, expr1, expr2, rightHasAssignments);
     2055}
     2056
     2057static ExpressionNode* makeLeftShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
    20492058{
    20502059    if (expr1->isNumber() && expr2->isNumber())
    2051         return makeNumberNode(globalPtr, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
    2052     return new (GLOBAL_DATA) LeftShiftNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
    2053 }
    2054 
    2055 static ExpressionNode* makeRightShiftNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
     2060        return makeNumberNode(globalData, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
     2061    return new (globalData) LeftShiftNode(globalData, expr1, expr2, rightHasAssignments);
     2062}
     2063
     2064static ExpressionNode* makeRightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
    20562065{
    20572066    if (expr1->isNumber() && expr2->isNumber())
    2058         return makeNumberNode(globalPtr, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
    2059     return new (GLOBAL_DATA) RightShiftNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
    2060 }
    2061 
    2062 /* called by yyparse on error */
    2063 int yyerror(const char *)
     2067        return makeNumberNode(globalData, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
     2068    return new (globalData) RightShiftNode(globalData, expr1, expr2, rightHasAssignments);
     2069}
     2070
     2071// Called by yyparse on error.
     2072int yyerror(const char*)
    20642073{
    20652074    return 1;
    20662075}
    20672076
    2068 /* may we automatically insert a semicolon ? */
     2077// May we automatically insert a semicolon?
    20692078static bool allowAutomaticSemicolon(Lexer& lexer, int yychar)
    20702079{
     
    20722081}
    20732082
    2074 static ExpressionNode* combineVarInitializers(void* globalPtr, ExpressionNode* list, AssignResolveNode* init)
     2083static ExpressionNode* combineVarInitializers(JSGlobalData* globalData, ExpressionNode* list, AssignResolveNode* init)
    20752084{
    20762085    if (!list)
    20772086        return init;
    2078     return new (GLOBAL_DATA) CommaNode(GLOBAL_DATA, list, init);
     2087    return new (globalData) CommaNode(globalData, list, init);
    20792088}
    20802089
     
    20822091// statements (which later get stripped out), because the actual
    20832092// declaration work is hoisted up to the start of the function body
    2084 static StatementNode* makeVarStatementNode(void* globalPtr, ExpressionNode* expr)
     2093static StatementNode* makeVarStatementNode(JSGlobalData* globalData, ExpressionNode* expr)
    20852094{
    20862095    if (!expr)
    2087         return new (GLOBAL_DATA) EmptyStatementNode(GLOBAL_DATA);
    2088     return new (GLOBAL_DATA) VarStatementNode(GLOBAL_DATA, expr);
    2089 }
    2090 
    2091 #undef GLOBAL_DATA
     2096        return new (globalData) EmptyStatementNode(globalData);
     2097    return new (globalData) VarStatementNode(globalData, expr);
     2098}
  • trunk/JavaScriptCore/parser/Lexer.cpp

    r43361 r43642  
    142142}
    143143
    144 void Lexer::setCode(const SourceCode& source)
    145 {
     144void Lexer::setCode(const SourceCode& source, ParserArena& arena)
     145{
     146    m_arena = &arena.identifierArena();
     147
    146148    m_lineNumber = source.firstLine();
    147149    m_delimited = false;
     
    205207}
    206208
    207 ALWAYS_INLINE Identifier* Lexer::makeIdentifier(const UChar* characters, size_t length)
    208 {
    209     m_identifiers.append(Identifier(m_globalData, characters, length));
    210     return &m_identifiers.last();
     209ALWAYS_INLINE const Identifier* Lexer::makeIdentifier(const UChar* characters, size_t length)
     210{
     211    return &JSC::makeIdentifier(*m_arena, m_globalData, characters, length);
    211212}
    212213
     
    909910}
    910911
    911 bool Lexer::scanRegExp()
     912bool Lexer::scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar prefix)
    912913{
    913914    ASSERT(m_buffer16.isEmpty());
    914915
     916    bool lastWasEscape = false;
     917    bool inBrackets = false;
     918
     919    if (prefix)
     920        record16(prefix);
     921
     922    while (true) {
     923        if (isLineTerminator(m_current) || m_current == -1) {
     924            m_buffer16.resize(0);
     925            return false;
     926        }
     927        if (m_current != '/' || lastWasEscape || inBrackets) {
     928            // keep track of '[' and ']'
     929            if (!lastWasEscape) {
     930                if (m_current == '[' && !inBrackets)
     931                    inBrackets = true;
     932                if (m_current == ']' && inBrackets)
     933                    inBrackets = false;
     934            }
     935            record16(m_current);
     936            lastWasEscape = !lastWasEscape && m_current == '\\';
     937        } else { // end of regexp
     938            pattern = makeIdentifier(m_buffer16.data(), m_buffer16.size());
     939            m_buffer16.resize(0);
     940            shift1();
     941            break;
     942        }
     943        shift1();
     944    }
     945
     946    while (isIdentPart(m_current)) {
     947        record16(m_current);
     948        shift1();
     949    }
     950    flags = makeIdentifier(m_buffer16.data(), m_buffer16.size());
     951    m_buffer16.resize(0);
     952
     953    return true;
     954}
     955
     956bool Lexer::skipRegExp()
     957{
    915958    bool lastWasEscape = false;
    916959    bool inBrackets = false;
     
    927970                    inBrackets = false;
    928971            }
    929             record16(m_current);
    930972            lastWasEscape = !lastWasEscape && m_current == '\\';
    931973        } else { // end of regexp
    932             m_pattern = UString(m_buffer16);
    933             m_buffer16.resize(0);
    934             shift1();
    935             break;
    936         }
    937         shift1();
    938     }
    939 
    940     while (isIdentPart(m_current)) {
    941         record16(m_current);
    942         shift1();
    943     }
    944     m_flags = UString(m_buffer16);
    945     m_buffer16.resize(0);
     974            shift1();
     975            break;
     976        }
     977        shift1();
     978    }
     979
     980    while (isIdentPart(m_current))
     981        shift1();
    946982
    947983    return true;
     
    950986void Lexer::clear()
    951987{
    952     m_identifiers.clear();
     988    m_arena = 0;
    953989    m_codeWithoutBOMs.clear();
    954990
     
    962998
    963999    m_isReparsing = false;
    964 
    965     m_pattern = UString();
    966     m_flags = UString();
    9671000}
    9681001
  • trunk/JavaScriptCore/parser/Lexer.h

    r43358 r43642  
    2424
    2525#include "Lookup.h"
    26 #include "SegmentedVector.h"
     26#include "ParserArena.h"
    2727#include "SourceCode.h"
    2828#include <wtf/ASCIICType.h>
     
    4343
    4444        // Functions to set up parsing.
    45         void setCode(const SourceCode&);
     45        void setCode(const SourceCode&, ParserArena&);
    4646        void setIsReparsing() { m_isReparsing = true; }
    4747
     
    5151        bool prevTerminator() const { return m_terminator; }
    5252        SourceCode sourceCode(int openBrace, int closeBrace, int firstLine);
    53         bool scanRegExp();
    54         const UString& pattern() const { return m_pattern; }
    55         const UString& flags() const { return m_flags; }
     53        bool scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar prefix = 0);
     54        bool skipRegExp();
    5655
    5756        // Functions for use after parsing.
     
    8079        const UChar* currentCharacter() const;
    8180
    82         JSC::Identifier* makeIdentifier(const UChar* buffer, size_t length);
     81        const Identifier* makeIdentifier(const UChar* characters, size_t length);
    8382
    8483        bool lastTokenWasRestrKeyword() const;
    8584
    8685        static const size_t initialReadBufferCapacity = 32;
    87         static const size_t initialIdentifierTableCapacity = 64;
    8886
    8987        int m_lineNumber;
     
    109107        int m_next3;
    110108       
    111         SegmentedVector<JSC::Identifier, initialIdentifierTableCapacity> m_identifiers;
     109        IdentifierArena* m_arena;
    112110
    113111        JSGlobalData* m_globalData;
    114 
    115         UString m_pattern;
    116         UString m_flags;
    117112
    118113        const HashTable m_keywordTable;
  • trunk/JavaScriptCore/parser/NodeConstructors.h

    r43488 r43642  
    2828namespace JSC {
    2929
     30    inline void* ParserArenaFreeable::operator new(size_t size, JSGlobalData* globalData)
     31    {
     32        return globalData->parser->arena().allocateFreeable(size);
     33    }
     34
    3035    inline void* ParserArenaDeletable::operator new(size_t size, JSGlobalData* globalData)
    3136    {
    32         ParserArenaDeletable* deletable = static_cast<ParserArenaDeletable*>(fastMalloc(size));
    33         globalData->parser->arena().deleteWithArena(deletable);
    34         return deletable;
    35     }
    36 
    37     inline void* ParserArenaDeletable::operator new(size_t size)
    38     {
    39         return fastMalloc(size);
     37        return globalData->parser->arena().allocateDeletable(size);
    4038    }
    4139
     
    7977    }
    8078
    81     inline StringNode::StringNode(JSGlobalData* globalData, const Identifier& v)
     79    inline StringNode::StringNode(JSGlobalData* globalData, const Identifier& value)
    8280        : ExpressionNode(globalData, ResultType::stringType())
    83         , m_value(v)
    84     {
    85     }
    86 
    87     inline RegExpNode::RegExpNode(JSGlobalData* globalData, const UString& pattern, const UString& flags)
     81        , m_value(value)
     82    {
     83    }
     84
     85    inline RegExpNode::RegExpNode(JSGlobalData* globalData, const Identifier& pattern, const Identifier& flags)
    8886        : ExpressionNode(globalData)
    8987        , m_pattern(pattern)
     
    145143    inline PropertyNode::PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* assign, Type type)
    146144        : m_name(name)
     145        , m_assign(assign)
     146        , m_type(type)
     147    {
     148    }
     149
     150    inline PropertyNode::PropertyNode(JSGlobalData* globalData, double name, ExpressionNode* assign, Type type)
     151        : m_name(globalData->parser->arena().makeNumericIdentifier(globalData, name))
    147152        , m_assign(assign)
    148153        , m_type(type)
     
    737742    inline ContinueNode::ContinueNode(JSGlobalData* globalData)
    738743        : StatementNode(globalData)
     744        , m_ident(globalData->propertyNames->nullIdentifier)
    739745    {
    740746    }
     
    748754    inline BreakNode::BreakNode(JSGlobalData* globalData)
    749755        : StatementNode(globalData)
     756        , m_ident(globalData->propertyNames->nullIdentifier)
    750757    {
    751758    }
     
    826833    }
    827834
    828     inline CaseClauseNode::CaseClauseNode(JSGlobalData*, ExpressionNode* expr)
     835    inline CaseClauseNode::CaseClauseNode(JSGlobalData*, ExpressionNode* expr, SourceElements* statements)
    829836        : m_expr(expr)
    830     {
    831     }
    832 
    833     inline CaseClauseNode::CaseClauseNode(JSGlobalData*, ExpressionNode* expr, SourceElements* children)
    834         : m_expr(expr)
    835     {
    836         if (children)
    837             children->releaseContentsIntoVector(m_children);
     837        , m_statements(statements)
     838    {
    838839    }
    839840
     
    873874    }
    874875
    875     inline BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children)
    876         : StatementNode(globalData)
    877     {
    878         if (children)
    879             children->releaseContentsIntoVector(m_children);
     876    inline BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* statements)
     877        : StatementNode(globalData)
     878        , m_statements(statements)
     879    {
    880880    }
    881881
    882882    inline ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
    883883        : StatementNode(globalData)
     884        , m_ident(globalData->propertyNames->nullIdentifier)
    884885        , m_init(0)
    885886        , m_lexpr(l)
  • trunk/JavaScriptCore/parser/Nodes.cpp

    r43619 r43642  
    5050namespace JSC {
    5151
    52 static void substitute(UString& string, const UString& substring) JSC_FAST_CALL;
     52/*
     53    Details of the emitBytecode function.
     54
     55    Return value: The register holding the production's value.
     56             dst: An optional parameter specifying the most efficient destination at
     57                  which to store the production's value. The callee must honor dst.
     58
     59    The dst argument provides for a crude form of copy propagation. For example,
     60
     61        x = 1
     62
     63    becomes
     64   
     65        load r[x], 1
     66   
     67    instead of
     68
     69        load r0, 1
     70        mov r[x], r0
     71   
     72    because the assignment node, "x =", passes r[x] as dst to the number node, "1".
     73*/
    5374
    5475// ------------------------------ ThrowableExpressionData --------------------------------
     
    6485}
    6586
    66 RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg)
     87RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* message)
    6788{
    6889    generator.emitExpressionInfo(divot(), startOffset(), endOffset());
    69     RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), msg));
     90    RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message));
    7091    generator.emitThrow(exception);
    7192    return exception;
    7293}
    7394
    74 RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label)
    75 {
    76     UString message = msg;
    77     substitute(message, label.ustring());
     95RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const UString& label)
     96{
     97    UString message = messageTemplate;
     98    substitute(message, label);
    7899    generator.emitExpressionInfo(divot(), startOffset(), endOffset());
    79     RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), message));
     100    RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message));
    80101    generator.emitThrow(exception);
    81102    return exception;
     103}
     104
     105inline RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const Identifier& label)
     106{
     107    return emitThrowError(generator, type, messageTemplate, label.ustring());
    82108}
    83109
     
    99125}
    100126
     127inline StatementNode* SourceElements::singleStatement() const
     128{
     129    size_t size = m_statements.size();
     130    return size == 1 ? m_statements[0] : 0;
     131}
     132
     133inline StatementNode* SourceElements::lastStatement() const
     134{
     135    size_t size = m_statements.size();
     136    return size ? m_statements[size - 1] : 0;
     137}
     138
    101139// ------------------------------ NullNode -------------------------------------
    102140
     
    139177RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    140178{
    141     RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern, m_flags);
     179    RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern.ustring(), m_flags.ustring());
    142180    if (!regExp->isValid())
    143         return emitThrowError(generator, SyntaxError, ("Invalid regular expression: " + UString(regExp->errorMessage())).UTF8String().c_str());
     181        return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", regExp->errorMessage());
    144182    if (dst == generator.ignoredResult())
    145183        return 0;
     
    593631RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
    594632{
    595     return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Postfix ++ operator applied to value that is not a reference." : "Postfix -- operator applied to value that is not a reference.");
     633    return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus
     634        ? "Postfix ++ operator applied to value that is not a reference."
     635        : "Postfix -- operator applied to value that is not a reference.");
    596636}
    597637
     
    755795RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
    756796{
    757     return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Prefix ++ operator applied to value that is not a reference." : "Prefix -- operator applied to value that is not a reference.");
     797    return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus
     798        ? "Prefix ++ operator applied to value that is not a reference."
     799        : "Prefix -- operator applied to value that is not a reference.");
    758800}
    759801
     
    12251267}
    12261268
    1227 // ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
    1228 
    1229 static inline void statementListEmitCode(const StatementVector& statements, BytecodeGenerator& generator, RegisterID* dst)
    1230 {
    1231     size_t size = statements.size();
     1269// ------------------------------ SourceElements -------------------------------
     1270
     1271inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
     1272{
     1273    size_t size = m_statements.size();
    12321274    for (size_t i = 0; i < size; ++i)
    1233         generator.emitNode(dst, statements[i]);
     1275        generator.emitNode(dst, m_statements[i]);
    12341276}
    12351277
    12361278// ------------------------------ BlockNode ------------------------------------
    12371279
     1280inline StatementNode* BlockNode::lastStatement() const
     1281{
     1282    return m_statements ? m_statements->lastStatement() : 0;
     1283}
     1284
    12381285RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    12391286{
    1240     statementListEmitCode(m_children, generator, dst);
     1287    if (m_statements)
     1288        m_statements->emitBytecode(generator, dst);
    12411289    return 0;
    12421290}
     
    15411589    generator.emitPopScope();
    15421590    return result;
     1591}
     1592
     1593// ------------------------------ CaseClauseNode --------------------------------
     1594
     1595inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
     1596{
     1597    if (m_statements)
     1598        m_statements->emitBytecode(generator, dst);
    15431599}
    15441600
     
    16641720    for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
    16651721        generator.emitLabel(labelVector[i++].get());
    1666         statementListEmitCode(list->getClause()->children(), generator, dst);
     1722        list->getClause()->emitBytecode(generator, dst);
    16671723    }
    16681724
    16691725    if (m_defaultClause) {
    16701726        generator.emitLabel(defaultLabel.get());
    1671         statementListEmitCode(m_defaultClause->children(), generator, dst);
     1727        m_defaultClause->emitBytecode(generator, dst);
    16721728    }
    16731729
    16741730    for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
    16751731        generator.emitLabel(labelVector[i++].get());
    1676         statementListEmitCode(list->getClause()->children(), generator, dst);
     1732        list->getClause()->emitBytecode(generator, dst);
    16771733    }
    16781734    if (!m_defaultClause)
     
    18021858// -----------------------------ScopeNodeData ---------------------------
    18031859
    1804 ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants)
     1860ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, int numConstants)
    18051861    : m_numConstants(numConstants)
     1862    , m_statements(statements)
    18061863{
    18071864    m_arena.swap(arena);
     
    18101867    if (funcStack)
    18111868        m_functionStack.swap(*funcStack);
    1812     if (children)
    1813         children->releaseContentsIntoVector(m_children);
    18141869}
    18151870
     
    18511906}
    18521907
     1908inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
     1909{
     1910    if (m_data->m_statements)
     1911        m_data->m_statements->emitBytecode(generator, dst);
     1912}
     1913
     1914inline StatementNode* ScopeNode::singleStatement() const
     1915{
     1916    return m_data->m_statements ? m_data->m_statements->singleStatement() : 0;
     1917}
     1918
    18531919// ------------------------------ ProgramNode -----------------------------
    18541920
     
    18751941    RefPtr<RegisterID> dstRegister = generator.newTemporary();
    18761942    generator.emitLoad(dstRegister.get(), jsUndefined());
    1877     statementListEmitCode(children(), generator, dstRegister.get());
     1943    emitStatementsBytecode(generator, dstRegister.get());
    18781944
    18791945    generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
     
    19191985    RefPtr<RegisterID> dstRegister = generator.newTemporary();
    19201986    generator.emitLoad(dstRegister.get(), jsUndefined());
    1921     statementListEmitCode(children(), generator, dstRegister.get());
     1987    emitStatementsBytecode(generator, dstRegister.get());
    19221988
    19231989    generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
     
    19372003
    19382004    // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time,
    1939     // so the entire ScopeNodeData cannot be destoyed.
    1940     children().clear();
     2005    // so the ScopeNodeData cannot be destroyed at this point. Maybe we can destroy part of it in the future?
    19412006}
    19422007
     
    20922157{
    20932158    generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
    2094     statementListEmitCode(children(), generator, generator.ignoredResult());
    2095     if (children().size() && children().last()->isBlock()) {
    2096         BlockNode* blockNode = static_cast<BlockNode*>(children().last());
    2097         if (blockNode->children().size() && blockNode->children().last()->isReturnNode())
     2159    emitStatementsBytecode(generator, generator.ignoredResult());
     2160    StatementNode* singleStatement = this->singleStatement();
     2161    if (singleStatement && singleStatement->isBlock()) {
     2162        StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement();
     2163        if (lastStatementInBlock && lastStatementInBlock->isReturnNode())
    20982164            return 0;
    20992165    }
  • trunk/JavaScriptCore/parser/Nodes.h

    r43479 r43642  
    3434#include "SourceCode.h"
    3535#include "SymbolTable.h"
     36#include <wtf/FastAllocBase.h>
    3637#include <wtf/MathExtras.h>
    3738#include <wtf/OwnPtr.h>
     
    9394    namespace DeclarationStacks {
    9495        enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
    95         typedef Vector<std::pair<Identifier, unsigned> > VarStack;
     96        typedef Vector<std::pair<const Identifier*, unsigned> > VarStack;
    9697        typedef Vector<FuncDeclNode*> FunctionStack;
    9798    }
     
    103104    };
    104105
    105     class ParserArenaDeletable {
    106     protected:
    107         ParserArenaDeletable() { }
    108 
     106    class ParserArenaFreeable : public FastAllocBase {
     107    public:
     108        using FastAllocBase::operator new;
     109
     110        // Objects created with this version of new are freed when the arena is deleted.
     111        // Destructors are not called. Clients must not call delete on such objects.
     112        void* operator new(size_t, JSGlobalData*);
     113    };
     114
     115    class ParserArenaDeletable : public FastAllocBase {
    109116    public:
    110117        virtual ~ParserArenaDeletable() { }
    111118
     119        using FastAllocBase::operator new;
     120
    112121        // Objects created with this version of new are deleted when the arena is deleted.
     122        // Clients must not call delete directly on such objects.
    113123        void* operator new(size_t, JSGlobalData*);
    114 
    115         // Objects created with this version of new are not deleted when the arena is deleted.
    116         // Other arrangements must be made.
    117         void* operator new(size_t);
    118124    };
    119125
     
    129135    };
    130136
    131     class Node : public ParserArenaDeletable {
     137    class Node : public ParserArenaFreeable {
    132138    protected:
    133139        Node(JSGlobalData*);
    134140
    135141    public:
    136         /*
    137             Return value: The register holding the production's value.
    138                      dst: An optional parameter specifying the most efficient
    139                           destination at which to store the production's value.
    140                           The callee must honor dst.
    141 
    142             dst provides for a crude form of copy propagation. For example,
    143 
    144             x = 1
    145 
    146             becomes
    147            
    148             load r[x], 1
    149            
    150             instead of
    151 
    152             load r0, 1
    153             mov r[x], r0
    154            
    155             because the assignment node, "x =", passes r[x] as dst to the number
    156             node, "1".
    157         */
     142        virtual ~Node() { }
     143
    158144        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) JSC_FAST_CALL = 0;
    159145
     
    249235    class StringNode : public ExpressionNode {
    250236    public:
    251         StringNode(JSGlobalData*, const Identifier& v);
     237        StringNode(JSGlobalData*, const Identifier&);
    252238
    253239        const Identifier& value() { return m_value; }
     240
    254241        virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; }
    255242
     
    259246        virtual bool isString() const JSC_FAST_CALL { return true; }
    260247
    261         Identifier m_value;
     248        const Identifier& m_value;
    262249    };
    263250   
     
    291278    protected:
    292279        RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg);
     280        RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg, const UString&);
    293281        RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg, const Identifier&);
    294282
     
    361349    class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
    362350    public:
    363         RegExpNode(JSGlobalData*, const UString& pattern, const UString& flags);
    364 
    365     private:
    366         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
    367 
    368         UString m_pattern;
    369         UString m_flags;
     351        RegExpNode(JSGlobalData*, const Identifier& pattern, const Identifier& flags);
     352
     353    private:
     354        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
     355
     356        const Identifier& m_pattern;
     357        const Identifier& m_flags;
    370358    };
    371359
     
    382370        ResolveNode(JSGlobalData*, const Identifier&, int startOffset);
    383371
    384         const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
     372        const Identifier& identifier() const { return m_ident; }
    385373
    386374    private:
     
    391379        virtual bool isResolveNode() const JSC_FAST_CALL { return true; }
    392380
    393         Identifier m_ident;
     381        const Identifier& m_ident;
    394382        int32_t m_startOffset;
    395383    };
    396384
    397     class ElementNode : public ParserArenaDeletable {
     385    class ElementNode : public ParserArenaFreeable {
    398386    public:
    399387        ElementNode(JSGlobalData*, int elision, ExpressionNode*);
     
    428416    };
    429417
    430     class PropertyNode : public ParserArenaDeletable {
     418    class PropertyNode : public ParserArenaFreeable {
    431419    public:
    432420        enum Type { Constant, Getter, Setter };
    433421
    434422        PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* value, Type);
     423        PropertyNode(JSGlobalData*, double name, ExpressionNode* value, Type);
    435424
    436425        const Identifier& name() const { return m_name; }
     
    438427    private:
    439428        friend class PropertyListNode;
    440         Identifier m_name;
     429        const Identifier& m_name;
    441430        ExpressionNode* m_assign;
    442431        Type m_type;
     
    488477        DotAccessorNode(JSGlobalData*, ExpressionNode* base, const Identifier&);
    489478
    490         ExpressionNode* base() const JSC_FAST_CALL { return m_base; }
    491         const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
     479        ExpressionNode* base() const { return m_base; }
     480        const Identifier& identifier() const { return m_ident; }
    492481
    493482    private:
     
    498487
    499488        ExpressionNode* m_base;
    500         Identifier m_ident;
     489        const Identifier& m_ident;
    501490    };
    502491
     
    513502    };
    514503
    515     class ArgumentsNode : public ParserArenaDeletable {
     504    class ArgumentsNode : public ParserArenaFreeable {
    516505    public:
    517506        ArgumentsNode(JSGlobalData*);
     
    561550        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
    562551
    563         Identifier m_ident;
     552        const Identifier& m_ident;
    564553        ArgumentsNode* m_args;
    565554        size_t m_index; // Used by LocalVarFunctionCallNode.
     
    588577    protected:
    589578        ExpressionNode* m_base;
    590         const Identifier m_ident;
     579        const Identifier& m_ident;
    591580        ArgumentsNode* m_args;
    592581    };
     
    613602
    614603    protected:
    615         const Identifier m_ident;
     604        const Identifier& m_ident;
    616605    };
    617606
     
    646635
    647636        ExpressionNode* m_base;
    648         Identifier m_ident;
     637        const Identifier& m_ident;
    649638        Operator m_operator;
    650639    };
     
    668657        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
    669658
    670         Identifier m_ident;
     659        const Identifier& m_ident;
    671660    };
    672661
     
    690679
    691680        ExpressionNode* m_base;
    692         Identifier m_ident;
     681        const Identifier& m_ident;
    693682    };
    694683
     
    717706        TypeOfResolveNode(JSGlobalData*, const Identifier&);
    718707
    719         const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
    720 
    721     private:
    722         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
    723 
    724         Identifier m_ident;
     708        const Identifier& identifier() const { return m_ident; }
     709
     710    private:
     711        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
     712
     713        const Identifier& m_ident;
    725714    };
    726715
     
    765754
    766755        ExpressionNode* m_base;
    767         Identifier m_ident;
     756        const Identifier& m_ident;
    768757        Operator m_operator;
    769758    };
     
    1007996        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
    1008997
    1009         Identifier m_ident;
     998        const Identifier& m_ident;
    1010999        ExpressionNode* m_right;
    10111000        size_t m_index; // Used by ReadModifyLocalVarNode.
     
    10211010        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
    10221011
    1023         Identifier m_ident;
     1012        const Identifier& m_ident;
    10241013        ExpressionNode* m_right;
    10251014        size_t m_index; // Used by ReadModifyLocalVarNode.
     
    10641053
    10651054        ExpressionNode* m_base;
    1066         Identifier m_ident;
     1055        const Identifier& m_ident;
    10671056        ExpressionNode* m_right;
    10681057        bool m_rightHasAssignments;
     
    10771066
    10781067        ExpressionNode* m_base;
    1079         Identifier m_ident;
     1068        const Identifier& m_ident;
    10801069        ExpressionNode* m_right;
    10811070        Operator m_operator : 31;
     
    11171106        virtual RegisterID* emitCodeSingle(BytecodeGenerator&) JSC_FAST_CALL;
    11181107
    1119         Identifier m_ident;
     1108        const Identifier& m_ident;
    11201109
    11211110    public:
     
    11361125    };
    11371126
    1138     typedef Vector<StatementNode*> StatementVector;
    1139 
    11401127    class SourceElements : public ParserArenaDeletable {
    11411128    public:
     
    11431130
    11441131        void append(StatementNode*);
    1145         void releaseContentsIntoVector(StatementVector& destination)
    1146         {
    1147             ASSERT(destination.isEmpty());
    1148             m_statements.swap(destination);
    1149             destination.shrinkToFit();
    1150         }
    1151 
    1152     private:
    1153         StatementVector m_statements;
     1132
     1133        StatementNode* singleStatement() const;
     1134        StatementNode* lastStatement() const;
     1135
     1136        void emitBytecode(BytecodeGenerator&, RegisterID* dst);
     1137
     1138    private:
     1139        Vector<StatementNode*> m_statements;
    11541140    };
    11551141
    11561142    class BlockNode : public StatementNode {
    11571143    public:
    1158         BlockNode(JSGlobalData*, SourceElements* children);
    1159 
    1160         StatementVector& children() { return m_children; }
     1144        BlockNode(JSGlobalData*, SourceElements* = 0);
     1145
     1146        StatementNode* lastStatement() const;
    11611147
    11621148    private:
     
    11651151        virtual bool isBlock() const JSC_FAST_CALL { return true; }
    11661152
    1167         StatementVector m_children;
     1153        SourceElements* m_statements;
    11681154    };
    11691155
     
    12751261        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
    12761262
    1277         Identifier m_ident;
     1263        const Identifier& m_ident;
    12781264        ExpressionNode* m_init;
    12791265        ExpressionNode* m_lexpr;
     
    12911277        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
    12921278
    1293         Identifier m_ident;
     1279        const Identifier& m_ident;
    12941280    };
    12951281
     
    13021288        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
    13031289
    1304         Identifier m_ident;
     1290        const Identifier& m_ident;
    13051291    };
    13061292
     
    13371323        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
    13381324
    1339         Identifier m_name;
     1325        const Identifier& m_name;
    13401326        StatementNode* m_statement;
    13411327    };
     
    13591345
    13601346        StatementNode* m_tryBlock;
    1361         Identifier m_exceptionIdent;
     1347        const Identifier& m_exceptionIdent;
    13621348        StatementNode* m_catchBlock;
    13631349        StatementNode* m_finallyBlock;
     
    13651351    };
    13661352
    1367     class ParameterNode : public ParserArenaDeletable {
     1353    class ParameterNode : public ParserArenaFreeable {
    13681354    public:
    13691355        ParameterNode(JSGlobalData*, const Identifier&);
     
    13741360
    13751361    private:
    1376         Identifier m_ident;
     1362        const Identifier& m_ident;
    13771363        ParameterNode* m_next;
    13781364    };
     
    13881374        FunctionStack m_functionStack;
    13891375        int m_numConstants;
    1390         StatementVector m_children;
     1376        SourceElements* m_statements;
    13911377
    13921378        void mark();
     
    14261412        FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
    14271413
    1428         StatementVector& children() { ASSERT(m_data); return m_data->m_children; }
    1429 
    14301414        int neededConstants()
    14311415        {
     
    14381422        virtual void mark() { }
    14391423
     1424        StatementNode* singleStatement() const; // 0 if there is not exactly one statement
     1425
    14401426    protected:
    14411427        void setSource(const SourceCode& source) { m_source = source; }
     1428
     1429        void emitStatementsBytecode(BytecodeGenerator&, RegisterID* dst);
    14421430
    14431431    private:
     
    15011489        virtual ~FunctionBodyNode();
    15021490
    1503         const Identifier* parameters() const JSC_FAST_CALL { return m_parameters; }
     1491        const Identifier* parameters() const { return m_parameters; }
    15041492        size_t parameterCount() const { return m_parameterCount; }
    15051493        UString paramString() const JSC_FAST_CALL;
     
    16061594    };
    16071595
    1608     class CaseClauseNode : public ParserArenaDeletable {
    1609     public:
    1610         CaseClauseNode(JSGlobalData*, ExpressionNode*);
    1611         CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements*);
     1596    class CaseClauseNode : public ParserArenaFreeable {
     1597    public:
     1598        CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements* = 0);
    16121599
    16131600        ExpressionNode* expr() const { return m_expr; }
    1614         StatementVector& children() { return m_children; }
    1615 
    1616     private:
    1617         ExpressionNode* m_expr;
    1618         StatementVector m_children;
    1619     };
    1620 
    1621     class ClauseListNode : public ParserArenaDeletable {
     1601
     1602        void emitBytecode(BytecodeGenerator&, RegisterID* dst);
     1603
     1604    private:
     1605        ExpressionNode* m_expr;
     1606        SourceElements* m_statements;
     1607    };
     1608
     1609    class ClauseListNode : public ParserArenaFreeable {
    16221610    public:
    16231611        ClauseListNode(JSGlobalData*, CaseClauseNode*);
     
    16321620    };
    16331621
    1634     class CaseBlockNode : public ParserArenaDeletable {
     1622    class CaseBlockNode : public ParserArenaFreeable {
    16351623    public:
    16361624        CaseBlockNode(JSGlobalData*, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
  • trunk/JavaScriptCore/parser/Parser.cpp

    r43479 r43642  
    5454
    5555    Lexer& lexer = *globalData->lexer;
    56     lexer.setCode(*m_source);
     56    lexer.setCode(*m_source, m_arena);
    5757
    5858    int parseError = jscyyparse(globalData);
  • trunk/JavaScriptCore/parser/Parser.h

    r43479 r43642  
    2626#include "Debugger.h"
    2727#include "Nodes.h"
     28#include "ParserArena.h"
    2829#include "SourceProvider.h"
    2930#include <wtf/Forward.h>
  • trunk/JavaScriptCore/parser/ParserArena.cpp

    r43479 r43642  
    3131namespace JSC {
    3232
     33ParserArena::ParserArena()
     34    : m_freeableMemory(0)
     35    , m_freeablePoolEnd(0)
     36    , m_identifierArena(new IdentifierArena)
     37{
     38}
     39
     40inline void* ParserArena::freeablePool()
     41{
     42    ASSERT(m_freeablePoolEnd);
     43    return m_freeablePoolEnd - freeablePoolSize;
     44}
     45
     46inline void ParserArena::deallocateObjects()
     47{
     48    if (m_freeablePoolEnd)
     49        fastFree(freeablePool());
     50
     51    size_t size = m_freeablePools.size();
     52    for (size_t i = 0; i < size; ++i)
     53        fastFree(m_freeablePools[i]);
     54
     55    size = m_deletableObjects.size();
     56    for (size_t i = 0; i < size; ++i) {
     57        ParserArenaDeletable* object = m_deletableObjects[i];
     58        object->~ParserArenaDeletable();
     59        fastFree(object);
     60    }
     61}
     62
    3363ParserArena::~ParserArena()
    3464{
    35     deleteAllValues(m_deletableObjects);
     65    deallocateObjects();
    3666}
    3767
     
    5383void ParserArena::reset()
    5484{
    55     deleteAllValues(m_deletableObjects);
    56     m_deletableObjects.shrink(0);
    57     m_refCountedObjects.shrink(0);
     85    // Since this code path is used only when parsing fails, it's not bothering to reuse
     86    // any of the memory the arena allocated. We could improve that later if we want to
     87    // efficiently reuse the same arena.
     88
     89    deallocateObjects();
     90
     91    m_freeableMemory = 0;
     92    m_freeablePoolEnd = 0;
     93    m_identifierArena->clear();
     94    m_freeablePools.clear();
     95    m_deletableObjects.clear();
     96    m_refCountedObjects.clear();
     97}
     98
     99const Identifier& ParserArena::makeNumericIdentifier(JSGlobalData* globalData, double number)
     100{
     101    m_identifierArena->append(Identifier(globalData, UString::from(number)));
     102    return m_identifierArena->last();
     103}
     104
     105void ParserArena::allocateFreeablePool()
     106{
     107    if (m_freeablePoolEnd)
     108        m_freeablePools.append(freeablePool());
     109
     110    char* pool = static_cast<char*>(fastMalloc(freeablePoolSize));
     111    m_freeableMemory = pool;
     112    m_freeablePoolEnd = pool + freeablePoolSize;
     113    ASSERT(freeablePool() == pool);
     114}
     115
     116bool ParserArena::isEmpty() const
     117{
     118    return !m_freeablePoolEnd
     119        && m_identifierArena->isEmpty()
     120        && m_freeablePools.isEmpty()
     121        && m_deletableObjects.isEmpty()
     122        && m_refCountedObjects.isEmpty();
    58123}
    59124
  • trunk/JavaScriptCore/parser/ParserArena.h

    r43479 r43642  
    2727#define ParserArena_h
    2828
    29 #include <wtf/PassRefPtr.h>
    30 #include <wtf/RefPtr.h>
    31 #include <wtf/Vector.h>
     29#include "Identifier.h"
     30#include "SegmentedVector.h"
    3231
    3332namespace JSC {
     
    3635    class ParserArenaRefCounted;
    3736
    38     class ParserArena {
     37    typedef SegmentedVector<Identifier, 64> IdentifierArena;
     38
     39    class ParserArena : Noncopyable {
    3940    public:
     41        ParserArena();
     42        ~ParserArena();
     43
    4044        void swap(ParserArena& otherArena)
    4145        {
     46            std::swap(m_freeableMemory, otherArena.m_freeableMemory);
     47            std::swap(m_freeablePoolEnd, otherArena.m_freeablePoolEnd);
     48            m_identifierArena.swap(otherArena.m_identifierArena);
     49            m_freeablePools.swap(otherArena.m_freeablePools);
    4250            m_deletableObjects.swap(otherArena.m_deletableObjects);
    4351            m_refCountedObjects.swap(otherArena.m_refCountedObjects);
    4452        }
    45         ~ParserArena();
    4653
    47         void deleteWithArena(ParserArenaDeletable* object) { m_deletableObjects.append(object); }
     54        void* allocateFreeable(size_t size)
     55        {
     56            ASSERT(size);
     57            ASSERT(size <= freeablePoolSize);
     58            size_t alignedSize = alignSize(size);
     59            ASSERT(alignedSize <= freeablePoolSize);
     60            if (UNLIKELY(static_cast<size_t>(m_freeablePoolEnd - m_freeableMemory) < alignedSize))
     61                allocateFreeablePool();
     62            void* block = m_freeableMemory;
     63            m_freeableMemory += alignedSize;
     64            return block;
     65        }
     66
     67        void* allocateDeletable(size_t size)
     68        {
     69            ParserArenaDeletable* deletable = static_cast<ParserArenaDeletable*>(fastMalloc(size));
     70            m_deletableObjects.append(deletable);
     71            return deletable;
     72        }
     73
    4874        void derefWithArena(PassRefPtr<ParserArenaRefCounted> object) { m_refCountedObjects.append(object); }
    49 
    5075        bool contains(ParserArenaRefCounted*) const;
    5176        ParserArenaRefCounted* last() const;
    5277        void removeLast();
    5378
    54         bool isEmpty() const { return m_deletableObjects.isEmpty() && m_refCountedObjects.isEmpty(); }
     79        bool isEmpty() const;
    5580        void reset();
    5681
     82        const Identifier& makeIdentifier(JSGlobalData*, const UChar* character, size_t length);
     83        const Identifier& makeNumericIdentifier(JSGlobalData*, double number);
     84
     85        IdentifierArena& identifierArena() { return *m_identifierArena; }
     86
    5787    private:
     88        static const size_t freeablePoolSize = 8000;
     89
     90        static size_t alignSize(size_t size)
     91        {
     92            return (size + sizeof(WTF::AllocAlignmentInteger) - 1) & ~(sizeof(WTF::AllocAlignmentInteger) - 1);
     93        }
     94
     95        void* freeablePool();
     96        void allocateFreeablePool();
     97        void deallocateObjects();
     98
     99        char* m_freeableMemory;
     100        char* m_freeablePoolEnd;
     101
     102        OwnPtr<IdentifierArena> m_identifierArena;
     103        Vector<void*> m_freeablePools;
    58104        Vector<ParserArenaDeletable*> m_deletableObjects;
    59105        Vector<RefPtr<ParserArenaRefCounted> > m_refCountedObjects;
    60106    };
    61107
     108    ALWAYS_INLINE const Identifier& makeIdentifier(IdentifierArena& arena, JSGlobalData* globalData, const UChar* characters, size_t length)
     109    {
     110        arena.append(Identifier(globalData, characters, length));
     111        return arena.last();
     112    }
     113
     114    ALWAYS_INLINE const Identifier& ParserArena::makeIdentifier(JSGlobalData* globalData, const UChar* characters, size_t length)
     115    {
     116        return JSC::makeIdentifier(*m_identifierArena, globalData, characters, length);
     117    }
     118
    62119}
    63120
Note: See TracChangeset for help on using the changeset viewer.