diff options
author | Ben Murdoch <benm@google.com> | 2009-08-11 17:01:47 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2009-08-11 18:21:02 +0100 |
commit | 0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5 (patch) | |
tree | 2943df35f62d885c89d01063cc528dd73b480fea /JavaScriptCore/bytecompiler | |
parent | 7e7a70bfa49a1122b2597a1e6367d89eb4035eca (diff) | |
download | external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.zip external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.gz external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.bz2 |
Merge in WebKit r47029.
Diffstat (limited to 'JavaScriptCore/bytecompiler')
-rw-r--r-- | JavaScriptCore/bytecompiler/BytecodeGenerator.cpp | 109 | ||||
-rw-r--r-- | JavaScriptCore/bytecompiler/BytecodeGenerator.h | 32 | ||||
-rw-r--r-- | JavaScriptCore/bytecompiler/RegisterID.h | 2 | ||||
-rw-r--r-- | JavaScriptCore/bytecompiler/SegmentedVector.h | 170 |
4 files changed, 48 insertions, 265 deletions
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index 21a3016..59537b6 100644 --- a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -196,17 +196,10 @@ bool BytecodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant, R return result.second; } -void BytecodeGenerator::allocateConstants(size_t count) +void BytecodeGenerator::preserveLastVar() { - m_codeBlock->m_numConstants = count; - if (!count) - return; - - m_nextConstantIndex = m_calleeRegisters.size(); - - for (size_t i = 0; i < count; ++i) - newRegister(); - m_lastConstant = &m_calleeRegisters.last(); + if ((m_firstConstantIndex = m_calleeRegisters.size()) != 0) + m_lastVar = &m_calleeRegisters.last(); } BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, ProgramCodeBlock* codeBlock) @@ -222,6 +215,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d , m_baseScopeDepth(0) , m_codeType(GlobalCode) , m_nextGlobalIndex(-1) + , m_nextConstantOffset(0) , m_globalConstantIndex(0) , m_globalData(&scopeChain.globalObject()->globalExec()->globalData()) , m_lastOpcodeID(op_end) @@ -272,7 +266,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d if (!globalObject->hasProperty(exec, varStack[i].first)) newVars.append(addGlobalVar(varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant)); - allocateConstants(programNode->neededConstants()); + preserveLastVar(); for (size_t i = 0; i < newVars.size(); ++i) emitLoad(newVars[i], jsUndefined()); @@ -290,7 +284,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d globalObject->putWithAttributes(exec, varStack[i].first, jsUndefined(), attributes); } - allocateConstants(programNode->neededConstants()); + preserveLastVar(); } } @@ -305,6 +299,7 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug , m_dynamicScopeDepth(0) , m_baseScopeDepth(0) , m_codeType(FunctionCode) + , m_nextConstantOffset(0) , m_globalConstantIndex(0) , m_globalData(&scopeChain.globalObject()->globalExec()->globalData()) , m_lastOpcodeID(op_end) @@ -332,7 +327,7 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug } else emitOpcode(op_enter); - if (usesArguments) { + if (usesArguments) { emitOpcode(op_init_arguments); // The debugger currently retrieves the arguments object from an activation rather than pulling @@ -372,7 +367,7 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug for (size_t i = 0; i < parameterCount; ++i) addParameter(parameters[i]); - allocateConstants(functionBody->neededConstants()); + preserveLastVar(); } BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock) @@ -387,6 +382,7 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge , m_dynamicScopeDepth(0) , m_baseScopeDepth(codeBlock->baseScopeDepth()) , m_codeType(EvalCode) + , m_nextConstantOffset(0) , m_globalConstantIndex(0) , m_globalData(&scopeChain.globalObject()->globalExec()->globalData()) , m_lastOpcodeID(op_end) @@ -401,7 +397,7 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge codeBlock->setGlobalData(m_globalData); m_codeBlock->m_numParameters = 1; // Allocate space for "this" - allocateConstants(evalNode->neededConstants()); + preserveLastVar(); } RegisterID* BytecodeGenerator::addParameter(const Identifier& ident) @@ -525,7 +521,7 @@ PassRefPtr<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, c m_labelScopes.removeLast(); // Allocate new label scope. - LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : 0); // Only loops have continue targets. + LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets. m_labelScopes.append(scope); return &m_labelScopes.last(); } @@ -791,34 +787,19 @@ unsigned BytecodeGenerator::addConstant(const Identifier& ident) return result.first->second; } -RegisterID* BytecodeGenerator::addConstant(JSValue v) +RegisterID* BytecodeGenerator::addConstantValue(JSValue v) { - pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(JSValue::encode(v), m_nextConstantIndex); - if (result.second) { - RegisterID& constant = m_calleeRegisters[m_nextConstantIndex]; - - ++m_nextConstantIndex; + int index = m_nextConstantOffset; + pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(JSValue::encode(v), m_nextConstantOffset); + if (result.second) { + m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset); + ++m_nextConstantOffset; m_codeBlock->addConstantRegister(JSValue(v)); - return &constant; - } - - return ®isterFor(result.first->second); -} - -unsigned BytecodeGenerator::addUnexpectedConstant(JSValue v) -{ - return m_codeBlock->addUnexpectedConstant(v); -} + } else + index = result.first->second; -RegisterID* BytecodeGenerator::emitLoadGlobalObject(RegisterID* dst, JSObject* globalObject) -{ - if (!m_globalConstantIndex) - m_globalConstantIndex = m_codeBlock->addUnexpectedConstant(globalObject); - emitOpcode(op_unexpected_load); - instructions().append(dst->index()); - instructions().append(m_globalConstantIndex); - return dst; + return &m_constantPoolRegisters[index]; } unsigned BytecodeGenerator::addRegExp(RegExp* r) @@ -880,9 +861,8 @@ RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, instructions().append(src2->index()); if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor || - opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub) { + opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div) instructions().append(types.toInt()); - } return dst; } @@ -898,8 +878,8 @@ RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst if (src1->index() == dstIndex && src1->isTemporary() && m_codeBlock->isConstantRegisterIndex(src2->index()) - && m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue().isString()) { - const UString& value = asString(m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue())->value(); + && m_codeBlock->constantRegister(src2->index()).jsValue().isString()) { + const UString& value = asString(m_codeBlock->constantRegister(src2->index()).jsValue())->value(); if (value == "undefined") { rewindUnaryOp(); emitOpcode(op_is_undefined); @@ -979,28 +959,12 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& ident RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v) { - RegisterID* constantID = addConstant(v); + RegisterID* constantID = addConstantValue(v); if (dst) return emitMove(dst, constantID); return constantID; } -RegisterID* BytecodeGenerator::emitUnexpectedLoad(RegisterID* dst, bool b) -{ - emitOpcode(op_unexpected_load); - instructions().append(dst->index()); - instructions().append(addUnexpectedConstant(jsBoolean(b))); - return dst; -} - -RegisterID* BytecodeGenerator::emitUnexpectedLoad(RegisterID* dst, double d) -{ - emitOpcode(op_unexpected_load); - instructions().append(dst->index()); - instructions().append(addUnexpectedConstant(jsNumber(globalData(), d))); - return dst; -} - bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, JSObject*& globalObject) { // Cases where we cannot statically optimize the lookup. @@ -1169,7 +1133,7 @@ RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier } // Global object is the base - return emitLoadGlobalObject(dst, globalObject); + return emitLoad(dst, JSValue(globalObject)); } RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property) @@ -1196,7 +1160,7 @@ RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, Register } // Global object is the base - emitLoadGlobalObject(baseDst, globalObject); + emitLoad(baseDst, JSValue(globalObject)); if (index != missingSymbolMarker() && !forceGlobalResolve) { // Directly index the property lookup across multiple scopes. @@ -1218,15 +1182,6 @@ RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, Register return baseDst; } -RegisterID* BytecodeGenerator::emitResolveFunction(RegisterID* baseDst, RegisterID* funcDst, const Identifier& property) -{ - emitOpcode(op_resolve_func); - instructions().append(baseDst->index()); - instructions().append(funcDst->index()); - instructions().append(addConstant(property)); - return baseDst; -} - void BytecodeGenerator::emitMethodCheck() { emitOpcode(op_method_check); @@ -1235,7 +1190,7 @@ void BytecodeGenerator::emitMethodCheck() RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property) { #if ENABLE(JIT) - m_codeBlock->addStructureStubInfo(StructureStubInfo(op_get_by_id)); + m_codeBlock->addStructureStubInfo(StructureStubInfo(access_get_by_id)); #else m_codeBlock->addPropertyAccessInstruction(instructions().size()); #endif @@ -1254,7 +1209,7 @@ RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, co RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value) { #if ENABLE(JIT) - m_codeBlock->addStructureStubInfo(StructureStubInfo(op_put_by_id)); + m_codeBlock->addStructureStubInfo(StructureStubInfo(access_put_by_id)); #else m_codeBlock->addPropertyAccessInstruction(instructions().size()); #endif @@ -1815,7 +1770,7 @@ RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end) { #if ENABLE(JIT) - HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, MacroAssembler::CodeLocationLabel() }; + HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() }; #else HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth }; #endif @@ -1831,7 +1786,7 @@ RegisterID* BytecodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSV emitOpcode(op_new_error); instructions().append(dst->index()); instructions().append(static_cast<int>(type)); - instructions().append(addUnexpectedConstant(message)); + instructions().append(addConstantValue(message)->index()); return dst; } @@ -1840,6 +1795,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, emitOpcode(op_jsr); instructions().append(retAddrDst->index()); instructions().append(finally->offsetFrom(instructions().size())); + emitLabel(newLabel().get()); // Record the fact that the next instruction is implicitly labeled, because op_sret will return to it. return finally; } @@ -1893,7 +1849,6 @@ static int32_t keyForImmediateSwitch(ExpressionNode* node, int32_t min, int32_t ASSERT(node->isNumber()); double value = static_cast<NumberNode*>(node)->value(); int32_t key = static_cast<int32_t>(value); - ASSERT(JSValue::makeInt32Fast(key) && (JSValue::makeInt32Fast(key).getInt32Fast() == value)); ASSERT(key == value); ASSERT(key >= min); ASSERT(key <= max); diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/JavaScriptCore/bytecompiler/BytecodeGenerator.h index 6813d69..c273597 100644 --- a/JavaScriptCore/bytecompiler/BytecodeGenerator.h +++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.h @@ -37,11 +37,12 @@ #include "LabelScope.h" #include "Interpreter.h" #include "RegisterID.h" -#include "SegmentedVector.h" #include "SymbolTable.h" #include "Debugger.h" #include "Nodes.h" +#include <wtf/FastAllocBase.h> #include <wtf/PassRefPtr.h> +#include <wtf/SegmentedVector.h> #include <wtf/Vector.h> namespace JSC { @@ -60,7 +61,7 @@ namespace JSC { FinallyContext finallyContext; }; - class BytecodeGenerator { + class BytecodeGenerator : public WTF::FastAllocBase { public: typedef DeclarationStacks::VarStack VarStack; typedef DeclarationStacks::FunctionStack FunctionStack; @@ -244,9 +245,6 @@ namespace JSC { RegisterID* emitLoad(RegisterID* dst, double); RegisterID* emitLoad(RegisterID* dst, const Identifier&); RegisterID* emitLoad(RegisterID* dst, JSValue); - RegisterID* emitUnexpectedLoad(RegisterID* dst, bool); - RegisterID* emitUnexpectedLoad(RegisterID* dst, double); - RegisterID* emitLoadGlobalObject(RegisterID* dst, JSObject* globalObject); RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src); RegisterID* emitBinaryOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes); @@ -278,7 +276,6 @@ namespace JSC { RegisterID* emitResolveBase(RegisterID* dst, const Identifier& property); RegisterID* emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property); - RegisterID* emitResolveFunction(RegisterID* baseDst, RegisterID* funcDst, const Identifier& property); void emitMethodCheck(); @@ -357,7 +354,7 @@ namespace JSC { PassRefPtr<Label> emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope); - typedef HashMap<EncodedJSValue, unsigned, PtrHash<EncodedJSValue>, JSValueHashTraits> JSValueMap; + typedef HashMap<EncodedJSValue, unsigned, EncodedJSValueHash, EncodedJSValueHashTraits> JSValueMap; struct IdentifierMapIndexHashTraits { typedef int TraitType; @@ -398,7 +395,7 @@ namespace JSC { RegisterID* addParameter(const Identifier&); - void allocateConstants(size_t); + void preserveLastVar(); RegisterID& registerFor(int index) { @@ -419,8 +416,7 @@ namespace JSC { unsigned addConstant(FuncDeclNode*); unsigned addConstant(FuncExprNode*); unsigned addConstant(const Identifier&); - RegisterID* addConstant(JSValue); - unsigned addUnexpectedConstant(JSValue); + RegisterID* addConstantValue(JSValue); unsigned addRegExp(RegExp*); Vector<Instruction>& instructions() { return m_codeBlock->instructions(); } @@ -449,12 +445,13 @@ namespace JSC { RegisterID m_thisRegister; RegisterID m_argumentsRegister; int m_activationRegisterIndex; - SegmentedVector<RegisterID, 32> m_calleeRegisters; - SegmentedVector<RegisterID, 32> m_parameters; - SegmentedVector<RegisterID, 32> m_globals; - SegmentedVector<Label, 32> m_labels; - SegmentedVector<LabelScope, 8> m_labelScopes; - RefPtr<RegisterID> m_lastConstant; + WTF::SegmentedVector<RegisterID, 32> m_constantPoolRegisters; + WTF::SegmentedVector<RegisterID, 32> m_calleeRegisters; + WTF::SegmentedVector<RegisterID, 32> m_parameters; + WTF::SegmentedVector<RegisterID, 32> m_globals; + WTF::SegmentedVector<Label, 32> m_labels; + WTF::SegmentedVector<LabelScope, 8> m_labelScopes; + RefPtr<RegisterID> m_lastVar; int m_finallyDepth; int m_dynamicScopeDepth; int m_baseScopeDepth; @@ -465,7 +462,8 @@ namespace JSC { int m_nextGlobalIndex; int m_nextParameterIndex; - int m_nextConstantIndex; + int m_firstConstantIndex; + int m_nextConstantOffset; unsigned m_globalConstantIndex; int m_globalVarStorageOffset; diff --git a/JavaScriptCore/bytecompiler/RegisterID.h b/JavaScriptCore/bytecompiler/RegisterID.h index 0223c2a..3532ad8 100644 --- a/JavaScriptCore/bytecompiler/RegisterID.h +++ b/JavaScriptCore/bytecompiler/RegisterID.h @@ -35,7 +35,7 @@ namespace JSC { - class RegisterID : Noncopyable { + class RegisterID : public Noncopyable { public: RegisterID() : m_refCount(0) diff --git a/JavaScriptCore/bytecompiler/SegmentedVector.h b/JavaScriptCore/bytecompiler/SegmentedVector.h deleted file mode 100644 index bbab04f..0000000 --- a/JavaScriptCore/bytecompiler/SegmentedVector.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SegmentedVector_h -#define SegmentedVector_h - -#include <wtf/Vector.h> - -namespace JSC { - - // SegmentedVector is just like Vector, but it doesn't move the values - // stored in its buffer when it grows. Therefore, it is safe to keep - // pointers into a SegmentedVector. - template <typename T, size_t SegmentSize> class SegmentedVector { - public: - SegmentedVector() - : m_size(0) - { - m_segments.append(&m_inlineSegment); - } - - ~SegmentedVector() - { - deleteAllSegments(); - } - - size_t size() const { return m_size; } - - T& at(size_t index) - { - if (index < SegmentSize) - return m_inlineSegment[index]; - return segmentFor(index)->at(subscriptFor(index)); - } - - T& operator[](size_t index) - { - return at(index); - } - - T& last() - { - return at(size() - 1); - } - - template <typename U> void append(const U& value) - { - ++m_size; - - if (m_size <= SegmentSize) { - m_inlineSegment.uncheckedAppend(value); - return; - } - - if (!segmentExistsFor(m_size - 1)) - m_segments.append(new Segment); - segmentFor(m_size - 1)->uncheckedAppend(value); - } - - void removeLast() - { - if (m_size <= SegmentSize) - m_inlineSegment.removeLast(); - else - segmentFor(m_size - 1)->removeLast(); - --m_size; - } - - void grow(size_t size) - { - ASSERT(size > m_size); - ensureSegmentsFor(size); - m_size = size; - } - - void clear() - { - deleteAllSegments(); - m_segments.resize(1); - m_inlineSegment.clear(); - m_size = 0; - } - - private: - typedef Vector<T, SegmentSize> Segment; - - void deleteAllSegments() - { - // Skip the first segment, because it's our inline segment, which was - // not created by new. - for (size_t i = 1; i < m_segments.size(); i++) - delete m_segments[i]; - } - - bool segmentExistsFor(size_t index) - { - return index / SegmentSize < m_segments.size(); - } - - Segment* segmentFor(size_t index) - { - return m_segments[index / SegmentSize]; - } - - size_t subscriptFor(size_t index) - { - return index % SegmentSize; - } - - void ensureSegmentsFor(size_t size) - { - size_t segmentCount = m_size / SegmentSize; - if (m_size % SegmentSize) - ++segmentCount; - segmentCount = std::max<size_t>(segmentCount, 1); // We always have at least our inline segment. - - size_t neededSegmentCount = size / SegmentSize; - if (size % SegmentSize) - ++neededSegmentCount; - - // Fill up to N - 1 segments. - size_t end = neededSegmentCount - 1; - for (size_t i = segmentCount - 1; i < end; ++i) - ensureSegment(i, SegmentSize); - - // Grow segment N to accomodate the remainder. - ensureSegment(end, subscriptFor(size - 1) + 1); - } - - void ensureSegment(size_t segmentIndex, size_t size) - { - ASSERT(segmentIndex <= m_segments.size()); - if (segmentIndex == m_segments.size()) - m_segments.append(new Segment); - m_segments[segmentIndex]->grow(size); - } - - size_t m_size; - Segment m_inlineSegment; - Vector<Segment*, 32> m_segments; - }; - -} // namespace JSC - -#endif // SegmentedVector_h |