Bug 1246061. r=jandem, r=bz, r=luke, r=froydnj

--HG--
extra : rebase_source : 5b314d4c4c6e0b553290884be7338f8e79c22f71
This commit is contained in:
Jeff Walden 2016-03-09 00:37:20 -08:00
Родитель 8473d1c60c
Коммит 1dd8dbc3f7
24 изменённых файлов: 291 добавлений и 39 удалений

Просмотреть файл

@ -149,7 +149,6 @@ class GCHashMapOperations
bool empty() const { return map().empty(); }
uint32_t count() const { return map().count(); }
size_t capacity() const { return map().capacity(); }
uint32_t generation() const { return map().generation(); }
bool has(const Lookup& l) const { return map().lookup(l).found(); }
};
@ -288,7 +287,6 @@ class GCHashSetOperations
bool empty() const { return set().empty(); }
uint32_t count() const { return set().count(); }
size_t capacity() const { return set().capacity(); }
uint32_t generation() const { return set().generation(); }
bool has(const Lookup& l) const { return set().lookup(l).found(); }
};

Просмотреть файл

@ -14,6 +14,7 @@
#include "mozilla/HashFunctions.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Move.h"
#include "mozilla/Opaque.h"
#include "mozilla/PodOperations.h"
#include "mozilla/ReentrancyGuard.h"
#include "mozilla/TemplateLib.h"
@ -34,6 +35,8 @@ namespace detail {
/*****************************************************************************/
using Generation = mozilla::Opaque<uint64_t>;
// A JS-friendly, STL-like container providing a hash-based map from keys to
// values. In particular, HashMap calls constructors and destructors of all
// objects added so non-PODs may be used safely.
@ -208,7 +211,9 @@ class HashMap
// If |generation()| is the same before and after a HashMap operation,
// pointers into the table remain valid.
uint32_t generation() const { return impl.generation(); }
Generation generation() const {
return impl.generation();
}
/************************************************** Shorthand operations */
@ -446,7 +451,9 @@ class HashSet
// If |generation()| is the same before and after a HashSet operation,
// pointers into the table remain valid.
uint32_t generation() const { return impl.generation(); }
Generation generation() const {
return impl.generation();
}
/************************************************** Shorthand operations */
@ -819,7 +826,7 @@ class HashTable : private AllocPolicy
Entry* entry_;
#ifdef JS_DEBUG
const HashTable* table_;
uint32_t generation;
Generation generation;
#endif
protected:
@ -927,7 +934,7 @@ class HashTable : private AllocPolicy
#ifdef JS_DEBUG
const HashTable* table_;
uint64_t mutationCount;
uint32_t generation;
Generation generation;
bool validEntry;
#endif
@ -1076,9 +1083,9 @@ class HashTable : private AllocPolicy
static const size_t CAP_BITS = 30;
public:
uint64_t gen:56; // entry storage generation number
uint64_t hashShift:8; // multiplicative hash shift
Entry* table; // entry storage
uint32_t gen:24; // entry storage generation number
uint32_t hashShift:8; // multiplicative hash shift
uint32_t entryCount; // number of entries in table
uint32_t removedCount; // removed entry sentinels in table
@ -1175,9 +1182,9 @@ class HashTable : private AllocPolicy
public:
explicit HashTable(AllocPolicy ap)
: AllocPolicy(ap)
, table(nullptr)
, gen(0)
, hashShift(sHashBits)
, table(nullptr)
, entryCount(0)
, removedCount(0)
#ifdef JS_DEBUG
@ -1616,10 +1623,10 @@ class HashTable : private AllocPolicy
return JS_BIT(sHashBits - hashShift);
}
uint32_t generation() const
Generation generation() const
{
MOZ_ASSERT(table);
return gen;
return Generation(gen);
}
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const

Просмотреть файл

@ -700,10 +700,10 @@ CheckDOMProxyExpandoDoesNotShadow(JSContext* cx, MacroAssembler& masm, JSObject*
ExpandoAndGeneration* expandoAndGeneration = (ExpandoAndGeneration*)expandoVal.toPrivate();
masm.movePtr(ImmPtr(expandoAndGeneration), tempVal.scratchReg());
masm.branch32(Assembler::NotEqual,
masm.branch64(Assembler::NotEqual,
Address(tempVal.scratchReg(),
ExpandoAndGeneration::offsetOfGeneration()),
Imm32(expandoAndGeneration->generation),
Imm64(expandoAndGeneration->generation),
&failDOMProxyCheck);
expandoVal = expandoAndGeneration->expando;

Просмотреть файл

@ -823,6 +823,13 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void branch32(Condition cond, wasm::SymbolicAddress lhs, Imm32 rhs, Label* label)
DEFINED_ON(arm, arm64, mips_shared, x86, x64);
inline void branch64(Condition cond, const Address& lhs, Imm64 val, Label* label) PER_ARCH;
// Compare the value at |lhs| with the value at |rhs|. The scratch
// register *must not* be the base of |lhs| or |rhs|.
inline void branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch,
Label* label) PER_ARCH;
inline void branchPtr(Condition cond, Register lhs, Register rhs, Label* label) PER_SHARED_ARCH;
inline void branchPtr(Condition cond, Register lhs, Imm32 rhs, Label* label) PER_SHARED_ARCH;
inline void branchPtr(Condition cond, Register lhs, ImmPtr rhs, Label* label) PER_SHARED_ARCH;

Просмотреть файл

@ -8,6 +8,7 @@
#include "mozilla/Casting.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/SizePrintfMacros.h"
#include "jslibmath.h"
@ -2177,10 +2178,10 @@ UpdateExistingGenerationalDOMProxyStub(ICGetProp_Fallback* stub,
iter->toGetProp_CallDOMProxyWithGenerationNative();
if (updateStub->expandoAndGeneration() == expandoAndGeneration) {
// Update generation
uint32_t generation = expandoAndGeneration->generation;
uint64_t generation = expandoAndGeneration->generation;
JitSpew(JitSpew_BaselineIC,
" Updating existing stub with generation, old value: %i, "
"new value: %i", updateStub->generation(),
"new value: %" PRIu64 "", updateStub->generation(),
generation);
updateStub->setGeneration(generation);
return true;
@ -3566,9 +3567,9 @@ CheckDOMProxyExpandoDoesNotShadow(JSContext* cx, MacroAssembler& masm, Register
masm.branchPrivatePtr(Assembler::NotEqual, expandoAddr, tempVal.scratchReg(),
&failDOMProxyCheck);
masm.load32(*generationAddr, scratch);
masm.branch32(Assembler::NotEqual,
Address(tempVal.scratchReg(), offsetof(ExpandoAndGeneration, generation)),
masm.branch64(Assembler::NotEqual,
Address(tempVal.scratchReg(), ExpandoAndGeneration::offsetOfGeneration()),
*generationAddr,
scratch, &failDOMProxyCheck);
masm.loadValue(Address(tempVal.scratchReg(), 0), tempVal);
@ -3696,7 +3697,7 @@ ICGetPropCallDOMProxyNativeCompiler::getStub(ICStubSpace* space)
Value expandoSlot = GetProxyExtra(proxy_, GetDOMProxyExpandoSlot());
RootedShape expandoShape(cx, nullptr);
ExpandoAndGeneration* expandoAndGeneration;
int32_t generation;
uint64_t generation;
Value expandoVal;
if (kind == ICStub::GetProp_CallDOMProxyNative) {
expandoVal = expandoSlot;

Просмотреть файл

@ -3103,13 +3103,13 @@ class ICGetProp_CallDOMProxyWithGenerationNative : public ICGetPropCallDOMProxyN
{
protected:
ExpandoAndGeneration* expandoAndGeneration_;
uint32_t generation_;
uint64_t generation_;
public:
ICGetProp_CallDOMProxyWithGenerationNative(JitCode* stubCode, ICStub* firstMonitorStub,
Shape* shape,
ExpandoAndGeneration* expandoAndGeneration,
uint32_t generation, Shape* expandoShape,
uint64_t generation, Shape* expandoShape,
JSObject* holder, Shape* holderShape,
JSFunction* getter, uint32_t pcOffset)
: ICGetPropCallDOMProxyNativeStub(ICStub::GetProp_CallDOMProxyWithGenerationNative,
@ -3127,11 +3127,11 @@ class ICGetProp_CallDOMProxyWithGenerationNative : public ICGetPropCallDOMProxyN
void* expandoAndGeneration() const {
return expandoAndGeneration_;
}
uint32_t generation() const {
uint64_t generation() const {
return generation_;
}
void setGeneration(uint32_t value) {
void setGeneration(uint64_t value) {
generation_ = value;
}

Просмотреть файл

@ -1136,6 +1136,18 @@ class Operand
}
};
inline Imm32
Imm64::firstHalf() const
{
return low();
}
inline Imm32
Imm64::secondHalf() const
{
return hi();
}
void
PatchJump(CodeLocationJump& jump_, CodeLocationLabel label,
ReprotectCode reprotect = DontReprotect);

Просмотреть файл

@ -515,6 +515,32 @@ MacroAssembler::branch32(Condition cond, wasm::SymbolicAddress lhs, Imm32 rhs, L
branch32(cond, scratch, rhs, label);
}
void
MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label)
{
MOZ_ASSERT(cond == Assembler::NotEqual,
"other condition codes not supported");
branch32(cond, lhs, val.firstHalf(), label);
branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), val.secondHalf(), label);
}
void
MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch,
Label* label)
{
MOZ_ASSERT(cond == Assembler::NotEqual,
"other condition codes not supported");
MOZ_ASSERT(lhs.base != scratch);
MOZ_ASSERT(rhs.base != scratch);
load32(rhs, scratch);
branch32(cond, lhs, scratch, label);
load32(Address(rhs.base, rhs.offset + sizeof(uint32_t)), scratch);
branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), scratch, label);
}
void
MacroAssembler::branchPtr(Condition cond, Register lhs, Register rhs, Label* label)
{

Просмотреть файл

@ -502,6 +502,18 @@ GetTempRegForIntArg(uint32_t usedIntArgs, uint32_t usedFloatArgs, Register* out)
return true;
}
inline Imm32
Imm64::firstHalf() const
{
return low();
}
inline Imm32
Imm64::secondHalf() const
{
return hi();
}
void PatchJump(CodeLocationJump& jump_, CodeLocationLabel label,
ReprotectCode reprotect = DontReprotect);

Просмотреть файл

@ -560,6 +560,27 @@ MacroAssembler::branch32(Condition cond, wasm::SymbolicAddress lhs, Imm32 rhs, L
branch32(cond, Address(scratch, 0), rhs, label);
}
void
MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label)
{
MOZ_ASSERT(cond == Assembler::NotEqual,
"other condition codes not supported");
branchPtr(cond, lhs, ImmWord(val.value), label);
}
void
MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch,
Label* label)
{
MOZ_ASSERT(cond == Assembler::NotEqual,
"other condition codes not supported");
MOZ_ASSERT(lhs.base != scratch);
MOZ_ASSERT(rhs.base != scratch);
loadPtr(rhs, scratch);
branchPtr(cond, lhs, scratch, label);
}
void
MacroAssembler::branchPtr(Condition cond, Register lhs, Register rhs, Label* label)
{

Просмотреть файл

@ -636,6 +636,18 @@ class Operand
}
};
inline Imm32
Imm64::firstHalf() const
{
return low();
}
inline Imm32
Imm64::secondHalf() const
{
return hi();
}
void
PatchJump(CodeLocationJump& jump_, CodeLocationLabel label,
ReprotectCode reprotect = DontReprotect);

