Bug 927318 - Make native functions singletons by default but make promise resolving functions generic objects r=jandem
authorJon Coppeard <jcoppeard@mozilla.com>
Thu, 27 Oct 2016 11:03:53 +0100
changeset 319704 472b12f33ecba8787c4bf3dbe5a3b6f5e9515bd5
parent 319703 70c4b5cde515fd6e47f7625e6b6581a77796afd4
child 319705 df256c6bf29f3bd7f75b3b955291c25ca527ee6a
push id30876
push usercbook@mozilla.com
push dateThu, 27 Oct 2016 14:45:11 +0000
treeherdermozilla-central@9888f1a23001 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs927318
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 927318 - Make native functions singletons by default but make promise resolving functions generic objects r=jandem
js/src/asmjs/WasmJS.cpp
js/src/builtin/Promise.cpp
js/src/jsfun.cpp
js/src/jsfun.h
js/src/vm/GeneratorObject.cpp
--- a/js/src/asmjs/WasmJS.cpp
+++ b/js/src/asmjs/WasmJS.cpp
@@ -768,17 +768,17 @@ WasmInstanceObject::getExportedFunction(
 
     const Instance& instance = instanceObj->instance();
     RootedAtom name(cx, instance.code().getFuncDefAtom(cx, funcDefIndex));
     if (!name)
         return false;
 
     unsigned numArgs = instance.metadata().lookupFuncDefExport(funcDefIndex).sig().args().length();
     fun.set(NewNativeConstructor(cx, WasmCall, numArgs, name, gc::AllocKind::FUNCTION_EXTENDED,
-                                 GenericObject, JSFunction::ASMJS_CTOR));
+                                 SingletonObject, JSFunction::ASMJS_CTOR));
     if (!fun)
         return false;
 
     fun->setExtendedSlot(FunctionExtended::WASM_INSTANCE_SLOT, ObjectValue(*instanceObj));
     fun->setExtendedSlot(FunctionExtended::WASM_FUNC_DEF_INDEX_SLOT, Int32Value(funcDefIndex));
 
     if (!instanceObj->exports().putNew(funcDefIndex, fun)) {
         ReportOutOfMemory(cx);
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -363,22 +363,22 @@ ResolvePromiseFunction(JSContext* cx, un
 // ES2016, 25.4.1.3.
 static MOZ_MUST_USE bool
 CreateResolvingFunctions(JSContext* cx, HandleValue promise,
                          MutableHandleValue resolveVal,
                          MutableHandleValue rejectVal)
 {
     RootedAtom funName(cx, cx->names().empty);
     RootedFunction resolve(cx, NewNativeFunction(cx, ResolvePromiseFunction, 1, funName,
-                                                 gc::AllocKind::FUNCTION_EXTENDED));
+                                                 gc::AllocKind::FUNCTION_EXTENDED, GenericObject));
     if (!resolve)
         return false;
 
     RootedFunction reject(cx, NewNativeFunction(cx, RejectPromiseFunction, 1, funName,
-                                                 gc::AllocKind::FUNCTION_EXTENDED));
+                                                 gc::AllocKind::FUNCTION_EXTENDED, GenericObject));
     if (!reject)
         return false;
 
     // The resolving functions are trusted, so self-hosted code should be able
     // to call them using callFunction instead of callContentFunction.
     resolve->setFlags(resolve->flags() | JSFunction::SELF_HOSTED);
     reject->setFlags(reject->flags() | JSFunction::SELF_HOSTED);
 
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1928,28 +1928,30 @@ JSFunction::needsNamedLambdaEnvironment(
         return false;
 
     return scope->hasEnvironment();
 }
 
 JSFunction*
 js::NewNativeFunction(ExclusiveContext* cx, Native native, unsigned nargs, HandleAtom atom,
                       gc::AllocKind allocKind /* = AllocKind::FUNCTION */,
-                      NewObjectKind newKind /* = GenericObject */)
+                      NewObjectKind newKind /* = SingletonObject */)
 {
+    MOZ_ASSERT(native);
     return NewFunctionWithProto(cx, native, nargs, JSFunction::NATIVE_FUN,
                                 nullptr, atom, nullptr, allocKind, newKind);
 }
 
 JSFunction*
 js::NewNativeConstructor(ExclusiveContext* cx, Native native, unsigned nargs, HandleAtom atom,
                          gc::AllocKind allocKind /* = AllocKind::FUNCTION */,
-                         NewObjectKind newKind /* = GenericObject */,
+                         NewObjectKind newKind /* = SingletonObject */,
                          JSFunction::Flags flags /* = JSFunction::NATIVE_CTOR */)
 {
+    MOZ_ASSERT(native);
     MOZ_ASSERT(flags & JSFunction::NATIVE_CTOR);
     return NewFunctionWithProto(cx, native, nargs, flags, nullptr, atom,
                                 nullptr, allocKind, newKind);
 }
 
 JSFunction*
 js::NewScriptedFunction(ExclusiveContext* cx, unsigned nargs,
                         JSFunction::Flags flags, HandleAtom atom,
@@ -1987,22 +1989,16 @@ js::NewFunctionWithProto(ExclusiveContex
                          NewObjectKind newKind /* = GenericObject */,
                          NewFunctionProtoHandling protoHandling /* = NewFunctionClassProto */)
 {
     MOZ_ASSERT(allocKind == AllocKind::FUNCTION || allocKind == AllocKind::FUNCTION_EXTENDED);
     MOZ_ASSERT_IF(native, !enclosingEnv);
     MOZ_ASSERT(NewFunctionEnvironmentIsWellFormed(cx, enclosingEnv));
 
     RootedObject funobj(cx);
-    // Don't mark asm.js module functions as singleton since they are
-    // cloned (via CloneFunctionObjectIfNotSingleton) which assumes that
-    // isSingleton implies isInterpreted.
-    if (native && !IsAsmJSModuleNative(native))
-        newKind = SingletonObject;
-
     if (protoHandling == NewFunctionClassProto) {
         funobj = NewObjectWithClassProto(cx, &JSFunction::class_, proto, allocKind,
                                          newKind);
     } else {
         funobj = NewObjectWithGivenTaggedProto(cx, &JSFunction::class_, AsTaggedProto(proto),
                                                allocKind, newKind);
     }
     if (!funobj)
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -596,27 +596,29 @@ fun_toStringHelper(JSContext* cx, js::Ha
 namespace js {
 
 extern bool
 Function(JSContext* cx, unsigned argc, Value* vp);
 
 extern bool
 Generator(JSContext* cx, unsigned argc, Value* vp);
 
-// Allocate a new function backed by a JSNative.
+// Allocate a new function backed by a JSNative.  Note that by default this
+// creates a singleton object.
 extern JSFunction*
 NewNativeFunction(ExclusiveContext* cx, JSNative native, unsigned nargs, HandleAtom atom,
                   gc::AllocKind allocKind = gc::AllocKind::FUNCTION,
-                  NewObjectKind newKind = GenericObject);
+                  NewObjectKind newKind = SingletonObject);
 
-// Allocate a new constructor backed by a JSNative.
+// Allocate a new constructor backed by a JSNative.  Note that by default this
+// creates a singleton object.
 extern JSFunction*
 NewNativeConstructor(ExclusiveContext* cx, JSNative native, unsigned nargs, HandleAtom atom,
                      gc::AllocKind allocKind = gc::AllocKind::FUNCTION,
-                     NewObjectKind newKind = GenericObject,
+                     NewObjectKind newKind = SingletonObject,
                      JSFunction::Flags flags = JSFunction::NATIVE_CTOR);
 
 // Allocate a new scripted function.  If enclosingEnv is null, the
 // global will be used.  In all cases the parent of the resulting object will be
 // the global.
 extern JSFunction*
 NewScriptedFunction(ExclusiveContext* cx, unsigned nargs, JSFunction::Flags flags,
                     HandleAtom atom, HandleObject proto = nullptr,
--- a/js/src/vm/GeneratorObject.cpp
+++ b/js/src/vm/GeneratorObject.cpp
@@ -317,17 +317,18 @@ GlobalObject::initStarGenerators(JSConte
 
     RootedValue function(cx, global->getConstructor(JSProto_Function));
     if (!function.toObjectOrNull())
         return false;
     RootedObject proto(cx, &function.toObject());
     RootedAtom name(cx, cx->names().GeneratorFunction);
     RootedObject genFunction(cx, NewFunctionWithProto(cx, Generator, 1,
                                                       JSFunction::NATIVE_CTOR, nullptr, name,
-                                                      proto));
+                                                      proto, gc::AllocKind::FUNCTION,
+                                                      SingletonObject));
     if (!genFunction)
         return false;
     if (!LinkConstructorAndPrototype(cx, genFunction, genFunctionProto))
         return false;
 
     global->setReservedSlot(STAR_GENERATOR_OBJECT_PROTO, ObjectValue(*genObjectProto));
     global->setReservedSlot(STAR_GENERATOR_FUNCTION, ObjectValue(*genFunction));
     global->setReservedSlot(STAR_GENERATOR_FUNCTION_PROTO, ObjectValue(*genFunctionProto));