Opened 10 years ago

Last modified 17 months ago

#15 new feature

Share constant enumeration values.

Reported by: benl Owned by:
Priority: normal Milestone:
Component: Core Transforms Version: 0.1.2
Keywords: Cc:

Description

Make sure we're not reallocating True, False and Unit values.

Change History (17)

comment:1 Changed 9 years ago by benl

  • Type changed from task to newbie

comment:2 Changed 9 years ago by benl

  • Milestone changed from 0.1.3 to 0.1.4

comment:3 Changed 8 years ago by tomberek

  • Cc tomberek@… added

Added a dump of the ptr to runtime/Debug/Dump.c _dumpDataRS and added dumpDataRS to DDC.Runtime.Debug.

fprintf (file, "        , address = 0x%x" , obj);

and

foreign import "_dumpDataRS"
    privDumpDataRS :: forall a . Ptr# File# -> a -(!File)> Void#

dumpDataRS :: a -(!File)> ()
dumpDataRS obj = do  
    privDumpDataRS stdout obj
    ()

The below code suggest that the pointers to x,y,a,b,c,d are all different and that we are reallocating True, False, user-defined enumerations, and ().

import DDC.Runtime.Debug

main () = do
    x = True
    y = True
    dumpDataRS x
    dumpDataRS y
    a = T
    b = T
    dumpDataRS a
    dumpDataRS b
    c = ()
    d = ()
    dumpDataRS c
    dumpDataRS d
    ()

data TBool = T | F | N

Output:

DataRS  { tag     = 0x000001
        , payload = [ 00 00 00 00 21 01 00 00 ]
        , address = 0xebf69394        }
DataRS  { tag     = 0x000001
        , payload = [ 00 00 00 00 21 00 00 00 ]
        , address = 0xebf6939c        }
DataRS  { tag     = 0x000000
        , payload = [ 00 00 00 00 21 00 00 00 ]
        , address = 0xebf693b4        }
DataRS  { tag     = 0x000000
        , payload = [ 00 00 00 00 21 00 00 00 ]
        , address = 0xebf693bc        }
DataRS  { tag     = 0x000000
        , payload = [ 00 00 00 00 21 00 00 00 ]
        , address = 0xebf693d4        }
DataRS  { tag     = 0x000000
        , payload = [ 00 00 00 00 21 00 00 00 ]
        , address = 0xebf693dc        }
Last edited 8 years ago by tomberek (previous) (diff)

comment:4 Changed 8 years ago by erikd

There's actually no need for a specialized dumpDataRS function because dumpObj is already polymorphic and the underlying C function _dumpObj already switches on the object tag, allowing it to dump any of the existing DDC runtime objects.

Also while what you have does indeed prove that we need to fix this, printing the address of the object is not something that would be useful for a test suite program because different runs of the program on different machines is likely to result in different addresses.

A better way to make this testable would be to function:

   objectAddr :: a -> Addr#

and then check the addresses of two True (or whatever) objects for equality using the function in Data.Numeric.Addr like.

    a = True
    b = True
    when (not $ primAddrU_eq (objectAddr a) (objectAddr b))
      $ error "Object addresses not equal"

Since this test doesn't rely on anything being at a specific address, it will be portable across different word sizes and OSes.

I would normally suggest that the objectAddr function should go in library/Foreign/Ptr.ds but since I can't see any use for this other than debugging maybe it should go in library/DDC/Runtime/Debug.ds.

Last edited 8 years ago by erikd (previous) (diff)

comment:5 Changed 8 years ago by tomberek

Found a function in DDC.Runtime.Store called peekDataR_payload which seems to have the a -> Addr# type (although I'm unsure about the R/RS difference).

Using peekDataR_payload I find that these two are shared:

x = True
z = x

while these are not:

x = True
y = True

comment:6 Changed 8 years ago by erikd

The first is expected and correct behavior.

The second is not surprising and while it is semantically correct, is sub-optimal because if we want to compare x and y for equality and they have the same pointer value, then that is all that's required to ensure equality. If they have different pointers, then the values pointed to by the pointers needs to be compared.

As for peekDataR_payload that is a reasonable analogue to the the address of the object itself.

comment:7 Changed 8 years ago by benl

A slight caveat with this is that you can only share values that are guaranteed to be constant. A value of type Bool %r can be shared if there is also a Const %r constraint, but not otherwise.

comment:8 Changed 8 years ago by benl

The way to fix this would be to define some static objects in the runtime system, import them through the libraries, and then add a new Core phase to rewrite True and False constructors to use these names.

In GHC they also share characters and small integer values (in the range [0..255]). You could define an top-level array of values that is initialised at runtime startup, then rewrite literals in the core program to use values from this array.

comment:9 Changed 7 years ago by benl

  • Milestone 0.1.4 deleted

Milestone 0.1.4 deleted

comment:10 Changed 7 years ago by benl

  • Milestone set to 0.3.0
  • Summary changed from Ensure we're sharing constant values of enumeration type. to Constant enumeration values are not being shared.

comment:11 Changed 7 years ago by benl

  • Type changed from newbie to defect

comment:12 Changed 7 years ago by benl

We could handle this with rewrite rules once we have multi-module compilation. Rewrite applications of the N# etc data constructor to point to CAFs in a global 'Constants' module.

comment:13 Changed 7 years ago by benl

  • Milestone changed from 0.3.0 to 0.4.0

comment:14 Changed 5 years ago by benl

  • Milestone 0.4.0 deleted

comment:15 Changed 5 years ago by benl

  • Version set to 0.1.2

comment:16 Changed 2 years ago by benl

  • Cc tomberek@… removed
  • Summary changed from Constant enumeration values are not being shared. to Share constant enumeration values.
  • Type changed from defect to enhancement

comment:17 Changed 17 months ago by benl

  • Type changed from enhancement to feature
Note: See TracTickets for help on using tickets.