Просмотреть файл

@ -268,6 +268,32 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest)
// ===============================================================
// Branch functions
void
MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label)
{
MOZ_ASSERT(cond == Assembler::NotEqual,
"other condition codes not supported");
branch32(cond, lhs, val.firstHalf(), label);
branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), val.secondHalf(), label);
}
void
MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch,
Label* label)
{
MOZ_ASSERT(cond == Assembler::NotEqual,
"other condition codes not supported");
MOZ_ASSERT(lhs.base != scratch);
MOZ_ASSERT(rhs.base != scratch);
load32(rhs, scratch);
branch32(cond, lhs, scratch, label);
load32(Address(rhs.base, rhs.offset + sizeof(uint32_t)), scratch);
branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), scratch, label);
}
void
MacroAssembler::branchPrivatePtr(Condition cond, const Address& lhs, Register rhs, Label* label)
{

Просмотреть файл

@ -207,6 +207,28 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest)
// ===============================================================
// Branch functions
void
MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label)
{
MOZ_ASSERT(cond == Assembler::NotEqual,
"other condition codes not supported");
branchPtr(cond, lhs, ImmWord(val.value), label);
}
void
MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch,
Label* label)
{
MOZ_ASSERT(cond == Assembler::NotEqual,
"other condition codes not supported");
MOZ_ASSERT(lhs.base != scratch);
MOZ_ASSERT(rhs.base != scratch);
loadPtr(rhs, scratch);
branchPtr(cond, lhs, scratch, label);
}
void
MacroAssembler::branchPrivatePtr(Condition cond, const Address& lhs, Register rhs, Label* label)
{

Просмотреть файл

@ -133,6 +133,17 @@ struct Imm64
explicit Imm64(uint64_t value) : value(value)
{ }
Imm32 low() const {
return Imm32(int32_t(value));
}
Imm32 hi() const {
return Imm32(int32_t(value >> 32));
}
inline Imm32 firstHalf() const;
inline Imm32 secondHalf() const;
};
#ifdef DEBUG

