GitLab will be upgraded to the 12.10.14-ce.0 on 28 Sept 2020 at 2.00pm (AEDT) to 2.30pm (AEDT). During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

test_gcbench.rs 5.52 KB
Newer Older
1 2 3 4 5 6 7 8 9
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(unused_imports)]

extern crate gc;
extern crate time;
10
extern crate utils;
11 12 13 14 15 16

use self::gc::heap;
use self::gc::heap::immix::ImmixMutatorLocal;
use self::gc::heap::immix::ImmixSpace;
use self::gc::heap::freelist;
use self::gc::heap::freelist::FreeListSpace;
17
use self::gc::objectmodel;
18
use self::utils::{ObjectReference, Address};
19 20 21
use std::mem::size_of;
use std::sync::atomic::Ordering;

22 23 24 25 26 27 28 29 30 31 32
extern crate log;
extern crate simple_logger;
use self::log::LogLevel;
pub fn start_logging() {

    match simple_logger::init_with_level(LogLevel::Trace) {
        Ok(_) => {},
        Err(_) => {}
    }
}

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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
const IMMIX_SPACE_SIZE : usize = 40 << 20;
const LO_SPACE_SIZE    : usize = 40 << 20;

const kStretchTreeDepth   : i32 = 18;
const kLongLivedTreeDepth : i32 = 16;
const kArraySize          : i32 = 500000;
const kMinTreeDepth       : i32 = 4;
const kMaxTreeDepth       : i32 = 16;

struct Node {
    left : *mut Node,
    right : *mut Node,
    i : i32,
    j : i32
}

struct Array {
    value : [f64; kArraySize as usize]
}

fn init_Node(me: *mut Node, l: *mut Node, r: *mut Node) {
    unsafe {
        (*me).left = l;
        (*me).right = r;
    }
}

fn TreeSize(i: i32) -> i32{
    (1 << (i + 1)) - 1
}

fn NumIters(i: i32) -> i32 {
    2 * TreeSize(kStretchTreeDepth) / TreeSize(i)
}

fn Populate(iDepth: i32, thisNode: *mut Node, mutator: &mut ImmixMutatorLocal) {
    if iDepth <= 0 {
        return;
    } else {
        unsafe {
            (*thisNode).left = alloc(mutator);
            (*thisNode).right = alloc(mutator);
            Populate(iDepth - 1, (*thisNode).left, mutator);
            Populate(iDepth - 1, (*thisNode).right, mutator);
        }
    }
}

fn MakeTree(iDepth: i32, mutator: &mut ImmixMutatorLocal) -> *mut Node {
    if iDepth <= 0 {
        alloc(mutator)
    } else {
        let left = MakeTree(iDepth - 1, mutator);
        let right = MakeTree(iDepth - 1, mutator);
        let result = alloc(mutator);
        init_Node(result, left, right);

        result
    }
}

fn PrintDiagnostics() {

}

fn TimeConstruction(depth: i32, mutator: &mut ImmixMutatorLocal) {
    let iNumIters = NumIters(depth);
    println!("creating {} trees of depth {}", iNumIters, depth);

    let tStart = time::now_utc();
    for _ in 0..iNumIters {
        let tempTree = alloc(mutator);
        Populate(depth, tempTree, mutator);

        // destroy tempTree
    }
    let tFinish = time::now_utc();
    println!("\tTop down construction took {} msec", (tFinish - tStart).num_milliseconds());

    let tStart = time::now_utc();
    for _ in 0..iNumIters {
        let tempTree = MakeTree(depth, mutator);
    }
    let tFinish = time::now_utc();
    println!("\tButtom up construction took {} msec", (tFinish - tStart).num_milliseconds());
}

120 121 122 123 124 125 126 127 128 129 130 131 132 133
#[cfg(feature = "use-sidemap")]
const FIXSIZE_REFx2_ENCODE : u64 = 0b1100_0011u64;
#[cfg(not(feature = "use-sidemap"))]
const FIXSIZE_REFx2_ENCODE : u64 = 0xb000000000000003u64;

#[inline(always)]
#[cfg(feature = "use-sidemap")]
fn alloc(mutator: &mut ImmixMutatorLocal) -> *mut Node {
    let addr = mutator.alloc(size_of::<Node>(), 8);
    mutator.init_object(addr, FIXSIZE_REFx2_ENCODE);

    addr.to_ptr_mut::<Node>()
}

134
#[inline(always)]
135
#[cfg(not(feature = "use-sidemap"))]
136 137
fn alloc(mutator: &mut ImmixMutatorLocal) -> *mut Node {
    let addr = mutator.alloc(size_of::<Node>(), 8);
138 139 140 141 142 143 144 145
    mutator.init_object(addr, FIXSIZE_REFx2_ENCODE);

    if cfg!(debug_assertions) {
        unsafe {
            let hdr = addr.offset(objectmodel::OBJECT_HEADER_OFFSET).load::<u64>();
            assert!(objectmodel::header_is_object_start(hdr));
        }
    }
146 147 148 149 150 151 152 153

    addr.to_ptr_mut::<Node>()
}

#[test]
fn start() {
    unsafe {heap::gc::set_low_water_mark();}

154 155
    start_logging();

156
    gc::gc_init(IMMIX_SPACE_SIZE, LO_SPACE_SIZE, 1);
157 158 159 160 161
    gc::gc_stats();

    let mut mutator = gc::new_mutator();

    println!("Garbage Collector Test");
162
    println!(" Node size = {}", size_of::<Node>());
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
    println!(" Live storage will peak at {} bytes.\n",
             2 * (size_of::<Node>() as i32) * TreeSize(kLongLivedTreeDepth) +
                 (size_of::<Array>() as i32));

    println!(" Stretching memory with a binary tree or depth {}", kStretchTreeDepth);
    PrintDiagnostics();

    let tStart = time::now_utc();
    // Stretch the memory space quickly
    let tempTree = MakeTree(kStretchTreeDepth, &mut mutator);
    // destroy tree

    // Create a long lived object
    println!(" Creating a long-lived binary tree of depth {}", kLongLivedTreeDepth);
    let longLivedTree = alloc(&mut mutator);
    Populate(kLongLivedTreeDepth, longLivedTree, &mut mutator);
179
    gc::add_to_root(unsafe{Address::from_mut_ptr(longLivedTree).to_object_reference()});
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207

    println!(" Creating a long-lived array of {} doubles", kArraySize);
    //    mm::alloc_large(&mut mutator, size_of::<Array>(), 8);

    PrintDiagnostics();

    let mut d = kMinTreeDepth;
    while d <= kMaxTreeDepth {
        TimeConstruction(d, &mut mutator);
        d += 2;
    }

    if longLivedTree.is_null() {
        println!("Failed(long lived tree wrong)");
    }

    //    if array.array[1000] != 1.0f64 / (1000 as f64) {
    //        println!("Failed(array element wrong)");
    //    }

    let tFinish = time::now_utc();
    let tElapsed = (tFinish - tStart).num_milliseconds();

    PrintDiagnostics();
    println!("Completed in {} msec", tElapsed);
    println!("Finished with {} collections", heap::gc::GC_COUNT.load(Ordering::SeqCst));

    mutator.destroy();
208
}