void
_obstack_newchunk (struct obstack
*
h,
int
length)
{
struct _obstack_chunk
*
old_chunk
=
h
-
>chunk;
struct _obstack_chunk
*
new_chunk;
long
new_size;
long
obj_size
=
h
-
>next_free
-
h
-
>object_base;
long
i;
long
already;
char
*
object_base;
/
*
Compute size
for
new chunk.
*
/
new_size
=
(obj_size
+
length)
+
(obj_size >>
3
)
+
h
-
>alignment_mask
+
100
;
if
(new_size < h
-
>chunk_size)
new_size
=
h
-
>chunk_size;
/
*
Allocate
and
initialize the new chunk.
*
/
new_chunk
=
CALL_CHUNKFUN (h, new_size);
/
/
调用函数位置
if
(!new_chunk)
(
*
obstack_alloc_failed_handler)();
h
-
>chunk
=
new_chunk;
new_chunk
-
>prev
=
old_chunk;
new_chunk
-
>limit
=
h
-
>chunk_limit
=
(char
*
) new_chunk
+
new_size;
/
*
Compute an aligned object_base
in
the new chunk
*
/
object_base
=
__PTR_ALIGN ((char
*
) new_chunk, new_chunk
-
>contents, h
-
>alignment_mask);
/
*
Move the existing
object
to the new chunk.
Word at a time
is
fast
and
is
safe
if
the
object
is
sufficiently aligned.
*
/
if
(h
-
>alignment_mask
+
1
>
=
DEFAULT_ALIGNMENT)
{
for
(i
=
obj_size
/
sizeof (COPYING_UNIT)
-
1
;
i >
=
0
; i
-
-
)
((COPYING_UNIT
*
) object_base)[i]
=
((COPYING_UNIT
*
) h
-
>object_base)[i];
/
*
We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
but that can cross a page boundary on a machine
which does
not
do strict alignment
for
COPYING_UNITS.
*
/
already
=
obj_size
/
sizeof (COPYING_UNIT)
*
sizeof (COPYING_UNIT);
}
else
already
=
0
;
/
*
Copy remaining bytes one by one.
*
/
for
(i
=
already; i < obj_size; i
+
+
)
object_base[i]
=
h
-
>object_base[i];
/
*
If the
object
just copied was the only data
in
OLD_CHUNK,
free that chunk
and
remove it
from
the chain.
But
not
if
that chunk might contain an empty
object
.
*
/
if
(!h
-
>maybe_empty_object
&& (h
-
>object_base
=
=
__PTR_ALIGN ((char
*
) old_chunk, old_chunk
-
>contents,
h
-
>alignment_mask)))
{
new_chunk
-
>prev
=
old_chunk
-
>prev;
CALL_FREEFUN (h, old_chunk);
}
h
-
>object_base
=
object_base;
h
-
>next_free
=
h
-
>object_base
+
obj_size;
/
*
The new chunk certainly contains no empty
object
yet.
*
/
h
-
>maybe_empty_object
=
0
;
}