Left: | ||
Right: |
OLD | NEW |
---|---|
1 #include "Python.h" | 1 #include "Python.h" |
2 #include "structmember.h" | 2 #include "structmember.h" |
3 #include "cPickle.h" | 3 #include "cPickle.h" |
4 | 4 |
5 PyDoc_STRVAR(cPickle_module_documentation, | 5 PyDoc_STRVAR(cPickle_module_documentation, |
6 "C implementation and optimization of the Python pickle module."); | 6 "C implementation and optimization of the Python pickle module."); |
7 | 7 |
8 #ifndef Py_eval_input | 8 #ifndef Py_eval_input |
9 #include <graminit.h> | 9 #include <graminit.h> |
10 #define Py_eval_input eval_input | 10 #define Py_eval_input eval_input |
11 #endif /* Py_eval_input */ | 11 #endif /* Py_eval_input */ |
12 | 12 |
13 #define DEL_LIST_SLICE(list, from, to) (PyList_SetSlice(list, from, to, NULL)) | 13 #define DEL_LIST_SLICE(list, from, to) (PyList_SetSlice(list, from, to, NULL)) |
14 | 14 |
15 /* Bump this when new opcodes are added to the pickle protocol. */ | 15 /* Bump this when new opcodes are added to the pickle protocol. */ |
16 #define HIGHEST_PROTOCOL 2 | 16 #define HIGHEST_PROTOCOL 2 |
17 | 17 |
18 /* Maximum size we ever allow the output buffer to get before flushing. */ | |
19 #define PICKLER_MAX_BUFSIZE 64*1024 | |
20 | |
18 /* | 21 /* |
19 * Pickle opcodes. These must be kept in synch with pickle.py. Extensive | 22 * Pickle opcodes. These must be kept in synch with pickle.py. Extensive |
20 * docs are in pickletools.py. | 23 * docs are in pickletools.py. |
21 */ | 24 */ |
22 #define MARK '(' | 25 #define MARK '(' |
23 #define STOP '.' | 26 #define STOP '.' |
24 #define POP '0' | 27 #define POP '0' |
25 #define POP_MARK '1' | 28 #define POP_MARK '1' |
26 #define DUP '2' | 29 #define DUP '2' |
27 #define FLOAT 'F' | 30 #define FLOAT 'F' |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
564 int proto; | 567 int proto; |
565 | 568 |
566 /* bool, true if proto > 0 */ | 569 /* bool, true if proto > 0 */ |
567 int bin; | 570 int bin; |
568 | 571 |
569 /* Does the pickle contain any of GET, BINGET or LONG_BINGET? */ | 572 /* Does the pickle contain any of GET, BINGET or LONG_BINGET? */ |
570 int uses_gets; | 573 int uses_gets; |
571 | 574 |
572 /* Write into a local buffer before flushing out to file. output_len | 575 /* Write into a local buffer before flushing out to file. output_len |
573 tracks the current size; when output_len >= max_output_len, we | 576 tracks the current size; when output_len >= max_output_len, we |
574 » PyMem_RESIZE. */ | 577 » PyMem_RESIZE. In any case if we are pickling to a file we flush |
578 » the buffer after it grows to more than PICKLER_MAX_BUFSIZE to | |
579 » avoid eating up all of memory in that case. */ | |
575 Py_ssize_t max_output_len; | 580 Py_ssize_t max_output_len; |
576 Py_ssize_t output_len; | 581 Py_ssize_t output_len; |
577 char *output_buffer; | 582 char *output_buffer; |
578 | 583 |
579 int fast; /* Fast mode doesn't save in memo, don't use if circ ref */ | 584 int fast; /* Fast mode doesn't save in memo, don't use if circ ref */ |
580 PyObject *dispatch_table; | 585 PyObject *dispatch_table; |
581 int fast_container; /* count nested container dumps */ | 586 int fast_container; /* count nested container dumps */ |
582 PyObject *fast_memo; | 587 PyObject *fast_memo; |
583 } Picklerobject; | 588 } Picklerobject; |
584 | 589 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
649 if (args) retval=args; | 654 if (args) retval=args; |
650 else { | 655 else { |
651 PyErr_SetObject(ErrType,Py_None); | 656 PyErr_SetObject(ErrType,Py_None); |
652 return NULL; | 657 return NULL; |
653 } | 658 } |
654 PyErr_SetObject(ErrType,retval); | 659 PyErr_SetObject(ErrType,retval); |
655 Py_DECREF(retval); | 660 Py_DECREF(retval); |
656 return NULL; | 661 return NULL; |
657 } | 662 } |
658 | 663 |
664 /* forward declarations needed by _Pickler_Write */ | |
665 static int _Pickler_FlushToFile(Picklerobject *); | |
666 static int _Pickler_ClearBuffer(Picklerobject *); | |
667 | |
659 static int | 668 static int |
660 _Pickler_Write(Picklerobject *self, const char *s, Py_ssize_t n) | 669 _Pickler_Write(Picklerobject *self, const char *s, Py_ssize_t n) |
661 { | 670 { |
662 Py_ssize_t i; | 671 Py_ssize_t i; |
663 char *buffer; | 672 char *buffer; |
664 | 673 |
665 if (self->output_len + n > self->max_output_len) { | 674 if (self->output_len + n > self->max_output_len) { |
666 self->max_output_len = (self->output_len + n) * 2; | 675 self->max_output_len = (self->output_len + n) * 2; |
667 buffer = self->output_buffer; | 676 buffer = self->output_buffer; |
668 PyMem_RESIZE(buffer, char, self->max_output_len); | 677 PyMem_RESIZE(buffer, char, self->max_output_len); |
669 if (buffer == NULL) { | 678 if (buffer == NULL) { |
670 PyErr_NoMemory(); | 679 PyErr_NoMemory(); |
671 return -1; | 680 return -1; |
672 } | 681 } |
673 self->output_buffer = buffer; | 682 self->output_buffer = buffer; |
674 } | 683 } |
675 /* This is faster than memcpy for the char *s we're copying. */ | 684 /* This is faster than memcpy for the char *s we're copying. */ |
676 for (i = 0; i < n; i++) { | 685 for (i = 0; i < n; i++) { |
677 self->output_buffer[self->output_len + i] = s[i]; | 686 self->output_buffer[self->output_len + i] = s[i]; |
678 } | 687 } |
679 self->output_len += n; | 688 self->output_len += n; |
689 | |
690 if (self.file && self->output_len >= PICKLER_MAX_BUFSIZE) { | |
691 /* suppress optimization since the optimizer won't get a | |
692 look at the entire pickled object */ | |
Antoine Pitrou
2010/01/13 13:08:12
You could probably do an early test on `n >= PICKL
Skip
2010/01/13 13:47:16
Sure, but this seems ever-so-slightly easier to ge
Skip
2010/01/13 13:48:59
Done.
| |
693 self->uses_gets = 1; | |
Antoine Pitrou
2010/01/13 13:08:12
I suppose this is unladen-swallow-specific? I see
Skip
2010/01/13 13:47:16
Correct. See _Pickler_Optimize. It removes PUT o
| |
694 if (_Pickler_FlushToFile(self) < 0) | |
695 return -1; | |
696 if (_Pickler_ClearBuffer(self) < 0) | |
697 return -1; | |
698 } | |
699 | |
680 return n; | 700 return n; |
681 } | 701 } |
682 | 702 |
683 static PyObject * | 703 static PyObject * |
684 _Pickler_GetString(Picklerobject *self) | 704 _Pickler_GetString(Picklerobject *self) |
685 { | 705 { |
686 return PyString_FromStringAndSize(self->output_buffer, | 706 return PyString_FromStringAndSize(self->output_buffer, |
687 self->output_len); | 707 self->output_len); |
688 } | 708 } |
689 | 709 |
(...skipping 5877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6567 "1.0", /* Original protocol 0 */ | 6587 "1.0", /* Original protocol 0 */ |
6568 "1.1", /* Protocol 0 + INST */ | 6588 "1.1", /* Protocol 0 + INST */ |
6569 "1.2", /* Original protocol 1 */ | 6589 "1.2", /* Original protocol 1 */ |
6570 "1.3", /* Protocol 1 + BINFLOAT */ | 6590 "1.3", /* Protocol 1 + BINFLOAT */ |
6571 "2.0"); /* Original protocol 2 */ | 6591 "2.0"); /* Original protocol 2 */ |
6572 PyDict_SetItemString(d, "format_version", format_version); | 6592 PyDict_SetItemString(d, "format_version", format_version); |
6573 PyDict_SetItemString(d, "compatible_formats", compatible_formats); | 6593 PyDict_SetItemString(d, "compatible_formats", compatible_formats); |
6574 Py_XDECREF(format_version); | 6594 Py_XDECREF(format_version); |
6575 Py_XDECREF(compatible_formats); | 6595 Py_XDECREF(compatible_formats); |
6576 } | 6596 } |
OLD | NEW |