Commit f66a9265 authored by Kunshan Wang's avatar Kunshan Wang

Fixed inconsistencies introducing by the C-based API.

parent 4d77a0e8
......@@ -17,21 +17,15 @@ Main specification:
- `Threads and Stacks <threads-stacks>`__
- `Memory and Garbage Collection <uvm-memory>`__
- `Memory Model <memory-model>`__
- `Portability and Implementation Advices <portability>`__
- `Native Interface <native-interface>`__
- `Heap Allocation and Initialisation Language (HAIL) <hail>`__
- `Portability and Implementation Advices <portability>`__
Platform-specific parts: These extends the main specification. The main
specification considers these parts as implementation-specific.
- `AMD64 Unix Native Interface <native-interface-x64-unix>`__
Working in progress:
(If there is any documents too experimental to be put into the content, it will
be listed here.)
- `Heap Allocation and Initialisation Language (HAIL) <hail>`__
Old documents:
- `Client Interface (old) <uvm-client-interface-old>`__
......
......@@ -39,12 +39,18 @@ instructions or changing the grammar.
Common instructions are not Mu functions and cannot be called by the
``CALL`` instruction, nor can it be directly used from the high-level
language that the client implements. The Mu client must understand common
instructions because it is the only source of IR code of Mu. For
special high-level language functions that cannot be directly implemented in
the high-level programming language, like the methods in the
``java.lang.Thread`` class, the client must translate those things that are
special in the high-level language to appropriate Mu IR code, which may or
may not involve common instructions.
instructions because it is the only source of IR code of Mu. That is to say,
*there is no way any higher-level program can express anything which Mu
knows but the client does not*. For special high-level language functions
that cannot be directly implemented in the high-level programming language,
like the methods in the ``java.lang.Thread`` class, the client must
implement those special high-level language functions in "ordinary" Mu IR
code, which may or may not involve common instructions. For example,
creating a thread is a "magic" in Java, but it is not more special than
executing an instruction (``@uvm.new_thread``) in Mu. Some Java libraries
require Mu to make a ``CCALL`` to some C functions which are provided by the
JVM, and they slip under the level of Mu. But Mu and the client always know
the fact that "it call C function" and it is not magic.
This document uses the following notation:
......@@ -115,22 +121,23 @@ Construct a ``tagref64`` value from an object reference ``%ref`` and a tag
- ``[0x217]@uvm.tr64.to_fp (%tr: tagref64) -> double``
Extract the floating point value from ``%tr``, assuming ``%tr`` contains a
floating point value.
floating point value. It has undefined behaviour if the assumption is wrong.
- ``[0x218]@uvm.tr64.to_int (%tr: tagref64) -> int<52>``
Extract the integer value from ``%tr``, assuming ``%tr`` contains an integer
value.
value. It has undefined behaviour if the assumption is wrong.
- ``[0x219]@uvm.tr64.to_ref (%tr: tagref64) -> ref<void>``
Extract the object reference from ``%tr``, assuming ``%tr`` contains reference
value.
value. It has undefined behaviour if the assumption is wrong.
- ``[0x21a]@uvm.tr64.to_ref (%tr: tagref64) -> int<6>``
Extract the ``int<6>`` tag accompanying the object reference from ``%tr``,
assuming ``%tr`` contains reference value.
assuming ``%tr`` contains reference value. It has undefined behaviour if the
assumption is wrong.
Math Instructions
=================
......@@ -143,6 +150,10 @@ Math Instructions
2. Floating point math functions. Example: trigonometric functions, testing
NaN, fused multiply-add, ...
It requires some work to decide a complete list of such functions. To work
around the limitations for now, please call native functions in libc or
libm using ``CCALL``.
Futex Instructions
==================
......@@ -352,7 +363,8 @@ arguments after ``%func``. Each will be an argument to ``%func``. Their types
must match the argument types of ``%func``.
The function's return type must match the expected return type of the previous
frame.
frame. If the previous frame is a native frame, the new function must have the
same return type as the previous Mu callee.
``%stack`` and ``%func`` must not be ``NULL``.
......
......@@ -22,7 +22,7 @@ via pointers, bypassing the handle-based API.
A **HAIL script** has a text format and a binary format. The text format is
similar to the text-based Mu IR, and the binary format is similar to the binary
form Mu IR
form Mu IR.
Lexical Structures
==================
......
This diff is collapsed.
......@@ -59,7 +59,7 @@ necessary and whether the ``relaxed`` order in C11 or the ``monotonic`` in LLVM
is suitable for Java is not yet known.
In LLVM, an atomic operation can be labelled ``singlethread``, in which case it
only synchronises with or participates in modification and seq_cst total
only synchronises with or participates in modification and ``seq_cst`` total
orderings with other operations running in the same thread (for example, in
signal handlers). C11 provides ``atomic_signal_fence`` for similar purposes.
......@@ -67,41 +67,41 @@ Concepts
========
data value
See `<type-system>`__
See `Type System <type-system>`__
SSA variable, instruction and evaluation
See `<instruction-set>`__
See `Instruction Set <instruction-set>`__
memory, initial value, load, store, access and conflict
See `<uvm-memory>`__
See `Mu and the Memory <uvm-memory>`__
thread
A thread is the unit of CPU scheduling. In this memory model, threads
include but are not limited to Mu threads. See `<threads-stacks>`__ for the
include but are not limited to Mu threads. See `Threads and Stacks <threads-stacks>`__ for the
definition of Mu threads.
stack, stack binding, stack unbinding, swap-stack
See `<threads-stacks>`__
See `Threads and Stacks <threads-stacks>`__
futex, futex_wait, futex_wake
See `<threads-stacks>`__
See `Threads and Stacks <threads-stacks>`__
Comparison of Terminology
-------------------------
The following table is a approximate comparison and may not strictly apply.
=================== ============================
=================== ================================
C Mu
=================== ============================
=================== ================================
value data value
expression SSA variable
object memory location
memory location (N/A)
memory location memory location of scalar type
(N/A) object
read load
modify store
=================== ============================
=================== ================================
Operations
==========
......@@ -147,18 +147,18 @@ external operation
Memory Operations
=================
Some instructions and API messages perform memory operations. Specifically,
Some instructions and API functions perform memory operations. Specifically,
- The ``LOAD`` instruction and the ``load`` API message perform a load
- The ``LOAD`` instruction and the ``load`` API function perform a load
operation.
- The ``STORE`` instruction and the ``store`` API message perform a store
- The ``STORE`` instruction and the ``store`` API function perform a store
operation.
- The ``CMPXCHG`` instruction and the ``cmpxchg`` API message perform a
- The ``CMPXCHG`` instruction and the ``cmpxchg`` API function perform a
compare-exchange operation, which is a kind of atomic read-modify-write
operation.
- The ``ATOMICRMW`` instruction and the ``atomicrmw`` API message perform an
- The ``ATOMICRMW`` instruction and the ``atomicrmw`` API function perform an
atomic read-modify-write operation.
- The ``FENCE`` instruction and the ``fence`` API message are a fence.
- The ``FENCE`` instruction and the ``fence`` API function are a fence.
- A concrete implementation may have other ways to perform those instructions.
..
......@@ -304,14 +304,15 @@ An evaluation A **synchronises with** another evaluation B if:
..
NOTE: A thread can be created by the ``@uvm.new_thread`` common instruction
or the ``new_thread`` API message.
or the ``new_thread`` API function.
NOTE: Since there is no explicit heap memory management in Mu, the
"synchronises with" relation in C involving ``free`` and ``realloc`` does
not apply in Mu.
NOTE: Mu only provides very primitive threading support. The "synchronises
with" relations involving ``call_once`` and ``thrd_join`` are not in Mu.
with" relations involving ``call_once`` and ``thrd_join`` are not in the
memory model, but can be implemented on a higher level.
NOTE: The "synchronises with" relation between the futex wake and wait is
necessary to ensure the visibility of values written by one thread to be
......
......@@ -4,6 +4,19 @@ Native Interface
This chapter defines the Mu native interface.
NOTE: The term **foreign function interface** may have been used in many
other places by experienced VM engineers to mean a heavy-weighted complex
interface with another language. JikesRVM users use **foreign function
interface** to refer to JNI and use **syscall** to refer to a light-weight
unsafe mechanism to call arbitrary C functions with minimal overhead.
The ``CCALL`` instruction is more similar to the latter. It has minimum
overhead, but provides no protection to malicious code. So it must be used
with care.
To reduce confusion, we use the term **unsafe native interface** or just
**native interface** instead of *foreign function interface*.
The **native interface** is a *light-weight* *unsafe* interface through which
*Mu IR programs* communicate with *native programs*.
......@@ -79,7 +92,9 @@ This interface has several aspects:
Raw Memory Access
=================
This section defines mechanisms for raw memory access.
This section defines mechanisms for raw memory access. *Pointers* give Mu
programs access to the native (raw) memory, while *pinning* gives native
programs access to the Mu memory.
Pointers
--------
......@@ -107,9 +122,6 @@ address. Type checking is not performed.
segments + offsets. However, apparently the trend is to move to a "flat"
memory space.
Exposing Mu Memory to the Native World
======================================
Pinning
-------
......@@ -139,7 +151,32 @@ his multi-set. A memory location is pinned as long as there is at least one
Calling between Mu and Native Functions
=======================================
Mu Functions calling Native functions
Calling Conventions
-------------------
The calling conventions involving native programs are platform-dependent and
implementation-dependent. It should be defined by platform-specific binary
interfaces (ABI) as supplements to this Mu specification. Mu implementations
should advertise what ABI it implements.
Calling conventions are identified by flags (``#XXXXXX``) in the IR. Mu defines
the flag ``#DEFAULT`` and its numerical value 0x00 for the default calling
convention of platforms. This flag is always available. Other calling
conventions can be defined by implementations.
The calling convention determines the type of value that are callable by the
``CCALL`` instruction (described below), and the type of the exposed value for
Mu functions (described below). The type is usually a ``ufuncptr<sig>`` for C
functions, which are called via their addresses. Other examples are:
* If it is desired to make system calls directly from Mu, then the type can be
an integer, i.e. the system call number.
* If it is something like `a SWAP-STACK operation implemented as a calling
convention <http://dl.acm.org/citation.cfm?id=2400695>`__, then the callee can
be a stack pointer in the form of ``uptr<void>``.
Mu Functions Calling Native Functions
-------------------------------------
The ``CCALL`` instruction calls a native function. Determined by calling
......@@ -147,7 +184,7 @@ conventions, the native function may be represented in different ways, and the
arguments are passed in different ways. The return value of the call will be the
return value of the ``CCALL`` instruction, which is a Mu SSA variable.
Native Functions calling Mu Functions
Native Functions Calling Mu Functions
-------------------------------------
A Mu function can be **exposed** as a native function pointer in three ways:
......@@ -160,7 +197,7 @@ A Mu function can be **exposed** as a native function pointer in three ways:
function, and the ``@uvm.native.unexpose`` common instruction deletes the
exposed value.
3. Dynamically, the ``expose`` and ``unexpose`` API messages do the same thing
3. Dynamically, the ``expose`` and ``unexpose`` API function do the same thing
as the above instructions.
A "cookie", which is a 64-bit integer value, can be attached to each exposed
......@@ -252,8 +289,8 @@ behaviours.
NOTE: Similar to native frames, Mu programs may have even more necessary
clean-up operations, such as GC barriers.
Changes in the Mu IR and the API
================================
Changes in the Mu IR and the API introduced by the native interface
===================================================================
**New types**:
......@@ -312,7 +349,7 @@ example:
See `Instruction Set <instruction-set>`__.
**New API messages**:
**New API functions**:
* ``ptrcast``
* ``pin``
......@@ -320,24 +357,14 @@ See `Instruction Set <instruction-set>`__.
* ``expose``
* ``unexpose``
**Modified API messages**:
The following messages: ``get_field_iref``, ``get_elem_iref``, ``shift_iref``,
``get_fixed_part_iref``, ``get_var_part_iref``, ``load``, ``store``, ``cmpxchg``
and ``atomicrmw`` work for both ``uptr<T>`` and ``iref<T>`` operands. No
changes to the parameters are required. The return values for memory addressing
messages are ``uptr<U>`` rather than ``iref<U>`` for some type U.
TODO: Currently the API assumes each handle has an attached type, and does
not require the client to supply the types for handles when using them. Is
the micro VM doing too much for the client? But I think the type information
always has to be maintained by the micro VM.
**Modified API functions**:
The ``current_func_ver`` message, in addition to returning the function version
The ``cur_func_ver`` function, in addition to returning the function version
ID, it may also return 0 if the selected frame is a native frame. (Multiple
native frames are counted as one between two Mu frames.)
The ``pop_frame`` message may pop native frames.
The ``pop_frame`` function has implementation-defined behaviours when popping
native frames.
During OSR, if the top frame is a native frame, the state of the stack is
``READY<T>`` where *T* is the return type of the previous frame on top of the
......
......@@ -183,6 +183,23 @@ replacement (i.e. OSR. Discussed later.)
See `Client Interface <uvm-client-interface>`__ for more details.
Unsafe Native Interface
-----------------------
The (unsafe) native interface is designed to directly interact with native
programs. It gives Mu program direct access to the memory via pointers, and
allows pinning Mu objects so that they can be accessed by native programs. It
also allows Mu to call a native (usually C) function directly, and allows native
programs to call back to selected Mu functions. (The .NET CLR takes similar
approach, i.e. giving the high-level program "unsafe" access to the lower
level.)
This interface is different from the client API. The main purpose is to
implement the system-interfacing part of the high-level language, such as the IO
and the networking library.
See `Native Interface <native-interface>`__ for more details.
Multi-Threading
---------------
......
......@@ -224,21 +224,7 @@ required for all types and signatures that are implemented and suitable.
Common Instructions
===================
Required:
+ @uvm.new_thread
+ @uvm.current_stack
+ @uvm.kill_stack
+ @uvm.thread_exit
+ @uvm.futex.wait for ``int<32>`` memory locations
+ @uvm.futex.wake for ``int<32>`` memory locations
+ @uvm.native.pin
+ @uvm.native.unpin
+ @uvm.native.expose
+ @uvm.native.unexpose
+ @uvm.native.get_cookie
Required when ``tagref64`` is implemented:
Required only when ``tagref64`` is implemented:
* @uvm.tr64.is_fp
* @uvm.tr64.is_int
......@@ -251,6 +237,8 @@ Required when ``tagref64`` is implemented:
* @uvm.tr64.from_int
* @uvm.tr64.from_ref
All other common instructions are always required.
The Mu implementation may add common instructions.
.. vim: tw=80
......@@ -52,6 +52,9 @@ A thread is always bound to one stack, with one exception: when executing a
current stack. It either rebinds to a stack (may be the old stack or another
stack) or terminates after returning from the trap handler.
TODO: https://github.com/microvm/microvm-meta/issues/42 Extend the unbinding
to undefined function handling.
States of Stacks
================
......@@ -85,12 +88,14 @@ undefined function ACTIVE N/A
stack-related errors ACTIVE N/A
======================= =============================== =======================
TODO: https://github.com/microvm/microvm-meta/issues/42 Executing undefined
functions would result in traps, too.
Stack and Thread Creation
=========================
Mu stacks and Mu threads can be created by Mu instructions ``NEWSTACK`` and
``@uvm.new_thread``, or the Mu client interface messages ``new_stack`` and
``new_thread``.
``@uvm.new_thread``, or the API function ``new_stack`` and ``new_thread``.
When a stack is created, a Mu function and all of its parameter must be
provided. The stack will contain a frame created for this function. This frame
......@@ -109,8 +114,8 @@ initial stack must be in the **READY<void>** state and will enter the **ACTIVE**
state after the thread is created. A newly created thread can execute
immediately.
NOTE: There is not a separate step to "start" a thread as in Java. A thread
starts when it is created.
NOTE: Unlike Java, there is not a separate step to "start" a thread. A
thread starts when it is created.
Thread Termination
==================
......@@ -131,26 +136,26 @@ Binding
-------
Some actions, including the ``@uvm.new_thread`` and the ``SWAPSTACK``
instruction, the ``new_thread`` API message and the trap handler, can bind a
instruction, the ``new_thread`` API function and the trap handler, can bind a
thread to a stack.
When **binding** a thread to a stack, the state of the stack changes from
**READY<T>** to **ACTIVE**. In this process, one of the following three actions
shall be performed on the stack:
A binding operation can **pass a value** of type *T* to the stack. In this
case, the stack must be in the **READY<T>** state where *T* is not ``void``,
and it **receives the value**.
- A binding operation can **pass a value** of type *T* to the stack. In this
case, the stack must be in the **READY<T>** state where *T* is not ``void``,
and it **receives the value**.
A binding operation can **pass void** to the stack. In this case, the
stack must be in the **READY<void>** state and it **receives void**.
- A binding operation can **pass void** to the stack. In this case, the stack
must be in the **READY<void>** state and it **receives void**.
NOTE: "Pass void" is just a more explicit way to say "not pass a value, but
continue normally".
A binding operation can **raise an exception** to the stack. In this case, the
stack can be in **READY<T>** with any *T* (including ``void``) and it **receives
the exception**.
- A binding operation can **raise an exception** to the stack. In this case, the
stack can be in **READY<T>** with any *T* (including ``void``) and it
**receives the exception**.
It gives undefined behaviour if the stack is not in the expected state.
......@@ -159,11 +164,18 @@ binds to the provided initial stack and *passes void* to it. When a newly
created stack is bound to a thread and *receives void*, it continues execution
from the beginning of the stack-bottom function.
The state of a stack is **READY<void>** after the ``push_frame`` API message.
The state of a stack is **READY<void>** after the ``push_frame`` API function.
When such a stack is rebound receiving void, it continues from the beginning of
the function. When such a stack is rebound receiving exception, the exception is
thrown out of the top frame.
When binding to a frame and the top frame is a native frame, it must be calling
back to Mu. The value passed from Mu becomes the value returned from Mu. If the
native frame expects void return value, passing void will return to the native
code. The expected type is previous Mu callee which has been popped via OSR
(this is the only case when a native frame can be the top frame of an unbound
stack).
Unbinding
---------
......@@ -200,7 +212,7 @@ thread to a different stack.
Stack Destruction
=================
The ``@uvm.kill_stack`` instruction, the ``kill_stack`` API message and all
The ``@uvm.kill_stack`` instruction, the ``kill_stack`` API function and all
operations that perform unbinding operations can destroy a stack. A destroyed
stack enters the **DEAD** state.
......@@ -214,7 +226,7 @@ On-stack Replacement
====================
The client can pop and push frames from or to a stack. The ``pop_frame`` API
message pops the top frame from a stack. The ``push_frame`` message creates a
function pops the top frame from a stack. The ``push_frame`` function creates a
new frame for a given function and its arguments on the top of a stack.
After popping a frame from a stack, the next stack below the top becomes the new
......
......@@ -581,9 +581,10 @@ Memory addressing
* ``get_elem_iref`` gets an iref to the ``index``-th element of the array or
vector referred by the iref ``opnd``.
* ``shift_iref`` assumes ``opnd`` refers to an element in a general memory
array. It returns the iref of ``opnd`` moved by ``offset`` (forward if
positive, backward if negative).
* ``shift_iref`` assumes ``opnd`` refers to an element in a memory array
(including arrays, vectors and the variable part of hybrids in the memory, see
`Mu and the Memory <uvm-memory>`__). It returns the iref of ``opnd`` moved by
``offset`` (forward if positive, backward if negative).
* ``get_fixed_part_iref`` gets an iref to the fixed part of the hybrid referred
by iref ``opnd``.
......@@ -754,18 +755,24 @@ On-stack replacement
void (*push_frame)(MuCtx *ctx, MuStackRefValue stack, MuFuncRefValue func, MuValue *args, int nargs);
* ``pop_frame`` pops the top frame of the stack. Popping native frames has
implementation-defined behaviour.
implementation-defined behaviour. Popping a Mu frame changes the state of the
stack to ``READY<T>`` where T is the return type of the function of the popped
frame.
* ``push_frame`` creates a new frame on the top of ``stack`` for function
``func``, using the values in the ``args`` array as its arguments. ``nargs``
is the number of arguments. Arguments must match the signature of ``func``.
The previous stack top frame must be pausing on the ``CALL`` instruction. The
return type of ``func`` must be the same as return type of the ``CALL``
instruction of the previous top. After ``push_frame``, the stack enters the
``READY<void>`` state. When the stack is rebound, it continues from the
beginning of ``func``. The return value or exceptions from ``func`` are
received by the ``CALL`` instruction.
If the previous stack top frame is a Mu frame, it must be pausing on the
``CALL`` instruction. The return type of ``func`` must be the same as return
type of the ``CALL`` instruction of the previous top.
If the previous stack top frame is a native frame, the new function must
have the same return type as the previous Mu callee.
After ``push_frame``, the stack enters the ``READY<void>`` state. When the
stack is rebound, it continues from the beginning of ``func``. The return
value or exceptions from ``func`` are received by the caller.
..
......
......@@ -470,6 +470,10 @@ A **constant constructor** can be the following:
.const @fpconst <@fpnoparamsnoret> = 0x7ff00000000
.const @nullptr <@ptri64> = 0
// Array constant. Not recommended to use unless intracting with native function.
.typedef @i64ary = array<@i64 3>
.const @constary <@i64ary> = {@oct1 @oct2 @dec1}
Global Cell Definition
======================
......@@ -627,17 +631,28 @@ instruction is defined separately in `<instruction-set>`__.
..
NOTE: It is allowed to give names to instructions that does not return
values (expressed as "returning void"). In this case, the client can refer
to this instruction using their names. So ``%br = BRANCH %head`` is still
valid. This is useful when performing stack introspection. Such an
instruction can be interpreted in two ways:
NOTE: It is allowed to give names to instructions that has void return
values. In this case, the client can refer to such instructions using their
names. It is usually used for OSR point instructions, most likely ``TRAP``.
For example, ``%tr = TRAP <@void>`` is still valid even if ``%tr`` has void
type. This is useful when performing stack introspection. The name
identifies the instruction itself, i.e. "Which ``TRAP`` is executed?"::
%trap1 = TRAP <@void>
...
%trap2 = TRAP <@void>
The name ``%tr`` can be interpreted in two ways:
- The name ``%tr`` identifies the particular instance of ``TRAP``
instruction.
- The name ``%br`` binds to the instruction itself.
- The name ``%br`` is a variable of type ``void`` and it is defined by the
``BRANCH`` instruction.
- The name ``%tr`` is an SSA variable of type ``void`` and it is defined by
the ``TRAP`` instruction.
Both interpretations are reasonable.
Both are correct. Both ways are true for any other instructions, including
those that actually have non-void values.
The last instruction of any basic block must be a **terminator instruction**,
which is one of the following:
......@@ -651,7 +666,8 @@ which is one of the following:
- ``LOAD``, ``STORE``, ``CMPXCHG``, ``ATOMICRMW``
- ``TRAP``, ``WATCHPOINT``
- ``NEWSTACK``, ``SWAPSTACK``
- Some common instructions via the generic ``COMMINST`` instruction
- Some common instructions via the generic ``COMMINST`` instruction (currently
none)
- ``BRANCH``, ``BRANCH2``, ``SWITCH``
- ``TAILCALL``
......@@ -672,7 +688,8 @@ The following instructions are starter instructions:
- ``PHI``
- ``LANDINGPAD``
- Some common instructions via the generic ``COMMINST`` instruction
- Some common instructions via the generic ``COMMINST`` instruction (currently
none)
..
......@@ -688,16 +705,16 @@ A **function exposing definition** has the following syntax:
where:
* ``Name`` is a global name of the exposed value.
* ``Name`` is a global name of the exposed function.
* ``FuncName`` is the name of a Mu function.
* ``CallConv`` is a flag that denotes the calling convention. See platform-specific ABI.
* ``Cookie`` is the cookie. Must be the global name to a ``int<64>`` constant.
This definition exposes a Mu function *FuncName* as a value *Name* according to
the calling convention *CallConv*. The *Cookie* is attached to this exposed
value.
This definition exposes a Mu function *FuncName* as an exposed value, identified
by *Name*, using the calling convention *CallConv*. The *Cookie* is attached to
this exposed value.
How such an exposed value can be called is implementation-specific.
How such an exposed function can be called is implementation-specific.
Example::
......@@ -722,13 +739,18 @@ function.
After a function definition redefines a function, all calls to the function that
happen after the bundle loading operation will call the newly defined version of
the function.
the function. Defines of functions (bundle loading) and uses of functions
(including function calls and the creation of stacks, i.e. the ``NEWSTACK``
instruction or the ``new_stack`` API) obey the memory model of the ``RELAXED``
order as if the definition is a store and the use is a load. See `Memory Model
<memory-model>``__.
All existing activations of any functions remain unchanged, that is, they remain
to be the old versions of the functions.
NOTE: Specifically, existing traps in older versions of functions remain
valid. During OSR, redefining a function will not affect any existing
function activations unless they are explicitly popped by the client.
NOTE: Specifically, existing traps (including watchpoints) in older versions
of functions remain valid. During OSR, redefining a function will not affect
any existing function activations unless they are explicitly popped by the
client.
.. vim: textwidth=80
......@@ -104,13 +104,12 @@ Memory Allocation and Deallocation
An allocation unit in the heap memory is called a **heap object**, or **object**
when unambiguous. It is created when executing the ``NEW`` or ``NEWHYBRID``
instructions or the ``new`` or ``new_hybrid`` API message. It is destroyed when
the object is collected by the garbage collector.
instructions or the ``new_fixed`` or ``new_hybrid`` API function. It is
destroyed when the object is collected by the garbage collector.
An allocation unit in the stack memory is called an **alloca cell**. It is
created when executing the ``ALLOCA`` or ``ALLOCAHYBRID`` instruction or during
on-stack replacement using API messages. It is destroyed when the stack frame
containing it is destroyed.
created when executing the ``ALLOCA`` or ``ALLOCAHYBRID`` instruction. It is
destroyed when the stack frame containing it is destroyed.
An allocation unit in the global memory is called a **global cell**. One global
cell is created for every ``.global`` declaration in a bundle submitted to Mu.
......@@ -170,9 +169,9 @@ have both a load and a store operation, but may have special atomic properties.
abstract operations are in lower case: load, store and access.
Memory access operations can be performed by some Mu instructions (see
`<instruction-set>`__, API messages (see `<uvm-client-interface>`__), native
programs which accesses the pinned Mu memory, or in other
implementation-specific ways.
`Instruction Set <instruction-set>`__, API functions (see `Client Interface
<uvm-client-interface>`__), native programs which accesses the pinned Mu memory,
or in other implementation-specific ways.
Two memory accesses **conflict** if one stores to a memory location and the
other loads from or stores to the same memory location.
......@@ -182,7 +181,7 @@ Parameters and Semantics of Memory Operations
Generally speaking, load operations copy values from the memory and store
operations copy values into the memory. The exact results are determined by the
memory model. See `<memory-model>`__.
memory model. See `Memory Model <memory-model>`__.
A **load** operation has parameters ``(ord, T, loc)``. *ord* is the memory order
of the operation. *T* is the type of *loc*, a memory location. The result is a
......@@ -261,7 +260,7 @@ operation.
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>`__
requirements specified in `Portability <portability>`__
Memory Operations on Pointers
-----------------------------
......@@ -395,10 +394,10 @@ of the type of *M*.
All prefixes of a memory location have the same beginning.
The ``REFCAST`` instruction or the ``refcast`` API message preserves the
The ``REFCAST`` instruction or the ``refcast`` API function preserves the
beginning of the operand. If it casts ``iref<T1>`` to ``iref<T2>``, the result
is an internal reference to the memory location of type ``T2`` at the same
beginning. (see `<instruction-set>`__)
beginning. (see `Instruction Set <instruction-set>`__)
Array Rule
----------
......
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