-
Notifications
You must be signed in to change notification settings - Fork 74
/
Copy pathlarge_object_allocator.rs
78 lines (67 loc) · 2.32 KB
/
large_object_allocator.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use std::sync::Arc;
use crate::policy::largeobjectspace::LargeObjectSpace;
use crate::policy::space::Space;
use crate::util::alloc::{allocator, Allocator};
use crate::util::opaque_pointer::*;
use crate::util::Address;
use crate::vm::VMBinding;
use super::allocator::AllocatorContext;
/// An allocator that only allocates at page granularity.
/// This is intended for large objects.
#[repr(C)]
pub struct LargeObjectAllocator<VM: VMBinding> {
/// [`VMThread`] associated with this allocator instance
pub tls: VMThread,
/// [`Space`](src/policy/space/Space) instance associated with this allocator instance.
space: &'static LargeObjectSpace<VM>,
context: Arc<AllocatorContext<VM>>,
}
impl<VM: VMBinding> Allocator<VM> for LargeObjectAllocator<VM> {
fn get_tls(&self) -> VMThread {
self.tls
}
fn get_context(&self) -> &AllocatorContext<VM> {
&self.context
}
fn get_space(&self) -> &'static dyn Space<VM> {
// Casting the interior of the Option: from &LargeObjectSpace to &dyn Space
self.space as &'static dyn Space<VM>
}
fn does_thread_local_allocation(&self) -> bool {
false
}
fn alloc(&mut self, size: usize, align: usize, offset: usize) -> Address {
let cell: Address = self.alloc_slow(size, align, offset);
// We may get a null ptr from alloc due to the VM being OOM
if !cell.is_zero() {
allocator::align_allocation::<VM>(cell, align, offset)
} else {
cell
}
}
fn alloc_slow_once(&mut self, size: usize, align: usize, _offset: usize) -> Address {
if self
.space
.will_oom_on_acquire(self.tls, size, !self.get_context().is_no_gc_on_fail())
{
return Address::ZERO;
}
let maxbytes = allocator::get_maximum_aligned_size::<VM>(size, align);
let pages = crate::util::conversions::bytes_to_pages_up(maxbytes);
self.space
.allocate_pages(self.tls, pages, self.get_context().is_no_gc_on_fail())
}
}
impl<VM: VMBinding> LargeObjectAllocator<VM> {
pub(crate) fn new(
tls: VMThread,
space: &'static LargeObjectSpace<VM>,
context: Arc<AllocatorContext<VM>>,
) -> Self {
LargeObjectAllocator {
tls,
space,
context,
}
}
}