Просмотреть файл

@ -307,6 +307,28 @@ MacroAssembler::branch32(Condition cond, wasm::SymbolicAddress lhs, Imm32 rhs, L
branch32(cond, Address(scratch, 0), rhs, label);
}
void
MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label)
{
MOZ_ASSERT(cond == Assembler::NotEqual,
"other condition codes not supported");
branchPtr(cond, lhs, ImmWord(val.value), label);
}
void
MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch,
Label* label)
{
MOZ_ASSERT(cond == Assembler::NotEqual,
"other condition codes not supported");
MOZ_ASSERT(lhs.base != scratch);
MOZ_ASSERT(rhs.base != scratch);
loadPtr(rhs, scratch);
branchPtr(cond, lhs, scratch, label);
}
void
MacroAssembler::branchPtr(Condition cond, const AbsoluteAddress& lhs, Register rhs, Label* label)
{

Просмотреть файл

@ -173,6 +173,18 @@ class Operand
}
};
inline Imm32
Imm64::firstHalf() const
{
return low();
}
inline Imm32
Imm64::secondHalf() const
{
return hi();
}
class CPUInfo
{
public:

Просмотреть файл

@ -308,6 +308,32 @@ MacroAssembler::branch32(Condition cond, wasm::SymbolicAddress lhs, Imm32 rhs, L
j(cond, label);
}
void
MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label)
{
MOZ_ASSERT(cond == Assembler::NotEqual,
"other condition codes not supported");
branch32(cond, lhs, val.firstHalf(), label);
branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), val.secondHalf(), label);
}
void
MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch,
Label* label)
{
MOZ_ASSERT(cond == Assembler::NotEqual,
"other condition codes not supported");
MOZ_ASSERT(lhs.base != scratch);
MOZ_ASSERT(rhs.base != scratch);
load32(rhs, scratch);
branch32(cond, lhs, scratch, label);
load32(Address(rhs.base, rhs.offset + sizeof(uint32_t)), scratch);
branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), scratch, label);
}
void
MacroAssembler::branchPtr(Condition cond, const AbsoluteAddress& lhs, Register rhs, Label* label)
{

Просмотреть файл

@ -308,10 +308,6 @@ class MOZ_RAII AutoHashMapRooter : protected AutoGCRooter
return map.sizeOfIncludingThis(mallocSizeOf);
}
uint32_t generation() const {
return map.generation();
}
/************************************************** Shorthand operations */
bool has(const Lookup& l) const {
@ -423,10 +419,6 @@ class MOZ_RAII AutoHashSetRooter : protected AutoGCRooter
return set.sizeOfIncludingThis(mallocSizeOf);
}
uint32_t generation() const {
return set.generation();
}
/************************************************** Shorthand operations */
bool has(const Lookup& l) const {

Просмотреть файл

@ -51,11 +51,11 @@ class MOZ_RAII AutoCycleDetector
bool foundCycle() { return cyclic; }
private:
Generation hashsetGenerationAtInit;
JSContext* cx;
RootedObject obj;
bool cyclic;
uint32_t hashsetGenerationAtInit;
Set::AddPtr hashsetAddPointer;
bool cyclic;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};

