diff options
author | wolfbeast <mcwerewolf@gmail.com> | 2018-09-17 08:51:49 +0200 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-09-17 08:51:49 +0200 |
commit | 882aaf5b1fda7b216051b55e268de78fd5126f42 (patch) | |
tree | ccb3f6f6299a5d1c603e6b73d3892f635bb96a8e /js/src/vm | |
parent | 8ee235ca5df26f39ca3066935bef90c4d28dd61a (diff) | |
parent | d118d486a680ed42030b1bdee263a29831da3e86 (diff) | |
download | UXP-882aaf5b1fda7b216051b55e268de78fd5126f42.tar UXP-882aaf5b1fda7b216051b55e268de78fd5126f42.tar.gz UXP-882aaf5b1fda7b216051b55e268de78fd5126f42.tar.lz UXP-882aaf5b1fda7b216051b55e268de78fd5126f42.tar.xz UXP-882aaf5b1fda7b216051b55e268de78fd5126f42.zip |
Merge branch 'master' into Pale_Moon-release
# Conflicts:
# application/palemoon/config/version.txt
# js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h
# toolkit/components/search/orginal/nsSearchService.js
Diffstat (limited to 'js/src/vm')
-rw-r--r-- | js/src/vm/Caches.h | 16 | ||||
-rw-r--r-- | js/src/vm/NativeObject.h | 11 | ||||
-rw-r--r-- | js/src/vm/Runtime.h | 15 | ||||
-rw-r--r-- | js/src/vm/Scope.cpp | 20 | ||||
-rw-r--r-- | js/src/vm/Scope.h | 120 | ||||
-rw-r--r-- | js/src/vm/String.h | 11 | ||||
-rw-r--r-- | js/src/vm/TypeInference.h | 20 |
7 files changed, 139 insertions, 74 deletions
diff --git a/js/src/vm/Caches.h b/js/src/vm/Caches.h index 91a78bdc8..b11dd9dcb 100644 --- a/js/src/vm/Caches.h +++ b/js/src/vm/Caches.h @@ -7,6 +7,8 @@ #ifndef vm_Caches_h #define vm_Caches_h +#include <new> + #include "jsatom.h" #include "jsbytecode.h" #include "jsobj.h" @@ -191,14 +193,20 @@ class NewObjectCache char templateObject[MAX_OBJ_SIZE]; }; - Entry entries[41]; // TODO: reconsider size + using EntryArray = Entry[41]; // TODO: reconsider size; + EntryArray entries; public: - typedef int EntryIndex; + using EntryIndex = int; + + NewObjectCache() + : entries{} // zeroes out the array + {} - NewObjectCache() { mozilla::PodZero(this); } - void purge() { mozilla::PodZero(this); } + void purge() { + new (&entries) EntryArray{}; // zeroes out the array + } /* Remove any cached items keyed on moved objects. */ void clearNurseryObjects(JSRuntime* rt); diff --git a/js/src/vm/NativeObject.h b/js/src/vm/NativeObject.h index d2c06eabc..4dbc167ab 100644 --- a/js/src/vm/NativeObject.h +++ b/js/src/vm/NativeObject.h @@ -876,7 +876,7 @@ class NativeObject : public ShapedObject MOZ_ASSERT(end <= getDenseInitializedLength()); MOZ_ASSERT(!denseElementsAreCopyOnWrite()); for (size_t i = start; i < end; i++) - elements_[i].HeapSlot::~HeapSlot(); + elements_[i].destroy(); } /* @@ -885,7 +885,7 @@ class NativeObject : public ShapedObject */ void prepareSlotRangeForOverwrite(size_t start, size_t end) { for (size_t i = start; i < end; i++) - getSlotAddressUnchecked(i)->HeapSlot::~HeapSlot(); + getSlotAddressUnchecked(i)->destroy(); } public: @@ -1085,7 +1085,8 @@ class NativeObject : public ShapedObject for (uint32_t i = 0; i < count; ++i) elements_[dstStart + i].set(this, HeapSlot::Element, dstStart + i, src[i]); } else { - memcpy(&elements_[dstStart], src, count * sizeof(HeapSlot)); + memcpy(reinterpret_cast<Value*>(&elements_[dstStart]), src, + count * sizeof(Value)); elementsRangeWriteBarrierPost(dstStart, count); } } @@ -1094,7 +1095,7 @@ class NativeObject : public ShapedObject MOZ_ASSERT(dstStart + count <= getDenseCapacity()); MOZ_ASSERT(!denseElementsAreCopyOnWrite()); MOZ_ASSERT(!denseElementsAreFrozen()); - memcpy(&elements_[dstStart], src, count * sizeof(HeapSlot)); + memcpy(reinterpret_cast<Value*>(&elements_[dstStart]), src, count * sizeof(Value)); elementsRangeWriteBarrierPost(dstStart, count); } @@ -1142,7 +1143,7 @@ class NativeObject : public ShapedObject MOZ_ASSERT(!denseElementsAreCopyOnWrite()); MOZ_ASSERT(!denseElementsAreFrozen()); - memmove(elements_ + dstStart, elements_ + srcStart, count * sizeof(Value)); + memmove(elements_ + dstStart, elements_ + srcStart, count * sizeof(HeapSlot)); elementsRangeWriteBarrierPost(dstStart, count); } diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index 735adadf2..f354d2069 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -11,11 +11,11 @@ #include "mozilla/Attributes.h" #include "mozilla/LinkedList.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/PodOperations.h" #include "mozilla/Scoped.h" #include "mozilla/ThreadLocal.h" #include "mozilla/Vector.h" +#include <algorithm> #include <setjmp.h> #include "jsatom.h" @@ -1504,20 +1504,21 @@ PerThreadData::exclusiveThreadsPresent() static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Value* vec, size_t len) { - mozilla::PodZero(vec, len); + // Don't PodZero here because JS::Value is non-trivial. + for (size_t i = 0; i < len; i++) + vec[i].setDouble(+0.0); } static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Value* beg, Value* end) { - mozilla::PodZero(beg, end - beg); + MakeRangeGCSafe(beg, end - beg); } static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(jsid* beg, jsid* end) { - for (jsid* id = beg; id != end; ++id) - *id = INT_TO_JSID(0); + std::fill(beg, end, INT_TO_JSID(0)); } static MOZ_ALWAYS_INLINE void @@ -1529,13 +1530,13 @@ MakeRangeGCSafe(jsid* vec, size_t len) static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Shape** beg, Shape** end) { - mozilla::PodZero(beg, end - beg); + std::fill(beg, end, nullptr); } static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Shape** vec, size_t len) { - mozilla::PodZero(vec, len); + MakeRangeGCSafe(vec, vec + len); } static MOZ_ALWAYS_INLINE void diff --git a/js/src/vm/Scope.cpp b/js/src/vm/Scope.cpp index 112b34586..a71c03695 100644 --- a/js/src/vm/Scope.cpp +++ b/js/src/vm/Scope.cpp @@ -191,12 +191,12 @@ template <typename ConcreteScope> static UniquePtr<typename ConcreteScope::Data> NewEmptyScopeData(ExclusiveContext* cx, uint32_t length = 0) { - uint8_t* bytes = cx->zone()->pod_calloc<uint8_t>(ConcreteScope::sizeOfData(length)); + uint8_t* bytes = cx->zone()->pod_malloc<uint8_t>(ConcreteScope::sizeOfData(length)); if (!bytes) ReportOutOfMemory(cx); auto data = reinterpret_cast<typename ConcreteScope::Data*>(bytes); if (data) - new (data) typename ConcreteScope::Data(); + new (data) typename ConcreteScope::Data(length); return UniquePtr<typename ConcreteScope::Data>(data); } @@ -273,7 +273,7 @@ Scope::XDRSizedBindingNames(XDRState<mode>* xdr, Handle<ConcreteScope*> scope, } for (uint32_t i = 0; i < length; i++) { - if (!XDRBindingName(xdr, &data->names[i])) { + if (!XDRBindingName(xdr, &data->trailingNames[i])) { if (mode == XDR_DECODE) { DeleteScopeData(data.get()); data.set(nullptr); @@ -1250,7 +1250,7 @@ BindingIter::init(LexicalScope::Data& data, uint32_t firstFrameSlot, uint8_t fla init(0, 0, 0, 0, 0, 0, CanHaveEnvironmentSlots | flags, firstFrameSlot, JSSLOT_FREE(&LexicalEnvironmentObject::class_), - data.names, data.length); + data.trailingNames.start(), data.length); } else { // imports - [0, 0) // positional formals - [0, 0) @@ -1262,7 +1262,7 @@ BindingIter::init(LexicalScope::Data& data, uint32_t firstFrameSlot, uint8_t fla init(0, 0, 0, 0, 0, data.constStart, CanHaveFrameSlots | CanHaveEnvironmentSlots | flags, firstFrameSlot, JSSLOT_FREE(&LexicalEnvironmentObject::class_), - data.names, data.length); + data.trailingNames.start(), data.length); } } @@ -1283,7 +1283,7 @@ BindingIter::init(FunctionScope::Data& data, uint8_t flags) init(0, data.nonPositionalFormalStart, data.varStart, data.varStart, data.length, data.length, flags, 0, JSSLOT_FREE(&CallObject::class_), - data.names, data.length); + data.trailingNames.start(), data.length); } void @@ -1299,7 +1299,7 @@ BindingIter::init(VarScope::Data& data, uint32_t firstFrameSlot) init(0, 0, 0, 0, data.length, data.length, CanHaveFrameSlots | CanHaveEnvironmentSlots, firstFrameSlot, JSSLOT_FREE(&VarEnvironmentObject::class_), - data.names, data.length); + data.trailingNames.start(), data.length); } void @@ -1315,7 +1315,7 @@ BindingIter::init(GlobalScope::Data& data) init(0, 0, 0, data.varStart, data.letStart, data.constStart, CannotHaveSlots, UINT32_MAX, UINT32_MAX, - data.names, data.length); + data.trailingNames.start(), data.length); } void @@ -1343,7 +1343,7 @@ BindingIter::init(EvalScope::Data& data, bool strict) // consts - [data.length, data.length) init(0, 0, 0, data.varStart, data.length, data.length, flags, firstFrameSlot, firstEnvironmentSlot, - data.names, data.length); + data.trailingNames.start(), data.length); } void @@ -1359,7 +1359,7 @@ BindingIter::init(ModuleScope::Data& data) init(data.varStart, data.varStart, data.varStart, data.varStart, data.letStart, data.constStart, CanHaveFrameSlots | CanHaveEnvironmentSlots, 0, JSSLOT_FREE(&ModuleEnvironmentObject::class_), - data.names, data.length); + data.trailingNames.start(), data.length); } PositionalFormalParameterIter::PositionalFormalParameterIter(JSScript* script) diff --git a/js/src/vm/Scope.h b/js/src/vm/Scope.h index 5304d6713..1d04fd9f6 100644 --- a/js/src/vm/Scope.h +++ b/js/src/vm/Scope.h @@ -12,6 +12,7 @@ #include "jsobj.h" #include "jsopcode.h" +#include "jsutil.h" #include "gc/Heap.h" #include "gc/Policy.h" @@ -111,6 +112,47 @@ class BindingName void trace(JSTracer* trc); }; +/** + * The various {Global,Module,...}Scope::Data classes consist of always-present + * bits, then a trailing array of BindingNames. The various Data classes all + * end in a TrailingNamesArray that contains sized/aligned space for *one* + * BindingName. Data instances that contain N BindingNames, are then allocated + * in sizeof(Data) + (space for (N - 1) BindingNames). Because this class's + * |data_| field is properly sized/aligned, the N-BindingName array can start + * at |data_|. + * + * This is concededly a very low-level representation, but we want to only + * allocate once for data+bindings both, and this does so approximately as + * elegantly as C++ allows. + */ +class TrailingNamesArray +{ + private: + alignas(BindingName) unsigned char data_[sizeof(BindingName)]; + + private: + // Some versions of GCC treat it as a -Wstrict-aliasing violation (ergo a + // -Werror compile error) to reinterpret_cast<> |data_| to |T*|, even + // through |void*|. Placing the latter cast in these separate functions + // breaks the chain such that affected GCC versions no longer warn/error. + void* ptr() { + return data_; + } + + public: + // Explicitly ensure no one accidentally allocates scope data without + // poisoning its trailing names. + TrailingNamesArray() = delete; + + explicit TrailingNamesArray(size_t nameCount) { + if (nameCount) + JS_POISON(&data_, 0xCC, sizeof(BindingName) * nameCount); + } + BindingName* start() { return reinterpret_cast<BindingName*>(ptr()); } + + BindingName& operator[](size_t i) { return start()[i]; } +}; + class BindingLocation { public: @@ -337,16 +379,19 @@ class LexicalScope : public Scope // // lets - [0, constStart) // consts - [constStart, length) - uint32_t constStart; - uint32_t length; + uint32_t constStart = 0; + uint32_t length = 0; // Frame slots [0, nextFrameSlot) are live when this is the innermost // scope. - uint32_t nextFrameSlot; + uint32_t nextFrameSlot = 0; // The array of tagged JSAtom* names, allocated beyond the end of the // struct. - BindingName names[1]; + TrailingNamesArray trailingNames; + + explicit Data(size_t nameCount) : trailingNames(nameCount) {} + Data() = delete; void trace(JSTracer* trc); }; @@ -433,11 +478,11 @@ class FunctionScope : public Scope // The canonical function of the scope, as during a scope walk we // often query properties of the JSFunction (e.g., is the function an // arrow). - GCPtrFunction canonicalFunction; + GCPtrFunction canonicalFunction = {}; // If parameter expressions are present, parameters act like lexical // bindings. - bool hasParameterExprs; + bool hasParameterExprs = false; // Bindings are sorted by kind in both frames and environments. // @@ -452,17 +497,20 @@ class FunctionScope : public Scope // positional formals - [0, nonPositionalFormalStart) // other formals - [nonPositionalParamStart, varStart) // vars - [varStart, length) - uint16_t nonPositionalFormalStart; - uint16_t varStart; - uint32_t length; + uint16_t nonPositionalFormalStart = 0; + uint16_t varStart = 0; + uint32_t length = 0; // Frame slots [0, nextFrameSlot) are live when this is the innermost // scope. - uint32_t nextFrameSlot; + uint32_t nextFrameSlot = 0; // The array of tagged JSAtom* names, allocated beyond the end of the // struct. - BindingName names[1]; + TrailingNamesArray trailingNames; + + explicit Data(size_t nameCount) : trailingNames(nameCount) {} + Data() = delete; void trace(JSTracer* trc); }; @@ -548,15 +596,18 @@ class VarScope : public Scope struct Data { // All bindings are vars. - uint32_t length; + uint32_t length = 0; // Frame slots [firstFrameSlot(), nextFrameSlot) are live when this is // the innermost scope. - uint32_t nextFrameSlot; + uint32_t nextFrameSlot = 0; // The array of tagged JSAtom* names, allocated beyond the end of the // struct. - BindingName names[1]; + TrailingNamesArray trailingNames; + + explicit Data(size_t nameCount) : trailingNames(nameCount) {} + Data() = delete; void trace(JSTracer* trc); }; @@ -638,14 +689,17 @@ class GlobalScope : public Scope // vars - [varStart, letStart) // lets - [letStart, constStart) // consts - [constStart, length) - uint32_t varStart; - uint32_t letStart; - uint32_t constStart; - uint32_t length; + uint32_t varStart = 0; + uint32_t letStart = 0; + uint32_t constStart = 0; + uint32_t length = 0; // The array of tagged JSAtom* names, allocated beyond the end of the // struct. - BindingName names[1]; + TrailingNamesArray trailingNames; + + explicit Data(size_t nameCount) : trailingNames(nameCount) {} + Data() = delete; void trace(JSTracer* trc); }; @@ -736,16 +790,19 @@ class EvalScope : public Scope // // top-level funcs - [0, varStart) // vars - [varStart, length) - uint32_t varStart; - uint32_t length; + uint32_t varStart = 0; + uint32_t length = 0; // Frame slots [0, nextFrameSlot) are live when this is the innermost // scope. - uint32_t nextFrameSlot; + uint32_t nextFrameSlot = 0; // The array of tagged JSAtom* names, allocated beyond the end of the // struct. - BindingName names[1]; + TrailingNamesArray trailingNames; + + explicit Data(size_t nameCount) : trailingNames(nameCount) {} + Data() = delete; void trace(JSTracer* trc); }; @@ -827,7 +884,7 @@ class ModuleScope : public Scope struct Data { // The module of the scope. - GCPtr<ModuleObject*> module; + GCPtr<ModuleObject*> module = {}; // Bindings are sorted by kind. // @@ -835,18 +892,21 @@ class ModuleScope : public Scope // vars - [varStart, letStart) // lets - [letStart, constStart) // consts - [constStart, length) - uint32_t varStart; - uint32_t letStart; - uint32_t constStart; - uint32_t length; + uint32_t varStart = 0; + uint32_t letStart = 0; + uint32_t constStart = 0; + uint32_t length = 0; // Frame slots [0, nextFrameSlot) are live when this is the innermost // scope. - uint32_t nextFrameSlot; + uint32_t nextFrameSlot = 0; // The array of tagged JSAtom* names, allocated beyond the end of the // struct. - BindingName names[1]; + TrailingNamesArray trailingNames; + + explicit Data(size_t nameCount) : trailingNames(nameCount) {} + Data() = delete; void trace(JSTracer* trc); }; diff --git a/js/src/vm/String.h b/js/src/vm/String.h index 1a0c58575..514e2c205 100644 --- a/js/src/vm/String.h +++ b/js/src/vm/String.h @@ -8,7 +8,6 @@ #define vm_String_h #include "mozilla/MemoryReporting.h" -#include "mozilla/PodOperations.h" #include "mozilla/Range.h" #include "jsapi.h" @@ -1087,19 +1086,17 @@ class StaticStrings static const size_t SMALL_CHAR_LIMIT = 128U; static const size_t NUM_SMALL_CHARS = 64U; - JSAtom* length2StaticTable[NUM_SMALL_CHARS * NUM_SMALL_CHARS]; + JSAtom* length2StaticTable[NUM_SMALL_CHARS * NUM_SMALL_CHARS] = {}; // zeroes public: /* We keep these public for the JITs. */ static const size_t UNIT_STATIC_LIMIT = 256U; - JSAtom* unitStaticTable[UNIT_STATIC_LIMIT]; + JSAtom* unitStaticTable[UNIT_STATIC_LIMIT] = {}; // zeroes static const size_t INT_STATIC_LIMIT = 256U; - JSAtom* intStaticTable[INT_STATIC_LIMIT]; + JSAtom* intStaticTable[INT_STATIC_LIMIT] = {}; // zeroes - StaticStrings() { - mozilla::PodZero(this); - } + StaticStrings() = default; bool init(JSContext* cx); void trace(JSTracer* trc); diff --git a/js/src/vm/TypeInference.h b/js/src/vm/TypeInference.h index 9ba1c3cc8..0e737bad7 100644 --- a/js/src/vm/TypeInference.h +++ b/js/src/vm/TypeInference.h @@ -807,12 +807,10 @@ class PreliminaryObjectArray private: // All objects with the type which have been allocated. The pointers in // this array are weak. - JSObject* objects[COUNT]; + JSObject* objects[COUNT] = {}; // zeroes public: - PreliminaryObjectArray() { - mozilla::PodZero(this); - } + PreliminaryObjectArray() = default; void registerNewObject(JSObject* res); void unregisterObject(JSObject* obj); @@ -906,11 +904,11 @@ class TypeNewScript private: // Scripted function which this information was computed for. - HeapPtr<JSFunction*> function_; + HeapPtr<JSFunction*> function_ = {}; // Any preliminary objects with the type. The analyses are not performed // until this array is cleared. - PreliminaryObjectArray* preliminaryObjects; + PreliminaryObjectArray* preliminaryObjects = nullptr; // After the new script properties analyses have been performed, a template // object to use for newly constructed objects. The shape of this object @@ -918,7 +916,7 @@ class TypeNewScript // allocation kind to use. This is null if the new objects have an unboxed // layout, in which case the UnboxedLayout provides the initial structure // of the object. - HeapPtr<PlainObject*> templateObject_; + HeapPtr<PlainObject*> templateObject_ = {}; // Order in which definite properties become initialized. We need this in // case the definite properties are invalidated (such as by adding a setter @@ -928,21 +926,21 @@ class TypeNewScript // shape. Property assignments in inner frames are preceded by a series of // SETPROP_FRAME entries specifying the stack down to the frame containing // the write. - Initializer* initializerList; + Initializer* initializerList = nullptr; // If there are additional properties found by the acquired properties // analysis which were not found by the definite properties analysis, this // shape contains all such additional properties (plus the definite // properties). When an object of this group acquires this shape, it is // fully initialized and its group can be changed to initializedGroup. - HeapPtr<Shape*> initializedShape_; + HeapPtr<Shape*> initializedShape_ = {}; // Group with definite properties set for all properties found by // both the definite and acquired properties analyses. - HeapPtr<ObjectGroup*> initializedGroup_; + HeapPtr<ObjectGroup*> initializedGroup_ = {}; public: - TypeNewScript() { mozilla::PodZero(this); } + TypeNewScript() = default; ~TypeNewScript() { js_delete(preliminaryObjects); js_free(initializerList); |