/* Update auto_gc_trigger. Make sure we trigger the next GC before
* running out of heap! */
- if (bytes_consed_between_gcs >= dynamic_space_size - bytes_allocated)
+ if (bytes_consed_between_gcs <= (dynamic_space_size - bytes_allocated))
auto_gc_trigger = bytes_allocated + bytes_consed_between_gcs;
else
auto_gc_trigger = bytes_allocated + (dynamic_space_size - bytes_allocated)/2;
#endif
void *new_obj;
void *new_free_pointer;
+ os_vm_size_t trigger_bytes = 0;
gc_assert(nbytes>0);
return(new_obj); /* yup */
}
+ /* We don't want to count nbytes against auto_gc_trigger unless we
+ * have to: it speeds up the tenuring of objects and slows down
+ * allocation. However, unless we do so when allocating _very_
+ * large objects we are in danger of exhausting the heap without
+ * running sufficient GCs.
+ */
+ if (nbytes >= bytes_consed_between_gcs)
+ trigger_bytes = nbytes;
+
/* we have to go the long way around, it seems. Check whether we
* should GC in the near future
*/
- if (auto_gc_trigger && bytes_allocated+nbytes > auto_gc_trigger) {
+ if (auto_gc_trigger && (bytes_allocated+trigger_bytes > auto_gc_trigger)) {
/* Don't flood the system with interrupts if the need to gc is
* already noted. This can happen for example when SUB-GC
* allocates or after a gc triggered in a WITHOUT-GCING. */
(with-test (:name :bug-936304)
(gc :full t)
- (assert (eq :ok (handler-case
- (progn
- (loop repeat 50 do (stress-gc))
- :ok)
- (storage-condition ()
- :oom)))))
+ (time
+ (assert (eq :ok (handler-case
+ (progn
+ (loop repeat 50 do (stress-gc))
+ :ok)
+ (storage-condition ()
+ :oom))))))
+
+(with-test (:name :bug-981106)
+ (gc :full t)
+ (time
+ (assert (eq :ok
+ (handler-case
+ (dotimes (runs 100 :ok)
+ (let ((len (length
+ (with-output-to-string (string)
+ (dotimes (i 1000000)
+ (write-sequence "hi there!" string))))))
+ (assert (eql len (* 1000000 (length "hi there!"))))))
+ (storage-condition ()
+ :oom))))))