Issue #9935: Speed up pickling of instances of user-defined classes.
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index e2d6406..fca9f2c 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -2840,6 +2840,28 @@
     return status;
 }
 
+static PyObject *
+get_class(PyObject *obj)
+{
+    PyObject *cls;
+    static PyObject *str_class;
+
+    if (str_class == NULL) {
+        str_class = PyUnicode_InternFromString("__class__");
+        if (str_class == NULL)
+            return NULL;
+    }
+    cls = PyObject_GetAttr(obj, str_class);
+    if (cls == NULL) {
+        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+            PyErr_Clear();
+            cls = (PyObject *) Py_TYPE(obj);
+            Py_INCREF(cls);
+        }
+    }
+    return cls;
+}
+
 /* We're saving obj, and args is the 2-thru-5 tuple returned by the
  * appropriate __reduce__ method for obj.
  */
@@ -2905,17 +2927,18 @@
     /* Protocol 2 special case: if callable's name is __newobj__, use
        NEWOBJ. */
     if (use_newobj) {
-        static PyObject *newobj_str = NULL;
-        PyObject *name_str;
+        static PyObject *newobj_str = NULL, *name_str = NULL;
+        PyObject *name;
 
         if (newobj_str == NULL) {
             newobj_str = PyUnicode_InternFromString("__newobj__");
-            if (newobj_str == NULL)
+            name_str = PyUnicode_InternFromString("__name__");
+            if (newobj_str == NULL || name_str == NULL)
                 return -1;
         }
 
-        name_str = PyObject_GetAttrString(callable, "__name__");
-        if (name_str == NULL) {
+        name = PyObject_GetAttr(callable, name_str);
+        if (name == NULL) {
             if (PyErr_ExceptionMatches(PyExc_AttributeError))
                 PyErr_Clear();
             else
@@ -2923,9 +2946,9 @@
             use_newobj = 0;
         }
         else {
-            use_newobj = PyUnicode_Check(name_str) && 
-                PyUnicode_Compare(name_str, newobj_str) == 0;
-            Py_DECREF(name_str);
+            use_newobj = PyUnicode_Check(name) &&
+                         PyUnicode_Compare(name, newobj_str) == 0;
+            Py_DECREF(name);
         }
     }
     if (use_newobj) {
@@ -2941,20 +2964,14 @@
         }
 
         cls = PyTuple_GET_ITEM(argtup, 0);
-        if (!PyObject_HasAttrString(cls, "__new__")) {
+        if (!PyType_Check(cls)) {
             PyErr_SetString(PicklingError, "args[0] from "
-                            "__newobj__ args has no __new__");
+                            "__newobj__ args is not a type");
             return -1;
         }
 
         if (obj != NULL) {
-            obj_class = PyObject_GetAttrString(obj, "__class__");
-            if (obj_class == NULL) {
-                if (PyErr_ExceptionMatches(PyExc_AttributeError))
-                    PyErr_Clear();
-                else
-                    return -1;
-            }
+            obj_class = get_class(obj);
             p = obj_class != cls;    /* true iff a problem */
             Py_DECREF(obj_class);
             if (p) {