guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: The relationship between SCM and scm_t_bits.


From: Dirk Herrmann
Subject: Re: The relationship between SCM and scm_t_bits.
Date: Sun, 03 Oct 2004 11:09:47 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4.2) Gecko/20040220

Marius Vollmer wrote:

 Dirk Herrmann <address@hidden> writes:

>> The reason is that there exits code that does essentially this:
>>
>> scm_t_bits heap_field;
>>
>> SCM value = whatever (); SCM *ptr = (SCM*)&heap_field; *ptr =
>> value;
>
> I assume that you mean that heap_field is actually an element of
> the heap.

 Yes.

> We already had the discussion that I suggest to discourage this
> style of coding since it violates a potential write barrier and
> will lead to problems if we ever switch to a generational garbage
> collection.

 Yes, that is the bigger issue. What we are discussing here are quite
 minor points, I'd say. There might be a time when we do want to
 have a write-barrier and then we can revisit whether to provide the
 *LOC accessors or not. Right now, removing them is not necessary.
 We should only remove them when there is an immediate benefit.

This did not answer my question from my previous mail, where I asked you for a clear statement about whether this style of coding is to be considered discouraged: Is there a strategy towards a generational gc, or not? Shall new code make use of the *LOC accessors or shall developers avoid it?

 I think we need to make the following guarantees:

- a SCM and a scm_t_bits have the same size in the sense that they >
can store exactly the same things. We always have

 SCM scm; scm_is_eq (SCM_PACK (SCM_UNPACK (scm)), scm)

 and

 scm_t_bits bits; SCM_UNPACK (SCM_PACK (bits)) == bits > (*)

 - a size_t can be cast to scm_t_bits and back without losing
 information. (This is for storing integers in heap words.)

 - a void* can be cast to scm_t_bits and back without losing
 information. (This is for storing pointers in heap words.)

 - a scm_t_bits can be cast to void* and back without losing
 information. (This is for storing SCMs in void* locations provided
 by external code.)

 This is not as elegant and clean as dropping the guarantee (*), but
 it allows heap words to be declared as type SCM which is desirable
 since local variables and function arguments are also declared to be
 of type SCM.

I am not quite sure, what you really want to state with (*):

A) For a variable "bits" of type "scm_t_bits" that holds a representation of a SCM value the expression "SCM_UNPACK (SCM_PACK (bits)) == bits" is guaranteed to evaluate to true.

B) For any variable "bits" of type "scm_t_bits" the expression "SCM_UNPACK (SCM_PACK (bits)) == bits" is guaranteed to evaluate to true.

If you only meant to say A), then I agree that we should make the above guarantees, including (*), if it was more accurately formulated.

If you meant to say B), then I disagree. It is one thing if Guile internally makes use of the fact that things happen to work that way (like you have done with your modification to scm_t_cell). It is another thing to make this an official guarantee.

 Please do not apply it. We are not completely clean, true, but I
doubt that we can attain perfect cleanliness anyway. Using a union >
would just complicate the issue without giving any benefit (that I > could see).

The effects of the patch are quite local. No other line of code in guile apart from the ones seen in the patch have to be modified.

Benefits are:
- Ease of documentation, since the current implementation needs to be documented in gc.h as a local uncleanlyness of the otherwise quite consequently used distinction between SCM and scm_t_bits. Maybe I am assuming too much here, but you had planned to document this, right? :-) - Possibility to modify SCM_PACK such that it does an assertion check on the value before actually converting it.

 Things started out simple, and got more complicated with the
 introduction of scm_t_bits as an alias of SCM. Let's not continue
 this trend by pretending that SCM and scm_t_bits are actually
 separate types. They are not, they are the same type essentially,
 but one allows certain low-level operations that the other prevents.

I think you are confusing a type as a collection of values, and the underlying representation. The type SCM is distinct from the type scm_t_bits, since only a subset of the values of type scm_t_bits can be used to create a valid SCM. It is directly comparable to having a type "natural numbers" implemented using a C unsigned int, and a type "even natural numbers", also implemented as a C unsigned int. Both have the same underlying representation, but are different types. Despite the poor type checking offered by standard C, by using tools like splint it is even possible to get warnings about undesired mixes between different typedefs in C code.

Best regards,
Dirk





reply via email to

[Prev in Thread] Current Thread [Next in Thread]