Commit 6f4a7fbb authored by Kunshan Wang's avatar Kunshan Wang

Defined memory operations in one place. Added concrete description of

memory accesses via pointers.
parent 73baed17
...@@ -2029,7 +2029,7 @@ loc ...@@ -2029,7 +2029,7 @@ loc
excClause excClause
*exception clause*: Used to handle NULL reference errors. *exception clause*: Used to handle NULL reference errors.
return value return value
Type is the strong variant of *T*: The value loaded from *loc* Type is the strong variant of *T*: The result of the load operation.
+------+------+------+-----+------+-----------+ +------+------+------+-----+------+-----------+
| opct | opct | opct | idt | idt | excClause | | opct | opct | opct | idt | idt | excClause |
...@@ -2037,11 +2037,10 @@ return value ...@@ -2037,11 +2037,10 @@ return value
| 0x1A | PTR | ord | T | loc | excClause | | 0x1A | PTR | ord | T | loc | excClause |
+------+------+------+-----+------+-----------+ +------+------+------+-----+------+-----------+
The ``LOAD`` instruction loads from the memory location/address *loc*. The ``LOAD`` instruction performs a *load* operation with argument (*ord*, *T*,
*loc*) as defined in `Mu and the Memory <uvm-memory>`__.
*ord* is the memory order. In the text form, the *ord* can be omitted and In the text form, *ord* can be omitted and defaults to ``NOT_ATOMIC``.
defaults to ``NOT_ATOMIC``. The instruction is atomic if *ord* is not
``NOT_ATOMIC``.
For LLVM users: This is the counterpart of the ``load`` instruction. For LLVM users: This is the counterpart of the ``load`` instruction.
``volatile`` is absent in Mu because memory accesses are part of the ``volatile`` is absent in Mu because memory accesses are part of the
...@@ -2084,12 +2083,10 @@ newVal ...@@ -2084,12 +2083,10 @@ newVal
| 0x1B | PTR | ord | T | loc | newVal | excClause | | 0x1B | PTR | ord | T | loc | newVal | excClause |
+------+------+------+-----+------+--------+-----------+ +------+------+------+-----+------+--------+-----------+
The ``STORE`` instruction stores *newVal* into the memory location/address The ``STORE`` instruction performs a *store* operation with argument (*ord*,
*loc*. *T*, *loc*, *newVal*) as defined in `Mu and the Memory <uvm-memory>`__.
*ord* is the memory order. In the text form, the *ord* can be omitted and In the text form, *ord* can be omitted and defaults to ``NOT_ATOMIC``.
defaults to ``NOT_ATOMIC``. The instruction is atomic if *ord* is not
``NOT_ATOMIC``.
For LLVM users: This is the counterpart of the ``store`` instruction. For LLVM users: This is the counterpart of the ``store`` instruction.
``volatile`` is absent. ``volatile`` is absent.
...@@ -2109,14 +2106,14 @@ defaults to ``NOT_ATOMIC``. The instruction is atomic if *ord* is not ...@@ -2109,14 +2106,14 @@ defaults to ``NOT_ATOMIC``. The instruction is atomic if *ord* is not
``CMPXCHG`` Instruction ``CMPXCHG`` Instruction
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
``CMPXCHG`` ``PTR`` :sub:`opt` ``WEAK`` :sub:`opt` *succOrd* *failOrd* ``<`` *T* ``CMPXCHG`` ``PTR`` :sub:`opt` ``WEAK`` :sub:`opt` *ordSucc* *ordFail* ``<`` *T*
``>`` *loc* *expected* *desired* *excClause* ``>`` *loc* *expected* *desired* *excClause*
``PTR`` :sub:`opt` ``PTR`` :sub:`opt`
If present, *loc* is a pointer. Otherwise it is an internal reference. If present, *loc* is a pointer. Otherwise it is an internal reference.
``WEAK`` :sub:`opt` ``WEAK`` :sub:`opt`
If present, the ``CMPXCHG`` operation is weak. If present, the ``CMPXCHG`` operation is weak.
succOrd, failOrd ordSucc, ordFail
*memory order*: The memory order for success and failure, respectively. *memory order*: The memory order for success and failure, respectively.
T T
*type*, must be EQ-comparable: The referent type of *loc*. *type*, must be EQ-comparable: The referent type of *loc*.
...@@ -2133,35 +2130,22 @@ excClause ...@@ -2133,35 +2130,22 @@ excClause
*exception clause*: Used to handle NULL reference errors. *exception clause*: Used to handle NULL reference errors.
return value: return value:
Type is ``struct<U int<1>>`` where *U* is the strong variant of *T*: Type is ``struct<U int<1>>`` where *U* is the strong variant of *T*:
A pair of the original value in the memory and whether this operation is The result of the compare exchange operation.
successful.
+------+------+------+---------+---------+-----+------+----------+---------+-----------+ +------+------+------+---------+---------+-----+------+----------+---------+-----------+
| opct | opct | opct | opct | opct | idt | idt | idt | idt | excClause | | opct | opct | opct | opct | opct | idt | idt | idt | idt | excClause |
+======+======+======+=========+=========+=====+======+==========+=========+===========+ +======+======+======+=========+=========+=====+======+==========+=========+===========+
| 0x1C | PTR | WEAK | succOrd | failOrd | T | loc | expected | desired | excClause | | 0x1C | PTR | WEAK | ordSucc | ordFail | T | loc | expected | desired | excClause |
+------+------+------+---------+---------+-----+------+----------+---------+-----------+ +------+------+------+---------+---------+-----+------+----------+---------+-----------+
``CMPXCHG`` loads the value from memory location/address *loc* and compare it The ``CMPXCHG`` instruction performs a *compare exchange* operation with
with the *expected* value. If the comparison succeeds, then store the *desired* argument (*isWeak*, *ordSucc*, *ordFail*, *T*, *loc*, *expected*, *desired*),
value to *loc*. If fails, no store operation will happen. The whole process where *isWeak* is true if ``WEAK`` is present, otherwise false. The operation
happens atomically. is defined in `Mu and the Memory <uvm-memory>`__.
A ``CMPXCHG`` instruction can be **strong** or **weak**. In the text form, it is The result is a struct. The two fields represents the *v* and *s* value as
weak if the flag ``WEAK`` is present, otherwise it is strong. In the binary defined in `Mu and the Memory <uvm-memory>`__. The second field is 1 for true
form, it is weak if the field *weak* is 1 and it is strong if *weak* is 0. and 0 for false.
If the instruction is strong, The comparison succeeds **if and only if** the
loaded value equals the *expected* value. If it is weak, the comparison succeeds
**only if** the loaded value equals the *expected* value and it may spuriously
fail, that is, it may fail even if the loaded value equals the *expected* value.
The return value of this instruction is a struct of two fields: The first field
is the value loaded from the memory. The second field is 1 if the comparison is
successful, or 0 otherwise.
The memory order of this instruction is *succOrd* if the comparison succeeds, or
*failOrd* otherwise.
For LLVM users: This is the counterpart of the ``cmpxchg`` instruction. For LLVM users: This is the counterpart of the ``cmpxchg`` instruction.
...@@ -2224,7 +2208,8 @@ opnd ...@@ -2224,7 +2208,8 @@ opnd
excClause excClause
*exception clause*: Used to handle NULL reference errors. *exception clause*: Used to handle NULL reference errors.
return value return value
Type is the strong variant of *T*: The original value in the memory. Type is the strong variant of *T*: The result of the atomic-x operation
where x is *op*.
+------+------+------+------+-----+------+------+-----------+ +------+------+------+------+-----+------+------+-----------+
| opct | opct | opct | opct | idt | idt | idt | excClause | | opct | opct | opct | opct | idt | idt | idt | excClause |
...@@ -2250,45 +2235,9 @@ UMAX 0x09 int unsigned max ...@@ -2250,45 +2235,9 @@ UMAX 0x09 int unsigned max
UMIN 0x0A int unsigned min UMIN 0x0A int unsigned min
=========== ====== === ============= =========== ====== === =============
The ``ATOMICRMW`` loads the value from memory location/address *loc*, perform an The ``ATOMICRMW`` instruction performs an *atomic-x* operation with argument
operation *op* with the loaded value as the left-hand-side operand and *opnd* as (*ord*, *T*, *loc*, *opnd*), where the *x* in *atomic-x* is *op*. The operation
the right-hand-side operand and store the result back to the memory is defined in `Mu and the Memory <uvm-memory>`__.
location/address *loc*. The whole process happen atomically.
All operators other than ``XCHG`` are only applicable for integer types.
``XCHG`` is allowed for any type. However, a Mu implementation may only
implement some combinations of operators and operand types according to the
requirements specified in `<portability>`__
The results of the operations are: (NOTE: the result of the operation is not the
return value of this instruction)
XCHG
The value of *opnd*.
ADD
The sum of the two operands.
SUB
The difference of the two operands.
AND
The bitwise AND of the two operands.
NAND
The bitwise NOT of the bitwise AND of the two operands.
OR
The bitwise inclusive OR of the two operands.
XOR
The bitwise exclusive OR of the two operands.
MAX
The maximum value of the two operands, considering both operand as signed.
MIN
The minimum value of the two operands, considering both operand as signed.
UMAX
The maximum value of the two operands, considering both operand as unsigned.
UMIN
The minimum value of the two operands, considering both operand as unsigned.
..
NOTE: In the C syntax, the semantic of NAND is ``~(op1 & op2)``.
.. ..
...@@ -2317,11 +2266,9 @@ ord ...@@ -2317,11 +2266,9 @@ ord
| 0x1E | ord | | 0x1E | ord |
+------+------+ +------+------+
The ``FENCE`` is used to introduce happen-before edges between operations. Its The ``FENCE`` is a fence of memory order *ord*. Its
semantic is specified in `<memory-model>`__. semantic is specified in `<memory-model>`__.
*ord* is the memory order of the fence.
For LLVM users: This is the counterpart of the ``fence`` instruction. For LLVM users: This is the counterpart of the ``fence`` instruction.
.. ..
......
...@@ -115,8 +115,9 @@ store ...@@ -115,8 +115,9 @@ store
A memory store. May be atomic or not. A memory store. May be atomic or not.
atomic read-modify-write atomic read-modify-write
A load and (maybe conditionally) a store as one atomic action. It has both a A load and (maybe conditionally) a store as one atomic action. It may
load and a store operation, but may have special atomic properties. contain both a load and a store operation, but may have special atomic
properties.
fence fence
A fence introduces memory orders. A fence introduces memory orders.
......
...@@ -122,48 +122,18 @@ Only a subset of types can be used as the type parameter of the ``ptr`` and the ...@@ -122,48 +122,18 @@ Only a subset of types can be used as the type parameter of the ``ptr`` and the
native-safe if all of their type arguments *T1*, *T2*, ..., *T*, *F*, *V* are native-safe if all of their type arguments *T1*, *T2*, ..., *T*, *F*, *V* are
native-safe. native-safe.
* ``ptr<T>`` is native-safe. It requires T to be native-safe. * ``ptr<T>`` is always native-safe. It requires T to be native-safe.
* ``funcptr<sig>`` is native-safe. It requires the return type and all parameter * ``funcptr<sig>`` is always native-safe. It requires the return type and all
types of *sig* to be native-safe. parameter types of *sig* to be native-safe.
* All other types are not native-safe. Specifically, they are ``ref``, ``iref``, * All other types are not native-safe. Specifically, they are ``ref``, ``iref``,
``weakref``, ``func``, ``thread``, ``stack``. ``weakref``, ``func``, ``thread``, ``stack`` as well as ``struct``, ``array``
or ``hybrid`` that contains them.
Exposing Mu Memory to the Native World Exposing Mu Memory to the Native World
====================================== ======================================
Memory Layout
-------------
The bytes in the address space can be interpreted as Mu values in an
implementation-dependent way. The bytes that represents a Mu value is the
**bytes representation** of that Mu value.
A memory location (in the Mu memory) can be **pinned**. In this state, it is
mapped to a contiguous region of bytes in the address space which contains the
bytes representation of the value the memory location holds. The beginning of
the memory location is mapped to the lowest address of the region. Different
components of a memory location which do not contain each other do not map to
overlapping regions in the address space.
For C programmers:
* Mu assumes 8-bit bytes.
* Mu does not have the bit-field type, but a client can implement bit-fields
using integer types and bit operations.
* Mu does not have union types. However, like C, directly casting an address
to a pointer has implementation-defined behaviours. If a Mu program
interfaces with native programs, it has to also depend on the platform.
* Unlike C, Mu operations work on SSA variables rather than memory locations
(the counterpart of objects in C).
* Mu forces the 2's complement representation, though the byte order and
alignment requirement are implementation-defined.
Pinning Pinning
------- -------
...@@ -190,22 +160,6 @@ his multi-set. A memory location is pinned as long as there is at least one ...@@ -190,22 +160,6 @@ his multi-set. A memory location is pinned as long as there is at least one
implemented as a thread-local buffer. In this case, if GC never happens, no implemented as a thread-local buffer. In this case, if GC never happens, no
expensive atomic memory access or inter-thread synchronisation is performed. expensive atomic memory access or inter-thread synchronisation is performed.
Memory Access and Memory Model
------------------------------
TODO:
* How does the atomic/non-atomic load/store/atomicrmw operations to the
bytes in the address space relate to the atomic/non-atomic
load/store/atomicrmw operations described in the Mu memory model? How does
the modification of bytes affect the values?
* How to model the modification of bytes that spans over more than one
memory location (in the Mu memory's sense)?
* And the attempt to look into the bytes representation of references must
be forbidden.
Calling between Mu and Native Functions Calling between Mu and Native Functions
======================================= =======================================
......
...@@ -852,9 +852,8 @@ The ``load`` message ...@@ -852,9 +852,8 @@ The ``load`` message
- return value: A handle of the loaded value. - return value: A handle of the loaded value.
The ``load`` message loads from the memory location/address of ``loc``. The ``load`` message performs a load operation with arguments (*ord*, *T*,
*loc*) where *T* is the referent type of *loc*.
This operation has the memory order ``ord``.
For JNI users: This is similar to the ``Get<type>Field`` routine. For JNI users: This is similar to the ``Get<type>Field`` routine.
...@@ -879,9 +878,8 @@ The ``store`` message ...@@ -879,9 +878,8 @@ The ``store`` message
``newval`` must have the unmarked type of the referent type of ``loc``. ``newval`` must have the unmarked type of the referent type of ``loc``.
The ``store`` message stores ``newval`` into the memory location/address of ``loc``. The ``store`` message performs a *store* operation with argument (*ord*,
*T*, *loc*, *newval*) where *T* is the referent type of *loc*.
This operation has the memory order ``ord``.
For JNI users: This is similar to the ``Set<type>Field`` routine. For JNI users: This is similar to the ``Set<type>Field`` routine.
...@@ -914,17 +912,11 @@ The ``cmpxchg`` message ...@@ -914,17 +912,11 @@ The ``cmpxchg`` message
``expected`` and ``desired`` must have the unmarked type of the referent type of ``expected`` and ``desired`` must have the unmarked type of the referent type of
``loc``. ``loc``.
The ``cmpxchg`` message loads form ``loc`` and compare with ``expected``. If The ``cmpxchg`` message performs a *compare exchange* operation with
successful, then store ``desired`` to ``loc``, otherwise do nothing. In both argument (*weak*, *ord_sicc*, *ord_fail*, *T*, *loc*, *expected*, *desired*),
cases, the old value ``oldval`` at memory location/address ``loc`` is returned. This where *T* is the referent type of *loc*.
whole process happen atomically.
If this operation is strong, The comparison is successful if and only if the ..
loaded value equals ``expected``. If weak, it may spuriously fail even if they
are equal.
This operation has the memory order ``ord_succ`` when successful and
``ord_fail`` when failed.
Example in Java:: Example in Java::
...@@ -958,14 +950,9 @@ The ``atomicrmw`` message ...@@ -958,14 +950,9 @@ The ``atomicrmw`` message
``opnd`` must have the unmarked type of the referent type of ``loc``. ``opnd`` must have the unmarked type of the referent type of ``loc``.
The ``atomicrmw`` message performs a binary operation ``op`` on the current The ``atomicrmw`` message performs an *atomic-x* operation with argument (*ord*,
value in ``loc`` as the left-hand-side and ``opnd`` as the right-hand-side and *T*, *loc*, *opnd*), where *T* is the referent type of *loc*, and the *x* in
stores the result to ``loc``. The whole process happen atomically. *atomic-x* is *op*.
``op`` is one operation defined in the ``ATOMICRMW`` instruction. (See
`<instruction-set>`__)
This operation has the memory order ``ord``.
Example Java signature: ``Handle ClientAgent.atomicrmw(MemoryOrder ord, AtomicRMWOp op, Handle loc, Handle opnd)`` Example Java signature: ``Handle ClientAgent.atomicrmw(MemoryOrder ord, AtomicRMWOp op, Handle loc, Handle opnd)``
...@@ -982,9 +969,7 @@ The ``fence`` message ...@@ -982,9 +969,7 @@ The ``fence`` message
- return value: None - return value: None
The ``fence`` is a memory fence. The ``fence`` is a memory fence of memory order ``ord``.
This operation has the memory order ``ord``.
Example Java signature: ``void ClientAgent.fence(MemoryOrder ord)`` Example Java signature: ``void ClientAgent.fence(MemoryOrder ord)``
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment