From c22a493144e39d76bfa42c46f9d6d17a5143ac35 Mon Sep 17 00:00:00 2001 From: wolfbeast <mcwerewolf@wolfbeast.com> Date: Sat, 22 Feb 2020 21:09:32 +0100 Subject: Revert #1142 - Remove unboxed objects - accounting for removal of watch()/unwatch() --- js/src/jsobj.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/jsobj.cpp') diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index ef1291079..3d7f294fe 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -42,7 +42,6 @@ #include "frontend/BytecodeCompiler.h" #include "gc/Marking.h" #include "gc/Policy.h" -#include "gc/StoreBuffer-inl.h" #include "jit/BaselineJIT.h" #include "js/MemoryMetrics.h" #include "js/Proxy.h" @@ -54,6 +53,7 @@ #include "vm/RegExpStaticsObject.h" #include "vm/Shape.h" #include "vm/TypedArrayCommon.h" +#include "vm/UnboxedObject-inl.h" #include "jsatominlines.h" #include "jsboolinlines.h" -- cgit v1.2.3 From af69cb07db0d810a1a1a507b890e6beb23dc421c Mon Sep 17 00:00:00 2001 From: wolfbeast <mcwerewolf@wolfbeast.com> Date: Sun, 23 Feb 2020 14:41:40 +0100 Subject: Revert #1137 - Remove unboxed arrays - accounting for removal of watch()/unwatch() - updated for intermediate code changes. --- js/src/jsobj.cpp | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'js/src/jsobj.cpp') diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 3d7f294fe..901a9f505 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1136,18 +1136,19 @@ js::CloneObject(JSContext* cx, HandleObject obj, Handle<js::TaggedProto> proto) } static bool -GetScriptArrayObjectElements(JSContext* cx, HandleArrayObject arr, MutableHandle<GCVector<Value>> values) +GetScriptArrayObjectElements(JSContext* cx, HandleObject obj, MutableHandle<GCVector<Value>> values) { - MOZ_ASSERT(!arr->isSingleton()); - MOZ_ASSERT(!arr->isIndexed()); + MOZ_ASSERT(!obj->isSingleton()); + MOZ_ASSERT(obj->is<ArrayObject>() || obj->is<UnboxedArrayObject>()); + MOZ_ASSERT(!obj->isIndexed()); - size_t length = arr->length(); + size_t length = GetAnyBoxedOrUnboxedArrayLength(obj); if (!values.appendN(MagicValue(JS_ELEMENTS_HOLE), length)) return false; - size_t initlen = arr->getDenseInitializedLength(); + size_t initlen = GetAnyBoxedOrUnboxedInitializedLength(obj); for (size_t i = 0; i < initlen; i++) - values[i].set(arr->getDenseElement(i)); + values[i].set(GetAnyBoxedOrUnboxedDenseElement(obj, i)); return true; } @@ -1199,12 +1200,13 @@ js::DeepCloneObjectLiteral(JSContext* cx, HandleObject obj, NewObjectKind newKin MOZ_ASSERT_IF(obj->isSingleton(), cx->compartment()->behaviors().getSingletonsAsTemplates()); MOZ_ASSERT(obj->is<PlainObject>() || - obj->is<ArrayObject>()); + obj->is<ArrayObject>() || + obj->is<UnboxedArrayObject>()); MOZ_ASSERT(newKind != SingletonObject); - if (obj->is<ArrayObject>()) { + if (obj->is<ArrayObject>() || obj->is<UnboxedArrayObject>()) { Rooted<GCVector<Value>> values(cx, GCVector<Value>(cx)); - if (!GetScriptArrayObjectElements(cx, obj.as<ArrayObject>(), &values)) + if (!GetScriptArrayObjectElements(cx, obj, &values)) return nullptr; // Deep clone any elements. @@ -1318,8 +1320,9 @@ js::XDRObjectLiteral(XDRState<mode>* xdr, MutableHandleObject obj) { if (mode == XDR_ENCODE) { MOZ_ASSERT(obj->is<PlainObject>() || - obj->is<ArrayObject>()); - isArray = obj->is<ArrayObject>() ? 1 : 0; + obj->is<ArrayObject>() || + obj->is<UnboxedArrayObject>()); + isArray = (obj->is<ArrayObject>() || obj->is<UnboxedArrayObject>()) ? 1 : 0; } if (!xdr->codeUint32(&isArray)) @@ -1331,11 +1334,8 @@ js::XDRObjectLiteral(XDRState<mode>* xdr, MutableHandleObject obj) if (isArray) { Rooted<GCVector<Value>> values(cx, GCVector<Value>(cx)); - if (mode == XDR_ENCODE) { - RootedArrayObject arr(cx, &obj->as<ArrayObject>()); - if (!GetScriptArrayObjectElements(cx, arr, &values)) - return false; - } + if (mode == XDR_ENCODE && !GetScriptArrayObjectElements(cx, obj, &values)) + return false; uint32_t initialized; if (mode == XDR_ENCODE) @@ -2315,6 +2315,11 @@ js::LookupOwnPropertyPure(ExclusiveContext* cx, JSObject* obj, jsid id, Shape** // us the resolve hook won't define a property with this id. if (ClassMayResolveId(cx->names(), obj->getClass(), id, obj)) return false; + } else if (obj->is<UnboxedArrayObject>()) { + if (obj->as<UnboxedArrayObject>().containsProperty(cx, id)) { + MarkNonNativePropertyFound<NoGC>(propp); + return true; + } } else if (obj->is<TypedObject>()) { if (obj->as<TypedObject>().typeDescr().hasProperty(cx->names(), id)) { MarkNonNativePropertyFound<NoGC>(propp); @@ -3606,6 +3611,16 @@ JSObject::allocKindForTenure(const js::Nursery& nursery) const if (IsProxy(this)) return as<ProxyObject>().allocKindForTenure(); + // Unboxed arrays use inline data if their size is small enough. + if (is<UnboxedArrayObject>()) { + const UnboxedArrayObject* nobj = &as<UnboxedArrayObject>(); + size_t nbytes = UnboxedArrayObject::offsetOfInlineElements() + + nobj->capacity() * nobj->elementSize(); + if (nbytes <= JSObject::MAX_BYTE_SIZE) + return GetGCObjectKindForBytes(nbytes); + return AllocKind::OBJECT0; + } + // Inlined typed objects are followed by their data, so make sure we copy // it all over to the new object. if (is<InlineTypedObject>()) { -- cgit v1.2.3 From 0d1eea2ebfcf1a3746ff0125a6fa340e8b90d722 Mon Sep 17 00:00:00 2001 From: wolfbeast <mcwerewolf@wolfbeast.com> Date: Sun, 23 Feb 2020 19:43:47 +0100 Subject: Revert #1091 Remove unboxed object code phase 1 + extras. This should be the last code backout for this. merging this branch should get us back to the way we were (+ additional code changes for later changes) as fasr as the unused unboxed code is concerned. --- js/src/jsobj.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 18 deletions(-) (limited to 'js/src/jsobj.cpp') diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 901a9f505..d4379bd7d 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -53,7 +53,6 @@ #include "vm/RegExpStaticsObject.h" #include "vm/Shape.h" #include "vm/TypedArrayCommon.h" -#include "vm/UnboxedObject-inl.h" #include "jsatominlines.h" #include "jsboolinlines.h" @@ -869,6 +868,9 @@ static inline JSObject* CreateThisForFunctionWithGroup(JSContext* cx, HandleObjectGroup group, NewObjectKind newKind) { + if (group->maybeUnboxedLayout() && newKind != SingletonObject) + return UnboxedPlainObject::create(cx, group, newKind); + if (TypeNewScript* newScript = group->newScript()) { if (newScript->analyzed()) { // The definite properties analysis has been performed for this @@ -1157,27 +1159,46 @@ static bool GetScriptPlainObjectProperties(JSContext* cx, HandleObject obj, MutableHandle<IdValueVector> properties) { - MOZ_ASSERT(obj->is<PlainObject>()); - PlainObject* nobj = &obj->as<PlainObject>(); + if (obj->is<PlainObject>()) { + PlainObject* nobj = &obj->as<PlainObject>(); - if (!properties.appendN(IdValuePair(), nobj->slotSpan())) - return false; + if (!properties.appendN(IdValuePair(), nobj->slotSpan())) + return false; - for (Shape::Range<NoGC> r(nobj->lastProperty()); !r.empty(); r.popFront()) { - Shape& shape = r.front(); - MOZ_ASSERT(shape.isDataDescriptor()); - uint32_t slot = shape.slot(); - properties[slot].get().id = shape.propid(); - properties[slot].get().value = nobj->getSlot(slot); + for (Shape::Range<NoGC> r(nobj->lastProperty()); !r.empty(); r.popFront()) { + Shape& shape = r.front(); + MOZ_ASSERT(shape.isDataDescriptor()); + uint32_t slot = shape.slot(); + properties[slot].get().id = shape.propid(); + properties[slot].get().value = nobj->getSlot(slot); + } + + for (size_t i = 0; i < nobj->getDenseInitializedLength(); i++) { + Value v = nobj->getDenseElement(i); + if (!v.isMagic(JS_ELEMENTS_HOLE) && !properties.append(IdValuePair(INT_TO_JSID(i), v))) + return false; + } + + return true; } - for (size_t i = 0; i < nobj->getDenseInitializedLength(); i++) { - Value v = nobj->getDenseElement(i); - if (!v.isMagic(JS_ELEMENTS_HOLE) && !properties.append(IdValuePair(INT_TO_JSID(i), v))) + if (obj->is<UnboxedPlainObject>()) { + UnboxedPlainObject* nobj = &obj->as<UnboxedPlainObject>(); + + const UnboxedLayout& layout = nobj->layout(); + if (!properties.appendN(IdValuePair(), layout.properties().length())) return false; + + for (size_t i = 0; i < layout.properties().length(); i++) { + const UnboxedLayout::Property& property = layout.properties()[i]; + properties[i].get().id = NameToId(property.name); + properties[i].get().value = nobj->getValue(property); + } + + return true; } - return true; + MOZ_CRASH("Bad object kind"); } static bool @@ -1199,9 +1220,8 @@ js::DeepCloneObjectLiteral(JSContext* cx, HandleObject obj, NewObjectKind newKin /* NB: Keep this in sync with XDRObjectLiteral. */ MOZ_ASSERT_IF(obj->isSingleton(), cx->compartment()->behaviors().getSingletonsAsTemplates()); - MOZ_ASSERT(obj->is<PlainObject>() || - obj->is<ArrayObject>() || - obj->is<UnboxedArrayObject>()); + MOZ_ASSERT(obj->is<PlainObject>() || obj->is<UnboxedPlainObject>() || + obj->is<ArrayObject>() || obj->is<UnboxedArrayObject>()); MOZ_ASSERT(newKind != SingletonObject); if (obj->is<ArrayObject>() || obj->is<UnboxedArrayObject>()) { @@ -1320,6 +1340,7 @@ js::XDRObjectLiteral(XDRState<mode>* xdr, MutableHandleObject obj) { if (mode == XDR_ENCODE) { MOZ_ASSERT(obj->is<PlainObject>() || + obj->is<UnboxedPlainObject>() || obj->is<ArrayObject>() || obj->is<UnboxedArrayObject>()); isArray = (obj->is<ArrayObject>() || obj->is<UnboxedArrayObject>()) ? 1 : 0; @@ -2315,6 +2336,11 @@ js::LookupOwnPropertyPure(ExclusiveContext* cx, JSObject* obj, jsid id, Shape** // us the resolve hook won't define a property with this id. if (ClassMayResolveId(cx->names(), obj->getClass(), id, obj)) return false; + } else if (obj->is<UnboxedPlainObject>()) { + if (obj->as<UnboxedPlainObject>().containsUnboxedOrExpandoProperty(cx, id)) { + MarkNonNativePropertyFound<NoGC>(propp); + return true; + } } else if (obj->is<UnboxedArrayObject>()) { if (obj->as<UnboxedArrayObject>().containsProperty(cx, id)) { MarkNonNativePropertyFound<NoGC>(propp); @@ -2576,6 +2602,11 @@ js::SetPrototype(JSContext* cx, HandleObject obj, HandleObject proto, JS::Object break; } + // Convert unboxed objects to their native representations before changing + // their prototype/group, as they depend on the group for their layout. + if (!MaybeConvertUnboxedObjectToNative(cx, obj)) + return false; + Rooted<TaggedProto> taggedProto(cx, TaggedProto(proto)); if (!SetClassAndProto(cx, obj, obj->getClass(), taggedProto)) return false; @@ -2599,6 +2630,9 @@ js::PreventExtensions(JSContext* cx, HandleObject obj, ObjectOpResult& result, I if (!obj->nonProxyIsExtensible()) return result.succeed(); + if (!MaybeConvertUnboxedObjectToNative(cx, obj)) + return false; + // Force lazy properties to be resolved. AutoIdVector props(cx); if (!js::GetPropertyKeys(cx, obj, JSITER_HIDDEN | JSITER_OWNONLY, &props)) @@ -3611,6 +3645,12 @@ JSObject::allocKindForTenure(const js::Nursery& nursery) const if (IsProxy(this)) return as<ProxyObject>().allocKindForTenure(); + // Unboxed plain objects are sized according to the data they store. + if (is<UnboxedPlainObject>()) { + size_t nbytes = as<UnboxedPlainObject>().layoutDontCheckGeneration().size(); + return GetGCObjectKindForBytes(UnboxedPlainObject::offsetOfData() + nbytes); + } + // Unboxed arrays use inline data if their size is small enough. if (is<UnboxedArrayObject>()) { const UnboxedArrayObject* nobj = &as<UnboxedArrayObject>(); -- cgit v1.2.3