Просмотреть файл

@ -1219,7 +1219,7 @@ NukeCrossCompartmentWrappers(JSContext* cx,
* * If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot
* should contain a private pointer to a ExpandoAndGeneration, which contains
* a JS::Value that should either be undefined or point to an expando object,
* and a uint32 value. If that value changes then the IC for getting a
* and a uint64 value. If that value changes then the IC for getting a
* property will be invalidated.
* * If Shadows is returned, that means the property is an own property of the
* proxy but doesn't live on the expando object.
@ -1248,7 +1248,7 @@ struct ExpandoAndGeneration {
}
JS::Heap<JS::Value> expando;
uint32_t generation;
uint64_t generation;
};
typedef enum DOMProxyShadowsResult {

Просмотреть файл

@ -27,15 +27,15 @@ namespace {
class AutoEntryHolder {
typedef WatchpointMap::Map Map;
Generation gen;
Map& map;
Map::Ptr p;
uint32_t gen;
RootedObject obj;
RootedId id;
public:
AutoEntryHolder(JSContext* cx, Map& map, Map::Ptr p)
: map(map), p(p), gen(map.generation()), obj(cx, p->key().object), id(cx, p->key().id)
: gen(map.generation()), map(map), p(p), obj(cx, p->key().object), id(cx, p->key().id)
{
MOZ_ASSERT(!p->value().held);
p->value().held = true;

Просмотреть файл

@ -733,7 +733,7 @@ ByAllocationStack::report(JSContext* cx, CountBase& countBase, MutableHandleValu
#ifdef DEBUG
// Check that nothing rehashes our table while we hold pointers into it.
uint32_t generation = count.table.generation();
Generation generation = count.table.generation();
#endif
// Build a vector of pointers to entries; sort by total; and then use

44
mfbt/Opaque.h Normal file
Просмотреть файл

@ -0,0 +1,44 @@
/* -*- 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/. */
/* An opaque integral type supporting only comparison operators. */
#ifndef mozilla_Opaque_h
#define mozilla_Opaque_h
#include "mozilla/TypeTraits.h"
namespace mozilla {
/**
* Opaque<T> is a replacement for integral T in cases where only comparisons
* must be supported, and it's desirable to prevent accidental dependency on
* exact values.
*/
template<typename T>
class Opaque final
{
static_assert(mozilla::IsIntegral<T>::value,
"mozilla::Opaque only supports integral types");
T mValue;
public:
Opaque() {}
explicit Opaque(T aValue) : mValue(aValue) {}
bool operator==(const Opaque& aOther) const {
return mValue == aOther.mValue;
}
bool operator!=(const Opaque& aOther) const {
return !(*this == aOther);
}
};
} // namespace mozilla
#endif /* mozilla_Opaque_h */

Просмотреть файл

@ -61,6 +61,7 @@ EXPORTS.mozilla = [
'Move.h',
'NullPtr.h',
'NumericLimits.h',
'Opaque.h',
'Pair.h',
'PodOperations.h',
'Poison.h',