Changeset 133688 in webkit


Ignore:
Timestamp:
Nov 6, 2012 4:13:54 PM (11 years ago)
Author:
oliver@apple.com
Message:

Reduce parser overhead in JSC
https://bugs.webkit.org/show_bug.cgi?id=101127

Reviewed by Filip Pizlo.

An exciting journey into the world of architecture in which our hero
adds yet another layer to JSC codegeneration.

This patch adds a marginally more compact form of bytecode that is
free from any data specific to a given execution context, and that
does store any data structures necessary for execution. To actually
execute this UnlinkedBytecode we still need to instantiate a real
CodeBlock, but this is a much faster linear time operation than any
of the earlier parsing or code generation passes.

As the unlinked code is context free we can then simply use a cache
from source to unlinked code mapping to completely avoid all of the
old parser overhead. The cache is currently very simple and memory
heavy, using the complete source text as a key (rather than SourceCode
or equivalent), and a random eviction policy.

This seems to produce a substantial win when loading identical content
in different contexts.

  • API/tests/testapi.c:

(main):

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/CodeBlock.cpp:
  • bytecode/CodeBlock.h:

Moved a number of fields, and a bunch of logic to UnlinkedCodeBlock.h/cpp

  • bytecode/Opcode.h:

Added a global const init no op instruction needed to get correct
behaviour without any associated semantics.

  • bytecode/UnlinkedCodeBlock.cpp: Added.
  • bytecode/UnlinkedCodeBlock.h: Added.

A fairly shallow, GC allocated version of the old CodeBlock
classes with a 32bit instruction size, and just metadata
size tracking.

  • bytecompiler/BytecodeGenerator.cpp:
  • bytecompiler/BytecodeGenerator.h:

Replace direct access to m_symbolTable with access through
symbolTable(). ProgramCode no longer has a symbol table at
all so some previously unconditional (and pointless) uses
of symbolTable get null checks.
A few other changes to deal with type changes due to us generating
unlinked code (eg. pointer free, so profile indices rather than
pointers).

  • dfg/DFGByteCodeParser.cpp:
  • dfg/DFGCapabilities.h:

Support global_init_nop

  • interpreter/Interpreter.cpp:

Now get the ProgramExecutable to initialise new global properties
before starting execution.

  • jit/JIT.cpp:
  • jit/JITDriver.h:
  • jit/JITStubs.cpp:
  • llint/LLIntData.cpp:
  • llint/LLIntSlowPaths.cpp:
  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:

Adding init_global_const_nop everywhere else

  • parser/Parser.h:
  • parser/ParserModes.h: Added.
  • parser/ParserTokens.h:

Parser no longer needs a global object or callframe to function

  • runtime/CodeCache.cpp: Added.
  • runtime/CodeCache.h: Added.

A simple, random eviction, Source->UnlinkedCode cache

  • runtime/Executable.cpp:
  • runtime/Executable.h:

Executables now reference their unlinked counterparts, and
request code specifically for the target global object.

  • runtime/JSGlobalData.cpp:
  • runtime/JSGlobalData.h:

GlobalData now owns a CodeCache and a set of new structures
for the unlinked code types.

  • runtime/JSGlobalObject.cpp:
  • runtime/JSGlobalObject.h:

Utility functions used by executables to perform compilation

  • runtime/JSType.h: Add new JSTypes for unlinked code
