Bug 1105261 - Revert fresh vectors to not prereserving their inline allocation space, because the guaranteed extent of that space is an implementation detail. r=nbp

--HG--
extra : rebase_source : ec5431786f504651b1f8a4a019da6e537b6ac175
This commit is contained in:
Jeff Walden 2014-11-26 16:01:19 -05:00
parent 2455228c4a
commit 4037ed512e
7 changed files with 121 additions and 13 deletions

View File

@ -827,7 +827,9 @@ HandleDynamicLinkFailure(JSContext *cx, CallArgs args, AsmJSModule &module, Hand
return false;
AutoNameVector formals(cx);
formals.reserve(3);
if (!formals.reserve(3))
return false;
if (module.globalArgumentName())
formals.infallibleAppend(module.globalArgumentName());
if (module.importArgumentName())

View File

@ -8328,7 +8328,8 @@ GenerateFFIInterpExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &e
MIRType_Int32, // argc
MIRType_Pointer }; // argv
MIRTypeVector invokeArgTypes(m.cx());
invokeArgTypes.infallibleAppend(typeArray, ArrayLength(typeArray));
if (!invokeArgTypes.append(typeArray, ArrayLength(typeArray)))
return false;
// At the point of the call, the stack layout shall be (sp grows to the left):
// | stack args | padding | Value argv[] | padding | retaddr | caller stack args |
@ -8445,7 +8446,9 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
// | stack args | padding | Value argv[1] | ...
// The padding between args and argv ensures that argv is aligned.
MIRTypeVector coerceArgTypes(m.cx());
coerceArgTypes.infallibleAppend(MIRType_Pointer); // argv
if (!coerceArgTypes.append(MIRType_Pointer)) // argv
return false;
unsigned offsetToCoerceArgv = AlignBytes(StackArgBytes(coerceArgTypes), sizeof(double));
unsigned totalCoerceBytes = offsetToCoerceArgv + sizeof(Value) + MaybeSavedGlobalReg;
unsigned coerceFrameSize = StackDecrementForCall(masm, AsmJSStackAlignment, totalCoerceBytes);
@ -8705,6 +8708,9 @@ GenerateBuiltinThunk(ModuleCompiler &m, AsmJSExit::BuiltinKind builtin)
MOZ_ASSERT(masm.framePushed() == 0);
MIRTypeVector argTypes(m.cx());
if (!argTypes.reserve(2))
return false;
switch (builtin) {
case AsmJSExit::Builtin_ToInt32:
argTypes.infallibleAppend(MIRType_Int32);

View File

@ -151,7 +151,7 @@ TokenStream::SourceCoords::SourceCoords(ExclusiveContext *cx, uint32_t ln)
// appends cannot fail because |lineStartOffsets_| has statically-allocated
// elements.
MOZ_ASSERT(lineStartOffsets_.capacity() >= 2);
(void)lineStartOffsets_.reserve(2);
MOZ_ALWAYS_TRUE(lineStartOffsets_.reserve(2));
lineStartOffsets_.infallibleAppend(0);
lineStartOffsets_.infallibleAppend(maxPtr);
}

View File

