From c87ac214cdddc6bce74858d886d5158abccb9556 Mon Sep 17 00:00:00 2001 From: Johannes Schulte Date: Wed, 17 Sep 2014 22:57:33 +0200 Subject: [PATCH] Bug 994018 - Remove Memcpy-optimization for Typed Objects. r=nmatsakis --- js/src/builtin/TypedObject.cpp | 32 ----------------------- js/src/builtin/TypedObject.h | 14 ---------- js/src/builtin/TypedObject.js | 48 +++++++++++++++++++--------------- js/src/vm/SelfHosting.cpp | 3 --- 4 files changed, 27 insertions(+), 70 deletions(-) diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index 3bbf9443b0e..4928b2ca304 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -2889,38 +2889,6 @@ js::ClampToUint8(ThreadSafeContext *, unsigned argc, Value *vp) JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(js::ClampToUint8JitInfo, ClampToUint8JitInfo, js::ClampToUint8); -bool -js::Memcpy(ThreadSafeContext *, unsigned argc, Value *vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - JS_ASSERT(args.length() == 5); - JS_ASSERT(args[0].isObject() && args[0].toObject().is()); - JS_ASSERT(args[1].isInt32()); - JS_ASSERT(args[2].isObject() && args[2].toObject().is()); - JS_ASSERT(args[3].isInt32()); - JS_ASSERT(args[4].isInt32()); - - TypedObject &targetTypedObj = args[0].toObject().as(); - int32_t targetOffset = args[1].toInt32(); - TypedObject &sourceTypedObj = args[2].toObject().as(); - int32_t sourceOffset = args[3].toInt32(); - int32_t size = args[4].toInt32(); - - JS_ASSERT(targetOffset >= 0); - JS_ASSERT(sourceOffset >= 0); - JS_ASSERT(size >= 0); - JS_ASSERT(size + targetOffset <= targetTypedObj.size()); - JS_ASSERT(size + sourceOffset <= sourceTypedObj.size()); - - uint8_t *target = targetTypedObj.typedMem(targetOffset); - uint8_t *source = sourceTypedObj.typedMem(sourceOffset); - memcpy(target, source, size); - args.rval().setUndefined(); - return true; -} - -JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(js::MemcpyJitInfo, MemcpyJitInfo, js::Memcpy); - bool js::GetTypedObjectModule(JSContext *cx, unsigned argc, Value *vp) { diff --git a/js/src/builtin/TypedObject.h b/js/src/builtin/TypedObject.h index 39a45da57d0..a2f88196fbb 100644 --- a/js/src/builtin/TypedObject.h +++ b/js/src/builtin/TypedObject.h @@ -851,20 +851,6 @@ extern const JSJitInfo TypedObjectIsAttachedJitInfo; bool ClampToUint8(ThreadSafeContext *cx, unsigned argc, Value *vp); extern const JSJitInfo ClampToUint8JitInfo; -/* - * Usage: Memcpy(targetDatum, targetOffset, - * sourceDatum, sourceOffset, - * size) - * - * Intrinsic function. Copies size bytes from the data for - * `sourceDatum` at `sourceOffset` into the data for - * `targetDatum` at `targetOffset`. - * - * Both `sourceDatum` and `targetDatum` must be attached. - */ -bool Memcpy(ThreadSafeContext *cx, unsigned argc, Value *vp); -extern const JSJitInfo MemcpyJitInfo; - /* * Usage: GetTypedObjectModule() * diff --git a/js/src/builtin/TypedObject.js b/js/src/builtin/TypedObject.js index 20bf84ba756..2eb959b4730 100644 --- a/js/src/builtin/TypedObject.js +++ b/js/src/builtin/TypedObject.js @@ -195,20 +195,6 @@ function TypedObjectSet(descr, typedObj, offset, fromValue) { if (!TypedObjectIsAttached(typedObj)) ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED); - // Fast path: `fromValue` is a typed object with same type - // representation as the destination. In that case, we can just do a - // memcpy. - if (IsObject(fromValue) && ObjectIsTypedObject(fromValue)) { - if (!descr.variable && DescrsEquiv(descr, TypedObjectTypeDescr(fromValue))) { - if (!TypedObjectIsAttached(fromValue)) - ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED); - - var size = DESCR_SIZE(descr); - Memcpy(typedObj, offset, fromValue, 0, size); - return; - } - } - switch (DESCR_KIND(descr)) { case JS_TYPEREPR_SCALAR_KIND: TypedObjectSetScalar(descr, typedObj, offset, fromValue); @@ -343,13 +329,33 @@ function TypedObjectSetReference(descr, typedObj, offset, fromValue) { // Sets `fromValue` to `this` assuming that `this` is a scalar type. function TypedObjectSetSimd(descr, typedObj, offset, fromValue) { - // It is only permitted to set a float32x4/int32x4 value from another - // float32x4/int32x4; in that case, the "fast path" that uses memcopy will - // have already matched. So if we get to this point, we're supposed - // to "adapt" fromValue, but there are no legal adaptions. - ThrowError(JSMSG_CANT_CONVERT_TO, - typeof(fromValue), - DESCR_STRING_REPR(descr)); + if (!IsObject(fromValue) || !ObjectIsTypedObject(fromValue)) + ThrowError(JSMSG_CANT_CONVERT_TO, + typeof(fromValue), + DESCR_STRING_REPR(descr)); + + if (!DescrsEquiv(descr, TypedObjectTypeDescr(fromValue))) + ThrowError(JSMSG_CANT_CONVERT_TO, + typeof(fromValue), + DESCR_STRING_REPR(descr)); + + var type = DESCR_TYPE(descr); + switch (type) { + case JS_SIMDTYPEREPR_FLOAT32: + Store_float32(typedObj, offset + 0, Load_float32(fromValue, 0)); + Store_float32(typedObj, offset + 4, Load_float32(fromValue, 4)); + Store_float32(typedObj, offset + 8, Load_float32(fromValue, 8)); + Store_float32(typedObj, offset + 12, Load_float32(fromValue, 12)); + break; + case JS_SIMDTYPEREPR_INT32: + Store_int32(typedObj, offset + 0, Load_int32(fromValue, 0)); + Store_int32(typedObj, offset + 4, Load_int32(fromValue, 4)); + Store_int32(typedObj, offset + 8, Load_int32(fromValue, 8)); + Store_int32(typedObj, offset + 12, Load_int32(fromValue, 12)); + break; + default: + assert(false, "Unhandled Simd type: " + type); + } } /////////////////////////////////////////////////////////////////////////// diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index acea0e90e4e..21f3457a739 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -897,9 +897,6 @@ static const JSFunctionSpec intrinsic_functions[] = { JS_FNINFO("ClampToUint8", JSNativeThreadSafeWrapper, &js::ClampToUint8JitInfo, 1, 0), - JS_FNINFO("Memcpy", - JSNativeThreadSafeWrapper, - &js::MemcpyJitInfo, 5, 0), JS_FN("GetTypedObjectModule", js::GetTypedObjectModule, 0, 0), JS_FN("GetFloat32x4TypeDescr", js::GetFloat32x4TypeDescr, 0, 0), JS_FN("GetInt32x4TypeDescr", js::GetInt32x4TypeDescr, 0, 0),