Location:
trunk/Source/JavaScriptCore
Files:
5 added
45 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r133564 r133688  
    6060    bytecode/StructureStubClearingWatchpoint.cpp
    6161    bytecode/StructureStubInfo.cpp
     62    bytecode/UnlinkedCodeBlock.cpp
    6263    bytecode/Watchpoint.cpp
    6364
     
    175176    runtime/BooleanPrototype.cpp
    176177    runtime/CallData.cpp
     178    runtime/CodeCache.cpp
    177179    runtime/CommonIdentifiers.cpp
    178180    runtime/Completion.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r133672 r133688  
     12012-11-06  Oliver Hunt  <oliver@apple.com>
     2
     3        Reduce parser overhead in JSC
     4        https://bugs.webkit.org/show_bug.cgi?id=101127
     5
     6        Reviewed by Filip Pizlo.
     7
     8        An exciting journey into the world of architecture in which our hero
     9        adds yet another layer to JSC codegeneration.
     10
     11        This patch adds a marginally more compact form of bytecode that is
     12        free from any data specific to a given execution context, and that
     13        does store any data structures necessary for execution.  To actually
     14        execute this UnlinkedBytecode we still need to instantiate a real
     15        CodeBlock, but this is a much faster linear time operation than any
     16        of the earlier parsing or code generation passes.
     17
     18        As the unlinked code is context free we can then simply use a cache
     19        from source to unlinked code mapping to completely avoid all of the
     20        old parser overhead.  The cache is currently very simple and memory
     21        heavy, using the complete source text as a key (rather than SourceCode
     22        or equivalent), and a random eviction policy.
     23
     24        This seems to produce a substantial win when loading identical content
     25        in different contexts.
     26
     27        * API/tests/testapi.c:
     28        (main):
     29        * CMakeLists.txt:
     30        * GNUmakefile.list.am:
     31        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
     32        * JavaScriptCore.xcodeproj/project.pbxproj:
     33        * bytecode/CodeBlock.cpp:
     34        * bytecode/CodeBlock.h:
     35            Moved a number of fields, and a bunch of logic to UnlinkedCodeBlock.h/cpp
     36        * bytecode/Opcode.h:
     37            Added a global const init no op instruction needed to get correct
     38            behaviour without any associated semantics.
     39        * bytecode/UnlinkedCodeBlock.cpp: Added.
     40        * bytecode/UnlinkedCodeBlock.h: Added.
     41            A fairly shallow, GC allocated version of the old CodeBlock
     42            classes with a 32bit instruction size, and just metadata
     43            size tracking.
     44        * bytecompiler/BytecodeGenerator.cpp:
     45        * bytecompiler/BytecodeGenerator.h:
     46            Replace direct access to m_symbolTable with access through
     47            symbolTable().  ProgramCode no longer has a symbol table at
     48            all so some previously unconditional (and pointless) uses
     49            of symbolTable get null checks.
     50            A few other changes to deal with type changes due to us generating
     51            unlinked code (eg. pointer free, so profile indices rather than
     52            pointers).
     53        * dfg/DFGByteCodeParser.cpp:
     54        * dfg/DFGCapabilities.h:
     55            Support global_init_nop       
     56        * interpreter/Interpreter.cpp:
     57            Now get the ProgramExecutable to initialise new global properties
     58            before starting execution.       
     59        * jit/JIT.cpp:
     60        * jit/JITDriver.h:
     61        * jit/JITStubs.cpp:
     62        * llint/LLIntData.cpp:
     63        * llint/LLIntSlowPaths.cpp:
     64        * llint/LowLevelInterpreter.asm:
     65        * llint/LowLevelInterpreter32_64.asm:
     66        * llint/LowLevelInterpreter64.asm:
     67            Adding init_global_const_nop everywhere else
     68        * parser/Parser.h:
     69        * parser/ParserModes.h: Added.
     70        * parser/ParserTokens.h:
     71            Parser no longer needs a global object or callframe to function       
     72        * runtime/CodeCache.cpp: Added.
     73        * runtime/CodeCache.h: Added.
     74            A simple, random eviction, Source->UnlinkedCode cache       
     75        * runtime/Executable.cpp:
     76        * runtime/Executable.h:
     77            Executables now reference their unlinked counterparts, and
     78            request code specifically for the target global object.       
     79        * runtime/JSGlobalData.cpp:
     80        * runtime/JSGlobalData.h:
     81            GlobalData now owns a CodeCache and a set of new structures
     82            for the unlinked code types. 
     83        * runtime/JSGlobalObject.cpp:
     84        * runtime/JSGlobalObject.h:
     85            Utility functions used by executables to perform compilation
     86 
     87        * runtime/JSType.h:
     88          Add new JSTypes for unlinked code
     89
    1902012-11-06  Michael Saboff  <msaboff@apple.com>
    291
     
    20182107        (JSC::JIT::compileOpStrictEq):
    20192108        (JSC::JIT::emit_op_catch):
    2020         (JSC::JIT::emit_op_throw_reference_error):
     2109        (JSC::JIT::emit_op_throw_static_error):
    20212110        (JSC::JIT::emit_op_eq_null):
    20222111        (JSC::JIT::emit_op_neq_null):
  • trunk/Source/JavaScriptCore/GNUmakefile.list.am

    r133564 r133688  
    139139        Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp \
    140140        Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h \
     141        Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp \
     142        Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h \
    141143        Source/JavaScriptCore/bytecode/ValueProfile.h \
    142144        Source/JavaScriptCore/bytecode/ValueRecovery.h \
     
    445447        Source/JavaScriptCore/parser/Parser.cpp \
    446448        Source/JavaScriptCore/parser/Parser.h \
     449        Source/JavaScriptCore/parser/ParserModes.h \
    447450        Source/JavaScriptCore/parser/ResultType.h \
    448451        Source/JavaScriptCore/parser/SourceCode.h \
     
    485488        Source/JavaScriptCore/runtime/CallData.h \
    486489        Source/JavaScriptCore/runtime/ClassInfo.h \
     490        Source/JavaScriptCore/runtime/CodeCache.cpp \
     491        Source/JavaScriptCore/runtime/CodeCache.h \
    487492        Source/JavaScriptCore/runtime/CodeSpecializationKind.h \
    488493        Source/JavaScriptCore/runtime/CommonIdentifiers.cpp \
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj

    r133564 r133688  
    639639                        </File>
    640640                        <File
     641                                RelativePath="..\..\runtime\CodeCache.cpp"
     642                                >
     643                        </File>
     644                        <File
     645                                RelativePath="..\..\runtime\CodeCache.h"
     646                                >
     647                        </File>
     648                        <File
    641649                                RelativePath="..\..\runtime\CommonIdentifiers.cpp"
    642650                                >
     
    17471755                        </File>
    17481756                        <File
     1757                                RelativePath="..\..\bytecode\UnlinkedCodeBlock.cpp"
     1758                                >
     1759                        </File>
     1760                        <File
     1761                                RelativePath="..\..\bytecode\UnlinkedCodeBlock.h"
     1762                                >
     1763                        </File>
     1764                        <File
    17491765                                RelativePath="..\..\bytecode\ValueProfile.h"
    17501766                                >
     
    22282244                        <File
    22292245                                RelativePath="..\..\parser\Parser.h"
     2246                                >
     2247                        </File>
     2248                        <File
     2249                                RelativePath="..\..\parser\ParserModes.h"
    22302250                                >
    22312251                        </File>
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r133564 r133688  
    581581                A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
    582582                A76C51761182748D00715B05 /* JSInterfaceJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = A76C51741182748D00715B05 /* JSInterfaceJIT.h */; settings = {ATTRIBUTES = (Private, ); }; };
     583                A76F279415F13C9600517D67 /* UnlinkedCodeBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A79E781E15EECBA80047C855 /* UnlinkedCodeBlock.cpp */; };
    583584                A76F54A313B28AAB00EF2BCE /* JITWriteBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */; };
     585                A77F1821164088B200640A47 /* CodeCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A77F181F164088B200640A47 /* CodeCache.cpp */; };
     586                A77F1822164088B200640A47 /* CodeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A77F1820164088B200640A47 /* CodeCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
     587                A77F1825164192C700640A47 /* ParserModes.h in Headers */ = {isa = PBXBuildFile; fileRef = A77F18241641925400640A47 /* ParserModes.h */; settings = {ATTRIBUTES = (Private, ); }; };
    584588                A784A26111D16622005776AC /* ASTBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7411B98B8D0065A14F /* ASTBuilder.h */; };
    585589                A784A26411D16622005776AC /* SyntaxChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7711B98B8D0065A14F /* SyntaxChecker.h */; };
     
    587591                A7B48F490EE8936F00DCBDB6 /* ExecutableAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */; };
    588592                A7B4ACAF1484C9CE00B38A36 /* JSExportMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B4ACAE1484C9CE00B38A36 /* JSExportMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
     593                A7B601821639FD2A00372BA3 /* UnlinkedCodeBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
    589594                A7C1E8E4112E72EF00A37F98 /* JITPropertyAccess32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */; };
    590595                A7DCB97312E5193F00911940 /* WriteBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = A7DCB77912E3D90500911940 /* WriteBarrier.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    13791384                A76C51741182748D00715B05 /* JSInterfaceJIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInterfaceJIT.h; sourceTree = "<group>"; };
    13801385                A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITWriteBarrier.h; sourceTree = "<group>"; };
     1386                A77F181F164088B200640A47 /* CodeCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeCache.cpp; sourceTree = "<group>"; };
     1387                A77F1820164088B200640A47 /* CodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeCache.h; sourceTree = "<group>"; };
     1388                A77F18241641925400640A47 /* ParserModes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ParserModes.h; sourceTree = "<group>"; };
     1389                A79E781E15EECBA80047C855 /* UnlinkedCodeBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkedCodeBlock.cpp; sourceTree = "<group>"; };
     1390                A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedCodeBlock.h; sourceTree = "<group>"; };
    13811391                A79EDB0811531CD60019E912 /* JSObjectRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObjectRefPrivate.h; sourceTree = "<group>"; };
    13821392                A7A7EE7411B98B8D0065A14F /* ASTBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTBuilder.h; sourceTree = "<group>"; };
     
    20642074                                E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */,
    20652075                                A7A7EE7711B98B8D0065A14F /* SyntaxChecker.h */,
     2076                                A77F18241641925400640A47 /* ParserModes.h */,
    20662077                        );
    20672078                        path = parser;
     
    22982309                                A7DCB77912E3D90500911940 /* WriteBarrier.h */,
    22992310                                C2D58C3315912FEE0021A844 /* GCActivityCallback.cpp */,
     2311                                A77F181F164088B200640A47 /* CodeCache.cpp */,
     2312                                A77F1820164088B200640A47 /* CodeCache.h */,
    23002313                        );
    23012314                        path = runtime;
     
    25682581                                0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */,
    25692582                                0F93329B14CA7DC10085F3C6 /* StructureSet.h */,
     2583                                A79E781E15EECBA80047C855 /* UnlinkedCodeBlock.cpp */,
     2584                                A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */,
    25702585                        );
    25712586                        path = bytecode;
     
    29943009                                0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */,
    29953010                                C2239D1B16262BDD005AC5FD /* GCThread.h in Headers */,
     3011                                A7B601821639FD2A00372BA3 /* UnlinkedCodeBlock.h in Headers */,
     3012                                A77F1822164088B200640A47 /* CodeCache.h in Headers */,
     3013                                A77F1825164192C700640A47 /* ParserModes.h in Headers */,
    29963014                        );
    29973015                        runOnlyForDeploymentPostprocessing = 0;
     
    35703588                                C2239D1716262BDD005AC5FD /* CopyVisitor.cpp in Sources */,
    35713589                                C2239D1A16262BDD005AC5FD /* GCThread.cpp in Sources */,
     3590                                A76F279415F13C9600517D67 /* UnlinkedCodeBlock.cpp in Sources */,
     3591                                A77F1821164088B200640A47 /* CodeCache.cpp in Sources */,
    35723592                        );
    35733593                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/JavaScriptCore/Target.pri

    r133564 r133688  
    7070    bytecode/StructureStubClearingWatchpoint.cpp \
    7171    bytecode/StructureStubInfo.cpp \
     72    bytecode/UnlinkedCodeBlock.cpp \
    7273    bytecode/Watchpoint.cpp \
    7374    bytecompiler/BytecodeGenerator.cpp \
     
    185186    runtime/BooleanPrototype.cpp \
    186187    runtime/CallData.cpp \
     188    runtime/CodeCache.cpp \
    187189    runtime/CommonIdentifiers.cpp \
    188190    runtime/Completion.cpp \
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r133669 r133688  
    528528    }
    529529
    530     if (m_rareData && !m_rareData->m_regexps.isEmpty()) {
     530    if (size_t count = m_unlinkedCode->numberOfRegExps()) {
    531531        dataLog("\nm_regexps:\n");
    532532        size_t i = 0;
    533533        do {
    534             dataLog("  re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_rareData->m_regexps[i].get()).utf8().data());
     534            dataLog("  re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_unlinkedCode->regexp(i)).utf8().data());
    535535            ++i;
    536         } while (i < m_rareData->m_regexps.size());
     536        } while (i < count);
    537537    }
    538538
     
    668668            int argv = (++it)->u.operand;
    669669            int argc = (++it)->u.operand;
    670             dataLog("[%4d] new_array_buffer %s, %d, %d", location, registerName(exec, dst).data(), argv, argc);
     670            dataLog("[%4d] new_array_buffer\t %s, %d, %d", location, registerName(exec, dst).data(), argv, argc);
    671671            dumpBytecodeCommentAndNewLine(location);
    672672            break;
     
    676676            int re0 = (++it)->u.operand;
    677677            dataLog("[%4d] new_regexp\t %s, ", location, registerName(exec, r0).data());
    678             if (r0 >=0 && r0 < (int)numberOfRegExps())
     678            if (r0 >=0 && r0 < (int)m_unlinkedCode->numberOfRegExps())
    679679                dataLog("%s", regexpName(re0, regexp(re0)).data());
    680680            else
     
    886886            break;
    887887        }
     888        case op_init_global_const_nop: {
     889            dataLog("[%4d] init_global_const_nop\t", location);
     890            dumpBytecodeCommentAndNewLine(location);
     891            it++;
     892            it++;
     893            it++;
     894            it++;
     895            break;
     896        }
    888897        case op_init_global_const: {
    889898            WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
     
    891900            dataLog("[%4d] init_global_const\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
    892901            dumpBytecodeCommentAndNewLine(location);
     902            it++;
     903            it++;
    893904            break;
    894905        }
     
    13921403            break;
    13931404        }
    1394         case op_throw_reference_error: {
     1405        case op_throw_static_error: {
    13951406            int k0 = (++it)->u.operand;
    1396             dataLog("[%4d] throw_reference_error\t %s", location, constantName(exec, k0, getConstant(k0)).data());
     1407            int k1 = (++it)->u.operand;
     1408            dataLog("[%4d] throw_static_error\t %s, %s", location, constantName(exec, k0, getConstant(k0)).data(), k1 ? "true" : "false");
    13971409            dumpBytecodeCommentAndNewLine(location);
    13981410            break;
     
    14921504        #undef GET_STATS
    14931505
    1494         if (!codeBlock->symbolTable().isEmpty()) {
     1506        if (codeBlock->symbolTable() && !codeBlock->symbolTable()->isEmpty()) {
    14951507            symbolTableIsNotEmpty++;
    1496             symbolTableTotalSize += (codeBlock->symbolTable().capacity() * (sizeof(SymbolTable::KeyType) + sizeof(SymbolTable::MappedType)));
     1508            symbolTableTotalSize += (codeBlock->symbolTable()->capacity() * (sizeof(SymbolTable::KeyType) + sizeof(SymbolTable::MappedType)));
    14971509        }
    14981510
     
    15621574    , m_numVars(other.m_numVars)
    15631575    , m_isConstructor(other.m_isConstructor)
     1576    , m_unlinkedCode(*other.m_globalData, other.m_ownerExecutable.get(), other.m_unlinkedCode.get())
    15641577    , m_ownerExecutable(*other.m_globalData, other.m_ownerExecutable.get(), other.m_ownerExecutable.get())
    15651578    , m_globalData(other.m_globalData)
     
    15681581    , m_argumentsRegister(other.m_argumentsRegister)
    15691582    , m_activationRegister(other.m_activationRegister)
    1570     , m_needsFullScopeChain(other.m_needsFullScopeChain)
    1571     , m_usesEval(other.m_usesEval)
    1572     , m_isNumericCompareFunction(other.m_isNumericCompareFunction)
    15731583    , m_isStrictMode(other.m_isStrictMode)
    1574     , m_codeType(other.m_codeType)
    15751584    , m_source(other.m_source)
    15761585    , m_sourceOffset(other.m_sourceOffset)
     
    15781587    , m_executionEntryCount(0)
    15791588#endif
    1580     , m_jumpTargets(other.m_jumpTargets)
    1581     , m_loopTargets(other.m_loopTargets)
    15821589    , m_identifiers(other.m_identifiers)
    15831590    , m_constantRegisters(other.m_constantRegisters)
    15841591    , m_functionDecls(other.m_functionDecls)
    15851592    , m_functionExprs(other.m_functionExprs)
    1586     , m_symbolTable(*other.m_globalData, other.m_ownerExecutable.get(), other.symbolTable())
    15871593    , m_osrExitCounter(0)
    15881594    , m_optimizationDelayCounter(0)
    15891595    , m_reoptimizationRetryCounter(0)
    1590     , m_lineInfo(other.m_lineInfo)
    15911596    , m_resolveOperations(other.m_resolveOperations)
    15921597    , m_putToBaseOperations(other.m_putToBaseOperations)
     
    16061611       
    16071612        m_rareData->m_exceptionHandlers = other.m_rareData->m_exceptionHandlers;
    1608         m_rareData->m_regexps = other.m_rareData->m_regexps;
    16091613        m_rareData->m_constantBuffers = other.m_rareData->m_constantBuffers;
    16101614        m_rareData->m_immediateSwitchJumpTables = other.m_rareData->m_immediateSwitchJumpTables;
    16111615        m_rareData->m_characterSwitchJumpTables = other.m_rareData->m_characterSwitchJumpTables;
    16121616        m_rareData->m_stringSwitchJumpTables = other.m_rareData->m_stringSwitchJumpTables;
    1613         m_rareData->m_expressionInfo = other.m_rareData->m_expressionInfo;
    1614     }
    1615 }
    1616 
    1617 CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject *globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, bool isConstructor, PassOwnPtr<CodeBlock> alternative)
     1617    }
     1618}
     1619
     1620CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, unsigned baseScopeDepth, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative)
    16181621    : m_globalObject(globalObject->globalData(), ownerExecutable, globalObject)
    16191622    , m_heap(&m_globalObject->globalData().heap)
    1620     , m_numCalleeRegisters(0)
    1621     , m_numVars(0)
    1622     , m_isConstructor(isConstructor)
    1623     , m_numParameters(0)
     1623    , m_numCalleeRegisters(unlinkedCodeBlock->m_numCalleeRegisters)
     1624    , m_numVars(unlinkedCodeBlock->m_numVars)
     1625    , m_isConstructor(unlinkedCodeBlock->isConstructor())
     1626    , m_unlinkedCode(globalObject->globalData(), ownerExecutable, unlinkedCodeBlock)
    16241627    , m_ownerExecutable(globalObject->globalData(), ownerExecutable, ownerExecutable)
    1625     , m_globalData(0)
    1626     , m_argumentsRegister(-1)
    1627     , m_needsFullScopeChain(ownerExecutable->needsActivation())
    1628     , m_usesEval(ownerExecutable->usesEval())
    1629     , m_isNumericCompareFunction(false)
    1630     , m_isStrictMode(ownerExecutable->isStrictMode())
    1631     , m_codeType(codeType)
     1628    , m_globalData(unlinkedCodeBlock->globalData())
     1629    , m_thisRegister(unlinkedCodeBlock->thisRegister())
     1630    , m_argumentsRegister(unlinkedCodeBlock->argumentsRegister())
     1631    , m_activationRegister(unlinkedCodeBlock->activationRegister())
     1632    , m_isStrictMode(unlinkedCodeBlock->isStrictMode())
    16321633    , m_source(sourceProvider)
    16331634    , m_sourceOffset(sourceOffset)
     
    16351636    , m_executionEntryCount(0)
    16361637#endif
    1637     , m_symbolTable(globalObject->globalData(), ownerExecutable, SharedSymbolTable::create(globalObject->globalData()))
    16381638    , m_alternative(alternative)
    16391639    , m_osrExitCounter(0)
     
    16441644#endif
    16451645{
     1646    m_globalData->startedCompiling(this);
     1647
    16461648    ASSERT(m_source);
     1649    setNumParameters(unlinkedCodeBlock->numParameters());
    16471650
    16481651    optimizeAfterWarmUp();
     
    16521655    liveCodeBlockSet.add(this);
    16531656#endif
    1654     // We have a stub putToBase operation to allow resolve_base to
    1655     // remain branchless
    1656     m_putToBaseOperations.append(PutToBaseOperation(isStrictMode()));
     1657    setIdentifiers(unlinkedCodeBlock->identifiers());
     1658    setConstantRegisters(unlinkedCodeBlock->constantRegisters());
     1659
     1660    m_functionDecls.grow(unlinkedCodeBlock->numberOfFunctionDecls());
     1661    for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) {
     1662        UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
     1663        unsigned lineCount = unlinkedExecutable->lineCount();
     1664        unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset();
     1665        unsigned startOffset = sourceOffset + unlinkedExecutable->startOffset();
     1666        unsigned sourceLength = unlinkedExecutable->sourceLength();
     1667        SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine);
     1668        FunctionExecutable* executable = FunctionExecutable::create(*m_globalData, code, unlinkedExecutable, firstLine, firstLine + lineCount);
     1669        m_functionDecls[i].set(*m_globalData, ownerExecutable, executable);
     1670    }
     1671
     1672    m_functionExprs.grow(unlinkedCodeBlock->numberOfFunctionExprs());
     1673    for (size_t count = unlinkedCodeBlock->numberOfFunctionExprs(), i = 0; i < count; ++i) {
     1674        UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i);
     1675        unsigned lineCount = unlinkedExecutable->lineCount();
     1676        unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset();
     1677        unsigned startOffset = sourceOffset + unlinkedExecutable->startOffset();
     1678        unsigned sourceLength = unlinkedExecutable->sourceLength();
     1679        SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine);
     1680        FunctionExecutable* executable = FunctionExecutable::create(*m_globalData, code, unlinkedExecutable, firstLine, firstLine + lineCount);
     1681        m_functionExprs[i].set(*m_globalData, ownerExecutable, executable);
     1682    }
     1683
     1684    if (unlinkedCodeBlock->hasRareData()) {
     1685        createRareDataIfNecessary();
     1686        if (size_t count = unlinkedCodeBlock->constantBufferCount()) {
     1687            m_rareData->m_constantBuffers.grow(count);
     1688            for (size_t i = 0; i < count; i++) {
     1689                const UnlinkedCodeBlock::ConstantBuffer& buffer = unlinkedCodeBlock->constantBuffer(i);
     1690                m_rareData->m_constantBuffers[i] = buffer;
     1691            }
     1692        }
     1693        if (size_t count = unlinkedCodeBlock->numberOfExceptionHandlers()) {
     1694            m_rareData->m_exceptionHandlers.grow(count);
     1695            for (size_t i = 0; i < count; i++) {
     1696                const UnlinkedHandlerInfo& handler = unlinkedCodeBlock->exceptionHandler(i);
     1697                m_rareData->m_exceptionHandlers[i].start = handler.start;
     1698                m_rareData->m_exceptionHandlers[i].end = handler.end;
     1699                m_rareData->m_exceptionHandlers[i].target = handler.target;
     1700                m_rareData->m_exceptionHandlers[i].scopeDepth = handler.scopeDepth + baseScopeDepth;
     1701#if ENABLE(JIT) && ENABLE(LLINT)
     1702                m_rareData->m_exceptionHandlers[i].nativeCode = CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(llint_op_catch)));
     1703#endif
     1704            }
     1705        }
     1706
     1707        if (size_t count = unlinkedCodeBlock->numberOfStringSwitchJumpTables()) {
     1708            m_rareData->m_stringSwitchJumpTables.grow(count);
     1709            for (size_t i = 0; i < count; i++) {
     1710                UnlinkedStringJumpTable::StringOffsetTable::iterator ptr = unlinkedCodeBlock->stringSwitchJumpTable(i).offsetTable.begin();
     1711                UnlinkedStringJumpTable::StringOffsetTable::iterator end = unlinkedCodeBlock->stringSwitchJumpTable(i).offsetTable.end();
     1712                for (; ptr != end; ++ptr) {
     1713                    OffsetLocation offset;
     1714                    offset.branchOffset = ptr->value;
     1715                    m_rareData->m_stringSwitchJumpTables[i].offsetTable.add(ptr->key, offset);
     1716                }
     1717            }
     1718        }
     1719
     1720        if (size_t count = unlinkedCodeBlock->numberOfImmediateSwitchJumpTables()) {
     1721            m_rareData->m_immediateSwitchJumpTables.grow(count);
     1722            for (size_t i = 0; i < count; i++) {
     1723                UnlinkedSimpleJumpTable& sourceTable = unlinkedCodeBlock->immediateSwitchJumpTable(i);
     1724                SimpleJumpTable& destTable = m_rareData->m_immediateSwitchJumpTables[i];
     1725                destTable.branchOffsets = sourceTable.branchOffsets;
     1726                destTable.min = sourceTable.min;
     1727            }
     1728        }
     1729
     1730        if (size_t count = unlinkedCodeBlock->numberOfCharacterSwitchJumpTables()) {
     1731            m_rareData->m_characterSwitchJumpTables.grow(count);
     1732            for (size_t i = 0; i < count; i++) {
     1733                UnlinkedSimpleJumpTable& sourceTable = unlinkedCodeBlock->characterSwitchJumpTable(i);
     1734                SimpleJumpTable& destTable = m_rareData->m_characterSwitchJumpTables[i];
     1735                destTable.branchOffsets = sourceTable.branchOffsets;
     1736                destTable.min = sourceTable.min;
     1737            }
     1738        }
     1739    }
     1740
     1741    // Allocate metadata buffers for the bytecode
     1742#if ENABLE(LLINT)
     1743    if (size_t size = unlinkedCodeBlock->numberOfLLintCallLinkInfos())
     1744        m_llintCallLinkInfos.grow(size);
     1745#endif
     1746#if ENABLE(DFG_JIT)
     1747    if (size_t size = unlinkedCodeBlock->numberOfArrayProfiles())
     1748        m_arrayProfiles.grow(size);
     1749    if (size_t size = unlinkedCodeBlock->numberOfValueProfiles())
     1750        m_valueProfiles.grow(size);
     1751#endif
     1752    if (size_t size = unlinkedCodeBlock->numberOfResolveOperations())
     1753        m_resolveOperations.grow(size);
     1754    size_t putToBaseCount = unlinkedCodeBlock->numberOfPutToBaseOperations();
     1755    m_putToBaseOperations.reserveCapacity(putToBaseCount);
     1756    for (size_t i = 0; i < putToBaseCount; ++i)
     1757        m_putToBaseOperations.append(PutToBaseOperation(isStrictMode()));
     1758
     1759    ASSERT(m_putToBaseOperations.capacity() == putToBaseCount);
     1760
     1761    // Copy and translate the UnlinkedInstructions
     1762    size_t instructionCount = unlinkedCodeBlock->instructions().size();
     1763    UnlinkedInstruction* pc = unlinkedCodeBlock->instructions().data();
     1764    Vector<Instruction> instructions(instructionCount);
     1765    for (size_t i = 0; i < unlinkedCodeBlock->instructions().size(); ) {
     1766        unsigned opLength = opcodeLength(pc[i].u.opcode);
     1767        instructions[i] = globalData()->interpreter->getOpcode(pc[i].u.opcode);
     1768        for (size_t j = 1; j < opLength; ++j) {
     1769            if (sizeof(int32_t) != sizeof(intptr_t))
     1770                instructions[i + j].u.pointer = 0;
     1771            instructions[i + j].u.operand = pc[i + j].u.operand;
     1772        }
     1773        switch (pc[i].u.opcode) {
     1774#if ENABLE(DFG_JIT)
     1775        case op_get_by_val:
     1776        case op_get_argument_by_val: {
     1777            int arrayProfileIndex = pc[i + opLength - 2].u.operand;
     1778            m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
     1779
     1780            instructions[i + opLength - 2] = &m_arrayProfiles[arrayProfileIndex];
     1781            // fallthrough
     1782        }
     1783        case op_convert_this:
     1784        case op_resolve:
     1785        case op_resolve_base:
     1786        case op_resolve_with_base:
     1787        case op_resolve_with_this:
     1788        case op_get_by_id:
     1789        case op_call_put_result: {
     1790            ValueProfile* profile = &m_valueProfiles[pc[i + opLength - 1].u.operand];
     1791            ASSERT(profile->m_bytecodeOffset == -1);
     1792            profile->m_bytecodeOffset = i;
     1793            instructions[i + opLength - 1] = profile;
     1794            break;
     1795        }
     1796        case op_put_by_val: {
     1797            int arrayProfileIndex = pc[i + opLength - 1].u.operand;
     1798            m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
     1799            instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex];
     1800            break;
     1801        }
     1802
     1803        case op_call:
     1804        case op_call_eval: {
     1805            int arrayProfileIndex = pc[i + opLength - 1].u.operand;
     1806            m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
     1807            instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex];
     1808            // fallthrough
     1809        }
     1810#endif
     1811#if ENABLE(LLINT)
     1812        case op_construct:
     1813            instructions[i + 4] = &m_llintCallLinkInfos[pc[i + 4].u.operand];
     1814            break;
     1815#endif
     1816        case op_get_by_id_out_of_line:
     1817        case op_get_by_id_self:
     1818        case op_get_by_id_proto:
     1819        case op_get_by_id_chain:
     1820        case op_get_by_id_getter_self:
     1821        case op_get_by_id_getter_proto:
     1822        case op_get_by_id_getter_chain:
     1823        case op_get_by_id_custom_self:
     1824        case op_get_by_id_custom_proto:
     1825        case op_get_by_id_custom_chain:
     1826        case op_get_by_id_generic:
     1827        case op_get_array_length:
     1828        case op_get_string_length:
     1829            CRASH();
     1830
     1831        case op_init_global_const_nop: {
     1832            ASSERT(codeType() == GlobalCode);
     1833            Identifier ident = identifier(pc[i + 4].u.operand);
     1834            SymbolTableEntry entry = globalObject->symbolTable()->get(ident.impl());
     1835            if (entry.isNull())
     1836                break;
     1837
     1838            if (entry.couldBeWatched()) {
     1839                instructions[i + 0] = globalData()->interpreter->getOpcode(op_init_global_const_check);
     1840                instructions[i + 1] = &globalObject->registerAt(entry.getIndex());
     1841                instructions[i + 3] = entry.addressOfIsWatched();
     1842                break;
     1843            }
     1844
     1845            instructions[i + 0] = globalData()->interpreter->getOpcode(op_init_global_const);
     1846            instructions[i + 1] = &globalObject->registerAt(entry.getIndex());
     1847            break;
     1848        }
     1849        default:
     1850            break;
     1851        }
     1852        i += opLength;
     1853    }
     1854    m_instructions = WTF::RefCountedArray<Instruction>(instructions);
     1855
     1856    if (BytecodeGenerator::dumpsGeneratedCode())
     1857        dump(m_globalObject->globalExec());
     1858    m_globalData->finishedCompiling(this);
    16571859}
    16581860
     
    17021904#if ENABLE(VALUE_PROFILER)
    17031905    m_argumentValueProfiles.resize(newValue);
    1704 #endif
    1705 }
    1706 
    1707 void CodeBlock::addParameter()
    1708 {
    1709     m_numParameters++;
    1710 
    1711 #if ENABLE(VALUE_PROFILER)
    1712     m_argumentValueProfiles.append(ValueProfile());
    17131906#endif
    17141907}
     
    17961989        m_alternative->visitAggregate(visitor);
    17971990
     1991    visitor.append(&m_unlinkedCode);
     1992
    17981993    // There are three things that may use unconditional finalizers: lazy bytecode freeing,
    17991994    // inline cache clearing, and jettisoning. The probability of us wanting to do at
     
    19102105    Interpreter* interpreter = m_globalData->interpreter;
    19112106    if (!!numberOfInstructions()) {
    1912         for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) {
    1913             Instruction* curInstruction = &instructions()[m_propertyAccessInstructions[i]];
     2107        const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
     2108        for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
     2109            Instruction* curInstruction = &instructions()[propertyAccessInstructions[i]];
    19142110            switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) {
    19152111            case op_get_by_id:
     
    20632259    visitor.append(&m_globalObject);
    20642260    visitor.append(&m_ownerExecutable);
    2065     visitor.append(&m_symbolTable);
    2066     if (m_rareData) {
     2261    visitor.append(&m_unlinkedCode);
     2262    if (m_rareData)
    20672263        m_rareData->m_evalCodeCache.visitAggregate(visitor);
    2068         size_t regExpCount = m_rareData->m_regexps.size();
    2069         WriteBarrier<RegExp>* regexps = m_rareData->m_regexps.data();
    2070         for (size_t i = 0; i < regExpCount; i++)
    2071             visitor.append(regexps + i);
    2072     }
    20732264    visitor.appendValues(m_constantRegisters.data(), m_constantRegisters.size());
    20742265    for (size_t i = 0; i < m_functionExprs.size(); ++i)
     
    21972388{
    21982389    ASSERT(bytecodeOffset < instructions().size());
    2199 
    2200     Vector<LineInfo>& lineInfo = m_lineInfo;
    2201 
    2202     int low = 0;
    2203     int high = lineInfo.size();
    2204     while (low < high) {
    2205         int mid = low + (high - low) / 2;
    2206         if (lineInfo[mid].instructionOffset <= bytecodeOffset)
    2207             low = mid + 1;
    2208         else
    2209             high = mid;
    2210     }
    2211 
    2212     if (!low)
    2213         return m_ownerExecutable->source().firstLine();
    2214     return lineInfo[low - 1].lineNumber;
     2390    return m_ownerExecutable->lineNo() + m_unlinkedCode->lineNumberForBytecodeOffset(bytecodeOffset);
    22152391}
    22162392
    22172393void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset)
    22182394{
    2219     ASSERT(bytecodeOffset < instructions().size());
    2220 
    2221     if (!m_rareData) {
    2222         startOffset = 0;
    2223         endOffset = 0;
    2224         divot = 0;
    2225         return;
    2226     }
    2227 
    2228     Vector<ExpressionRangeInfo>& expressionInfo = m_rareData->m_expressionInfo;
    2229 
    2230     int low = 0;
    2231     int high = expressionInfo.size();
    2232     while (low < high) {
    2233         int mid = low + (high - low) / 2;
    2234         if (expressionInfo[mid].instructionOffset <= bytecodeOffset)
    2235             low = mid + 1;
    2236         else
    2237             high = mid;
    2238     }
    2239 
    2240     ASSERT(low);
    2241     if (!low) {
    2242         startOffset = 0;
    2243         endOffset = 0;
    2244         divot = 0;
    2245         return;
    2246     }
    2247 
    2248     startOffset = expressionInfo[low - 1].startOffset;
    2249     endOffset = expressionInfo[low - 1].endOffset;
    2250     divot = expressionInfo[low - 1].divotPoint + m_sourceOffset;
    2251     return;
     2395    m_unlinkedCode->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset);
     2396    divot += m_sourceOffset;
    22522397}
    22532398
    22542399void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
    22552400{
    2256     m_propertyAccessInstructions.shrinkToFit();
    22572401#if ENABLE(LLINT)
    22582402    m_llintCallLinkInfos.shrinkToFit();
     
    22652409    if (shrinkMode == EarlyShrink)
    22662410        m_argumentValueProfiles.shrinkToFit();
    2267     m_valueProfiles.shrinkToFit();
    22682411    m_rareCaseProfiles.shrinkToFit();
    22692412    m_specialFastCaseProfiles.shrinkToFit();
     
    22772420    } // else don't shrink these, because we would have already pointed pointers into these tables.
    22782421
    2279     m_resolveOperations.shrinkToFit();
    2280     m_lineInfo.shrinkToFit();
    22812422    if (m_rareData) {
    22822423        m_rareData->m_exceptionHandlers.shrinkToFit();
    2283         m_rareData->m_regexps.shrinkToFit();
    22842424        m_rareData->m_immediateSwitchJumpTables.shrinkToFit();
    22852425        m_rareData->m_characterSwitchJumpTables.shrinkToFit();
    22862426        m_rareData->m_stringSwitchJumpTables.shrinkToFit();
    2287         m_rareData->m_expressionInfo.shrinkToFit();
    22882427#if ENABLE(JIT)
    22892428        m_rareData->m_callReturnIndexVector.shrinkToFit();
     
    23132452    ASSERT(needsFullScopeChain());
    23142453    ASSERT(!callFrame->uncheckedR(activationRegister()).jsValue());
    2315     JSActivation* activation = JSActivation::create(callFrame->globalData(), callFrame, static_cast<FunctionExecutable*>(ownerExecutable()));
     2454    JSActivation* activation = JSActivation::create(callFrame->globalData(), callFrame, this);
    23162455    callFrame->uncheckedR(activationRegister()) = JSValue(activation);
    23172456    callFrame->setScope(activation);
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r133669 r133688  
    121121        CodeBlock(CopyParsedBlockTag, CodeBlock& other);
    122122       
    123         CodeBlock(ScriptExecutable* ownerExecutable, CodeType, JSGlobalObject*, PassRefPtr<SourceProvider>, unsigned sourceOffset, bool isConstructor, PassOwnPtr<CodeBlock> alternative);
     123        CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSGlobalObject*, unsigned baseScopeDepth, PassRefPtr<SourceProvider>, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative);
    124124
    125125        WriteBarrier<JSGlobalObject> m_globalObject;
     
    131131        int numParameters() const { return m_numParameters; }
    132132        void setNumParameters(int newValue);
    133         void addParameter();
    134133       
    135134        int* addressOfNumParameters() { return &m_numParameters; }
     
    435434        }
    436435
    437         void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
    438         bool isNumericCompareFunction() { return m_isNumericCompareFunction; }
     436        bool isNumericCompareFunction() { return m_unlinkedCode->isNumericCompareFunction(); }
    439437
    440438        unsigned numberOfInstructions() const { return m_instructions.size(); }
     
    525523        int thisRegister() const { return m_thisRegister; }
    526524
    527         void setNeedsFullScopeChain(bool needsFullScopeChain) { m_needsFullScopeChain = needsFullScopeChain; }
    528         bool needsFullScopeChain() const { return m_needsFullScopeChain; }
    529         void setUsesEval(bool usesEval) { m_usesEval = usesEval; }
    530         bool usesEval() const { return m_usesEval; }
     525        bool needsFullScopeChain() const { return m_unlinkedCode->needsFullScopeChain(); }
     526        bool usesEval() const { return m_unlinkedCode->usesEval(); }
    531527       
    532528        void setArgumentsRegister(int argumentsRegister)
     
    590586                return true;
    591587
     588            // We're in global code so there are no locals to capture
     589            if (!symbolTable())
     590                return false;
     591
    592592            return operand >= symbolTable()->captureStart()
    593593                && operand < symbolTable()->captureEnd();
    594594        }
    595595
    596         CodeType codeType() const { return m_codeType; }
     596        CodeType codeType() const { return m_unlinkedCode->codeType(); }
    597597
    598598        SourceProvider* source() const { return m_source.get(); }
    599599        unsigned sourceOffset() const { return m_sourceOffset; }
    600600
    601         size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
    602         void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
    603         unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
    604         unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
     601        size_t numberOfJumpTargets() const { return m_unlinkedCode->numberOfJumpTargets(); }
     602        unsigned jumpTarget(int index) const { return m_unlinkedCode->jumpTarget(index); }
    605603
    606604        void createActivation(CallFrame*);
     
    609607       
    610608        String nameForRegister(int registerNumber);
    611        
    612         void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
    613         {
    614             m_propertyAccessInstructions.append(propertyAccessInstruction);
    615         }
    616 #if ENABLE(LLINT)
    617         LLIntCallLinkInfo* addLLIntCallLinkInfo()
    618         {
    619             m_llintCallLinkInfos.append(LLIntCallLinkInfo());
    620             return &m_llintCallLinkInfos.last();
    621         }
    622 #endif
     609
    623610#if ENABLE(JIT)
    624611        void setNumberOfStructureStubInfos(size_t size) { m_structureStubInfos.grow(size); }
     
    648635            return result;
    649636        }
    650        
    651         ValueProfile* addValueProfile(int bytecodeOffset)
    652         {
    653             ASSERT(bytecodeOffset != -1);
    654             ASSERT(m_valueProfiles.isEmpty() || m_valueProfiles.last().m_bytecodeOffset < bytecodeOffset);
    655             m_valueProfiles.append(ValueProfile(bytecodeOffset));
    656             return &m_valueProfiles.last();
    657         }
     637
    658638        unsigned numberOfValueProfiles() { return m_valueProfiles.size(); }
    659639        ValueProfile* valueProfile(int index)
     
    781761
    782762        size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
    783         void addExceptionHandler(const HandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); }
     763        void allocateHandlers(const Vector<UnlinkedHandlerInfo>& unlinkedHandlers)
     764        {
     765            size_t count = unlinkedHandlers.size();
     766            if (!count)
     767                return;
     768            createRareDataIfNecessary();
     769            m_rareData->m_exceptionHandlers.resize(count);
     770            for (size_t i = 0; i < count; ++i) {
     771                m_rareData->m_exceptionHandlers[i].start = unlinkedHandlers[i].start;
     772                m_rareData->m_exceptionHandlers[i].end = unlinkedHandlers[i].end;
     773                m_rareData->m_exceptionHandlers[i].target = unlinkedHandlers[i].target;
     774                m_rareData->m_exceptionHandlers[i].scopeDepth = unlinkedHandlers[i].scopeDepth;
     775            }
     776
     777        }
    784778        HandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
    785779
    786         void addExpressionInfo(const ExpressionRangeInfo& expressionInfo)
    787         {
    788             createRareDataIfNecessary();
    789             m_rareData->m_expressionInfo.append(expressionInfo);
    790         }
    791 
    792         void addLineInfo(unsigned bytecodeOffset, int lineNo)
    793         {
    794             Vector<LineInfo>& lineInfo = m_lineInfo;
    795             if (!lineInfo.size() || lineInfo.last().lineNumber != lineNo) {
    796                 LineInfo info = { bytecodeOffset, lineNo };
    797                 lineInfo.append(info);
    798             }
    799         }
    800 
    801         bool hasExpressionInfo() { return m_rareData && m_rareData->m_expressionInfo.size(); }
     780        bool hasExpressionInfo() { return m_unlinkedCode->hasExpressionInfo(); }
    802781
    803782#if ENABLE(JIT)
     
    874853            return result;
    875854        }
     855
     856
    876857        unsigned addOrFindConstant(JSValue);
    877858        WriteBarrier<Unknown>& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
     
    897878        FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
    898879
    899         unsigned addRegExp(RegExp* r)
    900         {
    901             createRareDataIfNecessary();
    902             unsigned size = m_rareData->m_regexps.size();
    903             m_rareData->m_regexps.append(WriteBarrier<RegExp>(*m_globalData, ownerExecutable(), r));
    904             return size;
    905         }
    906         unsigned numberOfRegExps() const
    907         {
    908             if (!m_rareData)
    909                 return 0;
    910             return m_rareData->m_regexps.size();
    911         }
    912         RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
     880        RegExp* regexp(int index) const { return m_unlinkedCode->regexp(index); }
    913881
    914882        unsigned numberOfConstantBuffers() const
     
    925893            return size;
    926894        }
    927         unsigned addConstantBuffer(unsigned length)
    928         {
    929             return addConstantBuffer(Vector<JSValue>(length));
    930         }
    931895
    932896        Vector<JSValue>& constantBufferAsVector(unsigned index)
     
    965929
    966930
    967         SharedSymbolTable* symbolTable() const { return m_symbolTable.get(); }
     931        SharedSymbolTable* symbolTable() const { return m_unlinkedCode->symbolTable(); }
    968932
    969933        EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
     
    12091173        virtual void finalizeUnconditionally();
    12101174
     1175        UnlinkedCodeBlock* unlinkedCodeBlock() const { return m_unlinkedCode.get(); }
     1176
    12111177    private:
    12121178        friend class DFGCodeBlocks;
     
    12201186        void updateAllPredictionsAndCountLiveness(OperationInProgress, unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles);
    12211187#endif
    1222        
     1188
     1189        void setIdentifiers(const Vector<Identifier>& identifiers)
     1190        {
     1191            ASSERT(m_identifiers.isEmpty());
     1192            m_identifiers.appendVector(identifiers);
     1193        }
     1194
     1195        void setConstantRegisters(const Vector<WriteBarrier<Unknown> >& constants)
     1196        {
     1197            size_t count = constants.size();
     1198            m_constantRegisters.resize(count);
     1199            for (size_t i = 0; i < count; i++)
     1200                m_constantRegisters[i].set(*m_globalData, ownerExecutable(), constants[i].get());
     1201        }
     1202
    12231203        void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&);
    12241204
     
    12701250        void resetStubInternal(RepatchBuffer&, StructureStubInfo&);
    12711251#endif
    1272        
     1252        WriteBarrier<UnlinkedCodeBlock> m_unlinkedCode;
    12731253        int m_numParameters;
    1274 
    12751254        WriteBarrier<ScriptExecutable> m_ownerExecutable;
    12761255        JSGlobalData* m_globalData;
    12771256
    12781257        RefCountedArray<Instruction> m_instructions;
    1279 
    12801258        int m_thisRegister;
    12811259        int m_argumentsRegister;
    12821260        int m_activationRegister;
    12831261
    1284         bool m_needsFullScopeChain;
    1285         bool m_usesEval;
    1286         bool m_isNumericCompareFunction;
    12871262        bool m_isStrictMode;
    1288 
    1289         CodeType m_codeType;
    12901263
    12911264        RefPtr<SourceProvider> m_source;
    12921265        unsigned m_sourceOffset;
    12931266
    1294         Vector<unsigned> m_propertyAccessInstructions;
    12951267#if ENABLE(LLINT)
    12961268        SegmentedVector<LLIntCallLinkInfo, 8> m_llintCallLinkInfos;
     
    13631335#endif
    13641336
    1365         Vector<unsigned> m_jumpTargets;
    1366         Vector<unsigned> m_loopTargets;
    1367 
    13681337        // Constant Pool
    13691338        Vector<Identifier> m_identifiers;
    13701339        COMPILE_ASSERT(sizeof(Register) == sizeof(WriteBarrier<Unknown>), Register_must_be_same_size_as_WriteBarrier_Unknown);
     1340        // TODO: This could just be a pointer to m_unlinkedCodeBlock's data, but the DFG mutates
     1341        // it, so we're stuck with it for now.
    13711342        Vector<WriteBarrier<Unknown> > m_constantRegisters;
    13721343        Vector<WriteBarrier<FunctionExecutable> > m_functionDecls;
    13731344        Vector<WriteBarrier<FunctionExecutable> > m_functionExprs;
    1374 
    1375         WriteBarrier<SharedSymbolTable> m_symbolTable;
    13761345
    13771346        OwnPtr<CodeBlock> m_alternative;
     
    13851354        uint16_t m_reoptimizationRetryCounter;
    13861355
    1387         Vector<LineInfo> m_lineInfo;
    1388 #if ENABLE(BYTECODE_COMMENTS)
    1389         Vector<Comment>  m_bytecodeComments;
    1390         size_t m_bytecodeCommentIterator;
    1391 #endif
    13921356        Vector<ResolveOperations> m_resolveOperations;
    13931357        Vector<PutToBaseOperation, 1> m_putToBaseOperations;
     
    13971361        public:
    13981362            Vector<HandlerInfo> m_exceptionHandlers;
    1399 
    1400             // Rare Constants
    1401             Vector<WriteBarrier<RegExp> > m_regexps;
    14021363
    14031364            // Buffers used for large array literals
     
    14111372            EvalCodeCache m_evalCodeCache;
    14121373
    1413             // Expression info - present if debugging.
    1414             Vector<ExpressionRangeInfo> m_expressionInfo;
    1415             // Line info - present if profiling or debugging.
    14161374#if ENABLE(JIT)
    14171375            Vector<CallReturnOffsetToBytecodeOffset> m_callReturnIndexVector;
     
    14411399        }
    14421400       
    1443         GlobalCodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative)
    1444             : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, false, alternative)
     1401        GlobalCodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, unsigned baseScopeDepth, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative)
     1402            : CodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, baseScopeDepth, sourceProvider, sourceOffset, alternative)
    14451403        {
    14461404        }
     
    14541412        }
    14551413
    1456         ProgramCodeBlock(ProgramExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, PassOwnPtr<CodeBlock> alternative)
    1457             : GlobalCodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, 0, alternative)
    1458         {
    1459         }
    1460        
     1414        ProgramCodeBlock(ProgramExecutable* ownerExecutable, UnlinkedProgramCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, PassOwnPtr<CodeBlock> alternative)
     1415            : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, 0, sourceProvider, 0, alternative)
     1416        {
     1417        }
     1418
    14611419#if ENABLE(JIT)
    14621420    protected:
     
    14731431        EvalCodeBlock(CopyParsedBlockTag, EvalCodeBlock& other)
    14741432            : GlobalCodeBlock(CopyParsedBlock, other)
    1475             , m_baseScopeDepth(other.m_baseScopeDepth)
    1476             , m_variables(other.m_variables)
    1477         {
    1478         }
    1479        
    1480         EvalCodeBlock(EvalExecutable* ownerExecutable, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth, PassOwnPtr<CodeBlock> alternative)
    1481             : GlobalCodeBlock(ownerExecutable, EvalCode, globalObject, sourceProvider, 0, alternative)
    1482             , m_baseScopeDepth(baseScopeDepth)
    1483         {
    1484         }
    1485 
    1486         int baseScopeDepth() const { return m_baseScopeDepth; }
    1487 
    1488         const Identifier& variable(unsigned index) { return m_variables[index]; }
    1489         unsigned numVariables() { return m_variables.size(); }
    1490         void adoptVariables(Vector<Identifier>& variables)
    1491         {
    1492             ASSERT(m_variables.isEmpty());
    1493             m_variables.swap(variables);
    1494         }
     1433        {
     1434        }
     1435       
     1436        EvalCodeBlock(EvalExecutable* ownerExecutable, UnlinkedEvalCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth, PassOwnPtr<CodeBlock> alternative)
     1437            : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, baseScopeDepth, sourceProvider, 0, alternative)
     1438        {
     1439        }
     1440
     1441        const Identifier& variable(unsigned index) { return unlinkedEvalCodeBlock()->variable(index); }
     1442        unsigned numVariables() { return unlinkedEvalCodeBlock()->numVariables(); }
    14951443       
    14961444#if ENABLE(JIT)
     
    15041452
    15051453    private:
    1506         int m_baseScopeDepth;
    1507         Vector<Identifier> m_variables;
     1454        UnlinkedEvalCodeBlock* unlinkedEvalCodeBlock() const { return jsCast<UnlinkedEvalCodeBlock*>(unlinkedCodeBlock()); }
    15081455    };
    15091456
     
    15151462        }
    15161463
    1517         FunctionCodeBlock(FunctionExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, bool isConstructor, PassOwnPtr<CodeBlock> alternative = nullptr)
    1518             : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, isConstructor, alternative)
     1464        FunctionCodeBlock(FunctionExecutable* ownerExecutable, UnlinkedFunctionCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative = nullptr)
     1465            : CodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, 0, sourceProvider, sourceOffset, alternative)
    15191466        {
    15201467        }
  • trunk/Source/JavaScriptCore/bytecode/Opcode.h

    r133564 r133688  
    119119        macro(op_put_to_base_variable, 5) \
    120120        \
    121         macro(op_init_global_const, 3) \
     121        macro(op_init_global_const_nop, 5) \
     122        macro(op_init_global_const, 5) \
    122123        macro(op_init_global_const_check, 5) \
    123124        macro(op_get_by_id, 9) /* has value profiling */ \
     
    205206        macro(op_catch, 2) \
    206207        macro(op_throw, 2) \
    207         macro(op_throw_reference_error, 2) \
     208        macro(op_throw_static_error, 3) \
    208209        \
    209210        macro(op_debug, 5) \
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r133564 r133688  
    159159}
    160160
    161 JSObject* BytecodeGenerator::generate()
     161ParserError BytecodeGenerator::generate()
    162162{
    163163    SamplingRegion samplingRegion("Bytecode Generation");
     
    170170        TryRange& range = m_tryRanges[i];
    171171        ASSERT(range.tryData->targetScopeDepth != UINT_MAX);
    172         HandlerInfo info = {
     172        UnlinkedHandlerInfo info = {
    173173            static_cast<uint32_t>(range.start->bind(0, 0)), static_cast<uint32_t>(range.end->bind(0, 0)),
    174             static_cast<uint32_t>(range.tryData->target->bind(0, 0)), static_cast<uint32_t>(range.tryData->targetScopeDepth)
    175 #if ENABLE(JIT)
    176             ,
    177 #if ENABLE(LLINT)
    178             CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(llint_op_catch)))
    179 #else
    180             CodeLocationLabel()
    181 #endif
    182 #endif
     174            static_cast<uint32_t>(range.tryData->target->bind(0, 0)),
     175            range.tryData->targetScopeDepth
    183176        };
    184177        m_codeBlock->addExceptionHandler(info);
    185178    }
    186179   
    187     m_codeBlock->instructions() = RefCountedArray<Instruction>(m_instructions);
    188 
    189     if (s_dumpsGeneratedCode)
    190         m_codeBlock->dump(m_scope->globalObject()->globalExec());
    191 
    192 #ifdef NDEBUG
    193     if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode)
    194         symbolTable().clear();
    195 #endif
    196 
    197     m_codeBlock->shrinkToFit(CodeBlock::EarlyShrink);
     180    m_codeBlock->instructions() = RefCountedArray<UnlinkedInstruction>(m_instructions);
     181
     182    m_codeBlock->shrinkToFit();
    198183
    199184    if (m_expressionTooDeep)
    200         return createOutOfMemoryError(m_scope->globalObject());
    201     return 0;
     185        return ParserError::OutOfMemory;
     186    return ParserError::ErrorNone;
    202187}
    203188
     
    217202}
    218203
    219 int BytecodeGenerator::addGlobalVar(
    220     const Identifier& ident, ConstantMode constantMode, FunctionMode functionMode)
    221 {
    222     UNUSED_PARAM(functionMode);
    223     int index = symbolTable().size();
    224     SymbolTableEntry newEntry(index, (constantMode == IsConstant) ? ReadOnly : 0);
    225     if (functionMode == IsFunctionToSpecialize)
    226         newEntry.attemptToWatch();
    227     SymbolTable::AddResult result = symbolTable().add(ident.impl(), newEntry);
    228     if (!result.isNewEntry) {
    229         result.iterator->value.notifyWrite();
    230         index = result.iterator->value.getIndex();
    231     }
    232     return index;
    233 }
    234 
    235204void BytecodeGenerator::preserveLastVar()
    236205{
     
    239208}
    240209
    241 BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, JSScope* scope, SharedSymbolTable* symbolTable, ProgramCodeBlock* codeBlock, CompilationKind compilationKind)
    242     : m_shouldEmitDebugHooks(scope->globalObject()->debugger())
    243     , m_shouldEmitProfileHooks(scope->globalObject()->globalObjectMethodTable()->supportsProfiling(scope->globalObject()))
    244     , m_shouldEmitRichSourceInfo(scope->globalObject()->globalObjectMethodTable()->supportsRichSourceInfo(scope->globalObject()))
    245     , m_scope(*scope->globalData(), scope)
    246     , m_symbolTable(symbolTable)
     210BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
     211    : m_shouldEmitDebugHooks(debuggerMode == DebuggerOn)
     212    , m_shouldEmitProfileHooks(profilerMode == ProfilerOn)
    247213#if ENABLE(BYTECODE_COMMENTS)
    248214    , m_currentCommentString(0)
    249215#endif
     216    , m_symbolTable(0)
    250217    , m_scopeNode(programNode)
    251     , m_codeBlock(codeBlock)
     218    , m_codeBlock(globalData, codeBlock)
    252219    , m_thisRegister(CallFrame::thisArgumentOffset())
    253220    , m_emptyValueRegister(0)
    254221    , m_finallyDepth(0)
    255222    , m_dynamicScopeDepth(0)
    256     , m_baseScopeDepth(0)
    257223    , m_codeType(GlobalCode)
    258224    , m_nextConstantOffset(0)
     
    261227    , m_firstLazyFunction(0)
    262228    , m_lastLazyFunction(0)
    263     , m_globalData(scope->globalData())
     229    , m_globalData(&globalData)
    264230    , m_lastOpcodeID(op_end)
    265231#ifndef NDEBUG
     
    270236    , m_expressionTooDeep(false)
    271237{
    272     m_globalData->startedCompiling(m_codeBlock);
    273    
    274238    if (m_shouldEmitDebugHooks)
    275239        m_codeBlock->setNeedsFullScopeChain(true);
    276240
    277     codeBlock->setGlobalData(m_globalData);
    278     symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());   
    279241    m_codeBlock->setNumParameters(1); // Allocate space for "this"
    280242
     
    282244    emitOpcode(op_enter);
    283245
    284     // FIXME: Move code that modifies the global object to Interpreter::execute.
    285    
    286     if (compilationKind == OptimizingCompilation)
    287         return;
    288 
    289     JSGlobalObject* globalObject = scope->globalObject();
    290     ExecState* exec = globalObject->globalExec();
    291    
    292     BatchedTransitionOptimizer optimizer(*m_globalData, globalObject);
    293 
    294246    const VarStack& varStack = programNode->varStack();
    295247    const FunctionStack& functionStack = programNode->functionStack();
    296248
    297     size_t newGlobals = varStack.size() + functionStack.size();
    298     if (!newGlobals)
    299         return;
    300     globalObject->addRegisters(newGlobals);
    301 
    302249    for (size_t i = 0; i < functionStack.size(); ++i) {
    303250        FunctionBodyNode* function = functionStack[i];
    304         bool propertyDidExist =
    305             globalObject->removeDirect(*m_globalData, function->ident()); // Newly declared functions overwrite existing properties.
    306 
    307         JSValue value = JSFunction::create(exec, FunctionExecutable::create(*m_globalData, function), scope);
    308         int index = addGlobalVar(
    309             function->ident(), IsVariable,
    310             !propertyDidExist ? IsFunctionToSpecialize : NotFunctionOrNotSpecializable);
    311         globalObject->registerAt(index).set(*m_globalData, globalObject, value);
    312     }
    313 
    314     for (size_t i = 0; i < varStack.size(); ++i) {
    315         if (globalObject->hasProperty(exec, *varStack[i].first))
    316             continue;
    317         addGlobalVar(
    318             *varStack[i].first,
    319             (varStack[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable,
    320             NotFunctionOrNotSpecializable);
    321     }
    322 }
    323 
    324 BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, JSScope* scope, SharedSymbolTable* symbolTable, CodeBlock* codeBlock, CompilationKind)
    325     : m_shouldEmitDebugHooks(scope->globalObject()->debugger())
    326     , m_shouldEmitProfileHooks(scope->globalObject()->globalObjectMethodTable()->supportsProfiling(scope->globalObject()))
    327     , m_shouldEmitRichSourceInfo(scope->globalObject()->globalObjectMethodTable()->supportsRichSourceInfo(scope->globalObject()))
    328     , m_scope(*scope->globalData(), scope)
    329     , m_symbolTable(symbolTable)
     251        UnlinkedFunctionExecutable* unlinkedFunction = makeFunction(function);
     252        codeBlock->addFunctionDeclaration(*m_globalData, function->ident(), unlinkedFunction);
     253    }
     254
     255    for (size_t i = 0; i < varStack.size(); ++i)
     256        codeBlock->addVariableDeclaration(*varStack[i].first, !!(varStack[i].second & DeclarationStacks::IsConstant));
     257
     258}
     259
     260BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, FunctionBodyNode* functionBody, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
     261    : m_shouldEmitDebugHooks(debuggerMode == DebuggerOn)
     262    , m_shouldEmitProfileHooks(profilerMode == ProfilerOn)
     263    , m_symbolTable(codeBlock->symbolTable())
    330264#if ENABLE(BYTECODE_COMMENTS)
    331265    , m_currentCommentString(0)
    332266#endif
    333267    , m_scopeNode(functionBody)
    334     , m_codeBlock(codeBlock)
     268    , m_codeBlock(globalData, codeBlock)
    335269    , m_activationRegister(0)
    336270    , m_emptyValueRegister(0)
    337271    , m_finallyDepth(0)
    338272    , m_dynamicScopeDepth(0)
    339     , m_baseScopeDepth(0)
    340273    , m_codeType(FunctionCode)
    341274    , m_nextConstantOffset(0)
     
    344277    , m_firstLazyFunction(0)
    345278    , m_lastLazyFunction(0)
    346     , m_globalData(scope->globalData())
     279    , m_globalData(&globalData)
    347280    , m_lastOpcodeID(op_end)
    348281#ifndef NDEBUG
     
    353286    , m_expressionTooDeep(false)
    354287{
    355     m_globalData->startedCompiling(m_codeBlock);
    356 
    357288    if (m_shouldEmitDebugHooks)
    358289        m_codeBlock->setNeedsFullScopeChain(true);
    359290
    360     codeBlock->setGlobalData(m_globalData);
    361     symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
    362     symbolTable->setParameterCountIncludingThis(functionBody->parameters()->size() + 1);
     291    m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
     292    m_symbolTable->setParameterCountIncludingThis(functionBody->parameters()->size() + 1);
    363293
    364294    prependComment("entering Function block");
     
    371301    }
    372302
    373     symbolTable->setCaptureStart(m_codeBlock->m_numVars);
     303    m_symbolTable->setCaptureStart(m_codeBlock->m_numVars);
    374304
    375305    if (functionBody->usesArguments() || codeBlock->usesEval() || m_shouldEmitDebugHooks) { // May reify arguments object.
     
    421351
    422352    if (capturesAnyArgumentByName && !codeBlock->isStrictMode()) {
    423         size_t parameterCount = symbolTable->parameterCount();
     353        size_t parameterCount = m_symbolTable->parameterCount();
    424354        OwnArrayPtr<SlowArgument> slowArguments = adoptArrayPtr(new SlowArgument[parameterCount]);
    425355        for (size_t i = 0; i < parameterCount; ++i) {
     
    432362            slowArguments[i].index = capturedArguments[i]->index();
    433363        }
    434         symbolTable->setSlowArguments(slowArguments.release());
     364        m_symbolTable->setSlowArguments(slowArguments.release());
    435365    }
    436366
     
    473403    }
    474404
    475     symbolTable->setCaptureEnd(codeBlock->m_numVars);
     405    m_symbolTable->setCaptureEnd(codeBlock->m_numVars);
    476406
    477407    m_firstLazyFunction = codeBlock->m_numVars;
     
    501431
    502432    if (shouldCaptureAllTheThings)
    503         symbolTable->setCaptureEnd(codeBlock->m_numVars);
     433        m_symbolTable->setCaptureEnd(codeBlock->m_numVars);
    504434
    505435    FunctionParameters& parameters = *functionBody->parameters();
     
    531461        instructions().append(m_thisRegister.index());
    532462    } else if (!codeBlock->isStrictMode() && (functionBody->usesThis() || codeBlock->usesEval() || m_shouldEmitDebugHooks)) {
    533         ValueProfile* profile = emitProfiledOpcode(op_convert_this);
     463        UnlinkedValueProfile profile = emitProfiledOpcode(op_convert_this);
    534464        instructions().append(m_thisRegister.index());
    535465        instructions().append(profile);
     
    537467}
    538468
    539 BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, JSScope* scope, SharedSymbolTable* symbolTable, EvalCodeBlock* codeBlock, CompilationKind)
    540     : m_shouldEmitDebugHooks(scope->globalObject()->debugger())
    541     , m_shouldEmitProfileHooks(scope->globalObject()->globalObjectMethodTable()->supportsProfiling(scope->globalObject()))
    542     , m_shouldEmitRichSourceInfo(scope->globalObject()->globalObjectMethodTable()->supportsRichSourceInfo(scope->globalObject()))
    543     , m_scope(*scope->globalData(), scope)
    544     , m_symbolTable(symbolTable)
     469BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
     470    : m_shouldEmitDebugHooks(debuggerMode == DebuggerOn)
     471    , m_shouldEmitProfileHooks(profilerMode == ProfilerOn)
     472    , m_symbolTable(codeBlock->symbolTable())
    545473#if ENABLE(BYTECODE_COMMENTS)
    546474    , m_currentCommentString(0)
    547475#endif
    548476    , m_scopeNode(evalNode)
    549     , m_codeBlock(codeBlock)
     477    , m_codeBlock(globalData, codeBlock)
    550478    , m_thisRegister(CallFrame::thisArgumentOffset())
    551479    , m_emptyValueRegister(0)
    552480    , m_finallyDepth(0)
    553481    , m_dynamicScopeDepth(0)
    554     , m_baseScopeDepth(codeBlock->baseScopeDepth())
    555482    , m_codeType(EvalCode)
    556483    , m_nextConstantOffset(0)
     
    559486    , m_firstLazyFunction(0)
    560487    , m_lastLazyFunction(0)
    561     , m_globalData(scope->globalData())
     488    , m_globalData(&globalData)
    562489    , m_lastOpcodeID(op_end)
    563490#ifndef NDEBUG
     
    568495    , m_expressionTooDeep(false)
    569496{
    570     m_globalData->startedCompiling(m_codeBlock);
    571 
    572     if (m_shouldEmitDebugHooks || m_baseScopeDepth)
    573         m_codeBlock->setNeedsFullScopeChain(true);
    574 
    575     codeBlock->setGlobalData(m_globalData);
    576     symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());   
     497    m_codeBlock->setNeedsFullScopeChain(true);
     498
     499    m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
    577500    m_codeBlock->setNumParameters(1);
    578501
     
    582505    const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
    583506    for (size_t i = 0; i < functionStack.size(); ++i)
    584         m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, functionStack[i]));
     507        m_codeBlock->addFunctionDecl(makeFunction(functionStack[i]));
    585508
    586509    const DeclarationStacks::VarStack& varStack = evalNode->varStack();
     
    596519BytecodeGenerator::~BytecodeGenerator()
    597520{
    598     m_globalData->finishedCompiling(m_codeBlock);
    599521}
    600522
     
    619541        instructions().append(m_calleeRegister.index());
    620542        instructions().append(ReadOnly | DontDelete);
    621 
    622         // Put a mirror object in compilation scope, so compile-time variable resolution sees the property name we'll see at runtime.
    623         m_scope.set(*globalData(),
    624             JSNameScope::create(
    625                 m_scope->globalObject()->globalExec(),
    626                 functionBodyNode->ident(),
    627                 jsUndefined(),
    628                 ReadOnly | DontDelete,
    629                 m_scope.get()
    630             )
    631         );
    632543        return 0;
    633544    }
     
    773684#endif
    774685    emitComment();
    775     instructions().append(globalData()->interpreter->getOpcode(opcodeID));
     686    instructions().append(opcodeID);
    776687    m_lastOpcodeID = opcodeID;
    777688}
     
    797708#endif
    798709
    799 ArrayProfile* BytecodeGenerator::newArrayProfile()
     710UnlinkedArrayProfile BytecodeGenerator::newArrayProfile()
    800711{
    801712#if ENABLE(VALUE_PROFILER)
    802     return m_codeBlock->addArrayProfile(instructions().size());
     713    return m_codeBlock->addArrayProfile();
    803714#else
    804715    return 0;
     
    806717}
    807718
    808 ValueProfile* BytecodeGenerator::emitProfiledOpcode(OpcodeID opcodeID)
     719UnlinkedValueProfile BytecodeGenerator::emitProfiledOpcode(OpcodeID opcodeID)
    809720{
    810721#if ENABLE(VALUE_PROFILER)
    811     ValueProfile* result = m_codeBlock->addValueProfile(instructions().size());
     722    UnlinkedValueProfile result = m_codeBlock->addValueProfile();
    812723#else
    813     ValueProfile* result = 0;
     724    UnlinkedValueProfile result = 0;
    814725#endif
    815726    emitOpcode(opcodeID);
     
    838749    size_t size = instructions().size();
    839750    dstIndex = instructions().at(size - 2).u.operand;
    840     srcIndex = instructions().at(size - 1).u.operand;
    841 }
    842 
    843 void BytecodeGenerator::retrieveLastUnaryOp(WriteBarrier<Unknown>*& dstPointer, int& srcIndex)
    844 {
    845     ASSERT(instructions().size() >= 3);
    846     size_t size = instructions().size();
    847     dstPointer = instructions().at(size - 2).u.registerPointer;
    848751    srcIndex = instructions().at(size - 1).u.operand;
    849752}
     
    13371240
    13381241    // Check if the property should be allocated in a register.
    1339     if (m_codeType != GlobalCode && shouldOptimizeLocals()) {
     1242    if (m_codeType != GlobalCode && shouldOptimizeLocals() && m_symbolTable) {
    13401243        SymbolTableEntry entry = symbolTable().get(property.impl());
    13411244        if (!entry.isNull()) {
     
    13531256{
    13541257    // Register-allocated const declarations.
    1355     if (m_codeType != EvalCode && m_codeType != GlobalCode) {
     1258    if (m_codeType != EvalCode && m_codeType != GlobalCode && m_symbolTable) {
    13561259        SymbolTableEntry entry = symbolTable().get(property.impl());
    13571260        if (!entry.isNull()) {
     
    13951298        return emitGetLocalVar(dst, resolveResult, property);
    13961299
    1397     ValueProfile* profile = emitProfiledOpcode(op_resolve);
     1300    UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve);
    13981301    instructions().append(dst->index());
    13991302    instructions().append(addConstant(property));
     
    14071310    ASSERT_UNUSED(resolveResult, !resolveResult.isRegister());
    14081311    // We can't optimise at all :-(
    1409     ValueProfile* profile = emitProfiledOpcode(op_resolve_base);
     1312    UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve_base);
    14101313    instructions().append(dst->index());
    14111314    instructions().append(addConstant(property));
     
    14211324    ASSERT_UNUSED(resolveResult, !resolveResult.isRegister());
    14221325    // We can't optimise at all :-(
    1423     ValueProfile* profile = emitProfiledOpcode(op_resolve_base);
     1326    UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve_base);
    14241327    instructions().append(dst->index());
    14251328    instructions().append(addConstant(property));
     
    14361339{
    14371340    ASSERT_UNUSED(resolveResult, !resolveResult.isRegister());
    1438     ValueProfile* profile = emitProfiledOpcode(op_resolve_with_base);
     1341    UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve_with_base);
    14391342    instructions().append(baseDst->index());
    14401343    instructions().append(propDst->index());
     
    14561359    }
    14571360
    1458     ValueProfile* profile = emitProfiledOpcode(op_resolve_with_this);
     1361    UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve_with_this);
    14591362    instructions().append(baseDst->index());
    14601363    instructions().append(propDst->index());
     
    14831386{
    14841387    ASSERT(m_codeType == GlobalCode);
    1485     JSGlobalObject* globalObject = m_codeBlock->globalObject();
    1486     SymbolTableEntry entry = globalObject->symbolTable()->get(identifier.impl());
    1487     if (entry.isNull())
    1488         return 0;
    1489    
    1490     if (entry.couldBeWatched()) {
    1491         emitOpcode(op_init_global_const_check);
    1492         instructions().append(&globalObject->registerAt(entry.getIndex()));
    1493         instructions().append(value->index());
    1494         instructions().append(entry.addressOfIsWatched());
    1495         instructions().append(addConstant(identifier));
    1496         return value;
    1497     }
    1498    
    1499     emitOpcode(op_init_global_const);
    1500     instructions().append(&globalObject->registerAt(entry.getIndex()));
     1388    emitOpcode(op_init_global_const_nop);
     1389    instructions().append(0);
    15011390    instructions().append(value->index());
     1391    instructions().append(0);
     1392    instructions().append(addConstant(identifier));
    15021393    return value;
    15031394}
     
    15071398    m_codeBlock->addPropertyAccessInstruction(instructions().size());
    15081399
    1509     ValueProfile* profile = emitProfiledOpcode(op_get_by_id);
     1400    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_id);
    15101401    instructions().append(dst->index());
    15111402    instructions().append(base->index());
     
    15931484RegisterID* BytecodeGenerator::emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
    15941485{
    1595     ArrayProfile* arrayProfile = newArrayProfile();
    1596     ValueProfile* profile = emitProfiledOpcode(op_get_argument_by_val);
     1486    UnlinkedArrayProfile arrayProfile = newArrayProfile();
     1487    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_argument_by_val);
    15971488    instructions().append(dst->index());
    15981489    ASSERT(base->index() == m_codeBlock->argumentsRegister());
     
    16191510        }
    16201511    }
    1621     ArrayProfile* arrayProfile = newArrayProfile();
    1622     ValueProfile* profile = emitProfiledOpcode(op_get_by_val);
     1512    UnlinkedArrayProfile arrayProfile = newArrayProfile();
     1513    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_val);
    16231514    instructions().append(dst->index());
    16241515    instructions().append(base->index());
     
    16311522RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
    16321523{
    1633     ArrayProfile* arrayProfile = newArrayProfile();
     1524    UnlinkedArrayProfile arrayProfile = newArrayProfile();
    16341525    emitOpcode(op_put_by_val);
    16351526    instructions().append(base->index());
     
    17011592            ASSERT(length == checkLength);
    17021593            unsigned constantBufferIndex = addConstantBuffer(length);
    1703             JSValue* constantBuffer = m_codeBlock->constantBuffer(constantBufferIndex);
     1594            JSValue* constantBuffer = m_codeBlock->constantBuffer(constantBufferIndex).data();
    17041595            unsigned index = 0;
    17051596            for (ElementNode* n = elements; index < length; n = n->next()) {
     
    17371628RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
    17381629{
    1739     return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, function)), false);
     1630    return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(function)), false);
    17401631}
    17411632
     
    17441635    FunctionOffsetMap::AddResult ptr = m_functionOffsets.add(function, 0);
    17451636    if (ptr.isNewEntry)
    1746         ptr.iterator->value = m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, function));
     1637        ptr.iterator->value = m_codeBlock->addFunctionDecl(makeFunction(function));
    17471638    return emitNewFunctionInternal(dst, ptr.iterator->value, true);
    17481639}
     
    17691660{
    17701661    FunctionBodyNode* function = n->body();
    1771     unsigned index = m_codeBlock->addFunctionExpr(FunctionExecutable::create(*m_globalData, function));
     1662    unsigned index = m_codeBlock->addFunctionExpr(makeFunction(function));
    17721663   
    17731664    createActivationIfNecessary();
     
    19201811   
    19211812    // Emit call.
    1922     ArrayProfile* arrayProfile = newArrayProfile();
     1813    UnlinkedArrayProfile arrayProfile = newArrayProfile();
    19231814    emitOpcode(opcodeID);
    19241815    instructions().append(func->index()); // func
     
    19321823    instructions().append(arrayProfile);
    19331824    if (dst != ignoredResult()) {
    1934         ValueProfile* profile = emitProfiledOpcode(op_call_put_result);
     1825        UnlinkedValueProfile profile = emitProfiledOpcode(op_call_put_result);
    19351826        instructions().append(dst->index()); // dst
    19361827        instructions().append(profile);
     
    19651856    instructions().append(firstFreeRegister->index());
    19661857    if (dst != ignoredResult()) {
    1967         ValueProfile* profile = emitProfiledOpcode(op_call_put_result);
     1858        UnlinkedValueProfile profile = emitProfiledOpcode(op_call_put_result);
    19681859        instructions().append(dst->index());
    19691860        instructions().append(profile);
     
    20481939    instructions().append(0);
    20491940    if (dst != ignoredResult()) {
    2050         ValueProfile* profile = emitProfiledOpcode(op_call_put_result);
     1941        UnlinkedValueProfile profile = emitProfiledOpcode(op_call_put_result);
    20511942        instructions().append(dst->index()); // dst
    20521943        instructions().append(profile);
     
    24272318   
    24282319    emitLabel(tryRange.tryData->target.get());
    2429     tryRange.tryData->targetScopeDepth = m_dynamicScopeDepth + m_baseScopeDepth;
     2320    tryRange.tryData->targetScopeDepth = m_dynamicScopeDepth;
    24302321
    24312322    emitOpcode(op_catch);
     
    24362327void BytecodeGenerator::emitThrowReferenceError(const String& message)
    24372328{
    2438     emitOpcode(op_throw_reference_error);
     2329    emitOpcode(op_throw_static_error);
    24392330    instructions().append(addConstantValue(jsString(globalData(), message))->index());
     2331    instructions().append(true);
    24402332}
    24412333
     
    24882380}
    24892381
    2490 static void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
     2382static void prepareJumpTableForImmediateSwitch(UnlinkedSimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
    24912383{
    24922384    jumpTable.min = min;
     
    25142406}
    25152407
    2516 static void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
     2408static void prepareJumpTableForCharacterSwitch(UnlinkedSimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
    25172409{
    25182410    jumpTable.min = min;
     
    25272419}
    25282420
    2529 static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes)
     2421static void prepareJumpTableForStringSwitch(UnlinkedStringJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes)
    25302422{
    25312423    for (uint32_t i = 0; i < clauseCount; ++i) {
     
    25362428        ASSERT(nodes[i]->isString());
    25372429        StringImpl* clause = static_cast<StringNode*>(nodes[i])->value().impl();
    2538         OffsetLocation location;
    2539         location.branchOffset = labels[i]->bind(switchAddress, switchAddress + 3);
    2540         jumpTable.offsetTable.add(clause, location);
     2430        jumpTable.offsetTable.add(clause, labels[i]->bind(switchAddress, switchAddress + 3));
    25412431    }
    25422432}
     
    25502440        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
    25512441
    2552         SimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable();
     2442        UnlinkedSimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable();
    25532443        prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
    25542444    } else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) {
     
    25562446        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
    25572447       
    2558         SimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable();
     2448        UnlinkedSimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable();
    25592449        prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
    25602450    } else {
     
    25632453        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
    25642454
    2565         StringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable();
     2455        UnlinkedStringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable();
    25662456        prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes);
    25672457    }
     
    25952485    if (!isStrictMode())
    25962486        return;
    2597 
    2598     RefPtr<RegisterID> error = emitLoad(newTemporary(), JSValue(createTypeError(scope()->globalObject()->globalExec(), StrictModeReadonlyPropertyWriteError)));
    2599     emitThrow(error.get());
     2487    emitOpcode(op_throw_static_error);
     2488    instructions().append(addConstantValue(jsString(globalData(), StrictModeReadonlyPropertyWriteError))->index());
     2489    instructions().append(false);
    26002490}
    26012491
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r133564 r133688  
    4242#include "Debugger.h"
    4343#include "Nodes.h"
     44#include "UnlinkedCodeBlock.h"
    4445#include <wtf/PassRefPtr.h>
    4546#include <wtf/SegmentedVector.h>
     
    212213        static bool dumpsGeneratedCode();
    213214
    214         BytecodeGenerator(ProgramNode*, JSScope*, SharedSymbolTable*, ProgramCodeBlock*, CompilationKind);
    215         BytecodeGenerator(FunctionBodyNode*, JSScope*, SharedSymbolTable*, CodeBlock*, CompilationKind);
    216         BytecodeGenerator(EvalNode*, JSScope*, SharedSymbolTable*, EvalCodeBlock*, CompilationKind);
     215        BytecodeGenerator(JSGlobalData&, ProgramNode*, UnlinkedProgramCodeBlock*, DebuggerMode, ProfilerMode);
     216        BytecodeGenerator(JSGlobalData&, FunctionBodyNode*, UnlinkedFunctionCodeBlock*, DebuggerMode, ProfilerMode);
     217        BytecodeGenerator(JSGlobalData&, EvalNode*, UnlinkedEvalCodeBlock*, DebuggerMode, ProfilerMode);
    217218
    218219        ~BytecodeGenerator();
     
    221222        const CommonIdentifiers& propertyNames() const { return *m_globalData->propertyNames; }
    222223
    223         bool isConstructor() { return m_codeBlock->m_isConstructor; }
    224 
    225         JSObject* generate();
     224        bool isConstructor() { return m_codeBlock->isConstructor(); }
     225
     226        ParserError generate();
    226227
    227228        bool isArgumentNumber(const Identifier&, int);
     
    333334        void emitExpressionInfo(unsigned divot, unsigned startOffset, unsigned endOffset)
    334335        {
    335             if (!m_shouldEmitRichSourceInfo)
    336                 return;
    337 
    338             divot -= m_codeBlock->sourceOffset();
     336            divot -= m_scopeNode->source().startOffset();
    339337            if (divot > ExpressionRangeInfo::MaxDivot) {
    340338                // Overflow has occurred, we can only give line number info for errors for this region
     
    509507       
    510508        bool isStrictMode() const { return m_codeBlock->isStrictMode(); }
    511        
    512         JSScope* scope() const { return m_scope.get(); }
    513509
    514510    private:
     
    528524
    529525        void emitOpcode(OpcodeID);
    530         ArrayProfile* newArrayProfile();
    531         ValueProfile* emitProfiledOpcode(OpcodeID);
     526        UnlinkedArrayProfile newArrayProfile();
     527        UnlinkedValueProfile emitProfiledOpcode(OpcodeID);
    532528        void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
    533529        void retrieveLastUnaryOp(int& dstIndex, int& srcIndex);
    534         void retrieveLastUnaryOp(WriteBarrier<Unknown>*& dstPointer, int& srcIndex);
    535530        ALWAYS_INLINE void rewindBinaryOp();
    536531        ALWAYS_INLINE void rewindUnaryOp();
     
    575570
    576571        // Returns the index of the added var.
    577         enum ConstantMode { IsConstant, IsVariable };
    578         enum FunctionMode { IsFunctionToSpecialize, NotFunctionOrNotSpecializable };
    579         int addGlobalVar(const Identifier&, ConstantMode, FunctionMode);
    580 
    581572        void addParameter(const Identifier&, int parameterIndex);
    582573        RegisterID* resolveCallee(FunctionBodyNode*);
     
    605596        unsigned addConstantBuffer(unsigned length);
    606597       
     598        UnlinkedFunctionExecutable* makeFunction(FunctionBodyNode* body)
     599        {
     600            return UnlinkedFunctionExecutable::create(m_globalData, m_scopeNode->source(), body);
     601        }
     602
    607603        JSString* addStringConstant(const Identifier&);
    608604
    609605        void addLineInfo(unsigned lineNo)
    610606        {
    611             m_codeBlock->addLineInfo(instructions().size(), lineNo);
     607            m_codeBlock->addLineInfo(instructions().size(), lineNo - m_scopeNode->firstLine());
    612608        }
    613609
     
    615611
    616612    public:
    617         Vector<Instruction>& instructions() { return m_instructions; }
     613        Vector<UnlinkedInstruction>& instructions() { return m_instructions; }
    618614
    619615        SharedSymbolTable& symbolTable() { return *m_symbolTable; }
     
    653649        RegisterID* createLazyRegisterIfNecessary(RegisterID*);
    654650       
    655         Vector<Instruction> m_instructions;
     651        Vector<UnlinkedInstruction> m_instructions;
    656652
    657653        bool m_shouldEmitDebugHooks;
    658654        bool m_shouldEmitProfileHooks;
    659         bool m_shouldEmitRichSourceInfo;
    660 
    661         Strong<JSScope> m_scope;
     655
    662656        SharedSymbolTable* m_symbolTable;
    663657
     
    668662
    669663        ScopeNode* m_scopeNode;
    670         CodeBlock* m_codeBlock;
     664        Strong<UnlinkedCodeBlock> m_codeBlock;
    671665
    672666        // Some of these objects keep pointers to one another. They are arranged
     
    686680        int m_finallyDepth;
    687681        int m_dynamicScopeDepth;
    688         int m_baseScopeDepth;
    689682        CodeType m_codeType;
    690683
  • trunk/Source/JavaScriptCore/debugger/Debugger.cpp

    r130612 r133688  
    8181    ExecState* exec = function->scope()->globalObject()->JSGlobalObject::globalExec();
    8282    executable->clearCodeIfNotCompiling();
     83    executable->clearUnlinkedCodeIfNotCompiling();
    8384    if (m_debugger == function->scope()->globalObject()->debugger())
    8485        m_sourceProviders.add(executable->source().provider(), exec);
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeCache.h

    r130612 r133688  
    159159            JSObject* exception;
    160160            value.owned = true;
    161             value.codeBlock = key.executable()->produceCodeBlockFor(scope, OptimizingCompilation, key.kind(), exception).leakPtr();
     161            value.codeBlock = key.executable()->produceCodeBlockFor(scope, key.kind(), exception).leakPtr();
    162162        }
    163163       
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r133564 r133688  
    26152615        }
    26162616
     2617        case op_init_global_const_nop: {
     2618            NEXT_OPCODE(op_init_global_const_nop);
     2619        }
     2620
    26172621        case op_init_global_const: {
    26182622            NodeIndex value = get(currentInstruction[2].u.operand);
     
    28522856            LAST_OPCODE(op_throw);
    28532857           
    2854         case op_throw_reference_error:
     2858        case op_throw_static_error:
    28552859            flushArgumentsAndCapturedVariables();
    28562860            addToGraph(ThrowReferenceError);
    2857             LAST_OPCODE(op_throw_reference_error);
     2861            LAST_OPCODE(op_throw_static_error);
    28582862           
    28592863        case op_call:
     
    35983602            codeBlock,
    35993603            codeTypeToString(codeBlock->codeType()),
    3600             codeBlock->symbolTable()->captureCount(),
     3604            codeBlock->symbolTable() ? codeBlock->symbolTable()->captureCount() : 0,
    36013605            codeBlock->needsFullScopeChain()?"true":"false",
    36023606            codeBlock->ownerExecutable()->needsActivation()?"true":"false",
  • trunk/Source/JavaScriptCore/dfg/DFGCapabilities.h

    r133564 r133688  
    167167    case op_put_by_id_transition_normal:
    168168    case op_put_by_id_transition_normal_out_of_line:
     169    case op_init_global_const_nop:
    169170    case op_init_global_const:
    170171    case op_init_global_const_check:
     
    200201    case op_to_primitive:
    201202    case op_throw:
    202     case op_throw_reference_error:
     203    case op_throw_static_error:
    203204    case op_call:
    204205    case op_construct:
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r132182 r133688  
    11581158    JSGlobalData& globalData = exec->globalData();
    11591159    NativeCallFrameTracer tracer(&globalData, exec);
    1160     JSActivation* activation = JSActivation::create(
    1161         globalData, exec, static_cast<FunctionExecutable*>(exec->codeBlock()->ownerExecutable()));
     1160    JSActivation* activation = JSActivation::create(globalData, exec, exec->codeBlock());
    11621161    exec->setScope(activation);
    11631162    return activation;
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r131791 r133688  
    3737#include "JSONObject.h"
    3838#include "Tracing.h"
     39#include "UnlinkedCodeBlock.h"
    3940#include "WeakSetInlines.h"
    4041#include <algorithm>
     
    485486        }
    486487#endif
    487    
     488
    488489        if (m_globalData->codeBlocksBeingCompiled.size()) {
    489490            GCPHASE(VisitActiveCodeBlock);
     
    491492                m_globalData->codeBlocksBeingCompiled[i]->visitAggregate(visitor);
    492493        }
    493    
     494
    494495        {
    495496            GCPHASE(VisitMachineRoots);
  • trunk/Source/JavaScriptCore/heap/MarkedAllocator.h

    r130303 r133688  
    7575{
    7676    MarkedBlock::FreeCell* head = m_freeList.head;
    77     if (UNLIKELY(!head))
    78         return allocateSlowCase(bytes);
     77    if (UNLIKELY(!head)) {
     78        void* result = allocateSlowCase(bytes);
     79#ifndef NDEBUG
     80        memset(result, 0xCD, bytes);
     81#endif
     82        return result;
     83    }
    7984   
    8085    m_freeList.head = head->next;
     86#ifndef NDEBUG
     87    memset(head, 0xCD, bytes);
     88#endif
    8189    return head;
    8290}
  • trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp

    r131938 r133688  
    295295        return;
    296296
     297    validate(cell);
     298
    297299    if (m_shouldHashConst && cell->isString()) {
    298300        JSString* string = jsCast<JSString*>(cell);
     
    356358        CRASH();
    357359    }
     360
     361    // Make sure we can walk the ClassInfo chain
     362    const ClassInfo* info = cell->classInfo();
     363    do { } while ((info = info->parentClass));
    358364}
    359365#else
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r132244 r133688  
    949949
    950950    // Compile source to bytecode if necessary:
    951     JSObject* error = program->compile(callFrame, scope);
    952     if (error)
     951    if (JSObject* error = program->initalizeGlobalProperties(globalData, callFrame, scope))
    953952        return checkedReturn(throwError(callFrame, error));
    954     CodeBlock* codeBlock = &program->generatedBytecode();
     953
     954    if (JSObject* error = program->compile(callFrame, scope))
     955        return checkedReturn(throwError(callFrame, error));
     956
     957    ProgramCodeBlock* codeBlock = &program->generatedBytecode();
    955958
    956959    // Push the call frame for this invocation:
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r133564 r133688  
    336336        DEFINE_OP(op_put_by_val)
    337337        DEFINE_OP(op_put_getter_setter)
     338        case op_init_global_const_nop:
     339            NEXT_OPCODE(op_init_global_const_nop);
    338340        DEFINE_OP(op_init_global_const)
    339341        DEFINE_OP(op_init_global_const_check)
     
    372374        DEFINE_OP(op_tear_off_arguments)
    373375        DEFINE_OP(op_throw)
    374         DEFINE_OP(op_throw_reference_error)
     376        DEFINE_OP(op_throw_static_error)
    375377        DEFINE_OP(op_to_jsnumber)
    376378        DEFINE_OP(op_to_primitive)
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r133564 r133688  
    732732        void emit_op_tear_off_arguments(Instruction*);
    733733        void emit_op_throw(Instruction*);
    734         void emit_op_throw_reference_error(Instruction*);
     734        void emit_op_throw_static_error(Instruction*);
    735735        void emit_op_to_jsnumber(Instruction*);
    736736        void emit_op_to_primitive(Instruction*);
  • trunk/Source/JavaScriptCore/jit/JITDriver.h

    r126695 r133688  
    7676}
    7777
    78 inline bool jitCompileFunctionIfAppropriate(ExecState* exec, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, WriteBarrier<SharedSymbolTable>& symbolTable, JITCode::JITType jitType, unsigned bytecodeIndex, JITCompilationEffort effort)
     78inline bool jitCompileFunctionIfAppropriate(ExecState* exec, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, JITCode::JITType jitType, unsigned bytecodeIndex, JITCompilationEffort effort)
    7979{
    8080    JSGlobalData& globalData = exec->globalData();
     
    100100        if (codeBlock->alternative()) {
    101101            codeBlock = static_pointer_cast<FunctionCodeBlock>(codeBlock->releaseAlternative());
    102             symbolTable.set(exec->globalData(), codeBlock->ownerExecutable(), codeBlock->symbolTable());
    103102            jitCode = oldJITCode;
    104103            jitCodeWithArityCheck = oldJITCodeWithArityCheck;
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r131977 r133688  
    10701070}
    10711071
    1072 void JIT::emit_op_throw_reference_error(Instruction* currentInstruction)
    1073 {
    1074     JITStubCall stubCall(this, cti_op_throw_reference_error);
     1072void JIT::emit_op_throw_static_error(Instruction* currentInstruction)
     1073{
     1074    JITStubCall stubCall(this, cti_op_throw_static_error);
    10751075    if (!m_codeBlock->getConstant(currentInstruction[1].u.operand).isNumber())
    10761076        stubCall.addArgument(TrustedImm64(JSValue::encode(m_codeBlock->getConstant(currentInstruction[1].u.operand))));
    10771077    else
    10781078        stubCall.addArgument(Imm64(JSValue::encode(m_codeBlock->getConstant(currentInstruction[1].u.operand))));
     1079    stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand));
    10791080    stubCall.call();
    10801081}
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r131822 r133688  
    14021402}
    14031403
    1404 void JIT::emit_op_throw_reference_error(Instruction* currentInstruction)
     1404void JIT::emit_op_throw_static_error(Instruction* currentInstruction)
    14051405{
    14061406    unsigned message = currentInstruction[1].u.operand;
    14071407
    1408     JITStubCall stubCall(this, cti_op_throw_reference_error);
     1408    JITStubCall stubCall(this, cti_op_throw_static_error);
    14091409    stubCall.addArgument(m_codeBlock->getConstant(message));
     1410    stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand));
    14101411    stubCall.call();
    14111412}
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r133564 r133688  
    21452145    STUB_INIT_STACK_FRAME(stackFrame);
    21462146
    2147     JSActivation* activation = JSActivation::create(stackFrame.callFrame->globalData(), stackFrame.callFrame, static_cast<FunctionExecutable*>(stackFrame.callFrame->codeBlock()->ownerExecutable()));
     2147    JSActivation* activation = JSActivation::create(stackFrame.callFrame->globalData(), stackFrame.callFrame, stackFrame.callFrame->codeBlock());
    21482148    stackFrame.callFrame->setScope(activation);
    21492149    return activation;
     
    33373337}
    33383338
    3339 DEFINE_STUB_FUNCTION(void, op_throw_reference_error)
     3339DEFINE_STUB_FUNCTION(void, op_throw_static_error)
    33403340{
    33413341    STUB_INIT_STACK_FRAME(stackFrame);
     
    33433343    CallFrame* callFrame = stackFrame.callFrame;
    33443344    String message = stackFrame.args[0].jsValue().toString(callFrame)->value(callFrame);
    3345     stackFrame.globalData->exception = createReferenceError(callFrame, message);
     3345    if (stackFrame.args[1].asInt32)
     3346        stackFrame.globalData->exception = createReferenceError(callFrame, message);
     3347    else
     3348        stackFrame.globalData->exception = createTypeError(callFrame, message);
    33463349    VM_THROW_EXCEPTION_AT_END();
    33473350}
  • trunk/Source/JavaScriptCore/jit/JITStubs.h

    r133564 r133688  
    453453    void JIT_STUB cti_op_tear_off_activation(STUB_ARGS_DECLARATION) WTF_INTERNAL;
    454454    void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS_DECLARATION) WTF_INTERNAL;
    455     void JIT_STUB cti_op_throw_reference_error(STUB_ARGS_DECLARATION) WTF_INTERNAL;
     455    void JIT_STUB cti_op_throw_static_error(STUB_ARGS_DECLARATION) WTF_INTERNAL;
    456456#if ENABLE(DFG_JIT)
    457457    void JIT_STUB cti_optimize(STUB_ARGS_DECLARATION) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/llint/LLIntData.cpp

    r131093 r133688  
    104104#endif
    105105    ASSERT(StringType == 5);
    106     ASSERT(ObjectType == 13);
     106    ASSERT(ObjectType == 17);
    107107    ASSERT(MasqueradesAsUndefined == 1);
    108108    ASSERT(ImplementsHasInstance == 2);
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r133546 r133688  
    461461    dataLog("Creating an activation, exec = %p!\n", exec);
    462462#endif
    463     JSActivation* activation = JSActivation::create(globalData, exec, static_cast<FunctionExecutable*>(exec->codeBlock()->ownerExecutable()));
     463    JSActivation* activation = JSActivation::create(globalData, exec, exec->codeBlock());
    464464    exec->setScope(activation);
    465465    LLINT_RETURN(JSValue(activation));
     
    16231623}
    16241624
    1625 LLINT_SLOW_PATH_DECL(slow_path_throw_reference_error)
    1626 {
    1627     LLINT_BEGIN();
    1628     LLINT_THROW(createReferenceError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
     1625LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
     1626{
     1627    LLINT_BEGIN();
     1628    if (pc[2].u.operand)
     1629        LLINT_THROW(createReferenceError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
     1630    else
     1631        LLINT_THROW(createTypeError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
    16291632}
    16301633
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h

    r131822 r133688  
    205205LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_push_name_scope);
    206206LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw);
    207 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw_reference_error);
     207LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw_static_error);
    208208LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_debug);
    209209LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_profile_will_call);
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r133564 r133688  
    9797# Type constants.
    9898const StringType = 5
    99 const ObjectType = 13
     99const ObjectType = 17
    100100
    101101# Type flags constants.
     
    12351235
    12361236
    1237 _llint_op_throw_reference_error:
    1238     traceExecution()
    1239     callSlowPath(_llint_slow_path_throw_reference_error)
    1240     dispatch(2)
     1237_llint_op_throw_static_error:
     1238    traceExecution()
     1239    callSlowPath(_llint_slow_path_throw_static_error)
     1240    dispatch(3)
    12411241
    12421242
     
    13271327    notSupported()
    13281328
     1329_llint_op_init_global_const_nop:
     1330    dispatch(5)
    13291331
    13301332# Indicate the end of LLInt.
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r133368 r133688  
    985985    storei t2, TagOffset[t0]
    986986    storei t3, PayloadOffset[t0]
    987     dispatch(3)
     987    dispatch(5)
    988988
    989989
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r133551 r133688  
    831831    writeBarrier(t2)
    832832    storeq t2, [t0]
    833     dispatch(3)
     833    dispatch(5)
    834834
    835835
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r132143 r133688  
    7777enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
    7878
     79struct ParserError {
     80    enum ErrorType { ErrorNone, StackOverflow, SyntaxError, EvalError, OutOfMemory } m_type;
     81    String m_message;
     82    int m_line;
     83    ParserError()
     84        : m_type(ErrorNone)
     85        , m_line(-1)
     86    {
     87    }
     88
     89    ParserError(ErrorType type)
     90        : m_type(type)
     91        , m_line(-1)
     92    {
     93    }
     94
     95    ParserError(ErrorType type, String msg, int line)
     96        : m_type(type)
     97        , m_message(msg)
     98        , m_line(line)
     99    {
     100    }
     101
     102    JSObject* toErrorObject(JSGlobalObject* globalObject, const SourceCode& source)
     103    {
     104        switch (m_type) {
     105        case ErrorNone:
     106            return 0;
     107        case SyntaxError:
     108            return addErrorInfo(globalObject->globalExec(), createSyntaxError(globalObject, m_message), m_line, source);
     109        case EvalError:
     110            return createSyntaxError(globalObject, m_message);
     111        case StackOverflow:
     112            return createStackOverflowError(globalObject);
     113        case OutOfMemory:
     114            return createOutOfMemoryError(globalObject);
     115        }
     116        CRASH();
     117        return createOutOfMemoryError(globalObject); // Appease Qt bot
     118    }
     119
     120};
     121
    79122template <typename T> inline bool isEvalNode() { return false; }
    80123template <> inline bool isEvalNode<EvalNode>() { return true; }
     
    371414
    372415    template <class ParsedNode>
    373     PassRefPtr<ParsedNode> parse(JSGlobalObject* lexicalGlobalObject, Debugger*, ExecState*, JSObject**);
     416    PassRefPtr<ParsedNode> parse(ParserError&);
    374417
    375418private:
     
    891934    }
    892935
    893     mutable const JSGlobalData* m_globalData;
     936    JSGlobalData* m_globalData;
    894937    const SourceCode* m_source;
    895938    ParserArena* m_arena;
     
    936979};
    937980
     981
    938982template <typename LexerType>
    939983template <class ParsedNode>
    940 PassRefPtr<ParsedNode> Parser<LexerType>::parse(JSGlobalObject* lexicalGlobalObject, Debugger* debugger, ExecState* debuggerExecState, JSObject** exception)
     984PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
    941985{
    942     ASSERT(lexicalGlobalObject);
    943     ASSERT(exception && !*exception);
    944986    int errLine;
    945987    String errMsg;
     
    9721014        location.line = m_lexer->lastLineNumber();
    9731015        location.column = m_lexer->currentColumnNumber();
    974         result = ParsedNode::create(&lexicalGlobalObject->globalData(),
     1016        result = ParsedNode::create(m_globalData,
    9751017                                    location,
    9761018                                    m_sourceElements,
     
    9821024                                    m_numConstants);
    9831025        result->setLoc(m_source->firstLine(), m_lastLine, m_lexer->currentColumnNumber());
    984     } else if (lexicalGlobalObject) {
     1026    } else {
    9851027        // We can never see a syntax error when reparsing a function, since we should have
    9861028        // reported the error when parsing the containing program or eval code. So if we're
     
    9901032        // likely, and we are currently unable to distinguish between the two cases.
    9911033        if (isFunctionBodyNode(static_cast<ParsedNode*>(0)) || m_hasStackOverflow)
    992             *exception = createStackOverflowError(lexicalGlobalObject);
     1034            error = ParserError::StackOverflow;
    9931035        else if (isEvalNode<ParsedNode>())
    994             *exception = createSyntaxError(lexicalGlobalObject, errMsg);
     1036            error = ParserError(ParserError::EvalError, errMsg, errLine);
    9951037        else
    996             *exception = addErrorInfo(lexicalGlobalObject->globalExec(), createSyntaxError(lexicalGlobalObject, errMsg), errLine, *m_source);
    997     }
    998 
    999     if (debugger && !ParsedNode::scopeIsFunction)
    1000         debugger->sourceParsed(debuggerExecState, m_source->provider(), errLine, errMsg);
     1038            error = ParserError(ParserError::SyntaxError, errMsg, errLine);
     1039    }
    10011040
    10021041    m_arena->reset();
     
    10061045
    10071046template <class ParsedNode>
    1008 PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, Debugger* debugger, ExecState* execState, JSObject** exception)
     1047PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ParserError& error)
    10091048{
    10101049    SamplingRegion samplingRegion("Parsing");
    10111050
    10121051    ASSERT(!source.provider()->source().isNull());
    1013 
    10141052    if (source.provider()->source().is8Bit()) {
    10151053        Parser< Lexer<LChar> > parser(globalData, source, parameters, name, strictness, parserMode);
    1016         return parser.parse<ParsedNode>(lexicalGlobalObject, debugger, execState, exception);
     1054        return parser.parse<ParsedNode>(error);
    10171055    }
    10181056    Parser< Lexer<UChar> > parser(globalData, source, parameters, name, strictness, parserMode);
    1019     return parser.parse<ParsedNode>(lexicalGlobalObject, debugger, execState, exception);
     1057    return parser.parse<ParsedNode>(error);
    10201058}
    10211059
    1022 } // namespace 
     1060} // namespace
    10231061#endif
  • trunk/Source/JavaScriptCore/parser/ParserTokens.h

    r124729 r133688  
    2626#ifndef ParserTokens_h
    2727#define ParserTokens_h
     28
     29#include "ParserModes.h"
    2830
    2931namespace JSC {
     
    162164};
    163165
    164 enum JSParserStrictness { JSParseNormal, JSParseStrict };
    165 enum JSParserMode { JSParseProgramCode, JSParseFunctionCode };
    166    
    167166}
    168167
  • trunk/Source/JavaScriptCore/runtime/Arguments.h

    r130303 r133688  
    268268        m_overrodeCaller = false;
    269269        m_isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();
    270 
    271         ASSERT(!jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->symbolTable()->slowArguments());
     270        ASSERT(!jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->symbolTable(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct)->slowArguments());
    272271
    273272        // The bytecode generator omits op_tear_off_activation in cases of no
  • trunk/Source/JavaScriptCore/runtime/Executable.cpp

    r129453 r133688  
    2727#include "Executable.h"
    2828
     29#include "BatchedTransitionOptimizer.h"
    2930#include "BytecodeGenerator.h"
    3031#include "CodeBlock.h"
     
    134135const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionExecutable) };
    135136
    136 FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, FunctionBodyNode* node)
    137     : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, node->source(), node->isStrictMode())
    138     , m_forceUsesArguments(node->usesArguments())
    139     , m_parameters(node->parameters())
    140     , m_name(node->ident())
    141     , m_inferredName(node->inferredName().isNull() ? globalData.propertyNames->emptyIdentifier : node->inferredName())
    142     , m_functionNameIsInScopeToggle(node->functionNameIsInScopeToggle())
    143 {
    144     m_firstLine = node->lineNo();
    145     m_lastLine = node->lastLine();
     137FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine)
     138    : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, source, unlinkedExecutable->isInStrictContext())
     139    , m_unlinkedExecutable(globalData, this, unlinkedExecutable)
     140{
     141    ASSERT(!source.isNull());
     142    ASSERT(source.length());
     143    m_firstLine = firstLine;
     144    m_lastLine = lastLine;
    146145}
    147146
     
    192191    UNUSED_PARAM(bytecodeIndex);
    193192#endif
    194     JSObject* exception = 0;
    195193    JSGlobalData* globalData = &exec->globalData();
    196194    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
     
    201199        m_evalCodeBlock = newCodeBlock.release();
    202200    } else {
     201        UNUSED_PARAM(scope);
     202        UNUSED_PARAM(globalData);
     203        UNUSED_PARAM(lexicalGlobalObject);
    203204        if (!lexicalGlobalObject->evalEnabled())
    204205            return throwError(exec, createEvalError(exec, lexicalGlobalObject->evalDisabledErrorMessage()));
    205         RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
    206         if (!evalNode) {
    207             ASSERT(exception);
     206
     207        JSObject* exception = 0;
     208        UnlinkedEvalCodeBlock* unlinkedEvalCode = lexicalGlobalObject->createEvalCodeBlock(exec, this, &exception);
     209        if (!unlinkedEvalCode)
    208210            return exception;
    209         }
    210         recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine());
    211        
    212         JSGlobalObject* globalObject = scope->globalObject();
    213        
     211
    214212        OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release();
    215213        ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
    216         m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scope->localDepth(), previousCodeBlock.release()));
    217         OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scope, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation)));
    218         if ((exception = generator->generate())) {
    219             m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative());
    220             evalNode->destroyData();
    221             return exception;
    222         }
    223        
    224         evalNode->destroyData();
     214        m_unlinkedEvalCodeBlock.set(*globalData, this, unlinkedEvalCode);
     215        m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, unlinkedEvalCode, lexicalGlobalObject, source().provider(), scope->localDepth(), previousCodeBlock.release()));
    225216        m_evalCodeBlock->copyPostParseDataFromAlternative();
    226217    }
     
    258249    if (thisObject->m_evalCodeBlock)
    259250        thisObject->m_evalCodeBlock->visitAggregate(visitor);
     251    visitor.append(&thisObject->m_unlinkedEvalCodeBlock);
    260252}
    261253
     
    273265{
    274266    m_evalCodeBlock.clear();
     267    m_unlinkedEvalCodeBlock.clear();
    275268    Base::clearCode();
    276269}
     
    278271JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
    279272{
    280     JSObject* exception = 0;
     273    ParserError error;
    281274    JSGlobalData* globalData = &exec->globalData();
    282275    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    283     RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
     276    RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, m_source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, error);
    284277    if (programNode)
    285278        return 0;
    286     ASSERT(exception);
    287     return exception;
     279    ASSERT(error.m_type != ParserError::ErrorNone);
     280    return error.toErrorObject(lexicalGlobalObject, m_source);
    288281}
    289282
     
    311304   
    312305#if !ENABLE(JIT)
     306    UNUSED_PARAM(exec);
    313307    UNUSED_PARAM(jitType);
    314308    UNUSED_PARAM(bytecodeIndex);
    315309#endif
    316     JSObject* exception = 0;
    317     JSGlobalData* globalData = &exec->globalData();
    318     JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    319    
    320310    if (!!m_programCodeBlock) {
    321311        OwnPtr<ProgramCodeBlock> newCodeBlock = adoptPtr(new ProgramCodeBlock(CodeBlock::CopyParsedBlock, *m_programCodeBlock));
     
    323313        m_programCodeBlock = newCodeBlock.release();
    324314    } else {
    325         RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
    326         if (!programNode) {
    327             ASSERT(exception);
    328             return exception;
    329         }
    330         recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine());
    331 
    332315        JSGlobalObject* globalObject = scope->globalObject();
    333    
    334         OwnPtr<CodeBlock> previousCodeBlock = m_programCodeBlock.release();
    335         ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
    336         m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider(), previousCodeBlock.release()));
    337         OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scope, globalObject->symbolTable(), m_programCodeBlock.get(), !!m_programCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation)));
    338         if ((exception = generator->generate())) {
    339             m_programCodeBlock = static_pointer_cast<ProgramCodeBlock>(m_programCodeBlock->releaseAlternative());
    340             programNode->destroyData();
    341             return exception;
    342         }
    343 
    344         programNode->destroyData();
     316        m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, m_unlinkedProgramCodeBlock.get(), globalObject, source().provider(), m_programCodeBlock.release()));
    345317        m_programCodeBlock->copyPostParseDataFromAlternative();
    346318    }
     
    377349    m_programCodeBlock->unlinkCalls();
    378350#endif
     351}
     352
     353int ProgramExecutable::addGlobalVar(JSGlobalObject* globalObject, const Identifier& ident, ConstantMode constantMode, FunctionMode functionMode)
     354{
     355    // Try to share the symbolTable if possible
     356    SharedSymbolTable* symbolTable = globalObject->symbolTable();
     357    UNUSED_PARAM(functionMode);
     358    int index = symbolTable->size();
     359    SymbolTableEntry newEntry(index, (constantMode == IsConstant) ? ReadOnly : 0);
     360    if (functionMode == IsFunctionToSpecialize)
     361        newEntry.attemptToWatch();
     362    SymbolTable::AddResult result = symbolTable->add(ident.impl(), newEntry);
     363    if (!result.isNewEntry) {
     364        result.iterator->value.notifyWrite();
     365        index = result.iterator->value.getIndex();
     366    }
     367    return index;
     368}
     369
     370JSObject* ProgramExecutable::initalizeGlobalProperties(JSGlobalData& globalData, CallFrame* callFrame, JSScope* scope)
     371{
     372    ASSERT(scope);
     373    JSGlobalObject* globalObject = scope->globalObject();
     374    ASSERT(globalObject);
     375    ASSERT(&globalObject->globalData() == &globalData);
     376
     377    JSObject* exception = 0;
     378    UnlinkedProgramCodeBlock* unlinkedCode = globalObject->createProgramCodeBlock(callFrame, this, &exception);
     379    if (exception)
     380        return exception;
     381
     382    m_unlinkedProgramCodeBlock.set(globalData, this, unlinkedCode);
     383
     384    BatchedTransitionOptimizer optimizer(globalData, globalObject);
     385
     386    const UnlinkedProgramCodeBlock::VariableDeclations& variableDeclarations = unlinkedCode->variableDeclarations();
     387    const UnlinkedProgramCodeBlock::FunctionDeclations& functionDeclarations = unlinkedCode->functionDeclarations();
     388
     389    size_t newGlobals = variableDeclarations.size() + functionDeclarations.size();
     390    if (!newGlobals)
     391        return 0;
     392    globalObject->addRegisters(newGlobals);
     393    CallFrame* globalExec = globalObject->globalExec();
     394
     395    for (size_t i = 0; i < functionDeclarations.size(); ++i) {
     396        bool propertyDidExist = globalObject->removeDirect(globalData, functionDeclarations[i].first); // Newly declared functions overwrite existing properties.
     397        UnlinkedFunctionExecutable* unlinkedFunctionExecutable = functionDeclarations[i].second.get();
     398        JSValue value = JSFunction::create(globalExec, unlinkedFunctionExecutable->link(globalData, m_source, lineNo(), 0), scope);
     399        int index = addGlobalVar(globalObject, functionDeclarations[i].first, IsVariable,
     400            !propertyDidExist ? IsFunctionToSpecialize : NotFunctionOrNotSpecializable);
     401        globalObject->registerAt(index).set(globalData, globalObject, value);
     402    }
     403
     404    for (size_t i = 0; i < variableDeclarations.size(); ++i) {
     405        if (globalObject->hasProperty(globalExec, variableDeclarations[i].first))
     406            continue;
     407        addGlobalVar(globalObject, variableDeclarations[i].first,
     408            (variableDeclarations[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable,
     409            NotFunctionOrNotSpecializable);
     410    }
     411    return 0;
    379412}
    380413
     
    386419    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
    387420    ScriptExecutable::visitChildren(thisObject, visitor);
     421    visitor.append(&thisObject->m_unlinkedProgramCodeBlock);
    388422    if (thisObject->m_programCodeBlock)
    389423        thisObject->m_programCodeBlock->visitAggregate(visitor);
     
    393427{
    394428    m_programCodeBlock.clear();
     429    m_unlinkedProgramCodeBlock.clear();
    395430    Base::clearCode();
    396431}
     
    439474bool FunctionExecutable::jitCompileForCall(ExecState* exec)
    440475{
    441     return jitCompileFunctionIfAppropriate(exec, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);
     476    return jitCompileFunctionIfAppropriate(exec, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);
    442477}
    443478
    444479bool FunctionExecutable::jitCompileForConstruct(ExecState* exec)
    445480{
    446     return jitCompileFunctionIfAppropriate(exec, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);
     481    return jitCompileFunctionIfAppropriate(exec, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);
    447482}
    448483#endif
     
    453488}
    454489
    455 PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(JSScope* scope, CompilationKind compilationKind, CodeSpecializationKind specializationKind, JSObject*& exception)
     490PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(JSScope* scope, CodeSpecializationKind specializationKind, JSObject*& exception)
    456491{
    457492    if (!!codeBlockFor(specializationKind))
    458493        return adoptPtr(new FunctionCodeBlock(CodeBlock::CopyParsedBlock, *codeBlockFor(specializationKind)));
    459    
    460     exception = 0;
     494
    461495    JSGlobalData* globalData = scope->globalData();
    462496    JSGlobalObject* globalObject = scope->globalObject();
    463     RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(
    464         globalData,
    465         globalObject,
    466         m_source,
    467         m_parameters.get(),
    468         name(),
    469         isStrictMode() ? JSParseStrict : JSParseNormal,
    470         FunctionBodyNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode,
    471         0,
    472         0,
    473         &exception
    474     );
    475 
    476     if (!body) {
    477         ASSERT(exception);
     497    ParserError error;
     498    DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff;
     499    ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff;
     500    UnlinkedFunctionCodeBlock* unlinkedCodeBlock = m_unlinkedExecutable->codeBlockFor(*globalData, m_source, specializationKind, debuggerMode, profilerMode, error);
     501    recordParse(m_unlinkedExecutable->features(), m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine());
     502
     503    if (!unlinkedCodeBlock) {
     504        exception = error.toErrorObject(globalObject, m_source);
    478505        return nullptr;
    479506    }
    480     if (m_forceUsesArguments)
    481         body->setUsesArguments();
    482     body->finishParsing(m_parameters, m_name, m_functionNameIsInScopeToggle);
    483     recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine());
    484 
    485     OwnPtr<FunctionCodeBlock> result;
    486     ASSERT((compilationKind == FirstCompilation) == !codeBlockFor(specializationKind));
    487     result = adoptPtr(new FunctionCodeBlock(this, FunctionCode, globalObject, source().provider(), source().startOffset(), specializationKind == CodeForConstruct));
    488     OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), scope, result->symbolTable(), result.get(), compilationKind)));
    489     exception = generator->generate();
    490     body->destroyData();
    491     if (exception)
    492         return nullptr;
    493 
     507
     508    OwnPtr<FunctionCodeBlock> result = adoptPtr(new FunctionCodeBlock(this, unlinkedCodeBlock, globalObject, source().provider(), source().startOffset()));
    494509    result->copyPostParseDataFrom(codeBlockFor(specializationKind).get());
    495510    return result.release();
    496511}
     512
    497513
    498514JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, unsigned bytecodeIndex)
     
    508524    ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForCall);
    509525    JSObject* exception;
    510     OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, !!m_codeBlockForCall ? OptimizingCompilation : FirstCompilation, CodeForCall, exception);
     526    OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, CodeForCall, exception);
    511527    if (!newCodeBlock)
    512528        return exception;
     
    517533    m_numParametersForCall = m_codeBlockForCall->numParameters();
    518534    ASSERT(m_numParametersForCall);
    519     m_symbolTable.set(exec->globalData(), this, m_codeBlockForCall->symbolTable());
    520 
    521 #if ENABLE(JIT)
    522     if (!prepareFunctionForExecution(exec, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, jitType, bytecodeIndex, CodeForCall))
     535
     536#if ENABLE(JIT)
     537    if (!prepareFunctionForExecution(exec, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, jitType, bytecodeIndex, CodeForCall))
    523538        return 0;
    524539#endif
     
    545560    ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForConstruct);
    546561    JSObject* exception;
    547     OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, !!m_codeBlockForConstruct ? OptimizingCompilation : FirstCompilation, CodeForConstruct, exception);
     562    OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, CodeForConstruct, exception);
    548563    if (!newCodeBlock)
    549564        return exception;
     
    554569    m_numParametersForConstruct = m_codeBlockForConstruct->numParameters();
    555570    ASSERT(m_numParametersForConstruct);
    556     m_symbolTable.set(exec->globalData(), this, m_codeBlockForConstruct->symbolTable());
    557 
    558 #if ENABLE(JIT)
    559     if (!prepareFunctionForExecution(exec, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, jitType, bytecodeIndex, CodeForConstruct))
     571
     572#if ENABLE(JIT)
     573    if (!prepareFunctionForExecution(exec, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, jitType, bytecodeIndex, CodeForConstruct))
    560574        return 0;
    561575#endif
     
    593607    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
    594608    ScriptExecutable::visitChildren(thisObject, visitor);
    595     visitor.append(&thisObject->m_nameValue);
    596     visitor.append(&thisObject->m_symbolTable);
    597609    if (thisObject->m_codeBlockForCall)
    598610        thisObject->m_codeBlockForCall->visitAggregate(visitor);
    599611    if (thisObject->m_codeBlockForConstruct)
    600612        thisObject->m_codeBlockForConstruct->visitAggregate(visitor);
     613    visitor.append(&thisObject->m_unlinkedExecutable);
    601614}
    602615
     
    608621}
    609622
     623void FunctionExecutable::clearUnlinkedCodeIfNotCompiling()
     624{
     625    if (isCompiling())
     626        return;
     627    m_unlinkedExecutable->clearCode();
     628}
     629
    610630void FunctionExecutable::clearCode()
    611631{
    612632    m_codeBlockForCall.clear();
    613633    m_codeBlockForConstruct.clear();
     634    m_unlinkedExecutable->clearCode();
    614635    Base::clearCode();
    615636}
     
    631652FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
    632653{
    633     JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    634     RefPtr<ProgramNode> program = parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, debugger, exec, exception);
    635     if (!program) {
    636         ASSERT(*exception);
    637         return 0;
    638     }
    639 
    640     // This function assumes an input string that would result in a single anonymous function expression.
    641     StatementNode* exprStatement = program->singleStatement();
    642     ASSERT(exprStatement);
    643     ASSERT(exprStatement->isExprStatement());
    644     ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
    645     ASSERT(funcExpr);
    646     ASSERT(funcExpr->isFuncExprNode());
    647     FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
    648     ASSERT(body);
    649     ASSERT(body->ident().isNull());
    650 
    651     FunctionExecutable* functionExecutable = FunctionExecutable::create(exec->globalData(), body);
    652     functionExecutable->m_nameValue.set(exec->globalData(), functionExecutable, jsString(&exec->globalData(), name.string()));
    653     return functionExecutable;
     654    UnlinkedFunctionExecutable* unlinkedFunction = UnlinkedFunctionExecutable::fromGlobalCode(name, exec, debugger, source, exception);
     655    if (!unlinkedFunction)
     656        return 0;
     657    unsigned firstLine = source.firstLine() + unlinkedFunction->firstLineOffset();
     658    unsigned startOffset = source.startOffset() + unlinkedFunction->startOffset();
     659    unsigned sourceLength = unlinkedFunction->sourceLength();
     660    SourceCode functionSource(source.provider(), startOffset, startOffset + sourceLength, firstLine);
     661    return FunctionExecutable::create(exec->globalData(), functionSource, unlinkedFunction, firstLine, unlinkedFunction->lineCount());
    654662}
    655663
    656664String FunctionExecutable::paramString() const
    657665{
    658     FunctionParameters& parameters = *m_parameters;
    659     StringBuilder builder;
    660     for (size_t pos = 0; pos < parameters.size(); ++pos) {
    661         if (!builder.isEmpty())
    662             builder.appendLiteral(", ");
    663         builder.append(parameters[pos].string());
    664     }
    665     return builder.toString();
    666 }
    667 
    668 }
     666    return m_unlinkedExecutable->paramString();
     667}
     668
     669}
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r130303 r133688  
    3636#include "Nodes.h"
    3737#include "SamplingTool.h"
     38#include "UnlinkedCodeBlock.h"
    3839#include <wtf/PassOwnPtr.h>
    3940
     
    365366
    366367        void unlinkCalls();
     368
     369        CodeFeatures features() const { return m_features; }
    367370       
    368371        static const ClassInfo s_info;
    369 
    370     protected:
    371         void finishCreation(JSGlobalData& globalData)
    372         {
    373             Base::finishCreation(globalData);
    374             globalData.heap.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode().
    375 
    376 #if ENABLE(CODEBLOCK_SAMPLING)
    377             if (SamplingTool* sampler = globalData.interpreter->sampler())
    378                 sampler->notifyOfScope(globalData, this);
    379 #endif
    380         }
    381372
    382373        void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
     
    386377            m_firstLine = firstLine;
    387378            m_lastLine = lastLine;
     379        }
     380
     381    protected:
     382        void finishCreation(JSGlobalData& globalData)
     383        {
     384            Base::finishCreation(globalData);
     385            globalData.heap.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode().
     386
     387#if ENABLE(CODEBLOCK_SAMPLING)
     388            if (SamplingTool* sampler = globalData.interpreter->sampler())
     389                sampler->notifyOfScope(globalData, this);
     390#endif
    388391        }
    389392
     
    449452        void clearCode();
    450453
     454        ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false); }
     455
    451456    private:
    452457        static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
     
    457462
    458463        OwnPtr<EvalCodeBlock> m_evalCodeBlock;
     464        WriteBarrier<UnlinkedEvalCodeBlock> m_unlinkedEvalCodeBlock;
    459465    };
    460466
     
    470476            return executable;
    471477        }
     478
     479
     480        JSObject* initalizeGlobalProperties(JSGlobalData&, CallFrame*, JSScope*);
    472481
    473482        static void destroy(JSCell*);
     
    516525        void clearCode();
    517526
     527        ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false); }
     528
    518529    private:
    519530        static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
     531
    520532        ProgramExecutable(ExecState*, const SourceCode&);
     533
     534        enum ConstantMode { IsConstant, IsVariable };
     535        enum FunctionMode { IsFunctionToSpecialize, NotFunctionOrNotSpecializable };
     536        int addGlobalVar(JSGlobalObject*, const Identifier&, ConstantMode, FunctionMode);
    521537
    522538        JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
    523539        static void visitChildren(JSCell*, SlotVisitor&);
    524540
     541        WriteBarrier<UnlinkedProgramCodeBlock> m_unlinkedProgramCodeBlock;
    525542        OwnPtr<ProgramCodeBlock> m_programCodeBlock;
    526543    };
     
    532549        typedef ScriptExecutable Base;
    533550
    534         static FunctionExecutable* create(JSGlobalData& globalData, FunctionBodyNode* node)
    535         {
    536             FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, node);
     551        static FunctionExecutable* create(JSGlobalData& globalData, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine)
     552        {
     553            FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, source, unlinkedExecutable, firstLine, lastLine);
    537554            executable->finishCreation(globalData);
    538555            return executable;
     
    555572        FunctionCodeBlock* codeBlockWithBytecodeFor(CodeSpecializationKind);
    556573       
    557         PassOwnPtr<FunctionCodeBlock> produceCodeBlockFor(JSScope*, CompilationKind, CodeSpecializationKind, JSObject*& exception);
     574        PassOwnPtr<FunctionCodeBlock> produceCodeBlockFor(JSScope*, CodeSpecializationKind, JSObject*& exception);
    558575
    559576        JSObject* compileForCall(ExecState* exec, JSScope* scope)
     
    680697        }
    681698       
    682         const Identifier& name() { return m_name; }
    683         const Identifier& inferredName() { return m_inferredName; }
    684         JSString* nameValue() const { return m_nameValue.get(); }
    685         size_t parameterCount() const { return m_parameters->size(); } // Excluding 'this'!
     699        const Identifier& name() { return m_unlinkedExecutable->name(); }
     700        const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }
     701        JSString* nameValue() const { return m_unlinkedExecutable->nameValue(); }
     702        size_t parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'!
    686703        String paramString() const;
    687         SharedSymbolTable* symbolTable() const { return m_symbolTable.get(); }
     704        SharedSymbolTable* symbolTable(CodeSpecializationKind kind) const { return m_unlinkedExecutable->symbolTable(kind); }
    688705
    689706        void clearCodeIfNotCompiling();
     707        void clearUnlinkedCodeIfNotCompiling();
    690708        static void visitChildren(JSCell*, SlotVisitor&);
    691709        static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
     
    700718        void clearCode();
    701719
    702     protected:
    703         void finishCreation(JSGlobalData& globalData)
    704         {
    705             Base::finishCreation(globalData);
    706             m_nameValue.set(globalData, this, jsString(&globalData, name().string()));
    707         }
    708 
    709720    private:
    710         FunctionExecutable(JSGlobalData&, FunctionBodyNode*);
     721        FunctionExecutable(JSGlobalData&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine);
    711722
    712723        JSObject* compileForCallInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
     
    733744
    734745        static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
    735         bool m_forceUsesArguments;
    736 
    737         RefPtr<FunctionParameters> m_parameters;
     746        WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;
    738747        OwnPtr<FunctionCodeBlock> m_codeBlockForCall;
    739748        OwnPtr<FunctionCodeBlock> m_codeBlockForConstruct;
    740         Identifier m_name;
    741         Identifier m_inferredName;
    742         FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
    743         WriteBarrier<JSString> m_nameValue;
    744         WriteBarrier<SharedSymbolTable> m_symbolTable;
    745749    };
    746750
  • trunk/Source/JavaScriptCore/runtime/ExecutionHarness.h

    r126695 r133688  
    5050}
    5151
    52 inline bool prepareFunctionForExecution(ExecState* exec, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, WriteBarrier<SharedSymbolTable>& symbolTable, JITCode::JITType jitType, unsigned bytecodeIndex, CodeSpecializationKind kind)
     52inline bool prepareFunctionForExecution(ExecState* exec, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, JITCode::JITType jitType, unsigned bytecodeIndex, CodeSpecializationKind kind)
    5353{
    5454#if ENABLE(LLINT)
     
    6262    UNUSED_PARAM(kind);
    6363#endif // ENABLE(LLINT)
    64     return jitCompileFunctionIfAppropriate(exec, codeBlock, jitCode, jitCodeWithArityCheck, symbolTable, jitType, bytecodeIndex, JITCode::isBaselineCode(jitType) ? JITCompilationMustSucceed : JITCompilationCanFail);
     64    return jitCompileFunctionIfAppropriate(exec, codeBlock, jitCode, jitCodeWithArityCheck, jitType, bytecodeIndex, JITCode::isBaselineCode(jitType) ? JITCompilationMustSucceed : JITCompilationCanFail);
    6565}
    6666
  • trunk/Source/JavaScriptCore/runtime/JSActivation.h

    r129426 r133688  
    4747        typedef JSVariableObject Base;
    4848
    49         static JSActivation* create(JSGlobalData& globalData, CallFrame* callFrame, FunctionExecutable* functionExecutable)
     49        static JSActivation* create(JSGlobalData& globalData, CallFrame* callFrame, CodeBlock* codeBlock)
    5050        {
     51            SharedSymbolTable* symbolTable = codeBlock->symbolTable();
    5152            JSActivation* activation = new (
    5253                NotNull,
    5354                allocateCell<JSActivation>(
    5455                    globalData.heap,
    55                     allocationSize(functionExecutable->symbolTable())
     56                    allocationSize(symbolTable)
    5657                )
    57             ) JSActivation(globalData, callFrame, functionExecutable->symbolTable());
     58            ) JSActivation(globalData, callFrame, symbolTable);
    5859            activation->finishCreation(globalData);
    5960            return activation;
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.cpp

    r133493 r133688  
    3131
    3232#include "ArgList.h"
     33#include "CodeCache.h"
    3334#include "CommonIdentifiers.h"
    3435#include "DebuggerActivation.h"
     
    5859#include "StrictEvalActivation.h"
    5960#include "StrongInlines.h"
     61#include "UnlinkedCodeBlock.h"
    6062#include <wtf/RetainPtr.h>
    6163#include <wtf/Threading.h>
     
    197199#endif
    198200    , m_inDefineOwnProperty(false)
     201    , m_codeCache(CodeCache::create())
    199202{
    200203    interpreter = new Interpreter(*this);
     
    222225    structureChainStructure.set(*this, StructureChain::createStructure(*this, 0, jsNull()));
    223226    sparseArrayValueMapStructure.set(*this, SparseArrayValueMap::createStructure(*this, 0, jsNull()));
     227    withScopeStructure.set(*this, JSWithScope::createStructure(*this, 0, jsNull()));
     228    unlinkedFunctionExecutableStructure.set(*this, UnlinkedFunctionExecutable::createStructure(*this, 0, jsNull()));
     229    unlinkedProgramCodeBlockStructure.set(*this, UnlinkedProgramCodeBlock::createStructure(*this, 0, jsNull()));
     230    unlinkedEvalCodeBlockStructure.set(*this, UnlinkedEvalCodeBlock::createStructure(*this, 0, jsNull()));
     231    unlinkedFunctionCodeBlockStructure.set(*this, UnlinkedFunctionCodeBlock::createStructure(*this, 0, jsNull()));
    224232
    225233    wtfThreadData().setCurrentIdentifierTable(existingEntryIdentifierTable);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.h

    r132143 r133688  
    6464
    6565    class CodeBlock;
     66    class CodeCache;
    6667    class CommonIdentifiers;
    6768    class HandleStack;
     
    8182    class RegExp;
    8283#endif
     84    class UnlinkedCodeBlock;
     85    class UnlinkedEvalCodeBlock;
     86    class UnlinkedFunctionExecutable;
     87    class UnlinkedProgramCodeBlock;
    8388
    8489    struct HashTable;
     
    224229        Strong<Structure> structureChainStructure;
    225230        Strong<Structure> sparseArrayValueMapStructure;
     231        Strong<Structure> withScopeStructure;
     232        Strong<Structure> unlinkedFunctionExecutableStructure;
     233        Strong<Structure> unlinkedProgramCodeBlockStructure;
     234        Strong<Structure> unlinkedEvalCodeBlockStructure;
     235        Strong<Structure> unlinkedFunctionCodeBlockStructure;
    226236
    227237        IdentifierTable* identifierTable;
     
    437447
    438448        JSLock& apiLock() { return m_apiLock; }
     449        CodeCache* codeCache() { return m_codeCache.get(); }
    439450
    440451    private:
     
    457468#endif
    458469        bool m_inDefineOwnProperty;
     470        OwnPtr<CodeCache> m_codeCache;
    459471
    460472        TypedArrayDescriptor m_int8ArrayDescriptor;
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r131644 r133688  
    3737#include "BooleanPrototype.h"
    3838#include "CodeBlock.h"
     39#include "CodeCache.h"
    3940#include "DateConstructor.h"
    4041#include "DatePrototype.h"
     
    581582}
    582583
     584UnlinkedProgramCodeBlock* JSGlobalObject::createProgramCodeBlock(CallFrame* callFrame, ProgramExecutable* executable, JSObject** exception)
     585{
     586    ParserError error;
     587    JSParserStrictness strictness = executable->isStrictMode() ? JSParseStrict : JSParseNormal;
     588    DebuggerMode debuggerMode = hasDebugger() ? DebuggerOn : DebuggerOff;
     589    ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff;
     590    UnlinkedProgramCodeBlock* unlinkedCode = globalData().codeCache()->getProgramCodeBlock(globalData(), executable, executable->source(), strictness, debuggerMode, profilerMode, error);
     591
     592    if (hasDebugger())
     593        debugger()->sourceParsed(callFrame, executable->source().provider(), error.m_line, error.m_message);
     594
     595    if (error.m_type != ParserError::ErrorNone) {
     596        *exception = error.toErrorObject(this, executable->source());
     597        return 0;
     598    }
     599   
     600    return unlinkedCode;
     601}
     602
     603UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CallFrame* callFrame, EvalExecutable* executable, JSObject** exception)
     604{
     605    ParserError error;
     606    JSParserStrictness strictness = executable->isStrictMode() ? JSParseStrict : JSParseNormal;
     607    DebuggerMode debuggerMode = hasDebugger() ? DebuggerOn : DebuggerOff;
     608    ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff;
     609    UnlinkedEvalCodeBlock* unlinkedCode = globalData().codeCache()->getEvalCodeBlock(globalData(), executable, executable->source(), strictness, debuggerMode, profilerMode, error);
     610
     611    if (hasDebugger())
     612        debugger()->sourceParsed(callFrame, executable->source().provider(), error.m_line, error.m_message);
     613
     614    if (error.m_type != ParserError::ErrorNone) {
     615        *exception = error.toErrorObject(this, executable->source());
     616        return 0;
     617    }
     618
     619    return unlinkedCode;
     620}
     621
     622UnlinkedFunctionExecutable* JSGlobalObject::createFunctionExecutableFromGlobalCode(CallFrame* callFrame, const Identifier& name, const SourceCode& code, JSObject** exception)
     623{
     624    ParserError error;
     625    UnlinkedFunctionExecutable* executable = globalData().codeCache()->getFunctionExecutableFromGlobalCode(globalData(), name, code, error);
     626    if (hasDebugger())
     627        debugger()->sourceParsed(callFrame, code.provider(), error.m_line, error.m_message);
     628
     629    if (error.m_type != ParserError::ErrorNone) {
     630        *exception = error.toErrorObject(this, code);
     631        return 0;
     632    }
     633
     634    return executable;
     635}
     636
     637
    583638} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r132759 r133688  
    4444    class ErrorConstructor;
    4545    class ErrorPrototype;
     46    class EvalCodeBlock;
     47    class EvalExecutable;
     48    class FunctionCodeBlock;
     49    class FunctionExecutable;
    4650    class FunctionPrototype;
    4751    class GetterSetter;
     
    5155    class NativeErrorConstructor;
    5256    class ProgramCodeBlock;
     57    class ProgramExecutable;
    5358    class RegExpConstructor;
    5459    class RegExpPrototype;
    55 
     60    class SourceCode;
    5661    struct ActivationStackNode;
    5762    struct HashTable;
     
    186191        static JS_EXPORTDATA const ClassInfo s_info;
    187192
     193        bool hasDebugger() const { return m_debugger; }
     194        bool hasProfiler() const { return globalObjectMethodTable()->supportsProfiling(this); }
     195
    188196    protected:
    189197        JS_EXPORT_PRIVATE explicit JSGlobalObject(JSGlobalData&, Structure*, const GlobalObjectMethodTable* = 0);
     
    367375        double weakRandomNumber() { return m_weakRandom.get(); }
    368376        unsigned weakRandomInteger() { return m_weakRandom.getUint32(); }
     377
     378        UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception);
     379        UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, JSObject** exception);
     380        UnlinkedFunctionExecutable* createFunctionExecutableFromGlobalCode(CallFrame*, const Identifier&, const SourceCode&, JSObject** exception);
     381
    369382    protected:
    370383
  • trunk/Source/JavaScriptCore/runtime/JSType.h

    r129685 r133688  
    4242    FunctionExecutableType,
    4343
     44    UnlinkedFunctionExecutableType,
     45    UnlinkedProgramCodeBlockType,
     46    UnlinkedEvalCodeBlockType,
     47    UnlinkedFunctionCodeBlockType,
     48
    4449    // The ObjectType value must come before any JSType that is a subclass of JSObject.
    4550    ObjectType,
Note: See TracChangeset for help on using the changeset viewer.