Ignore:
Timestamp:
Dec 12, 2008, 12:02:09 AM (16 years ago)
Author:
[email protected]
Message:

2008-12-11 Sam Weinig <[email protected]>

Reviewed by Geoffrey Garen.

Remove dependancy on having the Instruction buffer in order to
deref Structures used for property access and global resolves.
Instead, we put references to the necessary Structures in axillary
data structures on the CodeBlock. This is not an ideal solution,
as we still pay for having the Structures in two places and we
would like to eventually just hold on to offsets into the machine
code buffer.

  • Also removes CodeBlock bloat in non-JIT by #ifdefing the JIT only data structures.
  • GNUmakefile.am:
  • JavaScriptCore.pri:
  • JavaScriptCore.scons:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • JavaScriptCoreSources.bkl:
  • bytecode/CodeBlock.cpp: (JSC::isGlobalResolve): (JSC::isPropertyAccess): (JSC::instructionOffsetForNth): (JSC::printGlobalResolveInfo): (JSC::printStructureStubInfo): (JSC::CodeBlock::printStructures): (JSC::CodeBlock::dump): (JSC::CodeBlock::~CodeBlock): (JSC::CodeBlock::shrinkToFit):
  • bytecode/CodeBlock.h: (JSC::GlobalResolveInfo::GlobalResolveInfo): (JSC::getNativePC): (JSC::CodeBlock::instructions): (JSC::CodeBlock::getStubInfo): (JSC::CodeBlock::getBytecodeIndex): (JSC::CodeBlock::addPropertyAccessInstruction): (JSC::CodeBlock::addGlobalResolveInstruction): (JSC::CodeBlock::numberOfStructureStubInfos): (JSC::CodeBlock::addStructureStubInfo): (JSC::CodeBlock::structureStubInfo): (JSC::CodeBlock::addGlobalResolveInfo): (JSC::CodeBlock::globalResolveInfo): (JSC::CodeBlock::numberOfCallLinkInfos): (JSC::CodeBlock::addCallLinkInfo): (JSC::CodeBlock::callLinkInfo):
  • bytecode/Instruction.h: (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set): (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList):
  • bytecode/Opcode.h: (JSC::):
  • bytecode/StructureStubInfo.cpp: Copied from bytecode/CodeBlock.cpp. (JSC::StructureStubInfo::deref):
  • bytecode/StructureStubInfo.h: Copied from bytecode/CodeBlock.h. (JSC::StructureStubInfo::StructureStubInfo): (JSC::StructureStubInfo::initGetByIdSelf): (JSC::StructureStubInfo::initGetByIdProto): (JSC::StructureStubInfo::initGetByIdChain): (JSC::StructureStubInfo::initGetByIdSelfList): (JSC::StructureStubInfo::initGetByIdProtoList): (JSC::StructureStubInfo::initPutByIdTransition): (JSC::StructureStubInfo::initPutByIdReplace): (JSC::StructureStubInfo::):
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitResolve): (JSC::BytecodeGenerator::emitGetById): (JSC::BytecodeGenerator::emitPutById): (JSC::BytecodeGenerator::emitCall): (JSC::BytecodeGenerator::emitConstruct): (JSC::BytecodeGenerator::emitCatch):
  • interpreter/Interpreter.cpp: (JSC::Interpreter::tryCTICachePutByID): (JSC::Interpreter::tryCTICacheGetByID): (JSC::Interpreter::cti_op_get_by_id_self_fail): (JSC::getPolymorphicAccessStructureListSlot): (JSC::Interpreter::cti_op_get_by_id_proto_list): (JSC::Interpreter::cti_op_resolve_global):
  • jit/JIT.cpp: (JSC::JIT::JIT): (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileSlowCases): (JSC::JIT::privateCompile):
  • jit/JITPropertyAccess.cpp: (JSC::JIT::compileGetByIdHotPath): (JSC::JIT::compilePutByIdHotPath): (JSC::JIT::compileGetByIdSlowCase): (JSC::JIT::compilePutByIdSlowCase): (JSC::JIT::privateCompileGetByIdSelfList): (JSC::JIT::privateCompileGetByIdProtoList): (JSC::JIT::privateCompileGetByIdChainList):
