Loading js/src/builtin/TypedObject.cpp +19 −4 Original line number Diff line number Diff line Loading @@ -2215,18 +2215,24 @@ TypedObject::obj_enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op, } /* static */ size_t TypedObject::ownerOffset() TypedObject::offsetOfOwnerSlot() { return JSObject::getFixedSlotOffset(JS_TYPEDOBJ_SLOT_OWNER); } /* static */ size_t TypedObject::dataOffset() TypedObject::offsetOfDataSlot() { // the offset of 7 is based on the alloc kind return JSObject::getPrivateDataOffset(JS_TYPEDOBJ_SLOT_DATA); } /* static */ size_t TypedObject::offsetOfByteOffsetSlot() { return JSObject::getFixedSlotOffset(JS_TYPEDOBJ_SLOT_BYTEOFFSET); } void TypedObject::neuter(void *newData) { Loading Loading @@ -2712,12 +2718,21 @@ js::SetTypedObjectOffset(ThreadSafeContext *, unsigned argc, Value *vp) typedObj.setPrivate(typedObj.owner().dataPointer() + offset); typedObj.setReservedSlot(JS_TYPEDOBJ_SLOT_BYTEOFFSET, Int32Value(offset)); args.rval().setUndefined(); return true; } JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(js::SetTypedObjectOffsetJitInfo, bool js::intrinsic_SetTypedObjectOffset(JSContext *cx, unsigned argc, Value *vp) { // Do not use JSNativeThreadSafeWrapper<> so that ion can reference // this function more easily when inlining. return SetTypedObjectOffset(cx, argc, vp); } JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(js::intrinsic_SetTypedObjectOffsetJitInfo, SetTypedObjectJitInfo, js::SetTypedObjectOffset); SetTypedObjectOffset); bool js::ObjectIsTypeDescr(ThreadSafeContext *, unsigned argc, Value *vp) Loading js/src/builtin/TypedObject.h +8 −4 Original line number Diff line number Diff line Loading @@ -585,7 +585,7 @@ class TypedObject : public ArrayBufferViewObject MutableHandleValue statep, MutableHandleId idp); public: static size_t ownerOffset(); static size_t offsetOfOwnerSlot(); // Each typed object contains a void* pointer pointing at the // binary data that it represents. (That data may be owned by this Loading @@ -593,7 +593,10 @@ class TypedObject : public ArrayBufferViewObject // This function returns the offset in bytes within the object // where the `void*` pointer can be found. It is intended for use // by the JIT. static size_t dataOffset(); static size_t offsetOfDataSlot(); // Offset of the byte offset slot. static size_t offsetOfByteOffsetSlot(); // Helper for createUnattached() static TypedObject *createUnattachedWithClass(JSContext *cx, Loading Loading @@ -742,8 +745,9 @@ extern const JSJitInfo AttachTypedObjectJitInfo; * Changes the offset for `typedObj` within its buffer to `offset`. * `typedObj` must already be attached. */ bool SetTypedObjectOffset(ThreadSafeContext *cx, unsigned argc, Value *vp); extern const JSJitInfo SetTypedObjectOffsetJitInfo; bool intrinsic_SetTypedObjectOffset(JSContext *cx, unsigned argc, Value *vp); bool SetTypedObjectOffset(ThreadSafeContext *, unsigned argc, Value *vp); extern const JSJitInfo intrinsic_SetTypedObjectOffsetJitInfo; /* * Usage: ObjectIsTypeDescr(obj) Loading js/src/jit/CodeGenerator.cpp +51 −2 Original line number Diff line number Diff line Loading @@ -4112,7 +4112,7 @@ CodeGenerator::visitNeuterCheck(LNeuterCheck *lir) Register obj = ToRegister(lir->object()); Register temp = ToRegister(lir->temp()); masm.extractObject(Address(obj, TypedObject::ownerOffset()), temp); masm.extractObject(Address(obj, TypedObject::offsetOfOwnerSlot()), temp); masm.unboxInt32(Address(temp, ArrayBufferObject::flagsOffset()), temp); masm.and32(Imm32(ArrayBufferObject::neuteredFlag()), temp); Loading @@ -4126,7 +4126,56 @@ CodeGenerator::visitTypedObjectElements(LTypedObjectElements *lir) { Register obj = ToRegister(lir->object()); Register out = ToRegister(lir->output()); masm.loadPtr(Address(obj, TypedObject::dataOffset()), out); masm.loadPtr(Address(obj, TypedObject::offsetOfDataSlot()), out); return true; } bool CodeGenerator::visitSetTypedObjectOffset(LSetTypedObjectOffset *lir) { Register object = ToRegister(lir->object()); Register offset = ToRegister(lir->offset()); Register temp0 = ToRegister(lir->temp0()); // `offset` is an absolute offset into the base buffer. One way // to implement this instruction would be load the base address // from the buffer and add `offset`. But that'd be an extra load. // We can instead load the current base pointer and current // offset, compute the difference with `offset`, and then adjust // the current base pointer. This is two loads but to adjacent // fields in the same object, which should come in the same cache // line. // // The C code I would probably write is the following: // // void SetTypedObjectOffset(TypedObject *obj, int32_t offset) { // int32_t temp0 = obj->byteOffset; // obj->pointer = obj->pointer - temp0 + offset; // obj->byteOffset = offset; // } // // But what we actually compute is more like this, because it // saves us a temporary to do it this way: // // void SetTypedObjectOffset(TypedObject *obj, int32_t offset) { // int32_t temp0 = obj->byteOffset; // obj->pointer = obj->pointer - (temp0 - offset); // obj->byteOffset = offset; // } // temp0 = typedObj->byteOffset; masm.unboxInt32(Address(object, TypedObject::offsetOfByteOffsetSlot()), temp0); // temp0 -= offset; masm.subPtr(offset, temp0); // obj->pointer -= temp0; masm.subPtr(temp0, Address(object, TypedObject::offsetOfDataSlot())); // obj->byteOffset = offset; masm.storeValue(JSVAL_TYPE_INT32, offset, Address(object, TypedObject::offsetOfByteOffsetSlot())); return true; } Loading js/src/jit/CodeGenerator.h +1 −0 Original line number Diff line number Diff line Loading @@ -167,6 +167,7 @@ class CodeGenerator : public CodeGeneratorSpecific bool visitTypedArrayElements(LTypedArrayElements *lir); bool visitNeuterCheck(LNeuterCheck *lir); bool visitTypedObjectElements(LTypedObjectElements *lir); bool visitSetTypedObjectOffset(LSetTypedObjectOffset *lir); bool visitStringLength(LStringLength *lir); bool visitInitializedLength(LInitializedLength *lir); bool visitSetInitializedLength(LSetInitializedLength *lir); Loading js/src/jit/IonBuilder.h +1 −0 Original line number Diff line number Diff line Loading @@ -696,6 +696,7 @@ class IonBuilder : public MIRGenerator // TypedObject intrinsics. InliningStatus inlineObjectIsTypeDescr(CallInfo &callInfo); InliningStatus inlineSetTypedObjectOffset(CallInfo &callInfo); bool elementAccessIsTypedObjectArrayOfScalarType(MDefinition* obj, MDefinition* id, ScalarTypeDescr::Type *arrayType); Loading Loading
js/src/builtin/TypedObject.cpp +19 −4 Original line number Diff line number Diff line Loading @@ -2215,18 +2215,24 @@ TypedObject::obj_enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op, } /* static */ size_t TypedObject::ownerOffset() TypedObject::offsetOfOwnerSlot() { return JSObject::getFixedSlotOffset(JS_TYPEDOBJ_SLOT_OWNER); } /* static */ size_t TypedObject::dataOffset() TypedObject::offsetOfDataSlot() { // the offset of 7 is based on the alloc kind return JSObject::getPrivateDataOffset(JS_TYPEDOBJ_SLOT_DATA); } /* static */ size_t TypedObject::offsetOfByteOffsetSlot() { return JSObject::getFixedSlotOffset(JS_TYPEDOBJ_SLOT_BYTEOFFSET); } void TypedObject::neuter(void *newData) { Loading Loading @@ -2712,12 +2718,21 @@ js::SetTypedObjectOffset(ThreadSafeContext *, unsigned argc, Value *vp) typedObj.setPrivate(typedObj.owner().dataPointer() + offset); typedObj.setReservedSlot(JS_TYPEDOBJ_SLOT_BYTEOFFSET, Int32Value(offset)); args.rval().setUndefined(); return true; } JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(js::SetTypedObjectOffsetJitInfo, bool js::intrinsic_SetTypedObjectOffset(JSContext *cx, unsigned argc, Value *vp) { // Do not use JSNativeThreadSafeWrapper<> so that ion can reference // this function more easily when inlining. return SetTypedObjectOffset(cx, argc, vp); } JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(js::intrinsic_SetTypedObjectOffsetJitInfo, SetTypedObjectJitInfo, js::SetTypedObjectOffset); SetTypedObjectOffset); bool js::ObjectIsTypeDescr(ThreadSafeContext *, unsigned argc, Value *vp) Loading
js/src/builtin/TypedObject.h +8 −4 Original line number Diff line number Diff line Loading @@ -585,7 +585,7 @@ class TypedObject : public ArrayBufferViewObject MutableHandleValue statep, MutableHandleId idp); public: static size_t ownerOffset(); static size_t offsetOfOwnerSlot(); // Each typed object contains a void* pointer pointing at the // binary data that it represents. (That data may be owned by this Loading @@ -593,7 +593,10 @@ class TypedObject : public ArrayBufferViewObject // This function returns the offset in bytes within the object // where the `void*` pointer can be found. It is intended for use // by the JIT. static size_t dataOffset(); static size_t offsetOfDataSlot(); // Offset of the byte offset slot. static size_t offsetOfByteOffsetSlot(); // Helper for createUnattached() static TypedObject *createUnattachedWithClass(JSContext *cx, Loading Loading @@ -742,8 +745,9 @@ extern const JSJitInfo AttachTypedObjectJitInfo; * Changes the offset for `typedObj` within its buffer to `offset`. * `typedObj` must already be attached. */ bool SetTypedObjectOffset(ThreadSafeContext *cx, unsigned argc, Value *vp); extern const JSJitInfo SetTypedObjectOffsetJitInfo; bool intrinsic_SetTypedObjectOffset(JSContext *cx, unsigned argc, Value *vp); bool SetTypedObjectOffset(ThreadSafeContext *, unsigned argc, Value *vp); extern const JSJitInfo intrinsic_SetTypedObjectOffsetJitInfo; /* * Usage: ObjectIsTypeDescr(obj) Loading
js/src/jit/CodeGenerator.cpp +51 −2 Original line number Diff line number Diff line Loading @@ -4112,7 +4112,7 @@ CodeGenerator::visitNeuterCheck(LNeuterCheck *lir) Register obj = ToRegister(lir->object()); Register temp = ToRegister(lir->temp()); masm.extractObject(Address(obj, TypedObject::ownerOffset()), temp); masm.extractObject(Address(obj, TypedObject::offsetOfOwnerSlot()), temp); masm.unboxInt32(Address(temp, ArrayBufferObject::flagsOffset()), temp); masm.and32(Imm32(ArrayBufferObject::neuteredFlag()), temp); Loading @@ -4126,7 +4126,56 @@ CodeGenerator::visitTypedObjectElements(LTypedObjectElements *lir) { Register obj = ToRegister(lir->object()); Register out = ToRegister(lir->output()); masm.loadPtr(Address(obj, TypedObject::dataOffset()), out); masm.loadPtr(Address(obj, TypedObject::offsetOfDataSlot()), out); return true; } bool CodeGenerator::visitSetTypedObjectOffset(LSetTypedObjectOffset *lir) { Register object = ToRegister(lir->object()); Register offset = ToRegister(lir->offset()); Register temp0 = ToRegister(lir->temp0()); // `offset` is an absolute offset into the base buffer. One way // to implement this instruction would be load the base address // from the buffer and add `offset`. But that'd be an extra load. // We can instead load the current base pointer and current // offset, compute the difference with `offset`, and then adjust // the current base pointer. This is two loads but to adjacent // fields in the same object, which should come in the same cache // line. // // The C code I would probably write is the following: // // void SetTypedObjectOffset(TypedObject *obj, int32_t offset) { // int32_t temp0 = obj->byteOffset; // obj->pointer = obj->pointer - temp0 + offset; // obj->byteOffset = offset; // } // // But what we actually compute is more like this, because it // saves us a temporary to do it this way: // // void SetTypedObjectOffset(TypedObject *obj, int32_t offset) { // int32_t temp0 = obj->byteOffset; // obj->pointer = obj->pointer - (temp0 - offset); // obj->byteOffset = offset; // } // temp0 = typedObj->byteOffset; masm.unboxInt32(Address(object, TypedObject::offsetOfByteOffsetSlot()), temp0); // temp0 -= offset; masm.subPtr(offset, temp0); // obj->pointer -= temp0; masm.subPtr(temp0, Address(object, TypedObject::offsetOfDataSlot())); // obj->byteOffset = offset; masm.storeValue(JSVAL_TYPE_INT32, offset, Address(object, TypedObject::offsetOfByteOffsetSlot())); return true; } Loading
js/src/jit/CodeGenerator.h +1 −0 Original line number Diff line number Diff line Loading @@ -167,6 +167,7 @@ class CodeGenerator : public CodeGeneratorSpecific bool visitTypedArrayElements(LTypedArrayElements *lir); bool visitNeuterCheck(LNeuterCheck *lir); bool visitTypedObjectElements(LTypedObjectElements *lir); bool visitSetTypedObjectOffset(LSetTypedObjectOffset *lir); bool visitStringLength(LStringLength *lir); bool visitInitializedLength(LInitializedLength *lir); bool visitSetInitializedLength(LSetInitializedLength *lir); Loading
js/src/jit/IonBuilder.h +1 −0 Original line number Diff line number Diff line Loading @@ -696,6 +696,7 @@ class IonBuilder : public MIRGenerator // TypedObject intrinsics. InliningStatus inlineObjectIsTypeDescr(CallInfo &callInfo); InliningStatus inlineSetTypedObjectOffset(CallInfo &callInfo); bool elementAccessIsTypedObjectArrayOfScalarType(MDefinition* obj, MDefinition* id, ScalarTypeDescr::Type *arrayType); Loading