Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mu-impl-ref2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
5
Issues
5
List
Boards
Labels
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mu
mu-impl-ref2
Commits
e4fdc4b2
Commit
e4fdc4b2
authored
Sep 02, 2015
by
Kunshan Wang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Switched to JNR-FFI-based native memory access.
parent
1d03dfae
Changes
25
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
273 additions
and
218 deletions
+273
-218
src/main/scala/uvm/refimpl/MicroVM.scala
src/main/scala/uvm/refimpl/MicroVM.scala
+7
-4
src/main/scala/uvm/refimpl/clientInterface.scala
src/main/scala/uvm/refimpl/clientInterface.scala
+9
-4
src/main/scala/uvm/refimpl/exceptions.scala
src/main/scala/uvm/refimpl/exceptions.scala
+4
-1
src/main/scala/uvm/refimpl/itpr/ConstantPool.scala
src/main/scala/uvm/refimpl/itpr/ConstantPool.scala
+1
-1
src/main/scala/uvm/refimpl/itpr/InterpreterThread.scala
src/main/scala/uvm/refimpl/itpr/InterpreterThread.scala
+9
-6
src/main/scala/uvm/refimpl/itpr/ThreadStackManager.scala
src/main/scala/uvm/refimpl/itpr/ThreadStackManager.scala
+1
-1
src/main/scala/uvm/refimpl/itpr/TrapManager.scala
src/main/scala/uvm/refimpl/itpr/TrapManager.scala
+1
-1
src/main/scala/uvm/refimpl/itpr/operationHelpers.scala
src/main/scala/uvm/refimpl/itpr/operationHelpers.scala
+48
-48
src/main/scala/uvm/refimpl/mem/GlobalMemory.scala
src/main/scala/uvm/refimpl/mem/GlobalMemory.scala
+4
-2
src/main/scala/uvm/refimpl/mem/HeaderUtils.scala
src/main/scala/uvm/refimpl/mem/HeaderUtils.scala
+13
-10
src/main/scala/uvm/refimpl/mem/MemUtils.scala
src/main/scala/uvm/refimpl/mem/MemUtils.scala
+5
-5
src/main/scala/uvm/refimpl/mem/MemoryManager.scala
src/main/scala/uvm/refimpl/mem/MemoryManager.scala
+12
-11
src/main/scala/uvm/refimpl/mem/MemorySupport.scala
src/main/scala/uvm/refimpl/mem/MemorySupport.scala
+80
-51
src/main/scala/uvm/refimpl/mem/Mutator.scala
src/main/scala/uvm/refimpl/mem/Mutator.scala
+1
-1
src/main/scala/uvm/refimpl/mem/StackMemory.scala
src/main/scala/uvm/refimpl/mem/StackMemory.scala
+3
-2
src/main/scala/uvm/refimpl/mem/bumppointer/RewindableBumpPointerAllocator.scala
...impl/mem/bumppointer/RewindableBumpPointerAllocator.scala
+6
-5
src/main/scala/uvm/refimpl/mem/los/LargeObjectSpace.scala
src/main/scala/uvm/refimpl/mem/los/LargeObjectSpace.scala
+10
-11
src/main/scala/uvm/refimpl/mem/scanning/AllScanner.scala
src/main/scala/uvm/refimpl/mem/scanning/AllScanner.scala
+3
-2
src/main/scala/uvm/refimpl/mem/scanning/MemoryDataScanner.scala
...in/scala/uvm/refimpl/mem/scanning/MemoryDataScanner.scala
+12
-12
src/main/scala/uvm/refimpl/mem/scanning/fieldHandling.scala
src/main/scala/uvm/refimpl/mem/scanning/fieldHandling.scala
+6
-6
src/main/scala/uvm/refimpl/mem/simpleimmix/SimpleImmixCollector.scala
...la/uvm/refimpl/mem/simpleimmix/SimpleImmixCollector.scala
+12
-13
src/main/scala/uvm/refimpl/mem/simpleimmix/SimpleImmixDefragMutator.scala
...vm/refimpl/mem/simpleimmix/SimpleImmixDefragMutator.scala
+2
-1
src/main/scala/uvm/refimpl/mem/simpleimmix/SimpleImmixHeap.scala
...n/scala/uvm/refimpl/mem/simpleimmix/SimpleImmixHeap.scala
+4
-2
src/main/scala/uvm/refimpl/mem/simpleimmix/SimpleImmixMutator.scala
...cala/uvm/refimpl/mem/simpleimmix/SimpleImmixMutator.scala
+3
-2
src/main/scala/uvm/refimpl/mem/simpleimmix/SimpleImmixSpace.scala
.../scala/uvm/refimpl/mem/simpleimmix/SimpleImmixSpace.scala
+17
-16
No files found.
src/main/scala/uvm/refimpl/MicroVM.scala
View file @
e4fdc4b2
...
@@ -17,12 +17,15 @@ object MicroVM {
...
@@ -17,12 +17,15 @@ object MicroVM {
class
MicroVM
(
heapSize
:
Word
=
MicroVM
.
DEFAULT_HEAP_SIZE
,
class
MicroVM
(
heapSize
:
Word
=
MicroVM
.
DEFAULT_HEAP_SIZE
,
globalSize
:
Word
=
MicroVM
.
DEFAULT_GLOBAL_SIZE
,
globalSize
:
Word
=
MicroVM
.
DEFAULT_GLOBAL_SIZE
,
stackSize
:
Word
=
MicroVM
.
DEFAULT_STACK_SIZE
)
{
stackSize
:
Word
=
MicroVM
.
DEFAULT_STACK_SIZE
)
{
// implicitly injected resources
private
implicit
val
microVM
=
this
val
globalBundle
=
new
Bundle
()
val
globalBundle
=
new
Bundle
()
val
constantPool
=
new
ConstantPool
(
this
)
val
constantPool
=
new
ConstantPool
()
val
memoryManager
=
new
MemoryManager
(
heapSize
,
globalSize
,
stackSize
,
this
)
val
memoryManager
=
new
MemoryManager
(
heapSize
,
globalSize
,
stackSize
)
val
threadStackManager
=
new
ThreadStackManager
(
this
)
val
threadStackManager
=
new
ThreadStackManager
()
val
trapManager
=
new
TrapManager
(
this
)
val
trapManager
=
new
TrapManager
()
val
clientAgents
=
new
HashSet
[
ClientAgent
]()
val
clientAgents
=
new
HashSet
[
ClientAgent
]()
val
irReader
=
new
UIRTextReader
(
new
IDFactory
())
val
irReader
=
new
UIRTextReader
(
new
IDFactory
())
...
...
src/main/scala/uvm/refimpl/clientInterface.scala
View file @
e4fdc4b2
...
@@ -27,6 +27,11 @@ trait UndefinedFunctionHandler {
...
@@ -27,6 +27,11 @@ trait UndefinedFunctionHandler {
}
}
class
ClientAgent
(
microVM
:
MicroVM
)
{
class
ClientAgent
(
microVM
:
MicroVM
)
{
// Injectable resources (used by memory access operations)
private
implicit
val
microVM_
=
microVM
private
implicit
val
memorySupport
=
microVM
.
memoryManager
.
memorySupport
val
handles
=
new
HashSet
[
Handle
]()
val
handles
=
new
HashSet
[
Handle
]()
microVM
.
clientAgents
.
add
(
this
)
microVM
.
clientAgents
.
add
(
this
)
...
@@ -252,7 +257,7 @@ class ClientAgent(microVM: MicroVM) {
...
@@ -252,7 +257,7 @@ class ClientAgent(microVM: MicroVM) {
val
iRef
=
b
.
objRef
+
b
.
offset
val
iRef
=
b
.
objRef
+
b
.
offset
val
nb
=
ValueBox
.
makeBoxForType
(
uty
)
val
nb
=
ValueBox
.
makeBoxForType
(
uty
)
MemoryOperations
.
load
(
uty
,
iRef
,
nb
,
microVM
)
MemoryOperations
.
load
(
uty
,
iRef
,
nb
)
newHandle
(
uty
,
nb
)
newHandle
(
uty
,
nb
)
}
}
...
@@ -265,7 +270,7 @@ class ClientAgent(microVM: MicroVM) {
...
@@ -265,7 +270,7 @@ class ClientAgent(microVM: MicroVM) {
val
nvb
=
newVal
.
vb
val
nvb
=
newVal
.
vb
val
nb
=
ValueBox
.
makeBoxForType
(
uty
)
val
nb
=
ValueBox
.
makeBoxForType
(
uty
)
MemoryOperations
.
store
(
uty
,
iRef
,
nvb
,
nb
,
microVM
)
MemoryOperations
.
store
(
uty
,
iRef
,
nvb
,
nb
)
}
}
def
cmpXchg
(
ordSucc
:
MemoryOrder
,
ordFail
:
MemoryOrder
,
weak
:
Boolean
,
loc
:
Handle
,
expected
:
Handle
,
desired
:
Handle
)
:
(
Boolean
,
Handle
)
=
{
def
cmpXchg
(
ordSucc
:
MemoryOrder
,
ordFail
:
MemoryOrder
,
weak
:
Boolean
,
loc
:
Handle
,
expected
:
Handle
,
desired
:
Handle
)
:
(
Boolean
,
Handle
)
=
{
...
@@ -276,7 +281,7 @@ class ClientAgent(microVM: MicroVM) {
...
@@ -276,7 +281,7 @@ class ClientAgent(microVM: MicroVM) {
val
eb
=
expected
.
vb
val
eb
=
expected
.
vb
val
db
=
desired
.
vb
val
db
=
desired
.
vb
val
br
=
ValueBox
.
makeBoxForType
(
uty
)
val
br
=
ValueBox
.
makeBoxForType
(
uty
)
val
succ
=
MemoryOperations
.
cmpXchg
(
uty
,
iRef
,
eb
,
db
,
br
,
microVM
)
val
succ
=
MemoryOperations
.
cmpXchg
(
uty
,
iRef
,
eb
,
db
,
br
)
(
succ
,
newHandle
(
uty
,
br
))
(
succ
,
newHandle
(
uty
,
br
))
}
}
...
@@ -287,7 +292,7 @@ class ClientAgent(microVM: MicroVM) {
...
@@ -287,7 +292,7 @@ class ClientAgent(microVM: MicroVM) {
val
iRef
=
lb
.
objRef
+
lb
.
offset
val
iRef
=
lb
.
objRef
+
lb
.
offset
val
ob
=
opnd
.
vb
val
ob
=
opnd
.
vb
val
br
=
ValueBox
.
makeBoxForType
(
uty
)
val
br
=
ValueBox
.
makeBoxForType
(
uty
)
MemoryOperations
.
atomicRMW
(
uty
,
op
,
iRef
,
ob
,
br
,
microVM
)
MemoryOperations
.
atomicRMW
(
uty
,
op
,
iRef
,
ob
,
br
)
newHandle
(
uty
,
br
)
newHandle
(
uty
,
br
)
}
}
...
...
src/main/scala/uvm/refimpl/exceptions.scala
View file @
e4fdc4b2
...
@@ -19,4 +19,7 @@ class UnimplementedOprationException(message: String = null, cause: Throwable =
...
@@ -19,4 +19,7 @@ class UnimplementedOprationException(message: String = null, cause: Throwable =
class
UvmRuntimeException
(
message
:
String
=
null
,
cause
:
Throwable
=
null
)
extends
UvmRefImplException
(
message
,
cause
)
class
UvmRuntimeException
(
message
:
String
=
null
,
cause
:
Throwable
=
null
)
extends
UvmRefImplException
(
message
,
cause
)
/** Thrown when a division by zero is executed and the exception clause is not present. */
/** Thrown when a division by zero is executed and the exception clause is not present. */
class
UvmDivisionByZeroException
(
message
:
String
=
null
,
cause
:
Throwable
=
null
)
extends
UvmRuntimeException
(
message
,
cause
)
class
UvmDivisionByZeroException
(
message
:
String
=
null
,
cause
:
Throwable
=
null
)
extends
UvmRuntimeException
(
message
,
cause
)
\ No newline at end of file
/** Thrown when accessing Mu memory but the address is outside the allocated region. */
class
UvmIllegalMemoryAccessException
(
message
:
String
=
null
,
cause
:
Throwable
=
null
)
extends
UvmRuntimeException
(
message
,
cause
)
src/main/scala/uvm/refimpl/itpr/ConstantPool.scala
View file @
e4fdc4b2
...
@@ -6,7 +6,7 @@ import uvm.ssavariables._
...
@@ -6,7 +6,7 @@ import uvm.ssavariables._
import
uvm.refimpl.MicroVM
import
uvm.refimpl.MicroVM
import
scala.collection.mutable.HashMap
import
scala.collection.mutable.HashMap
class
ConstantPool
(
microVM
:
MicroVM
)
{
class
ConstantPool
(
implicit
microVM
:
MicroVM
)
{
val
globalVarBoxes
=
HashMap
[
GlobalVariable
,
ValueBox
]()
val
globalVarBoxes
=
HashMap
[
GlobalVariable
,
ValueBox
]()
def
addGlobalVar
(
g
:
GlobalVariable
)
{
def
addGlobalVar
(
g
:
GlobalVariable
)
{
...
...
src/main/scala/uvm/refimpl/itpr/InterpreterThread.scala
View file @
e4fdc4b2
...
@@ -15,9 +15,12 @@ object InterpreterThread {
...
@@ -15,9 +15,12 @@ object InterpreterThread {
val
logger
=
Logger
(
LoggerFactory
.
getLogger
(
getClass
.
getName
))
val
logger
=
Logger
(
LoggerFactory
.
getLogger
(
getClass
.
getName
))
}
}
class
InterpreterThread
(
val
id
:
Int
,
microVM
:
MicroVM
,
initialStack
:
InterpreterStack
,
val
mutator
:
Mutator
)
{
class
InterpreterThread
(
val
id
:
Int
,
implicit
private
val
microVM
:
MicroVM
,
initialStack
:
InterpreterStack
,
val
mutator
:
Mutator
)
{
import
InterpreterThread._
import
InterpreterThread._
// Injectable resources (used by memory access instructions)
implicit
private
val
memorySupport
=
microVM
.
memoryManager
.
memorySupport
// Thread states
// Thread states
/** The underlying stack. */
/** The underlying stack. */
...
@@ -683,7 +686,7 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
...
@@ -683,7 +686,7 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
if
(
la
==
0L
)
{
if
(
la
==
0L
)
{
nullRefError
(
excClause
)
nullRefError
(
excClause
)
}
else
{
}
else
{
MemoryOperations
.
load
(
uty
,
la
,
ib
,
microVM
)
MemoryOperations
.
load
(
uty
,
la
,
ib
)
continueNormally
()
continueNormally
()
}
}
}
}
...
@@ -698,7 +701,7 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
...
@@ -698,7 +701,7 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
if
(
la
==
0L
)
{
if
(
la
==
0L
)
{
nullRefError
(
excClause
)
nullRefError
(
excClause
)
}
else
{
}
else
{
MemoryOperations
.
store
(
uty
,
la
,
nvb
,
ib
,
microVM
)
MemoryOperations
.
store
(
uty
,
la
,
nvb
,
ib
)
continueNormally
()
continueNormally
()
}
}
}
}
...
@@ -714,7 +717,7 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
...
@@ -714,7 +717,7 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
if
(
la
==
0L
)
{
if
(
la
==
0L
)
{
nullRefError
(
excClause
)
nullRefError
(
excClause
)
}
else
{
}
else
{
MemoryOperations
.
cmpXchg
(
uty
,
la
,
eb
,
db
,
ib
,
microVM
)
MemoryOperations
.
cmpXchg
(
uty
,
la
,
eb
,
db
,
ib
)
continueNormally
()
continueNormally
()
}
}
}
}
...
@@ -729,7 +732,7 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
...
@@ -729,7 +732,7 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
if
(
la
==
0L
)
{
if
(
la
==
0L
)
{
nullRefError
(
excClause
)
nullRefError
(
excClause
)
}
else
{
}
else
{
MemoryOperations
.
atomicRMW
(
uty
,
op
,
la
,
ob
,
ib
,
microVM
)
MemoryOperations
.
atomicRMW
(
uty
,
op
,
la
,
ob
,
ib
)
continueNormally
()
continueNormally
()
}
}
}
}
...
...
src/main/scala/uvm/refimpl/itpr/ThreadStackManager.scala
View file @
e4fdc4b2
...
@@ -12,7 +12,7 @@ object ThreadStackManager {
...
@@ -12,7 +12,7 @@ object ThreadStackManager {
val
logger
=
Logger
(
LoggerFactory
.
getLogger
(
getClass
.
getName
))
val
logger
=
Logger
(
LoggerFactory
.
getLogger
(
getClass
.
getName
))
}
}
class
ThreadStackManager
(
microVM
:
MicroVM
)
{
class
ThreadStackManager
(
implicit
microVM
:
MicroVM
)
{
import
ThreadStackManager._
import
ThreadStackManager._
private
val
stackRegistry
=
new
HashMap
[
Int
,
InterpreterStack
]()
private
val
stackRegistry
=
new
HashMap
[
Int
,
InterpreterStack
]()
...
...
src/main/scala/uvm/refimpl/itpr/TrapManager.scala
View file @
e4fdc4b2
...
@@ -3,7 +3,7 @@ package uvm.refimpl.itpr
...
@@ -3,7 +3,7 @@ package uvm.refimpl.itpr
import
uvm.refimpl._
import
uvm.refimpl._
import
scala.collection.mutable.HashSet
import
scala.collection.mutable.HashSet
class
TrapManager
(
microVM
:
MicroVM
)
{
class
TrapManager
(
implicit
microVM
:
MicroVM
)
{
var
trapHandler
:
TrapHandler
=
DefaultTrapHandler
var
trapHandler
:
TrapHandler
=
DefaultTrapHandler
var
undefinedFunctionHandler
:
UndefinedFunctionHandler
=
DefaultUndefinedFunctionHandler
var
undefinedFunctionHandler
:
UndefinedFunctionHandler
=
DefaultUndefinedFunctionHandler
...
...
src/main/scala/uvm/refimpl/itpr/operationHelpers.scala
View file @
e4fdc4b2
This diff is collapsed.
Click to expand it.
src/main/scala/uvm/refimpl/mem/GlobalMemory.scala
View file @
e4fdc4b2
...
@@ -7,9 +7,11 @@ import uvm.refimpl.mem.TypeSizes._
...
@@ -7,9 +7,11 @@ import uvm.refimpl.mem.TypeSizes._
import
uvm.refimpl.mem.bumppointer.RewindableBumpPointerAllocator
import
uvm.refimpl.mem.bumppointer.RewindableBumpPointerAllocator
import
java.util.HashMap
import
java.util.HashMap
class
GlobalMemory
(
begin
:
Word
,
size
:
Word
,
microVM
:
MicroVM
)
extends
Space
(
"GlobalSpace"
,
begin
,
size
)
{
class
GlobalMemory
(
begin
:
Word
,
size
:
Word
)(
implicit
microVM
:
MicroVM
,
memorySupport
:
MemorySupport
)
extends
Space
(
"GlobalSpace"
,
begin
,
size
)
{
val
allocator
=
new
RewindableBumpPointerAllocator
(
begin
,
size
,
microVM
)
val
allocator
=
new
RewindableBumpPointerAllocator
(
begin
,
size
)
private
val
locationMap
=
new
HashMap
[
GlobalCell
,
Word
]()
private
val
locationMap
=
new
HashMap
[
GlobalCell
,
Word
]()
...
...
src/main/scala/uvm/refimpl/mem/HeaderUtils.scala
View file @
e4fdc4b2
...
@@ -6,32 +6,35 @@ import uvm.refimpl.mem.TypeSizes.Word
...
@@ -6,32 +6,35 @@ import uvm.refimpl.mem.TypeSizes.Word
import
com.typesafe.scalalogging._
import
com.typesafe.scalalogging._
import
org.slf4j.LoggerFactory
import
org.slf4j.LoggerFactory
/**
* Accessors to object headers. Require MemorySupport.
*/
object
HeaderUtils
extends
StrictLogging
{
object
HeaderUtils
extends
StrictLogging
{
def
postAllocScalar
(
addr
:
Word
,
tag
:
Word
)
{
def
postAllocScalar
(
addr
:
Word
,
tag
:
Word
)
(
implicit
memorySupport
:
MemorySupport
)
{
setTag
(
addr
,
tag
)
setTag
(
addr
,
tag
)
}
}
def
postAllocHybrid
(
addr
:
Word
,
tag
:
Word
,
len
:
Word
)
{
def
postAllocHybrid
(
addr
:
Word
,
tag
:
Word
,
len
:
Word
)
(
implicit
memorySupport
:
MemorySupport
)
{
postAllocScalar
(
addr
,
tag
)
postAllocScalar
(
addr
,
tag
)
setVarLength
(
addr
,
len
)
setVarLength
(
addr
,
len
)
}
}
def
getTag
(
objRef
:
Word
)
:
Word
=
{
def
getTag
(
objRef
:
Word
)
(
implicit
memorySupport
:
MemorySupport
)
:
Word
=
{
M
emorySupport
.
loadLong
(
objRef
+
TypeSizes
.
GC_HEADER_OFFSET_TAG
)
m
emorySupport
.
loadLong
(
objRef
+
TypeSizes
.
GC_HEADER_OFFSET_TAG
)
}
}
def
getVarLength
(
objRef
:
Word
)
:
Word
=
{
def
getVarLength
(
objRef
:
Word
)
(
implicit
memorySupport
:
MemorySupport
)
:
Word
=
{
M
emorySupport
.
loadLong
(
objRef
+
TypeSizes
.
GC_HEADER_OFFSET_HYBRID_LENGTH
)
m
emorySupport
.
loadLong
(
objRef
+
TypeSizes
.
GC_HEADER_OFFSET_HYBRID_LENGTH
)
}
}
def
setTag
(
objRef
:
Word
,
tag
:
Word
)
{
def
setTag
(
objRef
:
Word
,
tag
:
Word
)
(
implicit
memorySupport
:
MemorySupport
)
{
logger
.
debug
(
"Storing tag 0x%x at addr 0x%x"
.
format
(
tag
,
objRef
+
TypeSizes
.
GC_HEADER_OFFSET_TAG
))
logger
.
debug
(
"Storing tag 0x%x at addr 0x%x"
.
format
(
tag
,
objRef
+
TypeSizes
.
GC_HEADER_OFFSET_TAG
))
M
emorySupport
.
storeLong
(
objRef
+
TypeSizes
.
GC_HEADER_OFFSET_TAG
,
tag
)
m
emorySupport
.
storeLong
(
objRef
+
TypeSizes
.
GC_HEADER_OFFSET_TAG
,
tag
)
}
}
def
setVarLength
(
objRef
:
Word
,
len
:
Word
)
{
def
setVarLength
(
objRef
:
Word
,
len
:
Word
)
(
implicit
memorySupport
:
MemorySupport
)
{
M
emorySupport
.
storeLong
(
objRef
+
TypeSizes
.
GC_HEADER_OFFSET_HYBRID_LENGTH
,
len
)
m
emorySupport
.
storeLong
(
objRef
+
TypeSizes
.
GC_HEADER_OFFSET_HYBRID_LENGTH
,
len
)
}
}
def
getTypeID
(
tag
:
Word
)
:
Int
=
(
tag
&
0x00000000ffffffff
L
).
toInt
def
getTypeID
(
tag
:
Word
)
:
Int
=
(
tag
&
0x00000000ffffffff
L
).
toInt
...
...
src/main/scala/uvm/refimpl/mem/MemUtils.scala
View file @
e4fdc4b2
...
@@ -5,22 +5,22 @@ import TypeSizes._
...
@@ -5,22 +5,22 @@ import TypeSizes._
object
MemUtils
extends
StrictLogging
{
object
MemUtils
extends
StrictLogging
{
def
zeroRegion
(
start
:
Word
,
length
:
Word
)
{
def
zeroRegion
(
start
:
Word
,
length
:
Word
)
(
implicit
memorySupport
:
MemorySupport
)
{
val
end
=
start
+
length
val
end
=
start
+
length
logger
.
debug
(
"Zeroing [0x%x -> 0x%x] %d bytes"
.
format
(
start
,
end
,
length
))
logger
.
debug
(
"Zeroing [0x%x -> 0x%x] %d bytes"
.
format
(
start
,
end
,
length
))
var
a
=
start
var
a
=
start
while
(
a
<
end
)
{
while
(
a
<
end
)
{
MemorySupport
.
storeLong
(
a
,
0
)
memorySupport
.
storeLong
(
a
,
0L
)
a
+=
WORD_SIZE_BYTES
a
+=
WORD_SIZE_BYTES
}
}
}
}
def
memcpy
(
src
:
Word
,
dst
:
Word
,
length
:
Word
)
{
def
memcpy
(
src
:
Word
,
dst
:
Word
,
length
:
Word
)
(
implicit
memorySupport
:
MemorySupport
)
{
logger
.
debug
(
"Copying [0x%x -> 0x%x] %d bytes"
.
format
(
src
,
dst
,
length
))
logger
.
debug
(
"Copying [0x%x -> 0x%x] %d bytes"
.
format
(
src
,
dst
,
length
))
var
a
:
Word
=
0
var
a
:
Word
=
0
while
(
a
<
length
)
{
while
(
a
<
length
)
{
val
oldWord
=
M
emorySupport
.
loadLong
(
src
+
a
)
val
oldWord
=
m
emorySupport
.
loadLong
(
src
+
a
)
M
emorySupport
.
storeLong
(
dst
+
a
,
oldWord
)
m
emorySupport
.
storeLong
(
dst
+
a
,
oldWord
)
a
+=
WORD_SIZE_BYTES
a
+=
WORD_SIZE_BYTES
}
}
}
}
...
...
src/main/scala/uvm/refimpl/mem/MemoryManager.scala
View file @
e4fdc4b2
...
@@ -3,23 +3,24 @@ package uvm.refimpl.mem
...
@@ -3,23 +3,24 @@ package uvm.refimpl.mem
import
uvm.refimpl._
import
uvm.refimpl._
import
TypeSizes._
import
TypeSizes._
import
uvm.refimpl.mem.simpleimmix._
import
uvm.refimpl.mem.simpleimmix._
import
MemoryManager._
object
MemoryManager
{
class
MemoryManager
(
val
heapSize
:
Word
,
val
globalSize
:
Word
,
val
stackSize
:
Word
)(
implicit
microVM
:
MicroVM
)
{
val
MEMORY_BEGIN
=
0x100000
L
}
val
totalMemorySize
=
heapSize
+
globalSize
class
MemoryManager
(
val
heapSize
:
Word
,
val
globalSize
:
Word
,
val
stackSize
:
Word
,
microVM
:
MicroVM
)
{
implicit
val
memorySupport
=
new
MemorySupport
(
totalMemorySize
)
val
heap
=
new
SimpleImmixHeap
(
MEMORY_BEGIN
,
heapSize
,
microVM
)
val
memoryBegin
=
memorySupport
.
muMemoryBegin
val
heapBegin
=
TypeSizes
.
alignUp
(
memoryBegin
,
SimpleImmixSpace
.
BLOCK_SIZE
)
val
globalMemory
=
new
GlobalMemory
(
MEMORY_BEGIN
+
heapSize
,
globalSize
,
microVM
)
val
heap
=
new
SimpleImmixHeap
(
heapBegin
,
heapSize
)
val
globalMemory
=
new
GlobalMemory
(
heapBegin
+
heapSize
,
globalSize
)
def
makeMutator
()
:
Mutator
=
heap
.
makeMutator
()
def
makeMutator
()
:
Mutator
=
heap
.
makeMutator
()
def
makeStackMemory
(
mutator
:
Mutator
)
:
StackMemory
=
{
def
makeStackMemory
(
mutator
:
Mutator
)
:
StackMemory
=
{
val
objRef
=
mutator
.
newHybrid
(
InternalTypes
.
BYTE_ARRAY
,
stackSize
)
val
objRef
=
mutator
.
newHybrid
(
InternalTypes
.
BYTE_ARRAY
,
stackSize
)
val
stackMemory
=
new
StackMemory
(
objRef
,
stackSize
,
microVM
)
val
stackMemory
=
new
StackMemory
(
objRef
,
stackSize
)
stackMemory
stackMemory
}
}
}
}
src/main/scala/uvm/refimpl/mem/MemorySupport.scala
View file @
e4fdc4b2
...
@@ -3,100 +3,129 @@ package uvm.refimpl.mem
...
@@ -3,100 +3,129 @@ package uvm.refimpl.mem
import
uvm.refimpl.mem.TypeSizes.Word
import
uvm.refimpl.mem.TypeSizes.Word
import
java.nio.ByteBuffer
import
java.nio.ByteBuffer
import
uvm.ssavariables.AtomicRMWOptr._
import
uvm.ssavariables.AtomicRMWOptr._
import
jnr.ffi.
{
Runtime
,
Memory
,
Pointer
}
import
uvm.refimpl.UvmRuntimeException
import
uvm.refimpl.UvmIllegalMemoryAccessException
object
MemorySupport
{
/**
val
MEMORY_SIZE
:
Word
=
1024L
*
1024L
*
1024L
* Support for native memory access. Backed by JNR-FFI.
*/
class
MemorySupport
(
val
muMemorySize
:
Word
)
{
val
SIZE_LIMIT
:
Word
=
Int
.
MaxValue
.
toLong
val
bb
:
ByteBuffer
=
ByteBuffer
.
allocateDirect
(
MEMORY_SIZE
.
toInt
)
if
(
muMemorySize
>
SIZE_LIMIT
)
{
bb
.
order
(
java
.
nio
.
ByteOrder
.
LITTLE_ENDIAN
)
throw
new
UvmRuntimeException
(
"Memory too large (%d bytes requested)."
+
" Due to the limitation of JNR-FFI, the maximum available memory size is %d bytes."
.
format
(
muMemorySize
,
SIZE_LIMIT
))
}
val
jnrRuntime
=
Runtime
.
getSystemRuntime
val
muMemory
=
Memory
.
allocateDirect
(
jnrRuntime
,
muMemorySize
.
toInt
,
true
)
val
muMemoryBegin
=
muMemory
.
address
()
val
muMemoryEnd
=
muMemoryBegin
+
muMemorySize
val
theMemory
=
Pointer
.
wrap
(
jnrRuntime
,
0L
)
def
isInMuMemory
(
addr
:
Word
)
:
Boolean
=
muMemoryBegin
<=
addr
&&
addr
<
muMemoryEnd
def
assertInMuMemory
(
inMu
:
Boolean
,
addr
:
Word
)
:
Unit
=
{
if
(
inMu
&&
!
isInMuMemory
(
addr
))
{
throw
new
UvmIllegalMemoryAccessException
(
"Accessed address 0x%x outside the Mu memory [0x%x-0x%x]."
.
format
(
addr
,
muMemoryBegin
,
muMemoryEnd
))
}
}
def
loadByte
(
loc
:
Word
)
:
Byte
=
bb
.
get
(
loc
.
toInt
)
def
loadByte
(
addr
:
Word
,
inMu
:
Boolean
=
true
)
:
Byte
=
{
assertInMuMemory
(
inMu
,
addr
);
theMemory
.
getByte
(
addr
)
}
def
loadShort
(
loc
:
Word
)
:
Short
=
bb
.
getShort
(
loc
.
toInt
)
def
loadShort
(
addr
:
Word
,
inMu
:
Boolean
=
true
)
:
Short
=
{
assertInMuMemory
(
inMu
,
addr
);
theMemory
.
getShort
(
addr
)
}
def
loadInt
(
loc
:
Word
)
:
Int
=
bb
.
getInt
(
loc
.
toInt
)
def
loadInt
(
addr
:
Word
,
inMu
:
Boolean
=
true
)
:
Int
=
{
assertInMuMemory
(
inMu
,
addr
);
theMemory
.
getInt
(
addr
)
}
def
loadLong
(
loc
:
Word
)
:
Long
=
bb
.
getLong
(
loc
.
toInt
)
def
loadLong
(
addr
:
Word
,
inMu
:
Boolean
=
true
)
:
Long
=
{
assertInMuMemory
(
inMu
,
addr
);
theMemory
.
getLong
(
addr
)
}
def
loadI128
(
loc
:
Word
)
:
(
Long
,
Long
)
=
(
bb
.
getLong
(
loc
.
toInt
),
bb
.
getLong
(
loc
.
toInt
+
8
))
def
loadI128
(
addr
:
Word
,
inMu
:
Boolean
=
true
)
:
(
Long
,
Long
)
=
{
assertInMuMemory
(
inMu
,
addr
);
(
theMemory
.
getLong
(
addr
),
theMemory
.
getLong
(
addr
+
8
))
}
def
loadFloat
(
loc
:
Word
)
:
Float
=
bb
.
getFloat
(
loc
.
toInt
)
def
loadFloat
(
addr
:
Word
,
inMu
:
Boolean
=
true
)
:
Float
=
{
assertInMuMemory
(
inMu
,
addr
);
theMemory
.
getFloat
(
addr
)
}
def
loadDouble
(
loc
:
Word
)
:
Double
=
bb
.
getDouble
(
loc
.
toInt
)
def
loadDouble
(
addr
:
Word
,
inMu
:
Boolean
=
true
)
:
Double
=
{
assertInMuMemory
(
inMu
,
addr
);
theMemory
.
getDouble
(
addr
)
}
def
storeByte
(
loc
:
Word
,
v
:
Byte
)
:
Unit
=
bb
.
put
(
loc
.
toInt
,
v
)
def
storeByte
(
addr
:
Word
,
v
:
Byte
,
inMu
:
Boolean
=
true
)
:
Unit
=
{
assertInMuMemory
(
inMu
,
addr
);
theMemory
.
putByte
(
addr
,
v
)
}
def
storeShort
(
loc
:
Word
,
v
:
Short
)
:
Unit
=
bb
.
putShort
(
loc
.
toInt
,
v
)
def
storeShort
(
addr
:
Word
,
v
:
Short
,
inMu
:
Boolean
=
true
)
:
Unit
=
{
assertInMuMemory
(
inMu
,
addr
);
theMemory
.
putShort
(
addr
,
v
)
}
def
storeInt
(
loc
:
Word
,
v
:
Int
)
:
Unit
=
bb
.
putInt
(
loc
.
toInt
,
v
)
def
storeInt
(
addr
:
Word
,
v
:
Int
,
inMu
:
Boolean
=
true
)
:
Unit
=
{
assertInMuMemory
(
inMu
,
addr
);
theMemory
.
putInt
(
addr
,
v
)
}
def
storeLong
(
loc
:
Word
,
v
:
Long
)
:
Unit
=
bb
.
putLong
(
loc
.
toInt
,
v
)
def
storeLong
(
addr
:
Word
,
v
:
Long
,
inMu
:
Boolean
=
true
)
:
Unit
=
{
assertInMuMemory
(
inMu
,
addr
);
theMemory
.
putLong
(
addr
,
v
)
}
def
storeI128
(
loc
:
Word
,
v
:
(
Long
,
Long
))
:
Unit
=
{
val
(
low
,
high
)
=
v
;
bb
.
putLong
(
loc
.
toInt
,
low
);
bb
.
putLong
(
loc
.
toInt
+
8
,
high
)
}
def
storeI128
(
addr
:
Word
,
v
:
(
Long
,
Long
),
inMu
:
Boolean
=
true
)
:
Unit
=
{
assertInMuMemory
(
inMu
,
addr
);
val
(
low
,
high
)
=
v
;
theMemory
.
putLong
(
addr
,
low
);
theMemory
.
putLong
(
addr
+
8
,
high
)
}
def
storeFloat
(
loc
:
Word
,
v
:
Float
)
:
Unit
=
bb
.
putFloat
(
loc
.
toInt
,
v
)
def
storeFloat
(
addr
:
Word
,
v
:
Float
,
inMu
:
Boolean
=
true
)
:
Unit
=
{
assertInMuMemory
(
inMu
,
addr
);
theMemory
.
putFloat
(
addr
,
v
)
}
def
storeDouble
(
loc
:
Word
,
v
:
Double
)
:
Unit
=
bb
.
putDouble
(
loc
.
toInt
,
v
)
def
storeDouble
(
addr
:
Word
,
v
:
Double
,
inMu
:
Boolean
=
true
)
:
Unit
=
{
assertInMuMemory
(
inMu
,
addr
);
theMemory
.
putDouble
(
addr
,
v
)
}
def
cmpXchgInt
(
loc
:
Word
,
expected
:
Int
,
desired
:
Int
)
:
(
Boolean
,
Int
)
=
{
def
cmpXchgInt
(
addr
:
Word
,
expected
:
Int
,
desired
:
Int
,
inMu
:
Boolean
=
true
)
:
(
Boolean
,
Int
)
=
{
val
oldVal
=
loadInt
(
loc
)
assertInMuMemory
(
inMu
,
addr
)
val
oldVal
=
loadInt
(
addr
)
if
(
oldVal
==
expected
)
{
if
(
oldVal
==
expected
)
{
storeInt
(
loc
,
desired
)
storeInt
(
addr
,
desired
)
return
(
true
,
oldVal
)
return
(
true
,
oldVal
)
}
else
{
}
else
{
return
(
false
,
oldVal
)
return
(
false
,
oldVal
)
}
}
}
}
def
cmpXchgLong
(
loc
:
Word
,
expected
:
Long
,
desired
:
Long
)
:
(
Boolean
,
Long
)
=
{
def
cmpXchgLong
(
addr
:
Word
,
expected
:
Long
,
desired
:
Long
,
inMu
:
Boolean
=
true
)
:
(
Boolean
,
Long
)
=
{
val
oldVal
=
loadLong
(
loc
)
assertInMuMemory
(
inMu
,
addr
)
val
oldVal
=
loadLong
(
addr
)
if
(
oldVal
==
expected
)
{
if
(
oldVal
==
expected
)
{
storeLong
(
loc
,
desired
)
storeLong
(
addr
,
desired
)
return
(
true
,
oldVal
)
return
(
true
,
oldVal
)
}
else
{
}
else
{
return
(
false
,
oldVal
)
return
(
false
,
oldVal
)
}
}
}
}
def
cmpXchgI128
(
loc
:
Word
,
expected
:
(
Long
,
Long
),
desired
:
(
Long
,
Long
))
:
(
Boolean
,
(
Long
,
Long
))
=
{
def
cmpXchgI128
(
addr
:
Word
,
expected
:
(
Long
,
Long
),
desired
:
(
Long
,
Long
),
inMu
:
Boolean
=
true
)
:
(
Boolean
,
(
Long
,
Long
))
=
{
val
oldVal
=
loadI128
(
loc
)
assertInMuMemory
(
inMu
,
addr
)
val
oldVal
=
loadI128
(
addr
)
if
(
oldVal
==
expected
)
{
if
(
oldVal
==
expected
)
{
storeI128
(
loc
,
desired
)
storeI128
(
addr
,
desired
)
return
(
true
,
oldVal
)
return
(
true
,
oldVal
)
}
else
{
}
else
{
return
(
false
,
oldVal
)
return
(
false
,
oldVal
)
}
}
}
}
def
atomicRMWInt
(
optr
:
AtomicRMWOptr
,
loc
:
Word
,
opnd
:
Int
)
:
Int
=
{
def
atomicRMWInt
(
optr
:
AtomicRMWOptr
,
addr
:
Word
,
opnd
:
Int
,
inMu
:
Boolean
=
true
)
:
Int
=
{
val
oldVal
=
loadInt
(
loc
)
assertInMuMemory
(
inMu
,
addr
)
val
oldVal
=
loadInt
(
addr
)
val
newVal
=
optr
match
{
val
newVal
=
optr
match
{
case
XCHG
=>
opnd
case
XCHG
=>
opnd
case
ADD
=>
oldVal
+
opnd
case
ADD
=>
oldVal
+
opnd
case
SUB
=>
oldVal
-
opnd
case
SUB
=>
oldVal
-
opnd
case
AND
=>
oldVal
&
opnd
case
AND
=>
oldVal
&
opnd
case
NAND
=>
~(
oldVal
&
opnd
)
case
NAND
=>
~(
oldVal
&
opnd
)
case
OR
=>
oldVal
|
opnd
case
OR
=>
oldVal
|
opnd
case
XOR
=>
oldVal
^
opnd
case
XOR
=>
oldVal
^
opnd
case
MAX
=>
Math
.
max
(
oldVal
,
opnd
)
case
MAX
=>
Math
.
max
(
oldVal
,
opnd
)
case
MIN
=>
Math
.
min
(
oldVal
,
opnd
)
case
MIN
=>
Math
.
min
(
oldVal
,
opnd
)
case
UMAX
=>
Math
.
max
(
oldVal
-
Int
.
MinValue
,
opnd
-
Int
.
MinValue
)
+
Int
.
MinValue
case
UMAX
=>
Math
.
max
(
oldVal
-
Int
.
MinValue
,
opnd
-
Int
.
MinValue
)
+
Int
.
MinValue
case
UMIN
=>
Math
.
min
(
oldVal
-
Int
.
MinValue
,
opnd
-
Int
.
MinValue
)
+
Int
.
MinValue
case
UMIN
=>
Math
.
min
(
oldVal
-
Int
.
MinValue
,
opnd
-
Int
.
MinValue
)
+
Int
.
MinValue
}
}
storeInt
(
loc
,
newVal
)
storeInt
(
addr
,
newVal
)
return
oldVal
return
oldVal
}
}
def
atomicRMWLong
(
optr
:
AtomicRMWOptr
,
loc
:
Word
,
opnd
:
Long
)
:
Long
=
{
def
atomicRMWLong
(
optr
:
AtomicRMWOptr
,
addr
:
Word
,
opnd
:
Long
,
inMu
:
Boolean
=
true
)
:
Long
=
{
val
oldVal
=
loadLong
(
loc
)
assertInMuMemory
(
inMu
,
addr
)
val
oldVal
=
loadLong
(
addr
)
val
newVal
=
optr
match
{
val
newVal
=
optr
match
{
case
XCHG
=>
opnd
case
XCHG
=>
opnd
case
ADD
=>
oldVal
+
opnd
case
ADD
=>
oldVal
+
opnd
case
SUB
=>
oldVal
-
opnd
case
SUB
=>
oldVal
-
opnd
case
AND
=>
oldVal
&
opnd
case
AND
=>
oldVal
&
opnd
case
NAND
=>
~(
oldVal
&
opnd
)
case
NAND
=>
~(
oldVal
&
opnd
)
case
OR
=>
oldVal
|
opnd
case
OR
=>
oldVal
|
opnd
case
XOR
=>
oldVal
^
opnd
case
XOR
=>
oldVal
^
opnd
case
MAX
=>
Math
.
max
(
oldVal
,
opnd
)
case
MAX
=>
Math
.
max
(
oldVal
,
opnd
)
case
MIN
=>
Math
.
min
(
oldVal
,
opnd
)
case
MIN
=>
Math
.
min
(
oldVal
,
opnd
)
case
UMAX
=>
Math
.
max
(
oldVal
-
Long
.
MinValue
,
opnd
-
Long
.
MinValue
)
+
Long
.
MinValue
case
UMAX
=>
Math
.
max
(
oldVal
-
Long
.
MinValue
,
opnd
-
Long
.
MinValue
)
+
Long
.
MinValue
case
UMIN
=>
Math
.
min
(
oldVal
-
Long
.
MinValue
,
opnd
-
Long
.
MinValue
)
+
Long
.
MinValue
case
UMIN
=>
Math
.
min
(
oldVal
-
Long
.
MinValue
,
opnd
-
Long
.
MinValue
)
+
Long
.
MinValue
}
}
storeLong
(
loc
,
newVal
)
storeLong
(
addr
,
newVal
)
return
oldVal
return
oldVal
}
}
def
xchgI128
(
loc
:
Word
,
desired
:
(
Long
,
Long
))
:
(
Long
,
Long
)
=
{
def
xchgI128
(
addr
:
Word
,
desired
:
(
Long
,
Long
),
inMu
:
Boolean
=
true
)
:
(
Long
,
Long
)
=
{
val
oldVal
=
loadI128
(
loc
)
assertInMuMemory
(
inMu
,
addr
)
storeI128
(
loc
,
desired
)
val
oldVal
=
loadI128
(
addr
)
storeI128
(
addr
,
desired
)
return
oldVal
return
oldVal
}
}
}
}
\ No newline at end of file
src/main/scala/uvm/refimpl/mem/Mutator.scala
View file @
e4fdc4b2
...
@@ -3,7 +3,7 @@ package uvm.refimpl.mem
...
@@ -3,7 +3,7 @@ package uvm.refimpl.mem
import
uvm.types._
import
uvm.types._
import
TypeSizes._
import
TypeSizes._
abstract
class
Mutator
{
abstract
class
Mutator
(
implicit
memorySupport
:
MemorySupport
)
{
def
alloc
(
size
:
Word
,
align
:
Word
,
headerSize
:
Word
)
:
Word
def
alloc
(
size
:
Word
,
align
:
Word
,
headerSize
:
Word
)
:
Word
...
...
src/main/scala/uvm/refimpl/mem/StackMemory.scala
View file @
e4fdc4b2
...
@@ -9,5 +9,6 @@ import TypeSizes.Word
...
@@ -9,5 +9,6 @@ import TypeSizes.Word
* <p>
* <p>
* If the stack is Dead, the stackObjRef will be a dangling pointer.
* If the stack is Dead, the stackObjRef will be a dangling pointer.
*/
*/
class
StackMemory
(
val
stackObjRef
:
Word
,
extend
:
Word
,
microVM
:
MicroVM
)
class
StackMemory
(
val
stackObjRef
:
Word
,
extend
:
Word
)(
extends
RewindableBumpPointerAllocator
(
stackObjRef
,
extend
,
microVM
)
implicit
microVM
:
MicroVM
,
memorySupport
:
MemorySupport
)
extends
RewindableBumpPointerAllocator
(
stackObjRef
,
extend
)
src/main/scala/uvm/refimpl/mem/bumppointer/RewindableBumpPointerAllocator.scala
View file @
e4fdc4b2
...
@@ -14,8 +14,9 @@ object RewindableBumpPointerAllocator {
...
@@ -14,8 +14,9 @@ object RewindableBumpPointerAllocator {
val
logger
:
Logger
=
Logger
(
LoggerFactory
.
getLogger
(
getClass
.
getName