File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/bytecode/StructureStubInfo.h

    r39218 r39229  
    11/*
    22 * Copyright (C) 2008 Apple Inc. All rights reserved.
    3  * Copyright (C) 2008 Cameron Zwarich <[email protected]>
    43 *
    54 * Redistribution and use in source and binary forms, with or without
    65 * modification, are permitted provided that the following conditions
    76 * are met:
     7 * 1. Redistributions of source code must retain the above copyright
     8 *    notice, this list of conditions and the following disclaimer.
     9 * 2. Redistributions in binary form must reproduce the above copyright
     10 *    notice, this list of conditions and the following disclaimer in the
     11 *    documentation and/or other materials provided with the distribution.
    812 *
    9  * 1.  Redistributions of source code must retain the above copyright
    10  *     notice, this list of conditions and the following disclaimer.
    11  * 2.  Redistributions in binary form must reproduce the above copyright
    12  *     notice, this list of conditions and the following disclaimer in the
    13  *     documentation and/or other materials provided with the distribution.
    14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
    15  *     its contributors may be used to endorse or promote products derived
    16  *     from this software without specific prior written permission.
    17  *
    18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
    19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
    22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2824 */
    2925
    30 #ifndef CodeBlock_h
    31 #define CodeBlock_h
     26#ifndef StructureStubInfo_h
     27#define StructureStubInfo_h
    3228
    33 #include "EvalCodeCache.h"
    3429#include "Instruction.h"
    35 #include "JSGlobalObject.h"
    36 #include "JumpTable.h"
    37 #include "Nodes.h"
    38 #include "RegExp.h"
    39 #include "UString.h"
    40 #include <wtf/RefPtr.h>
    41 #include <wtf/Vector.h>
     30#include "Opcode.h"
     31#include "Structure.h"
    4232
    4333namespace JSC {
    4434
    45     class ExecState;
    46 
    47     enum CodeType { GlobalCode, EvalCode, FunctionCode };
    48 
    49     static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); }
    50 
    51     struct HandlerInfo {
    52         uint32_t start;
    53         uint32_t end;
    54         uint32_t target;
    55         uint32_t scopeDepth;
    56         void* nativeCode;
    57     };
    58 
    59     struct ExpressionRangeInfo {
    60         enum {
    61             MaxOffset = (1 << 7) - 1,
    62             MaxDivot = (1 << 25) - 1
    63         };
    64         uint32_t instructionOffset : 25;
    65         uint32_t divotPoint : 25;
    66         uint32_t startOffset : 7;
    67         uint32_t endOffset : 7;
    68     };
    69 
    70     struct LineInfo {
    71         uint32_t instructionOffset;
    72         int32_t lineNumber;
    73     };
    74 
     35#if ENABLE(JIT)
    7536    struct StructureStubInfo {
    76         StructureStubInfo(unsigned bytecodeIndex)
    77             : bytecodeIndex(bytecodeIndex)
     37        StructureStubInfo(OpcodeID opcodeID)
     38            : opcodeID(opcodeID)
    7839            , stubRoutine(0)
    7940            , callReturnLocation(0)
     
    8142        {
    8243        }
     44
     45        void initGetByIdSelf(Structure* baseObjectStructure)
     46        {
     47            opcodeID = op_get_by_id_self;
     48
     49            u.getByIdSelf.baseObjectStructure = baseObjectStructure;
     50            baseObjectStructure->ref();
     51        }
     52
     53        void initGetByIdProto(Structure* baseObjectStructure, Structure* prototypeStructure)
     54        {
     55            opcodeID = op_get_by_id_proto;
     56
     57            u.getByIdProto.baseObjectStructure = baseObjectStructure;
     58            baseObjectStructure->ref();
     59
     60            u.getByIdProto.prototypeStructure = prototypeStructure;
     61            prototypeStructure->ref();
     62        }
     63
     64        void initGetByIdChain(Structure* baseObjectStructure, StructureChain* chain)
     65        {
     66            opcodeID = op_get_by_id_chain;
     67
     68            u.getByIdChain.baseObjectStructure = baseObjectStructure;
     69            baseObjectStructure->ref();
     70
     71            u.getByIdChain.chain = chain;
     72            chain->ref();
     73        }
     74
     75        void initGetByIdSelfList(PolymorphicAccessStructureList* structureList, int listSize)
     76        {
     77            opcodeID = op_get_by_id_self_list;
     78
     79            u.getByIdProtoList.structureList = structureList;
     80            u.getByIdProtoList.listSize = listSize;
     81        }
     82
     83        void initGetByIdProtoList(PolymorphicAccessStructureList* structureList, int listSize)
     84        {
     85            opcodeID = op_get_by_id_proto_list;
     86
     87            u.getByIdProtoList.structureList = structureList;
     88            u.getByIdProtoList.listSize = listSize;
     89        }
     90
     91        // PutById*
     92
     93        void initPutByIdTransition(Structure* previousStructure, Structure* structure, StructureChain* chain)
     94        {
     95            opcodeID = op_put_by_id_transition;
     96
     97            u.putByIdTransition.previousStructure = previousStructure;
     98            previousStructure->ref();
     99
     100            u.putByIdTransition.structure = structure;
     101            structure->ref();
     102
     103            u.putByIdTransition.chain = chain;
     104            chain->ref();
     105        }
     106
     107        void initPutByIdReplace(Structure* baseObjectStructure)
     108        {
     109            opcodeID = op_put_by_id_replace;
    83110   
    84         unsigned bytecodeIndex;
     111            u.putByIdReplace.baseObjectStructure = baseObjectStructure;
     112            baseObjectStructure->ref();
     113        }
     114
     115        void deref();
     116
     117        OpcodeID opcodeID;
     118        union {
     119            struct {
     120                Structure* baseObjectStructure;
     121            } getByIdSelf;
     122            struct {
     123                Structure* baseObjectStructure;
     124                Structure* prototypeStructure;
     125            } getByIdProto;
     126            struct {
     127                Structure* baseObjectStructure;
     128                StructureChain* chain;
     129            } getByIdChain;
     130            struct {
     131                PolymorphicAccessStructureList* structureList;
     132                int listSize;
     133            } getByIdSelfList;
     134            struct {
     135                PolymorphicAccessStructureList* structureList;
     136                int listSize;
     137            } getByIdProtoList;
     138            struct {
     139                Structure* previousStructure;
     140                Structure* structure;
     141                StructureChain* chain;
     142            } putByIdTransition;
     143            struct {
     144                Structure* baseObjectStructure;
     145            } putByIdReplace;
     146        } u;
     147
    85148        void* stubRoutine;
    86149        void* callReturnLocation;
    87150        void* hotPathBegin;
    88151    };
    89 
    90     struct CallLinkInfo {
    91         CallLinkInfo()
    92             : callReturnLocation(0)
    93             , hotPathBegin(0)
    94             , hotPathOther(0)
    95             , coldPathOther(0)
    96             , callee(0)
    97         {
    98         }
    99    
    100         unsigned bytecodeIndex;
    101         void* callReturnLocation;
    102         void* hotPathBegin;
    103         void* hotPathOther;
    104         void* coldPathOther;
    105         CodeBlock* callee;
    106         unsigned position;
    107        
    108         void setUnlinked() { callee = 0; }
    109         bool isLinked() { return callee; }
    110     };
    111 
    112 #if ENABLE(JIT)
    113     struct PC {
    114         PC(void* nativePC, unsigned bytecodeIndex)
    115             : nativePC(nativePC)
    116             , bytecodeIndex(bytecodeIndex)
    117         {
    118         }
    119        
    120         void* nativePC;
    121         unsigned bytecodeIndex;
    122     };
    123152#endif
    124 
    125     // valueAtPosition helpers for the binaryChop algorithm below.
    126 
    127     inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo)
    128     {
    129         return structureStubInfo->callReturnLocation;
    130     }
    131 
    132     inline void* getCallLinkInfoReturnLocation(CallLinkInfo* callLinkInfo)
    133     {
    134         return callLinkInfo->callReturnLocation;
    135     }
    136 
    137 #if ENABLE(JIT)
    138     inline void* getNativePC(PC* pc)
    139     {
    140         return pc->nativePC;
    141     }
    142 #endif
    143 
    144     // Binary chop algorithm, calls valueAtPosition on pre-sorted elements in array,
    145     // compares result with key (KeyTypes should be comparable with '--', '<', '>').
    146     // Optimized for cases where the array contains the key, checked by assertions.
    147     template<typename ArrayType, typename KeyType, KeyType(*valueAtPosition)(ArrayType*)>
    148     inline ArrayType* binaryChop(ArrayType* array, size_t size, KeyType key)
    149     {
    150         // The array must contain at least one element (pre-condition, array does conatin key).
    151         // If the array only contains one element, no need to do the comparison.
    152         while (size > 1) {
    153             // Pick an element to check, half way through the array, and read the value.
    154             int pos = (size - 1) >> 1;
    155             KeyType val = valueAtPosition(&array[pos]);
    156            
    157             // If the key matches, success!
    158             if (val == key)
    159                 return &array[pos];
    160             // The item we are looking for is smaller than the item being check; reduce the value of 'size',
    161             // chopping off the right hand half of the array.
    162             else if (key < val)
    163                 size = pos;
    164             // Discard all values in the left hand half of the array, up to and including the item at pos.
    165             else {
    166                 size -= (pos + 1);
    167                 array += (pos + 1);
    168             }
    169 
    170             // 'size' should never reach zero.
    171             ASSERT(size);
    172         }
    173        
    174         // If we reach this point we've chopped down to one element, no need to check it matches
    175         ASSERT(size == 1);
    176         ASSERT(key == valueAtPosition(&array[0]));
    177         return &array[0];
    178     }
    179 
    180     class CodeBlock {
    181         friend class JIT;
    182     public:
    183         CodeBlock(ScopeNode* ownerNode, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset);
    184         ~CodeBlock();
    185 
    186         static void dumpStatistics();
    187 
    188 #if ENABLE(JIT)
    189         void unlinkCallers();
    190 #endif
    191 
    192         void addCaller(CallLinkInfo* caller)
    193         {
    194             caller->callee = this;
    195             caller->position = m_linkedCallerList.size();
    196             m_linkedCallerList.append(caller);
    197         }
    198 
    199         void removeCaller(CallLinkInfo* caller)
    200         {
    201             unsigned pos = caller->position;
    202             unsigned lastPos = m_linkedCallerList.size() - 1;
    203 
    204             if (pos != lastPos) {
    205                 m_linkedCallerList[pos] = m_linkedCallerList[lastPos];
    206                 m_linkedCallerList[pos]->position = pos;
    207             }
    208             m_linkedCallerList.shrink(lastPos);
    209         }
    210 
    211         inline bool isKnownNotImmediate(int index)
    212         {
    213             if (index == m_thisRegister)
    214                 return true;
    215 
    216             if (isConstantRegisterIndex(index))
    217                 return !JSImmediate::isImmediate(getConstant(index));
    218 
    219             return false;
    220         }
    221 
    222         ALWAYS_INLINE bool isConstantRegisterIndex(int index)
    223         {
    224             return index >= m_numVars && index < m_numVars + m_numConstants;
    225         }
    226 
    227         ALWAYS_INLINE JSValue* getConstant(int index)
    228         {
    229             return m_constantRegisters[index - m_numVars].getJSValue();
    230         }
    231 
    232         ALWAYS_INLINE bool isTemporaryRegisterIndex(int index)
    233         {
    234             return index >= m_numVars + m_numConstants;
    235         }
    236 
    237 #if !defined(NDEBUG) || ENABLE_OPCODE_SAMPLING
    238         void dump(ExecState*) const;
    239         void printStructures(const Instruction*) const;
    240         void printStructure(const char* name, const Instruction*, int operand) const;
    241 #endif
    242         int expressionRangeForVPC(const Instruction*, int& divot, int& startOffset, int& endOffset);
    243         int lineNumberForVPC(const Instruction* vPC);
    244         HandlerInfo* handlerForVPC(const Instruction* vPC);
    245 
    246         void mark();
    247         void refStructures(Instruction* vPC) const;
    248         void derefStructures(Instruction* vPC) const;
    249 
    250         StructureStubInfo& getStubInfo(void* returnAddress)
    251         {
    252             return *(binaryChop<StructureStubInfo, void*, getStructureStubInfoReturnLocation>(m_propertyAccessInstructions.begin(), m_propertyAccessInstructions.size(), returnAddress));
    253         }
    254 
    255         CallLinkInfo& getCallLinkInfo(void* returnAddress)
    256         {
    257             return *(binaryChop<CallLinkInfo, void*, getCallLinkInfoReturnLocation>(m_callLinkInfos.begin(), m_callLinkInfos.size(), returnAddress));
    258         }
    259 
    260 #if ENABLE(JIT)
    261         unsigned getBytecodeIndex(void* nativePC)
    262         {
    263             return binaryChop<PC, void*, getNativePC>(m_pcVector.begin(), m_pcVector.size(), nativePC)->bytecodeIndex;
    264         }
    265 #endif
    266 
    267         Vector<Instruction>& instructions() { return m_instructions; }
    268 #if ENABLE(JIT)
    269         void setJITCode(void* jitCode) { m_jitCode = jitCode; }
    270         void* jitCode() { return m_jitCode; }
    271         ExecutablePool* executablePool() { return m_executablePool.get(); }
    272         void setExecutablePool(ExecutablePool* pool) { m_executablePool = pool; }
    273 #endif
    274 
    275         ScopeNode* ownerNode() const { return m_ownerNode; }
    276 
    277         void setGlobalData(JSGlobalData* globalData) { m_globalData = globalData; }
    278 
    279         void setThisRegister(int thisRegister) { m_thisRegister = thisRegister; }
    280         int thisRegister() const { return m_thisRegister; }
    281 
    282         void setNeedsFullScopeChain(bool needsFullScopeChain) { m_needsFullScopeChain = needsFullScopeChain; }
    283         bool needsFullScopeChain() const { return m_needsFullScopeChain; }
    284         void setUsesEval(bool usesEval) { m_usesEval = usesEval; }
    285         bool usesEval() const { return m_usesEval; }
    286         void setUsesArguments(bool usesArguments) { m_usesArguments = usesArguments; }
    287         bool usesArguments() const { return m_usesArguments; }
    288 
    289         CodeType codeType() const { return m_codeType; }
    290 
    291         SourceProvider* source() const { return m_source.get(); }
    292         unsigned sourceOffset() const { return m_sourceOffset; }
    293 
    294         void addGlobalResolveInstruction(unsigned globalResolveInstructions) { m_globalResolveInstructions.append(globalResolveInstructions); }
    295 
    296         size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions.size(); }
    297         void addPropertyAccessInstruction(unsigned propertyAccessInstructions) { m_propertyAccessInstructions.append(StructureStubInfo(propertyAccessInstructions)); }
    298         StructureStubInfo& propertyAccessInstruction(int index) { return m_propertyAccessInstructions[index]; }
    299 
    300         size_t numberOfCallLinkInfos() const { return m_callLinkInfos.size(); }
    301         void addCallLinkInfo() { m_callLinkInfos.append(CallLinkInfo()); }
    302         CallLinkInfo& callLinkInfo(int index) { return m_callLinkInfos[index]; }
    303 
    304         size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
    305         void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
    306         unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
    307         unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
    308 
    309         size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
    310         void addExceptionHandler(const HandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); }
    311         HandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
    312 
    313         void addExpressionInfo(const ExpressionRangeInfo& expressionInfo) { return m_expressionInfo.append(expressionInfo); }
    314 
    315         size_t numberOfLineInfos() const { return m_lineInfo.size(); }
    316         void addLineInfo(const LineInfo& lineInfo) { return m_lineInfo.append(lineInfo); }
    317         LineInfo& lastLineInfo() { return m_lineInfo.last(); }
    318 
    319 #if ENABLE(JIT)
    320         Vector<PC>& pcVector() { return m_pcVector; }
    321 #endif
    322 
    323         // Constant Pool
    324 
    325         size_t numberOfIdentifiers() const { return m_identifiers.size(); }
    326         void addIdentifier(const Identifier& i) { return m_identifiers.append(i); }
    327         Identifier& identifier(int index) { return m_identifiers[index]; }
    328 
    329         size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
    330         void addConstantRegister(const Register& r) { return m_constantRegisters.append(r); }
    331         Register& constantRegister(int index) { return m_constantRegisters[index]; }
    332 
    333         unsigned addFunctionExpression(FuncExprNode* n) { unsigned size = m_functionExpressions.size(); m_functionExpressions.append(n); return size; }
    334         FuncExprNode* functionExpression(int index) const { return m_functionExpressions[index].get(); }
    335 
    336         unsigned addFunction(FuncDeclNode* n) { createRareDataIfNecessary(); unsigned size = m_rareData->m_functions.size(); m_rareData->m_functions.append(n); return size; }
    337         FuncDeclNode* function(int index) const { ASSERT(m_rareData); return m_rareData->m_functions[index].get(); }
    338 
    339         unsigned addUnexpectedConstant(JSValue* v) { createRareDataIfNecessary(); unsigned size = m_rareData->m_unexpectedConstants.size(); m_rareData->m_unexpectedConstants.append(v); return size; }
    340         JSValue* unexpectedConstant(int index) const { ASSERT(m_rareData); return m_rareData->m_unexpectedConstants[index]; }
    341 
    342         unsigned addRegExp(RegExp* r) { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); m_rareData->m_regexps.append(r); return size; }
    343         RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
    344 
    345 
    346         // Jump Tables
    347 
    348         size_t numberOfImmediateSwitchJumpTables() const { return m_rareData ? m_rareData->m_immediateSwitchJumpTables.size() : 0; }
    349         SimpleJumpTable& addImmediateSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_immediateSwitchJumpTables.append(SimpleJumpTable()); return m_rareData->m_immediateSwitchJumpTables.last(); }
    350         SimpleJumpTable& immediateSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_immediateSwitchJumpTables[tableIndex]; }
    351 
    352         size_t numberOfCharacterSwitchJumpTables() const { return m_rareData ? m_rareData->m_characterSwitchJumpTables.size() : 0; }
    353         SimpleJumpTable& addCharacterSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_characterSwitchJumpTables.append(SimpleJumpTable()); return m_rareData->m_characterSwitchJumpTables.last(); }
    354         SimpleJumpTable& characterSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_characterSwitchJumpTables[tableIndex]; }
    355 
    356         size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
    357         StringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(StringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
    358         StringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
    359 
    360 
    361         SymbolTable& symbolTable() { return m_symbolTable; }
    362 
    363         EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
    364 
    365         void shrinkToFit();
    366 
    367         // FIXME: Make these remaining members private.
    368 
    369         int m_numCalleeRegisters;
    370         // NOTE: numConstants holds the number of constant registers allocated
    371         // by the code generator, not the number of constant registers used.
    372         // (Duplicate constants are uniqued during code generation, and spare
    373         // constant registers may be allocated.)
    374         int m_numConstants;
    375         int m_numVars;
    376         int m_numParameters;
    377 
    378     private:
    379 #if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
    380         void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const;
    381 #endif
    382 
    383         void createRareDataIfNecessary()
    384         {
    385             if (!m_rareData)
    386                 m_rareData.set(new RareData);
    387         }
    388 
    389 
    390         ScopeNode* m_ownerNode;
    391         JSGlobalData* m_globalData;
    392 
    393         Vector<Instruction> m_instructions;
    394 #if ENABLE(JIT)
    395         void* m_jitCode;
    396         RefPtr<ExecutablePool> m_executablePool;
    397 #endif
    398 
    399         int m_thisRegister;
    400 
    401         bool m_needsFullScopeChain;
    402         bool m_usesEval;
    403         bool m_usesArguments;
    404 
    405         CodeType m_codeType;
    406 
    407         RefPtr<SourceProvider> m_source;
    408         unsigned m_sourceOffset;
    409 
    410         Vector<unsigned> m_globalResolveInstructions;
    411         Vector<StructureStubInfo> m_propertyAccessInstructions;
    412         Vector<CallLinkInfo> m_callLinkInfos;
    413         Vector<CallLinkInfo*> m_linkedCallerList;
    414 
    415         Vector<unsigned> m_jumpTargets;
    416 
    417         Vector<ExpressionRangeInfo> m_expressionInfo;
    418         Vector<LineInfo> m_lineInfo;
    419 
    420 #if ENABLE(JIT)
    421         Vector<PC> m_pcVector;
    422 #endif
    423 
    424         // Constant Pool
    425         Vector<Identifier> m_identifiers;
    426         Vector<Register> m_constantRegisters;
    427         Vector<RefPtr<FuncExprNode> > m_functionExpressions;
    428 
    429         SymbolTable m_symbolTable;
    430 
    431         struct RareData {
    432             Vector<HandlerInfo> m_exceptionHandlers;
    433 
    434             // Rare Constants
    435             Vector<RefPtr<FuncDeclNode> > m_functions;
    436             Vector<JSValue*> m_unexpectedConstants;
    437             Vector<RefPtr<RegExp> > m_regexps;
    438 
    439             // Jump Tables
    440             Vector<SimpleJumpTable> m_immediateSwitchJumpTables;
    441             Vector<SimpleJumpTable> m_characterSwitchJumpTables;
    442             Vector<StringJumpTable> m_stringSwitchJumpTables;
    443 
    444             EvalCodeCache m_evalCodeCache;
    445         };
    446 
    447         OwnPtr<RareData> m_rareData;
    448     };
    449 
    450     // Program code is not marked by any function, so we make the global object
    451     // responsible for marking it.
    452 
    453     class ProgramCodeBlock : public CodeBlock {
    454     public:
    455         ProgramCodeBlock(ScopeNode* ownerNode, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider)
    456             : CodeBlock(ownerNode, codeType, sourceProvider, 0)
    457             , m_globalObject(globalObject)
    458         {
    459             m_globalObject->codeBlocks().add(this);
    460         }
    461 
    462         ~ProgramCodeBlock()
    463         {
    464             if (m_globalObject)
    465                 m_globalObject->codeBlocks().remove(this);
    466         }
    467 
    468         void clearGlobalObject() { m_globalObject = 0; }
    469 
    470     private:
    471         JSGlobalObject* m_globalObject; // For program and eval nodes, the global object that marks the constant pool.
    472     };
    473 
    474     class EvalCodeBlock : public ProgramCodeBlock {
    475     public:
    476         EvalCodeBlock(ScopeNode* ownerNode, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider)
    477             : ProgramCodeBlock(ownerNode, EvalCode, globalObject, sourceProvider)
    478         {
    479         }
    480     };
    481153
    482154} // namespace JSC
    483155
    484 #endif // CodeBlock_h
     156#endif // StructureStubInfo_h
Note: See TracChangeset for help on using the changeset viewer.