95 lines
3.5 KiB
Markdown
95 lines
3.5 KiB
Markdown
# Object Management
|
|
|
|
**Location**: `crates/core/src/objects/`
|
|
|
|
## Object Representation
|
|
|
|
Java objects are represented through a multi-layered abstraction:
|
|
|
|
```rust
|
|
pub struct Object {
|
|
pub id: u32, // Unique identifier
|
|
pub class: Arc<RuntimeClass>, // Runtime class reference
|
|
pub fields: DashMap<String, Value>, // Concurrent field storage
|
|
}
|
|
|
|
pub type ObjectReference = Arc<Mutex<Object>>;
|
|
```
|
|
|
|
- **Objects**: Contain a unique ID (u32), runtime class reference, and field storage (DashMap)
|
|
- **ObjectReference**: `Arc<Mutex<Object>>` - reference-counted, thread-safe smart pointer
|
|
- **Value wrapper**: The `Value` enum encapsulates both primitives and references for operand stack/local variable storage
|
|
|
|
## Array Management
|
|
|
|
Arrays are type-safe with separate variants for primitives and objects:
|
|
|
|
```rust
|
|
pub enum ArrayReference {
|
|
Int(Arc<Mutex<Array<jint>>>),
|
|
Byte(Arc<Mutex<Array<jbyte>>>),
|
|
Short(Arc<Mutex<Array<jshort>>>),
|
|
Long(Arc<Mutex<Array<jlong>>>),
|
|
Float(Arc<Mutex<Array<jfloat>>>),
|
|
Double(Arc<Mutex<Array<jdouble>>>),
|
|
Char(Arc<Mutex<Array<jchar>>>),
|
|
Boolean(Arc<Mutex<Array<jboolean>>>),
|
|
Object(Arc<Mutex<Array<Option<ReferenceKind>>>>),
|
|
}
|
|
```
|
|
|
|
- **Primitive arrays**: Int, Byte, Short, Long, Float, Double, Char, Boolean
|
|
- **Object arrays**: Can hold references to other objects
|
|
- **Array structure**: Each array wraps a boxed slice `Box<[T]>` with id, class, and backing storage
|
|
- **Thread-safe**: All arrays use `Arc<Mutex<Array<T>>>` for concurrent access
|
|
|
|
## Allocation Strategy
|
|
|
|
Allocation is centralized in **ObjectManager**:
|
|
|
|
- **Object allocation**: `new_object()` generates unique IDs via atomic counter and stores references in HashMap
|
|
- **Array allocation**: Separate methods for primitive arrays (`new_primitive_array()`) and object arrays (`new_object_array()`)
|
|
- **String interning**: `new_string()` creates UTF-16 encoded strings with automatic interning via string pool
|
|
- **Memory tracking**: `bytes_in_use()` calculates total heap usage across all objects/arrays
|
|
|
|
All allocated objects are registered in `objects: HashMap<u32, ReferenceKind>` for global access.
|
|
|
|
## Reference Handling
|
|
|
|
Two-level reference system:
|
|
|
|
1. **ReferenceKind enum**: Distinguishes between `ObjectReference` and `ArrayReference`
|
|
2. **Reference type alias**: `Option<ReferenceKind>` (None = null)
|
|
3. **Conversion methods**: Safe conversions with `try_into_object_reference()` and `try_into_array_reference()`
|
|
|
|
## Memory Management
|
|
|
|
**No explicit garbage collection** - relies on Rust's reference counting:
|
|
|
|
- Arc ensures objects live as long as references exist
|
|
- Mutex provides thread-safe field/element access
|
|
- Shallow cloning for `clone()` operations (copies references, not objects)
|
|
- Array copy operations handle both primitive and object types with bounds checking
|
|
|
|
## Object Synchronization
|
|
|
|
Monitor-based concurrency for synchronized operations:
|
|
|
|
```rust
|
|
pub struct Monitor {
|
|
owner: Option<ThreadId>,
|
|
entry_count: u32,
|
|
condition: Condvar,
|
|
mutex: Mutex<()>,
|
|
}
|
|
```
|
|
|
|
- **Operations**: `monitor_enter()`, `monitor_exit()`, `wait()`, `notify_one()`, `notify_all()`
|
|
- **Wait semantics**: Full support for Java-style wait/notify with timeout
|
|
- **Reentrant**: Same thread can enter multiple times (tracked by entry_count)
|
|
|
|
## Special Features
|
|
|
|
- **String handling**: UTF-16 LE encoding with automatic String object creation
|
|
- **Reflection support**: Methods to create Constructor, Method, MethodHandle objects
|
|
- **Class mirrors**: Every class has an associated mirror object (java/lang/Class) |