From 265003df1a6418f37ba21116c46d0a3fbfb1d9cc Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 10 Aug 2018 01:20:14 +0200 Subject: [PATCH] deprecated regionized pointers --- changelog.md | 3 ++ compiler/semtypes.nim | 2 + doc/manual.rst | 62 ----------------------------- lib/pure/concurrency/threadpool.nim | 6 +-- tests/parallel/tptr_to_ref.nim | 4 +- 5 files changed, 9 insertions(+), 68 deletions(-) diff --git a/changelog.md b/changelog.md index 426b63b7ef..a77c576319 100644 --- a/changelog.md +++ b/changelog.md @@ -173,6 +173,9 @@ - The ``{.this.}`` pragma has been deprecated. It never worked within generics and we found the resulting code harder to read than the more explicit ``obj.field`` syntax. +- "Memory regions" for pointer types have been deprecated, they were hardly used + anywhere. Note that this has **nothing** to do with the ``--gc:regions`` switch + of managing memory. ### Tool changes diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 972c8c709b..99f2cf20da 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -193,6 +193,8 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType = if region.skipTypes({tyGenericInst, tyAlias, tySink}).kind notin { tyError, tyObject}: message c.config, n[i].info, errGenerated, "region needs to be an object type" + else: + message(c.config, n.info, warnDeprecated, "region for pointer types") addSonSkipIntLit(result, region) addSonSkipIntLit(result, t) if tfPartial in result.flags: diff --git a/doc/manual.rst b/doc/manual.rst index 460468fe5b..7aeec73906 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -1507,68 +1507,6 @@ non nilable pointers. The details of this analysis are still to be specified here. -Memory regions --------------- - -The types ``ref`` and ``ptr`` can get an optional ``region`` annotation. -A region has to be an object type. - -Regions are very useful to separate user space and kernel memory in the -development of OS kernels: - -.. code-block:: nim - type - Kernel = object - Userspace = object - - var a: Kernel ptr Stat - var b: Userspace ptr Stat - - # the following does not compile as the pointer types are incompatible: - a = b - -As the example shows ``ptr`` can also be used as a binary -operator, ``region ptr T`` is a shortcut for ``ptr[region, T]``. - -In order to make generic code easier to write ``ptr T`` is a subtype -of ``ptr[R, T]`` for any ``R``. - -Furthermore the subtype relation of the region object types is lifted to -the pointer types: If ``A <: B`` then ``ptr[A, T] <: ptr[B, T]``. This can be -used to model subregions of memory. As a special typing rule ``ptr[R, T]`` is -not compatible to ``pointer`` to prevent the following from compiling: - -.. code-block:: nim - # from system - proc dealloc(p: pointer) - - # wrap some scripting language - type - PythonsHeap = object - PyObjectHeader = object - rc: int - typ: pointer - PyObject = ptr[PythonsHeap, PyObjectHeader] - - proc createPyObject(): PyObject {.importc: "...".} - proc destroyPyObject(x: PyObject) {.importc: "...".} - - var foo = createPyObject() - # type error here, how convenient: - dealloc(foo) - - -Future directions: - -* Memory regions might become available for ``string`` and ``seq`` too. -* Builtin regions like ``private``, ``global`` and ``local`` might be - useful for an OpenCL target. -* Builtin "regions" can model ``lent`` and ``unique`` pointers. -* An assignment operator can be attached to a region so that proper write - barriers can be generated. This would imply that the GC can be implemented - completely in user-space. - - Procedural type --------------- A procedural type is internally a pointer to a procedure. ``nil`` is diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index 6ec71e912c..826e42b6c6 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -89,8 +89,6 @@ proc closeBarrier(b: ptr Barrier) {.compilerProc.} = # ---------------------------------------------------------------------------- type - foreign* = object ## a region that indicates the pointer comes from a - ## foreign thread heap. AwaitInfo = object cv: Semaphore idx: int @@ -231,10 +229,10 @@ proc awaitAndThen*[T](fv: FlowVar[T]; action: proc (x: T) {.closure.}) = action(fv.blob) finished(fv) -proc unsafeRead*[T](fv: FlowVar[ref T]): foreign ptr T = +proc unsafeRead*[T](fv: FlowVar[ref T]): ptr T = ## blocks until the value is available and then returns this value. await(fv) - result = cast[foreign ptr T](fv.data) + result = cast[ptr T](fv.data) proc `^`*[T](fv: FlowVar[ref T]): ref T = ## blocks until the value is available and then returns this value. diff --git a/tests/parallel/tptr_to_ref.nim b/tests/parallel/tptr_to_ref.nim index fee210dcd0..ae02c16e5c 100644 --- a/tests/parallel/tptr_to_ref.nim +++ b/tests/parallel/tptr_to_ref.nim @@ -11,7 +11,7 @@ type Killer* = object lock: Lock bailed {.guard: lock.}: bool - processes {.guard: lock.}: array[0..MAX_WORKERS-1, foreign ptr Process] + processes {.guard: lock.}: array[0..MAX_WORKERS-1, ptr Process] # Hold a lock for a statement. template hold(lock: Lock, body: untyped) = @@ -32,7 +32,7 @@ proc initKiller*(): Killer = var killer = initKiller() # remember that a process has been launched, killing it if we have bailed. -proc launched*(process: foreign ptr Process): int {.gcsafe.} = +proc launched*(process: ptr Process): int {.gcsafe.} = result = killer.processes.high + 1 killer.lock.hold: if killer.bailed: