2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
12 /* This code is in the public domain.
13 ** Version: 1.1 Author: Walt Karas
16 #include "hmm_intrnl.h"
18 void U(shrink_chunk
)(U(descriptor
) *desc
, U(size_bau
) n_baus_to_shrink
)
20 head_record
*dummy_end_block
= (head_record
*)
21 BAUS_BACKWARD(desc
->end_of_shrinkable_chunk
, DUMMY_END_BLOCK_BAUS
);
25 if (dummy_end_block
->block_size
!= 0)
26 /* Chunk does not have valid dummy end block. */
33 head_record
*last_block
= (head_record
*)
35 dummy_end_block
, dummy_end_block
->previous_block_size
);
38 AUDIT_BLOCK(last_block
)
41 if (last_block
== desc
->last_freed
)
43 U(size_bau
) bs
= BLOCK_BAUS(last_block
);
45 /* Chunk will not be shrunk out of existence if
46 ** 1. There is at least one allocated block in the chunk
47 ** and the amount to shrink is exactly the size of the
49 ** 2. After the last block is shrunk, there will be enough
50 ** BAUs left in it to form a minimal size block. */
51 int chunk_will_survive
=
52 (PREV_BLOCK_BAUS(last_block
) && (n_baus_to_shrink
== bs
)) ||
53 (n_baus_to_shrink
<= (U(size_bau
))(bs
- MIN_BLOCK_BAUS
));
55 if (chunk_will_survive
||
56 (!PREV_BLOCK_BAUS(last_block
) &&
58 (U(size_bau
))(bs
+ DUMMY_END_BLOCK_BAUS
))))
62 if (chunk_will_survive
)
64 bs
-= n_baus_to_shrink
;
68 /* The last (non-dummy) block was not completely
69 ** eliminated by the shrink. */
71 last_block
->block_size
= bs
;
73 /* Create new dummy end record.
76 (head_record
*) BAUS_FORWARD(last_block
, bs
);
77 dummy_end_block
->previous_block_size
= bs
;
78 dummy_end_block
->block_size
= 0;
82 if (desc
->avl_tree_root
)
83 AUDIT_BLOCK(PTR_REC_TO_HEAD(desc
->avl_tree_root
))
86 U(into_free_collection
)(desc
, last_block
);
90 /* The last (non-dummy) block was completely
91 ** eliminated by the shrink. Make its head
92 ** the new dummy end block.
94 last_block
->block_size
= 0;
95 last_block
->previous_block_size
&= ~HIGH_BIT_BAU_SIZE
;
100 #ifdef HMM_AUDIT_FAIL
106 #ifdef HMM_AUDIT_FAIL