@ -2112,7 +2112,7 @@ ASTSerializer::importDeclaration(ParseNode *pn, MutableHandleValue dst)
MOZ_ASSERT(pn->pn_right->isKind(PNK_STRING));
NodeVector elts(cx);
if (!elts.reserve(pn->pn_count))
if (!elts.reserve(pn->pn_left->pn_count))
return false;
for (ParseNode *next = pn->pn_left->pn_head; next; next = next->pn_next) {
@ -2151,7 +2151,7 @@ ASTSerializer::exportDeclaration(ParseNode *pn, MutableHandleValue dst)
ParseNode *kid = pn->isKind(PNK_EXPORT) ? pn->pn_kid : pn->pn_left;
switch (ParseNodeKind kind = kid->getKind()) {
case PNK_EXPORT_SPEC_LIST:
if (!elts.reserve(pn->pn_count))
if (!elts.reserve(pn->pn_left->pn_count))
return false;
for (ParseNode *next = pn->pn_left->pn_head; next; next = next->pn_next) {

View File

@ -215,6 +215,10 @@ struct VectorImpl<T, N, AP, ThisVector, true>
}
};
// A struct for TestVector.cpp to access private internal fields.
// DO NOT DEFINE IN YOUR OWN CODE.
struct VectorTesting;
} // namespace detail
/*
@ -233,6 +237,8 @@ class VectorBase : private AllocPolicy
typedef detail::VectorImpl<T, N, AllocPolicy, ThisVector, kElemIsPod> Impl;
friend struct detail::VectorImpl<T, N, AllocPolicy, ThisVector, kElemIsPod>;
friend struct detail::VectorTesting;
bool growStorageBy(size_t aIncr);
bool convertToHeapStorage(size_t aNewCap);
@ -327,10 +333,17 @@ class VectorBase : private AllocPolicy
}
#ifdef DEBUG
/**
* The amount of explicitly allocated space in this vector that is immediately
* available to be filled by appending additional elements. This value is
* always greater than or equal to |length()| -- the vector's actual elements
* are implicitly reserved. This value is always less than or equal to
* |capacity()|. It may be explicitly increased using the |reserve()| method.
*/
size_t reserved() const
{
MOZ_ASSERT(mReserved <= mCapacity);
MOZ_ASSERT(mLength <= mReserved);
MOZ_ASSERT(mReserved <= mCapacity);
return mReserved;
}
#endif
@ -450,8 +463,12 @@ public:
bool initCapacity(size_t aRequest);
/**
* If reserve(length() + N) succeeds, the N next appends are guaranteed to
* succeed.
* If reserve(aRequest) succeeds and |aRequest >= length()|, then appending
* |aRequest - length()| elements, in any sequence of append/appendAll calls,
* is guaranteed to succeed.
*
* A request to reserve an amount less than the current length does not affect
* reserved space.
*/
bool reserve(size_t aRequest);
@ -622,7 +639,7 @@ VectorBase<T, N, AP, TV>::VectorBase(AP aAP)
, mLength(0)
, mCapacity(kInlineCapacity)
#ifdef DEBUG
, mReserved(kInlineCapacity)
, mReserved(0)
, mEntered(false)
#endif
{
@ -662,7 +679,7 @@ VectorBase<T, N, AllocPolicy, TV>::VectorBase(TV&& aRhs)
aRhs.mCapacity = kInlineCapacity;
aRhs.mLength = 0;
#ifdef DEBUG
aRhs.mReserved = kInlineCapacity;
aRhs.mReserved = 0;
#endif
}
}
@ -941,7 +958,7 @@ VectorBase<T, N, AP, TV>::clearAndFree()
mBegin = static_cast<T*>(mStorage.addr());
mCapacity = kInlineCapacity;
#ifdef DEBUG
mReserved = kInlineCapacity;
mReserved = 0;
#endif
}
@ -1155,7 +1172,7 @@ VectorBase<T, N, AP, TV>::extractRawBuffer()
mLength = 0;
mCapacity = kInlineCapacity;
#ifdef DEBUG
mReserved = kInlineCapacity;
mReserved = 0;
#endif
}
return ret;

82
mfbt/tests/TestVector.cpp Normal file
View File

@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Move.h"
#include "mozilla/Vector.h"
using mozilla::detail::VectorTesting;
using mozilla::Move;
using mozilla::Vector;
struct mozilla::detail::VectorTesting
{
static void testReserved();
};
void
mozilla::detail::VectorTesting::testReserved()
{
#ifdef DEBUG
Vector<bool> bv;
MOZ_RELEASE_ASSERT(bv.reserved() == 0);
MOZ_RELEASE_ASSERT(bv.append(true));
MOZ_RELEASE_ASSERT(bv.reserved() == 1);
Vector<bool> otherbv;
MOZ_RELEASE_ASSERT(otherbv.append(false));
MOZ_RELEASE_ASSERT(otherbv.append(true));
MOZ_RELEASE_ASSERT(bv.appendAll(otherbv));
MOZ_RELEASE_ASSERT(bv.reserved() == 3);
MOZ_RELEASE_ASSERT(bv.reserve(5));
MOZ_RELEASE_ASSERT(bv.reserved() == 5);
MOZ_RELEASE_ASSERT(bv.reserve(1));
MOZ_RELEASE_ASSERT(bv.reserved() == 5);
Vector<bool> bv2(Move(bv));
MOZ_RELEASE_ASSERT(bv.reserved() == 0);
MOZ_RELEASE_ASSERT(bv2.reserved() == 5);
bv2.clearAndFree();
MOZ_RELEASE_ASSERT(bv2.reserved() == 0);
Vector<int, 42> iv;
MOZ_RELEASE_ASSERT(iv.reserved() == 0);
MOZ_RELEASE_ASSERT(iv.append(17));
MOZ_RELEASE_ASSERT(iv.reserved() == 1);
Vector<int, 42> otheriv;
MOZ_RELEASE_ASSERT(otheriv.append(42));
MOZ_RELEASE_ASSERT(otheriv.append(37));
MOZ_RELEASE_ASSERT(iv.appendAll(otheriv));
MOZ_RELEASE_ASSERT(iv.reserved() == 3);
MOZ_RELEASE_ASSERT(iv.reserve(5));
MOZ_RELEASE_ASSERT(iv.reserved() == 5);
MOZ_RELEASE_ASSERT(iv.reserve(1));
MOZ_RELEASE_ASSERT(iv.reserved() == 5);
MOZ_RELEASE_ASSERT(iv.reserve(55));
MOZ_RELEASE_ASSERT(iv.reserved() == 55);
Vector<int, 42> iv2(Move(iv));
MOZ_RELEASE_ASSERT(iv.reserved() == 0);
MOZ_RELEASE_ASSERT(iv2.reserved() == 55);
iv2.clearAndFree();
MOZ_RELEASE_ASSERT(iv2.reserved() == 0);
#endif
}
int
main()
{
VectorTesting::testReserved();
}

View File

@ -30,6 +30,7 @@ CppUnitTests([
'TestTypedEnum',
'TestTypeTraits',
'TestUniquePtr',
'TestVector',
'TestWeakPtr',
])