blob: 2b9c56c94dd60a5f356485c41815834d6489fdce [file] [log] [blame]
//===-------- Selected.cpp - Implementation of the Selected class --------===//
//
// The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MutatorThread.h"
#include "MvmGC.h"
#include "mvm/VirtualMachine.h"
#include <sys/mman.h>
#include <set>
using namespace mvm;
uintptr_t Collector::TraceLocal = 0;
int Collector::verbose = 0;
extern "C" void* JnJVM_org_mmtk_plan_marksweep_MSMutator_alloc__IIIII(uintptr_t Mutator, int32_t sz, int32_t align, int32_t offset, int32_t allocator, int32_t site) __attribute__((always_inline));
extern "C" int32_t JnJVM_org_mmtk_plan_MutatorContext_checkAllocator__III(uintptr_t Mutator, int32_t bytes, int32_t align, int32_t allocator) __attribute__((always_inline));
extern "C" void JnJVM_org_mmtk_plan_marksweep_MSMutator_postAlloc__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_ObjectReference_2II(uintptr_t Mutator, uintptr_t ref, uintptr_t typeref,
int32_t bytes, int32_t allocator) __attribute__((always_inline));
extern "C" uint32_t MMTkMutatorSize;
extern "C" void JnJVM_org_j3_config_Selected_00024Mutator__0003Cinit_0003E__(uintptr_t);
extern "C" VirtualTable* org_j3_config_Selected_4Mutator_VT;
extern "C" void JnJVM_org_mmtk_plan_MutatorContext_initMutator__I(uintptr_t, int32_t);
extern "C" void JnJVM_org_mmtk_plan_MutatorContext_deinitMutator__(uintptr_t);
extern "C" void JnJVM_org_j3_config_Selected_00024Collector__0003Cinit_0003E__(uintptr_t);
extern "C" VirtualTable* org_j3_config_Selected_4Collector_VT;
extern "C" uint32_t MMTkCollectorSize;
extern "C" void JnJVM_org_mmtk_utility_heap_HeapGrowthManager_boot__Lorg_vmmagic_unboxed_Extent_2Lorg_vmmagic_unboxed_Extent_2(intptr_t, intptr_t);
extern "C" uintptr_t* org_j3_config_Selected_4Plan_static;
extern "C" void MMTkPlanBoot(uintptr_t);
extern "C" void MMTkPlanPostBoot(uintptr_t);
extern "C" void MMTkPlanFullBoot(uintptr_t);
extern "C" void Java_org_j3_mmtk_Collection_triggerCollection__I(uintptr_t, int32_t);
//===-------------------- TODO: make those virtual. -------------------===//
extern "C" void JnJVM_org_mmtk_plan_TraceLocal_reportDelayedRootEdge__Lorg_vmmagic_unboxed_Address_2(uintptr_t TraceLocal, void** slot);
extern "C" void JnJVM_org_mmtk_plan_TraceLocal_processEdge__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_Address_2(
uintptr_t TraceLocal, void* source, void* slot);
extern "C" void JnJVM_org_mmtk_plan_TraceLocal_processRootEdge__Lorg_vmmagic_unboxed_Address_2Z(
uintptr_t TraceLocal, void* slot, uint8_t untraced);
extern "C" gc* JnJVM_org_mmtk_plan_TraceLocal_retainForFinalize__Lorg_vmmagic_unboxed_ObjectReference_2(uintptr_t TraceLocal, void* obj);
extern "C" gc* JnJVM_org_mmtk_plan_TraceLocal_retainReferent__Lorg_vmmagic_unboxed_ObjectReference_2(uintptr_t TraceLocal, void* obj);
extern "C" gc* JnJVM_org_mmtk_plan_TraceLocal_getForwardedReference__Lorg_vmmagic_unboxed_ObjectReference_2(uintptr_t TraceLocal, void* obj);
extern "C" gc* JnJVM_org_mmtk_plan_TraceLocal_getForwardedReferent__Lorg_vmmagic_unboxed_ObjectReference_2(uintptr_t TraceLocal, void* obj);
extern "C" gc* JnJVM_org_mmtk_plan_TraceLocal_getForwardedFinalizable__Lorg_vmmagic_unboxed_ObjectReference_2(uintptr_t TraceLocal, void* obj);
extern "C" uint8_t JnJVM_org_mmtk_plan_marksweep_MSTraceLocal_isLive__Lorg_vmmagic_unboxed_ObjectReference_2(uintptr_t TraceLocal, void* obj);
extern "C" void* gcmalloc(uint32_t sz, void* _VT) {
gc* res = 0;
llvm_gcroot(res, 0);
VirtualTable* VT = (VirtualTable*)_VT;
sz = llvm::RoundUpToAlignment(sz, sizeof(void*));
uintptr_t Mutator = mvm::MutatorThread::get()->MutatorContext;
int allocator = JnJVM_org_mmtk_plan_MutatorContext_checkAllocator__III(Mutator, sz, 0, 0);
res = (gc*)JnJVM_org_mmtk_plan_marksweep_MSMutator_alloc__IIIII(Mutator, sz, 0, 0, allocator, 0);
res->setVirtualTable(VT);
JnJVM_org_mmtk_plan_marksweep_MSMutator_postAlloc__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_ObjectReference_2II(Mutator, (uintptr_t)res, (uintptr_t)VT, sz, allocator);
return res;
}
extern "C" void addFinalizationCandidate(void* obj) __attribute__((always_inline));
extern "C" void addFinalizationCandidate(void* obj) {
llvm_gcroot(obj, 0);
mvm::Thread::get()->MyVM->addFinalizationCandidate((gc*)obj);
}
extern "C" void* gcmallocUnresolved(uint32_t sz, VirtualTable* VT) {
gc* res = 0;
llvm_gcroot(res, 0);
res = (gc*)gcmalloc(sz, VT);
if (VT->destructor) addFinalizationCandidate(res);
return res;
}
void MutatorThread::init(Thread* _th) {
MutatorThread* th = (MutatorThread*)_th;
th->MutatorContext =
(uintptr_t)th->Allocator.Allocate(MMTkMutatorSize, "Mutator");
((VirtualTable**)th->MutatorContext)[0] = org_j3_config_Selected_4Mutator_VT;
JnJVM_org_j3_config_Selected_00024Mutator__0003Cinit_0003E__(th->MutatorContext);
JnJVM_org_mmtk_plan_MutatorContext_initMutator__I(th->MutatorContext, (int32_t)_th->getThreadID());
th->realRoutine(_th);
JnJVM_org_mmtk_plan_MutatorContext_deinitMutator__(th->MutatorContext);
}
bool Collector::isLive(gc* ptr) {
return JnJVM_org_mmtk_plan_marksweep_MSTraceLocal_isLive__Lorg_vmmagic_unboxed_ObjectReference_2(TraceLocal, ptr);
}
void Collector::scanObject(void** ptr) {
JnJVM_org_mmtk_plan_TraceLocal_reportDelayedRootEdge__Lorg_vmmagic_unboxed_Address_2(TraceLocal, ptr);
}
void Collector::markAndTrace(void* source, void* ptr) {
assert(TraceLocal && "scanning without a trace local");
JnJVM_org_mmtk_plan_TraceLocal_processEdge__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_Address_2(TraceLocal, source, ptr);
}
void Collector::markAndTraceRoot(void* ptr) {
assert(TraceLocal && "scanning without a trace local");
JnJVM_org_mmtk_plan_TraceLocal_processRootEdge__Lorg_vmmagic_unboxed_Address_2Z(TraceLocal, ptr, true);
}
gc* Collector::retainForFinalize(gc* val) {
assert(TraceLocal && "scanning without a trace local");
return JnJVM_org_mmtk_plan_TraceLocal_retainForFinalize__Lorg_vmmagic_unboxed_ObjectReference_2(TraceLocal, val);
}
gc* Collector::retainReferent(gc* val) {
assert(TraceLocal && "scanning without a trace local");
return JnJVM_org_mmtk_plan_TraceLocal_retainReferent__Lorg_vmmagic_unboxed_ObjectReference_2(TraceLocal, val);
}
gc* Collector::getForwardedFinalizable(gc* val) {
assert(TraceLocal && "scanning without a trace local");
return JnJVM_org_mmtk_plan_TraceLocal_getForwardedFinalizable__Lorg_vmmagic_unboxed_ObjectReference_2(TraceLocal, val);
}
gc* Collector::getForwardedReference(gc* val) {
assert(TraceLocal && "scanning without a trace local");
return JnJVM_org_mmtk_plan_TraceLocal_getForwardedReference__Lorg_vmmagic_unboxed_ObjectReference_2(TraceLocal, val);
}
gc* Collector::getForwardedReferent(gc* val) {
assert(TraceLocal && "scanning without a trace local");
return JnJVM_org_mmtk_plan_TraceLocal_getForwardedReferent__Lorg_vmmagic_unboxed_ObjectReference_2(TraceLocal, val);
}
void Collector::collect() {
Java_org_j3_mmtk_Collection_triggerCollection__I(NULL, 2);
}
void Collector::initialise() {
// Allocate the memory for MMTk right now, to avoid conflicts with
// other allocators.
#if defined (__MACH__)
uint32 flags = MAP_PRIVATE | MAP_ANON | MAP_FIXED;
#else
uint32 flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED;
#endif
void* baseAddr = mmap((void*)0x30000000, 0x40000000, PROT_READ | PROT_WRITE,
flags, -1, 0);
if (baseAddr == MAP_FAILED) {
perror("mmap");
abort();
}
JnJVM_org_mmtk_utility_heap_HeapGrowthManager_boot__Lorg_vmmagic_unboxed_Extent_2Lorg_vmmagic_unboxed_Extent_2(128 * 1024 * 1024, 1024 * 1024 * 1024);
uintptr_t Plan = *org_j3_config_Selected_4Plan_static;
MMTkPlanBoot(Plan);
MMTkPlanPostBoot(Plan);
MMTkPlanFullBoot(Plan);
}
extern "C" void* MMTkMutatorAllocate(uint32_t size, VirtualTable* VT) {
void* val = MutatorThread::get()->Allocator.Allocate(size, "MMTk");
((void**)val)[0] = VT;
return val;
}
//TODO: Remove these.
std::set<gc*> __InternalSet__;
void* Collector::begOf(gc* obj) {
abort();
}