aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2012-06-04 11:51:03 +0200
committerLukas Larsson <[email protected]>2012-06-04 11:59:03 +0200
commit0374be0e7caf06a9d1af3daef2cea1f7b20a57ab (patch)
tree23385b33daa358eaf0a7dc290257f82207d412c9 /erts/emulator/beam
parent868f5446c1f133cc29fc2ef274697460886374c6 (diff)
parent9cfeeb9b7e66a3345cbc0e5b4b634cb5965635fc (diff)
downloadotp-0374be0e7caf06a9d1af3daef2cea1f7b20a57ab.tar.gz
otp-0374be0e7caf06a9d1af3daef2cea1f7b20a57ab.tar.bz2
otp-0374be0e7caf06a9d1af3daef2cea1f7b20a57ab.zip
Merge branch 'maint'
* maint: Remove stale code for hybrid heap and incremental GC Remove the hipe_bifs:show_message_area/0 BIF Remove support for erlang:system_info(global_heaps_size) Remove the erlang:garbage_collect_message_area/0 BIF Remove workarounds for hybrid and shared heaps in test suites Conflicts: erts/doc/src/erlang.xml erts/emulator/beam/erl_message.c erts/emulator/beam/erl_process.c erts/emulator/beam/erl_process.h erts/emulator/hipe/hipe_bif2.tab lib/hipe/cerl/erl_bif_types.erl
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/atom.names2
-rw-r--r--erts/emulator/beam/beam_bif_load.c4
-rw-r--r--erts/emulator/beam/beam_emu.c55
-rw-r--r--erts/emulator/beam/benchmark.c32
-rw-r--r--erts/emulator/beam/benchmark.h11
-rw-r--r--erts/emulator/beam/bif.c16
-rw-r--r--erts/emulator/beam/bif.tab2
-rw-r--r--erts/emulator/beam/copy.c433
-rw-r--r--erts/emulator/beam/dist.c4
-rw-r--r--erts/emulator/beam/erl_alloc.c3
-rw-r--r--erts/emulator/beam/erl_alloc.types13
-rwxr-xr-xerts/emulator/beam/erl_bif_info.c59
-rw-r--r--erts/emulator/beam/erl_bif_port.c2
-rw-r--r--erts/emulator/beam/erl_debug.c268
-rw-r--r--erts/emulator/beam/erl_debug.h18
-rw-r--r--erts/emulator/beam/erl_fun.h4
-rw-r--r--erts/emulator/beam/erl_init.c98
-rw-r--r--erts/emulator/beam/erl_message.c50
-rw-r--r--erts/emulator/beam/erl_nmgc.c1401
-rw-r--r--erts/emulator/beam/erl_nmgc.h364
-rw-r--r--erts/emulator/beam/erl_node_tables.c12
-rw-r--r--erts/emulator/beam/erl_process.c88
-rw-r--r--erts/emulator/beam/erl_process.h22
-rw-r--r--erts/emulator/beam/erl_vm.h19
-rw-r--r--erts/emulator/beam/external.c4
-rwxr-xr-xerts/emulator/beam/global.h201
26 files changed, 9 insertions, 3176 deletions
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index 78c566ed38..106fad030b 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -244,7 +244,6 @@ atom gather_sched_wall_time_result
atom getting_linked
atom getting_unlinked
atom global
-atom global_heaps_size
atom Gt='>'
atom grun
atom group_leader
@@ -259,7 +258,6 @@ atom hide
atom high
atom hipe_architecture
atom http httph https http_response http_request http_header http_eoh http_error http_bin httph_bin
-atom hybrid
atom id
atom if_clause
atom imports
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index 768c38dae1..4bf1c13421 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -688,10 +688,8 @@ check_process_code(Process* rp, Module* modp)
Uint mod_size;
BeamInstr* end;
Eterm* sp;
-#ifndef HYBRID /* FIND ME! */
struct erl_off_heap_header* oh;
int done_gc = 0;
-#endif
#define INSIDE(a) (start <= (a) && (a) < end)
@@ -750,7 +748,6 @@ check_process_code(Process* rp, Module* modp)
* See if there are funs that refer to the old version of the module.
*/
-#ifndef HYBRID /* FIND ME! */
rescan:
for (oh = MSO(rp).first; oh; oh = oh->next) {
if (thing_subtag(oh->thing_word) == FUN_SUBTAG) {
@@ -776,7 +773,6 @@ check_process_code(Process* rp, Module* modp)
}
}
}
-#endif
/*
* See if there are constants inside the module referenced by the process.
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 3973d1d378..15a937289d 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -26,7 +26,6 @@
#include "erl_vm.h"
#include "global.h"
#include "erl_process.h"
-#include "erl_nmgc.h"
#include "error.h"
#include "bif.h"
#include "big.h"
@@ -249,20 +248,6 @@ void** beam_ops;
extern int count_instructions;
#endif
-#if defined(HYBRID)
-#define SWAPIN \
- g_htop = global_htop; \
- g_hend = global_hend; \
- HTOP = HEAP_TOP(c_p); \
- E = c_p->stop
-
-#define SWAPOUT \
- global_htop = g_htop; \
- global_hend = g_hend; \
- HEAP_TOP(c_p) = HTOP; \
- c_p->stop = E
-
-#else
#define SWAPIN \
HTOP = HEAP_TOP(c_p); \
E = c_p->stop
@@ -290,8 +275,6 @@ extern int count_instructions;
#define LIGHT_SWAPIN HTOP = HEAP_TOP(c_p)
-#endif
-
#ifdef FORCE_HEAP_FRAGS
# define HEAP_SPACE_VERIFIED(Words) do { \
c_p->space_verified = (Words); \
@@ -453,36 +436,6 @@ extern int count_instructions;
CHECK_TERM(r(0)); \
} while (0)
-#ifdef HYBRID
-#ifdef INCREMENTAL
-#define TestGlobalHeap(Nh, Live, hp) \
- do { \
- unsigned need = (Nh); \
- ASSERT(global_heap <= g_htop && g_htop <= global_hend); \
- SWAPOUT; \
- reg[0] = r(0); \
- FCALLS -= need; \
- (hp) = IncAlloc(c_p,need,reg,(Live)); \
- r(0) = reg[0]; \
- SWAPIN; \
- } while (0)
-#else
-#define TestGlobalHeap(Nh, Live, hp) \
- do { \
- unsigned need = (Nh); \
- ASSERT(global_heap <= g_htop && g_htop <= global_hend); \
- if (g_hend - g_htop < need) { \
- SWAPOUT; \
- reg[0] = r(0); \
- FCALLS -= erts_global_garbage_collect(c_p, need, reg, (Live)); \
- r(0) = reg[0]; \
- SWAPIN; \
- } \
- (hp) = global_htop; \
- } while (0)
-#endif
-#endif /* HYBRID */
-
#define Init(N) make_blank(yb(N))
#define Init2(Y1, Y2) do { make_blank(Y1); make_blank(Y2); } while (0)
@@ -1174,12 +1127,6 @@ void process_main(void)
*/
register Eterm* HTOP REG_htop = NULL;
-
-#ifdef HYBRID
- Eterm *g_htop;
- Eterm *g_hend;
-#endif
-
/* Stack pointer. Grows downwards; points
* to last item pushed (normally a saved
* continuation pointer).
@@ -6534,10 +6481,8 @@ new_fun(Process* p, Eterm* reg, ErlFunEntry* fe, int num_free)
hp = funp->env;
erts_refc_inc(&fe->refc, 2);
funp->thing_word = HEADER_FUN;
-#ifndef HYBRID /* FIND ME! */
funp->next = MSO(p).first;
MSO(p).first = (struct erl_off_heap_header*) funp;
-#endif
funp->fe = fe;
funp->num_free = num_free;
funp->creator = p->id;
diff --git a/erts/emulator/beam/benchmark.c b/erts/emulator/beam/benchmark.c
index 7fbf44a03c..7ac14b8e8b 100644
--- a/erts/emulator/beam/benchmark.c
+++ b/erts/emulator/beam/benchmark.c
@@ -33,17 +33,6 @@ unsigned long long messages_copied;
unsigned long long messages_ego;
unsigned long long minor_gc;
unsigned long long major_gc;
-#ifdef HYBRID
-unsigned long long minor_global_gc;
-unsigned long long major_global_gc;
-unsigned long long gc_in_copy;
-#ifdef INCREMENTAL
-unsigned long long minor_gc_cycles;
-unsigned long long major_gc_cycles;
-unsigned long long minor_gc_stages;
-unsigned long long major_gc_stages;
-#endif
-#endif
#endif /* BM_COUNTERS */
#ifdef BM_TIMERS
@@ -191,17 +180,6 @@ void init_benchmarking()
messages_ego = 0;
minor_gc = 0;
major_gc = 0;
-#ifdef HYBRID
- minor_global_gc = 0;
- major_global_gc = 0;
- gc_in_copy = 0;
-#ifdef INCREMENTAL
- minor_gc_cycles = 0;
- major_gc_cycles = 0;
- minor_gc_stages = 0;
- major_gc_stages = 0;
-#endif
-#endif
#endif /* BM_COUNTERS */
#ifdef BM_HEAP_SIZES
@@ -243,16 +221,6 @@ void save_statistics()
erts_fprintf(file,"Number of processes spawned: %lld\n",processes_spawned);
erts_fprintf(file,"Number of local minor GCs: %lld\n",minor_gc);
erts_fprintf(file,"Number of local major GCs: %lld\n",major_gc);
-#ifdef HYBRID
- erts_fprintf(file,"Number of global minor GCs: %lld\n",minor_global_gc);
- erts_fprintf(file,"Number of global major GCs: %lld\n",major_global_gc);
-#ifdef INCREMENTAL
- erts_fprintf(file,"Number of minor GC-cycles: %lld\n",minor_gc_cycles);
- erts_fprintf(file,"Number of major GC-cycles: %lld\n",major_gc_cycles);
- erts_fprintf(file,"Number of minor GC-stages: %lld\n",minor_gc_stages);
- erts_fprintf(file,"Number of major GC-stages: %lld\n",major_gc_stages);
-#endif
-#endif
erts_fprintf(file,"Number of messages sent: %lld\n",messages_sent);
erts_fprintf(file,"Number of messages copied: %lld\n",messages_copied);
erts_fprintf(file,"Number of messages sent to self: %lld\n",messages_ego);
diff --git a/erts/emulator/beam/benchmark.h b/erts/emulator/beam/benchmark.h
index eedb06a1b6..003e821bce 100644
--- a/erts/emulator/beam/benchmark.h
+++ b/erts/emulator/beam/benchmark.h
@@ -99,17 +99,6 @@ extern unsigned long long messages_copied;
extern unsigned long long messages_ego;
extern unsigned long long minor_gc;
extern unsigned long long major_gc;
-#ifdef HYBRID
-extern unsigned long long minor_global_gc;
-extern unsigned long long major_global_gc;
-extern unsigned long long gc_in_copy;
-#ifdef INCREMENTAL
-extern unsigned long long minor_gc_cycles;
-extern unsigned long long major_gc_cycles;
-extern unsigned long long minor_gc_stages;
-extern unsigned long long major_gc_stages;
-#endif
-#endif
#define BM_COUNT(var) (var)++;
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index fcb130655a..6943c8852c 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -3507,22 +3507,6 @@ BIF_RETTYPE garbage_collect_0(BIF_ALIST_0)
}
/**********************************************************************/
-/* Perform garbage collection of the message area */
-
-BIF_RETTYPE garbage_collect_message_area_0(BIF_ALIST_0)
-{
-#if defined(HYBRID) && !defined(INCREMENTAL)
- int reds = 0;
-
- FLAGS(BIF_P) |= F_NEED_FULLSWEEP;
- reds = erts_global_garbage_collect(BIF_P, 0, NULL, 0);
- BIF_RET2(am_true, reds);
-#else
- BIF_RET(am_false);
-#endif
-}
-
-/**********************************************************************/
/* Return a list of active ports */
BIF_RETTYPE ports_0(BIF_ALIST_0)
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index 698bbf0098..f7dad2767f 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -99,8 +99,6 @@ bif erlang:garbage_collect/0
bif 'erl.system':garbage_collect/0 ebif_garbage_collect_0
bif erlang:garbage_collect/1
bif 'erl.system':garbage_collect/1 ebif_garbage_collect_1
-bif erlang:garbage_collect_message_area/0
-bif 'erl.system':garbage_collect_message_area/0 ebif_garbage_collect_message_area_0
bif erlang:get/0
bif 'erl.lang.proc.pdict':get/0 ebif_get_0
bif erlang:get/1
diff --git a/erts/emulator/beam/copy.c b/erts/emulator/beam/copy.c
index d7345c2f54..36eda04de2 100644
--- a/erts/emulator/beam/copy.c
+++ b/erts/emulator/beam/copy.c
@@ -26,30 +26,13 @@
#include "global.h"
#include "erl_process.h"
#include "erl_gc.h"
-#include "erl_nmgc.h"
#include "big.h"
#include "erl_binary.h"
#include "erl_bits.h"
#include "dtrace-wrapper.h"
-#ifdef HYBRID
-MA_STACK_DECLARE(src);
-MA_STACK_DECLARE(dst);
-MA_STACK_DECLARE(offset);
-#endif
-
static void move_one_frag(Eterm** hpp, Eterm* src, Uint src_sz, ErlOffHeap*);
-void
-init_copy(void)
-{
-#ifdef HYBRID
- MA_STACK_ALLOC(src);
- MA_STACK_ALLOC(dst);
- MA_STACK_ALLOC(offset);
-#endif
-}
-
/*
* Copy object "obj" to process p.
*/
@@ -432,12 +415,10 @@ Eterm copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
while (i--) {
*htop++ = *objp++;
}
-#ifndef HYBRID /* FIND ME! */
funp = (ErlFunThing *) tp;
funp->next = off_heap->first;
off_heap->first = (struct erl_off_heap_header*) funp;
erts_refc_inc(&funp->fe->refc, 2);
-#endif
*argp = make_fun_rel(tp, dst_base);
}
break;
@@ -500,420 +481,6 @@ Eterm copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
return res;
}
-#ifdef HYBRID
-
-#ifdef BM_MESSAGE_SIZES
-# define BM_ADD(var,val) (var) += (val);
-#else
-# define BM_ADD(var,val)
-#endif
-
-#ifdef DEBUG
-# define CLEARMEM(PTR,SIZE) memset(PTR,0,SIZE*sizeof(Eterm))
-#else
-# define CLEARMEM(PTR,SIZE)
-#endif
-
-#ifdef INCREMENTAL
-#define GlobalAlloc(p, need, hp) \
-do { \
- Uint n = (need); \
- BM_ADD(words_copied,n); \
- BM_SWAP_TIMER(copy,system); \
- /* If a new collection cycle is started during copy, the message * \
- * will end up in the old generation and all allocations * \
- * thereafter must go directly into the old generation. */ \
- if (alloc_old) { \
- erts_incremental_gc((p),n,&dest,1); \
- (hp) = erts_inc_alloc(n); \
- } else { \
- (hp) = IncAlloc((p),n,&dest,1); \
- if (ma_gc_flags & GC_CYCLE_START) { \
- alloc_old = 1; \
- global_htop = global_heap; \
- (hp) = erts_inc_alloc(n); \
- } \
- } \
- CLEARMEM((hp),(n)); \
- BM_SWAP_TIMER(system,copy); \
-} while(0)
-
-#else /* no INCREMELNTAL */
-
-#define GlobalAlloc(p, need, hp) \
-do { \
- Uint n = (need); \
- total_need += n; \
- if (total_need >= global_heap_sz) \
- erl_exit(ERTS_ABORT_EXIT, "Copying a message (%d words) larger than the nursery simply won't work...\n", total_need); \
- if (global_hend - n < global_htop) { \
- BM_SWAP_TIMER(copy,system); \
- erts_global_garbage_collect((p),total_need,NULL,0); \
- BM_SWAP_TIMER(system,copy); \
- total_need = 0; \
- ma_src_top = 0; \
- ma_dst_top = 0; \
- ma_offset_top = 0; \
- goto copy_start; \
- } \
- (hp) = global_htop; \
- global_htop += n; \
- BM_ADD(words_copied,n); \
-} while(0)
-#endif /* INCREMENTAL */
-
-/* Copy a message to the message area. */
-Eterm copy_struct_lazy(Process *from, Eterm orig, Uint offs)
-{
- Eterm obj;
- Eterm dest;
-#ifdef INCREMENTAL
- int alloc_old = 0;
-#else
- int total_need = 0;
-#endif
-
- VERBOSE(DEBUG_MESSAGES,
- ("COPY START; %T is sending a message @ 0x%016x\n%T\n",
- from->id, orig, orig));
-
-#ifndef INCREMENTAL
- copy_start:
-#endif
- MA_STACK_PUSH(src,orig);
- MA_STACK_PUSH(dst,&dest);
- MA_STACK_PUSH(offset,offs);
-
- while (ma_src_top > 0) {
- obj = MA_STACK_POP(src);
-
- /* copy_struct_lazy should never be called with something that
- * do not need to be copied. Within the loop, nothing that do
- * not need copying should be placed in the src-stack.
- */
- ASSERT(!NO_COPY(obj));
-
- switch (primary_tag(obj)) {
- case TAG_PRIMARY_LIST: {
- Eterm *hp;
- Eterm *objp;
-
- GlobalAlloc(from,2,hp);
- objp = list_val(obj);
-
- MA_STACK_UPDATE(dst,MA_STACK_POP(offset),make_list(hp));
- MA_STACK_POP(dst);
-
- /* TODO: Byt ordningen nedan så att CDR pushas först. */
-
- if (NO_COPY(*objp)) {
- hp[0] = *objp;
-#ifdef INCREMENTAL
- if (ptr_within(ptr_val(*objp),inc_fromspc,inc_fromend))
- INC_STORE(gray,hp,2);
-#endif
- } else {
- MA_STACK_PUSH(src,*objp);
- MA_STACK_PUSH(dst,hp);
- MA_STACK_PUSH(offset,0);
- }
-
- objp++;
-
- if (NO_COPY(*objp)) {
- hp[1] = *objp;
-#ifdef INCREMENTAL
- if (ptr_within(ptr_val(*objp),inc_fromspc,inc_fromend))
- INC_STORE(gray,hp,2);
-#endif
- }
- else {
- MA_STACK_PUSH(src,*objp);
- MA_STACK_PUSH(dst,hp);
- MA_STACK_PUSH(offset,1);
- }
- continue;
- }
-
- case TAG_PRIMARY_BOXED: {
- Eterm *objp = boxed_val(obj);
-
- switch (*objp & _TAG_HEADER_MASK) {
- case ARITYVAL_SUBTAG: {
- Uint ari = arityval(*objp);
- Uint i;
- Eterm *hp;
- GlobalAlloc(from,ari + 1,hp);
- /* A GC above might invalidate the value of objp */
- objp = boxed_val(obj);
- MA_STACK_UPDATE(dst,MA_STACK_POP(offset),make_tuple(hp));
- MA_STACK_POP(dst);
- *hp = *objp++;
- for (i = 1; i <= ari; i++) {
- switch (primary_tag(*objp)) {
- case TAG_PRIMARY_LIST:
- case TAG_PRIMARY_BOXED:
- if (NO_COPY(*objp)) {
- hp[i] = *objp;
-#ifdef INCREMENTAL
- if (ptr_within(ptr_val(*objp),
- inc_fromspc,inc_fromend))
- INC_STORE(gray,hp,BOXED_NEED(hp,*hp));
-#endif
- objp++;
- } else {
- MA_STACK_PUSH(src,*objp++);
- MA_STACK_PUSH(dst,hp);
- MA_STACK_PUSH(offset,i);
- }
- break;
- default:
- hp[i] = *objp++;
- }
- }
- continue;
- }
-
- case REFC_BINARY_SUBTAG: {
- ProcBin *pb;
- Uint i = thing_arityval(*objp) + 1;
- Eterm *hp;
- GlobalAlloc(from,i,hp);
- /* A GC above might invalidate the value of objp */
- objp = boxed_val(obj);
- MA_STACK_UPDATE(dst,MA_STACK_POP(offset),make_binary(hp));
- MA_STACK_POP(dst);
- pb = (ProcBin*) hp;
- while (i--) {
- *hp++ = *objp++;
- }
- erts_refc_inc(&pb->val->refc, 2);
- pb->next = erts_global_offheap.first;
- erts_global_offheap.first = pb;
- OH_OVERHEAD(off_heap, pb->size / sizeof(Eterm));
- continue;
- }
-
- case FUN_SUBTAG: {
- ErlFunThing *funp = (ErlFunThing*) objp;
- Uint i = thing_arityval(*objp) + 1;
- Uint j = i + 1 + funp->num_free;
- Uint k = i;
- Eterm *hp, *hp_start;
- GlobalAlloc(from,j,hp);
- /* A GC above might invalidate the value of objp */
- objp = boxed_val(obj);
- hp_start = hp;
- MA_STACK_UPDATE(dst,MA_STACK_POP(offset),make_fun(hp));
- MA_STACK_POP(dst);
- funp = (ErlFunThing*) hp;
- while (i--) {
- *hp++ = *objp++;
- }
-#ifndef HYBRID /* FIND ME! */
- funp->next = erts_global_offheap.first;
- erts_global_offheap.first = funp;
- erts_refc_inc(&funp->fe->refc, 2);
-#endif
- for (i = k; i < j; i++) {
- switch (primary_tag(*objp)) {
- case TAG_PRIMARY_LIST:
- case TAG_PRIMARY_BOXED:
- if (NO_COPY(*objp)) {
-#ifdef INCREMENTAL
- if (ptr_within(ptr_val(*objp),
- inc_fromspc,inc_fromend))
- INC_STORE(gray,hp,BOXED_NEED(hp,*hp));
-#endif
- *hp++ = *objp++;
- } else {
- MA_STACK_PUSH(src,*objp++);
- MA_STACK_PUSH(dst,hp_start);
- MA_STACK_PUSH(offset,i);
- hp++;
- }
- break;
- default:
- *hp++ = *objp++;
- }
- }
- continue;
- }
-
- case EXTERNAL_PID_SUBTAG:
- case EXTERNAL_PORT_SUBTAG:
- case EXTERNAL_REF_SUBTAG: {
- ExternalThing *etp;
- Uint i = thing_arityval(*objp) + 1;
- Eterm *hp;
- GlobalAlloc(from,i,hp);
- /* A GC above might invalidate the value of objp */
- objp = boxed_val(obj);
- MA_STACK_UPDATE(dst,MA_STACK_POP(offset),make_external(hp));
- MA_STACK_POP(dst);
- etp = (ExternalThing*) hp;
- while (i--) {
- *hp++ = *objp++;
- }
-
- etp->next = erts_global_offheap.first;
- erts_global_offheap.first = etp;
- erts_refc_inc(&etp->node->refc, 2);
- continue;
- }
-
- case SUB_BINARY_SUBTAG: {
- ErlSubBin *sb = (ErlSubBin *) objp;
- Eterm *hp;
- Eterm res_binary;
- Eterm real_bin = sb->orig;
- Uint bit_offset = sb->bitoffs;
- Uint bit_size = sb -> bitsize;
- Uint sub_offset = sb->offs;
- size_t size = sb->size;
- Uint extra_bytes;
- Uint real_size;
- Uint sub_binary_heapneed;
- if ((bit_size + bit_offset) > 8) {
- extra_bytes = 2;
- sub_binary_heapneed = ERL_SUB_BIN_SIZE;
- } else if ((bit_size + bit_offset) > 0) {
- extra_bytes = 1;
- sub_binary_heapneed = ERL_SUB_BIN_SIZE;
- } else {
- extra_bytes = 0;
- sub_binary_heapneed = 0;
- }
-
- real_size = size+extra_bytes;
- objp = binary_val(real_bin);
- if (thing_subtag(*objp) == HEAP_BINARY_SUBTAG) {
- ErlHeapBin *from_bin;
- ErlHeapBin *to_bin;
- Uint i = heap_bin_size(real_size);
- GlobalAlloc(from,i+sub_binary_heapneed,hp);
- from_bin = (ErlHeapBin *) objp;
- to_bin = (ErlHeapBin *) hp;
- to_bin->thing_word = header_heap_bin(real_size);
- to_bin->size = real_size;
- sys_memcpy(to_bin->data, ((byte *)from_bin->data) +
- sub_offset, real_size);
- res_binary = make_binary(to_bin);
- hp += i;
- } else {
- ProcBin *from_bin;
- ProcBin *to_bin;
-
- ASSERT(thing_subtag(*objp) == REFC_BINARY_SUBTAG);
- from_bin = (ProcBin *) objp;
- erts_refc_inc(&from_bin->val->refc, 2);
- GlobalAlloc(from,PROC_BIN_SIZE+sub_binary_heapneed,hp);
- to_bin = (ProcBin *) hp;
- to_bin->thing_word = HEADER_PROC_BIN;
- to_bin->size = real_size;
- to_bin->val = from_bin->val;
- to_bin->bytes = from_bin->bytes + sub_offset;
- to_bin->next = erts_global_offheap.first;
- erts_global_offheap.first = to_bin;
- OH_OVERHEAD(&erts_global_offheap, to_bin->size / sizeof(Eterm));
- res_binary=make_binary(to_bin);
- hp += PROC_BIN_SIZE;
- }
- if (extra_bytes != 0) {
- ErlSubBin* res;
- res = (ErlSubBin *) hp;
- res->thing_word = HEADER_SUB_BIN;
- res->size = size;
- res->bitsize = bit_size;
- res->bitoffs = bit_offset;
- res->offs = 0;
- res->is_writable = 0;
- res->orig = res_binary;
- res_binary = make_binary(hp);
- }
- MA_STACK_UPDATE(dst,MA_STACK_POP(offset),res_binary);
- MA_STACK_POP(dst);
- continue;
- }
-
- case BIN_MATCHSTATE_SUBTAG:
- erl_exit(ERTS_ABORT_EXIT,
- "copy_struct_lazy: matchstate term not allowed");
-
- default: {
- Uint size = thing_arityval(*objp) + 1;
- Eterm *hp;
- GlobalAlloc(from,size,hp);
- /* A GC above might invalidate the value of objp */
- objp = boxed_val(obj);
- MA_STACK_UPDATE(dst,MA_STACK_POP(offset),make_boxed(hp));
- MA_STACK_POP(dst);
- while (size--) {
- *hp++ = *objp++;
- }
- continue;
- }
- }
- continue;
- }
-
- case TAG_PRIMARY_HEADER:
- ASSERT((obj & _TAG_HEADER_MASK) == ARITYVAL_SUBTAG);
- {
- Eterm *objp = &obj;
- Uint ari = arityval(obj);
- Uint i;
- Eterm *hp;
- GlobalAlloc(from,ari + 1,hp);
- MA_STACK_UPDATE(dst,MA_STACK_POP(offset),make_tuple(hp));
- MA_STACK_POP(dst);
- *hp = *objp++;
- for (i = 1; i <= ari; i++) {
- switch (primary_tag(*objp)) {
- case TAG_PRIMARY_LIST:
- case TAG_PRIMARY_BOXED:
- if (NO_COPY(*objp)) {
-#ifdef INCREMENTAL
- if (ptr_within(ptr_val(*objp),inc_fromspc,inc_fromend))
- INC_STORE(gray,hp,ari + 1);
-#endif
- hp[i] = *objp++;
- } else {
- MA_STACK_PUSH(src,*objp++);
- MA_STACK_PUSH(dst,hp);
- MA_STACK_PUSH(offset,i);
- }
- break;
- default:
- hp[i] = *objp++;
- }
- }
- continue;
- }
-
- default:
- erl_exit(ERTS_ABORT_EXIT,
- "%s, line %d: Internal error in copy_struct_lazy: 0x%08x\n",
- __FILE__, __LINE__,obj);
- }
- }
-
- VERBOSE(DEBUG_MESSAGES,
- ("Copy allocated @ 0x%08lx:\n%T\n",
- (unsigned long)ptr_val(dest),dest));
-
- ma_gc_flags &= ~GC_CYCLE_START;
-
- ASSERT(eq(orig, dest));
- ASSERT(ma_src_top == 0);
- ASSERT(ma_dst_top == 0);
- ASSERT(ma_offset_top == 0);
- return dest;
-}
-
-#undef NO_COPY
-#endif /* HYBRID */
-
/*
* Copy a term that is guaranteed to be contained in a single
* heap block. The heap block is copied word by word, and any
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index 4b85909828..300c2b708f 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -1578,11 +1578,9 @@ int erts_net_message(Port *prt,
}
erts_cleanup_offheap(&off_heap);
-#ifndef HYBRID /* FIND ME! */
if (ctl != ctl_default) {
erts_free(ERTS_ALC_T_DCTRL_BUF, (void *) ctl);
}
-#endif
UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE);
ERTS_SMP_CHK_NO_PROC_LOCKS;
return 0;
@@ -1595,11 +1593,9 @@ int erts_net_message(Port *prt,
data_error:
PURIFY_MSG("data error");
erts_cleanup_offheap(&off_heap);
-#ifndef HYBRID /* FIND ME! */
if (ctl != ctl_default) {
erts_free(ERTS_ALC_T_DCTRL_BUF, (void *) ctl);
}
-#endif
UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE);
erts_do_exit_port(prt, dep->cid, am_killed);
ERTS_SMP_CHK_NO_PROC_LOCKS;
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index c501b79b1f..918a800555 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -2138,9 +2138,6 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
tmp = alcu_size(ERTS_ALC_A_EHEAP, NULL, 0);
}
tmp += erts_max_processes*sizeof(Process*);
-#ifdef HYBRID
- tmp += erts_max_processes*sizeof(Process*);
-#endif
tmp += erts_bif_timer_memory_size();
tmp += erts_tot_link_lh_size();
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index 4c1424350f..134de6dfa6 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -320,19 +320,6 @@ type ACTIVE_PROCS STANDARD PROCESSES active_procs
+endif
-+if hybrid
-
-type ACTIVE_PROCS STANDARD PROCESSES active_procs
-
-# Used for all memory involved in incremental gc of the message area
-# that is, young (x2) and old generation, forwarding pointers and blackmap
-type MESSAGE_AREA LONG_LIVED PROCESSES message_area
-
-# Used in MA_STACK (global.h) and INC_STORAGE (erl_nmgc.h)
-type OBJECT_STACK STANDARD PROCESSES object_stack
-
-+endif
-
+if smp
type SL_PTIMER SHORT_LIVED SYSTEM ptimer_sl
type LL_PTIMER STANDARD SYSTEM ptimer_ll
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index eb98d2f6dd..e2f7c8673f 100755
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -25,7 +25,6 @@
#include "erl_vm.h"
#include "global.h"
#include "erl_process.h"
-#include "erl_nmgc.h"
#include "error.h"
#include "erl_driver.h"
#include "bif.h"
@@ -89,12 +88,6 @@ static char erts_system_version[] = ("Erlang " ERLANG_OTP_RELEASE
#ifdef ERTS_ENABLE_KERNEL_POLL
" [kernel-poll:%s]"
#endif
-#ifdef HYBRID
- " [hybrid heap]"
-#endif
-#ifdef INCREMENTAL
- " [incremental GC]"
-#endif
#ifdef ET_DEBUG
#if ET_DEBUG
" [type-assertions]"
@@ -576,9 +569,6 @@ static Eterm pi_args[] = {
am_min_bin_vheap_size,
am_current_location,
am_current_stacktrace,
-#ifdef HYBRID
- am_message_binary
-#endif
};
#define ERTS_PI_ARGS ((int) (sizeof(pi_args)/sizeof(Eterm)))
@@ -626,9 +616,6 @@ pi_arg2ix(Eterm arg)
case am_min_bin_vheap_size: return 28;
case am_current_location: return 29;
case am_current_stacktrace: return 30;
-#ifdef HYBRID
- case am_message_binary: return 31;
-#endif
default: return -1;
}
}
@@ -1081,12 +1068,8 @@ process_info_aux(Process *BIF_P,
if (rp != BIF_P) {
Eterm msg = ERL_MESSAGE_TERM(mq[i].msgp);
if (is_value(msg)) {
- mq[i].copy_struct_size = (is_immed(msg)
-#ifdef HYBRID
- || NO_COPY(msg)
-#endif
- ? 0
- : size_object(msg));
+ mq[i].copy_struct_size = (is_immed(msg)? 0 :
+ size_object(msg));
}
else if (mq[i].msgp->data.attached) {
mq[i].copy_struct_size
@@ -1528,16 +1511,6 @@ process_info_aux(Process *BIF_P,
break;
}
-#ifdef HYBRID
- case am_message_binary: {
- Uint sz = 3;
- (void) bld_bin_list(NULL, &sz, erts_global_offheap.mso);
- hp = HAlloc(BIF_P, sz);
- res = bld_bin_list(&hp, NULL, erts_global_offheap.mso);
- break;
- }
-#endif
-
case am_sequential_trace_token:
res = copy_object(rp->seq_trace_token, BIF_P);
hp = HAlloc(BIF_P, 3);
@@ -2356,36 +2329,8 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
#endif
} else if (BIF_ARG_1 == am_heap_sizes) {
return erts_heap_sizes(BIF_P);
- } else if (BIF_ARG_1 == am_global_heaps_size) {
-#ifdef HYBRID
- Uint hsz = 0;
- Uint sz = 0;
-
- sz += global_heap_sz;
-#ifdef INCREMENTAL
- /* The size of the old generation is a bit hard to define here...
- * The amount of live data in the last collection perhaps..? */
- sz = 0;
-#else
- if (global_old_hend && global_old_heap)
- sz += global_old_hend - global_old_heap;
-#endif
-
- sz *= sizeof(Eterm);
-
- (void) erts_bld_uint(NULL, &hsz, sz);
- hp = hsz ? HAlloc(BIF_P, hsz) : NULL;
- res = erts_bld_uint(&hp, NULL, sz);
-#else
- res = make_small(0);
-#endif
- return res;
} else if (BIF_ARG_1 == am_heap_type) {
-#if defined(HYBRID)
- return am_hybrid;
-#else
return am_private;
-#endif
} else if (ERTS_IS_ATOM_STR("cpu_topology", BIF_ARG_1)) {
res = erts_get_cpu_topology_term(BIF_P, am_used);
BIF_TRAP1(erts_format_cpu_topology_trap, BIF_P, res);
diff --git a/erts/emulator/beam/erl_bif_port.c b/erts/emulator/beam/erl_bif_port.c
index 5525426824..2a1b01b107 100644
--- a/erts/emulator/beam/erl_bif_port.c
+++ b/erts/emulator/beam/erl_bif_port.c
@@ -265,7 +265,7 @@ port_call(Process* c_p, Eterm arg1, Eterm arg2, Eterm arg3)
Eterm res;
Sint result_size;
Eterm *hp;
- Eterm *hp_end; /* To satisfy hybrid heap architecture */
+ Eterm *hp_end;
unsigned ret_flags = 0U;
int fpe_was_unmasked;
diff --git a/erts/emulator/beam/erl_debug.c b/erts/emulator/beam/erl_debug.c
index d7d6fcf0a2..2121f72fd2 100644
--- a/erts/emulator/beam/erl_debug.c
+++ b/erts/emulator/beam/erl_debug.c
@@ -25,7 +25,6 @@
#include "erl_vm.h"
#include "global.h"
#include "erl_process.h"
-#include "erl_nmgc.h"
#include "big.h"
#include "bif.h"
#include "beam_catches.h"
@@ -33,34 +32,9 @@
#define WITHIN(ptr, x, y) ((x) <= (ptr) && (ptr) < (y))
-#if defined(HYBRID)
-#if defined(INCREMENTAL)
-/* Hybrid + Incremental */
-#define IN_HEAP(p, ptr) \
- (WITHIN((ptr), p->heap, p->hend) || \
- (OLD_HEAP(p) && WITHIN((ptr), OLD_HEAP(p), OLD_HEND(p))) || \
- WITHIN((ptr), global_heap, global_hend) || \
- (inc_fromspc && WITHIN((ptr), inc_fromspc, inc_fromend)) || \
- WITHIN((ptr), global_old_heap, global_old_hend))
-
-#define IN_MA(ptr) \
- (WITHIN((ptr), global_heap, global_hend) || \
- (inc_fromspc && WITHIN((ptr), inc_fromspc, inc_fromend)) || \
- WITHIN((ptr), global_old_heap, global_old_hend))
-#else
-/* Hybrid */
-#define IN_HEAP(p, ptr) \
- (WITHIN((ptr), p->heap, p->hend) || \
- (OLD_HEAP(p) && WITHIN((ptr), OLD_HEAP(p), OLD_HEND(p))) || \
- WITHIN((ptr), global_heap, global_hend) || \
- (global_old_heap && WITHIN((ptr),global_old_heap,global_old_hend)))
-#endif
-#else
-/* Private */
#define IN_HEAP(p, ptr) \
(WITHIN((ptr), p->heap, p->hend) || \
(OLD_HEAP(p) && WITHIN((ptr), OLD_HEAP(p), OLD_HEND(p))))
-#endif
#ifdef __GNUC__
@@ -266,13 +240,6 @@ static int verify_eterm(Process *p,Eterm element)
}
}
}
-#ifdef INCREMENTAL
- else {
- if (IN_MA(ptr))
- return 1;
- }
-#endif
-
return 0;
}
@@ -447,51 +414,12 @@ void verify_process(Process *p)
VERIFY_ETERM("fvalue",p->fvalue);
VERIFY_ETERM("ftrace",p->ftrace);
-#ifdef HYBRID
- VERIFY_AREA("rrma",p->rrma,p->nrr);
-#endif
-
VERBOSE(DEBUG_MEMORY,("...done\n"));
#undef VERIFY_AREA
#undef VERIFY_ETERM
}
-void verify_everything()
-{
-#ifdef HYBRID
- Uint i;
- Uint n = erts_num_active_procs;
-
-#ifdef INCREMENTAL_FREE_SIZES_NEEDS_TO_BE_TAGGED_AS_HEADERS_WITH_ARITY
- INC_Page *page = inc_used_mem;
-#endif
-
- for (i = 0; i < n; i++) {
- verify_process(erts_active_procs[i]);
- }
-
- erts_check_memory(NULL,global_heap,global_htop);
-
-#ifdef INCREMENTAL_FREE_SIZES_NEEDS_TO_BE_TAGGED_AS_HEADERS_WITH_ARITY
- while (page)
- {
- Eterm *end = page + INC_PAGE_SIZE;
- Eterm *pos = page->start;
-
- while( pos < end) {
- Eterm val = *pos++;
- if(is_header(val))
- pos += thing_arityval(val);
- else
- verify_eterm(NULL,val);
- }
- page = page->next;
- }
-#endif
-#endif /* HYBRID */
-}
-
/*
* print_untagged_memory will print the contents of given memory area.
*/
@@ -582,83 +510,6 @@ void print_tagged_memory(Eterm *pos, Eterm *end)
erts_printf("+-%s-+-%s-+\n",dashes,dashes);
}
-#ifdef HYBRID
-void print_ma_info(void)
-{
- erts_printf("Message Area (start - top - end): "
- "0x%0*lx - 0x%0*lx - 0x%0*lx\n",
- PTR_SIZE, (unsigned long)global_heap,
- PTR_SIZE, (unsigned long)global_htop,
- PTR_SIZE, (unsigned long)global_hend);
-#ifndef INCREMENTAL
- erts_printf(" High water: 0x%0*lx "
- "Old gen: 0x%0*lx - 0x%0*lx - 0x%0*lx\n",
- PTR_SIZE, (unsigned long)global_high_water,
- PTR_SIZE, (unsigned long)global_old_heap,
- PTR_SIZE, (unsigned long)global_old_htop,
- PTR_SIZE, (unsigned long)global_old_hend);
-#endif
-}
-
-void print_message_area(void)
-{
- Eterm *pos = global_heap;
- Eterm *end = global_htop;
-
- erts_printf("From: 0x%0*lx to 0x%0*lx\n",
- PTR_SIZE,(unsigned long)pos,PTR_SIZE,(unsigned long)end);
- erts_printf("(Old generation: 0x%0*lx to 0x%0*lx\n",
- PTR_SIZE, (unsigned long)global_old_heap,
- PTR_SIZE, (unsigned long)global_old_hend);
- erts_printf("| %-*s | %-*s |\n",PTR_SIZE,"Address",PTR_SIZE,"Contents");
- erts_printf("|-%s-|-%s-|\n",dashes,dashes);
- while( pos < end ) {
- Eterm val = pos[0];
- erts_printf("| 0x%0*lx | 0x%0*lx | ",
- PTR_SIZE,(unsigned long)pos,PTR_SIZE,(unsigned long)val);
- ++pos;
- if( is_arity_value(val) ) {
- erts_printf("Arity(%lu)", arityval(val));
- } else if( is_thing(val) ) {
- unsigned int ari = thing_arityval(val);
- erts_printf("Thing Arity(%u) Tag(%lu)", ari, thing_subtag(val));
- while( ari ) {
- erts_printf("\n| 0x%0*lx | 0x%0*lx | THING",
- PTR_SIZE, (unsigned long)pos,
- PTR_SIZE, (unsigned long)*pos);
- ++pos;
- --ari;
- }
- } else
- erts_printf("%.30T", val);
- erts_printf("\n");
- }
- erts_printf("+-%s-+-%s-+\n",dashes,dashes);
-}
-
-void check_message_area()
-{
- Eterm *pos = global_heap;
- Eterm *end = global_htop;
-
- while( pos < end ) {
- Eterm val = *pos++;
- if(is_header(val))
- pos += thing_arityval(val);
- else if(!is_immed(val))
- if ((ptr_val(val) < global_heap || ptr_val(val) >= global_htop) &&
- (ptr_val(val) < global_old_heap ||
- ptr_val(val) >= global_old_hend))
- {
- erts_printf("check_message_area: Stray pointer found\n");
- print_message_area();
- erts_printf("Crashing to make it look real...\n");
- pos = 0;
- }
- }
-}
-#endif /* HYBRID */
-
static void print_process_memory(Process *p);
static void print_process_memory(Process *p)
{
@@ -703,19 +554,6 @@ static void print_process_memory(Process *p)
erts_printf(" Fvalue: 0x%0*lx\n",PTR_SIZE,p->fvalue);
erts_printf(" Ftrace: 0x%0*lx\n",PTR_SIZE,p->ftrace);
-#ifdef HYBRID
- if (p->nrr > 0) {
- int i;
- erts_printf(" Remembered Roots:\n");
- for (i = 0; i < p->nrr; i++)
- if (p->rrsrc[i] != NULL)
- erts_printf("0x%0*lx -> 0x%0*lx\n",
- PTR_SIZE, (unsigned long)p->rrsrc[i],
- PTR_SIZE, (unsigned long)p->rrma[i]);
- erts_printf("\n");
- }
-#endif
-
erts_printf("+- %-*s -+ 0x%0*lx 0x%0*lx %s-%s-+\n",
PTR_SIZE, "Stack",
PTR_SIZE, (unsigned long)STACK_TOP(p),
@@ -757,92 +595,6 @@ void print_memory(Process *p)
if (p != NULL) {
print_process_memory(p);
}
-#ifdef HYBRID
- else {
- Uint i;
- Uint n = erts_num_active_procs;
-
- for (i = 0; i < n; i++) {
- Process *p = erts_active_procs[i];
- print_process_memory(p);
- }
-
- erts_printf("==================\n");
- erts_printf("|| Message area ||\n");
- erts_printf("==================\n");
- erts_printf("+-%s-+-%s-%s-%s-%s-+\n",
- dashes,dashes,dashes,dashes,dashes);
- erts_printf("| %-*s | 0x%0*lx - 0x%0*lx - 0x%0*lx%*s|\n",
- PTR_SIZE, "Young",
- PTR_SIZE, (unsigned long)global_heap,
- PTR_SIZE, (unsigned long)global_htop,
- PTR_SIZE, (unsigned long)global_hend,
- PTR_SIZE, "");
- erts_printf("+-%s-+-%s-%s-%s-%s-+\n",
- dashes,dashes,dashes,dashes,dashes);
-
- print_untagged_memory(global_heap,global_htop);
-
-
- erts_printf("+-%s-+-%s-%s-%s-%s-+\n",
- dashes,dashes,dashes,dashes,dashes);
- erts_printf("| %-*s | 0x%0*lx - 0x%0*lx %*s |\n",
- PTR_SIZE, "Old",
- PTR_SIZE, (unsigned long)global_old_heap,
- PTR_SIZE, (unsigned long)global_old_hend,
- 2 * PTR_SIZE, "");
- erts_printf("+-%s-+-%s-%s-%s-%s-+\n",
- dashes,dashes,dashes,dashes,dashes);
-
-#ifdef INCREMENTAL
- {
- INC_Page *page = inc_used_mem;
- /* Genom att g� igenom fri-listan f�rst kan vi markera de
- omr�den som inte �r allokerade och bara skriva ut de som
- lever.
- char markarea[INC_PAGESIZE];
- */
-
- while (page) {
- Eterm *ptr = (Eterm*)page->start;
- Eterm *end = (Eterm*)page->start + INC_PAGESIZE;
-
- erts_printf("| %*s | This: 0x%0*lx Next: 0x%0*lx %*s|\n",
- PTR_SIZE, "",
- PTR_SIZE, (unsigned long)page,
- PTR_SIZE, (unsigned long)page->next,
- 2 * PTR_SIZE - 8, "");
- print_untagged_memory(ptr,end);
- page = page->next;
- }
- }
-
- {
- INC_MemBlock *this = inc_free_list;
-
- erts_printf("-- %-*s --%s-%s-%s-%s-\n",PTR_SIZE+2,"Free list",
- dashes,dashes,dashes,dashes);
- while (this) {
- erts_printf("Block @ 0x%0*lx sz: %8d prev: 0x%0*lx next: 0x%0*lx\n",
- PTR_SIZE, (unsigned long)this,this->size,
- PTR_SIZE, (unsigned long)this->prev,
- PTR_SIZE, (unsigned long)this->next);
- this = this->next;
- }
- erts_printf("--%s---%s-%s-%s-%s--\n",
- dashes,dashes,dashes,dashes,dashes);
- }
-
- if (inc_fromspc != NULL) {
- erts_printf("-- fromspace - 0x%0*lx 0x%0*lx "
- "------------------------------\n",
- PTR_SIZE, (unsigned long)inc_fromspc,
- PTR_SIZE, (unsigned long)inc_fromend);
- print_untagged_memory(inc_fromspc,inc_fromend);
- }
-#endif /* INCREMENTAL */
- }
-#endif /* HYBRID */
}
void print_memory_info(Process *p)
@@ -869,26 +621,6 @@ void print_memory_info(Process *p)
erts_printf("|| Memory info ||\n");
erts_printf("=================\n");
}
-#ifdef HYBRID
- erts_printf("|- message area --%s-%s-%s-%s-|\n",
- dashes,dashes,dashes,dashes);
- erts_printf("| Young | 0x%0*lx - 0x%0*lx - 0x%0*lx %*s |\n",
- PTR_SIZE, (unsigned long)global_heap,
- PTR_SIZE, (unsigned long)global_htop,
- PTR_SIZE, (unsigned long)global_hend,
- PTR_SIZE, "");
- erts_printf("| Old | 0x%0*lx - 0x%0*lx %*s |\n",
- PTR_SIZE, (unsigned long)global_old_heap,
- PTR_SIZE, (unsigned long)global_old_hend,
- 2 * PTR_SIZE, "");
-#endif
-#ifdef INCREMENTAL
- if (inc_fromspc != NULL)
- erts_printf("| Frmsp | 0x%0*lx - 0x%0*lx %*s |\n",
- PTR_SIZE, (unsigned long)inc_fromspc,
- PTR_SIZE, (unsigned long)inc_fromend,
- 2 * PTR_SIZE, "");
-#endif
erts_printf("+-----------------%s-%s-%s-%s-+\n",dashes,dashes,dashes,dashes);
}
#if !HEAP_ON_C_STACK && defined(DEBUG)
diff --git a/erts/emulator/beam/erl_debug.h b/erts/emulator/beam/erl_debug.h
index c49354a2b3..a028a95fef 100644
--- a/erts/emulator/beam/erl_debug.h
+++ b/erts/emulator/beam/erl_debug.h
@@ -42,12 +42,11 @@
#define DEBUG_DEFAULT 0x0000 /* No flags are set per default */
#define DEBUG_SYSTEM 0x0001 /* Misc system info at startup and end */
#define DEBUG_PRIVATE_GC 0x0002 /* GC of private heaps */
-#define DEBUG_HYBRID_GC 0x0004 /* GC of the message area */
-#define DEBUG_ALLOCATION 0x0008 /* HAlloc. To find holes in the heap */
-#define DEBUG_MESSAGES 0x0010 /* Message passing */
-#define DEBUG_THREADS 0x0020 /* Thread-related stuff */
-#define DEBUG_PROCESSES 0x0040 /* Process creation and removal */
-#define DEBUG_MEMORY 0x0080 /* Display results of memory checks */
+#define DEBUG_ALLOCATION 0x0004 /* HAlloc. To find holes in the heap */
+#define DEBUG_MESSAGES 0x0008 /* Message passing */
+#define DEBUG_THREADS 0x0010 /* Thread-related stuff */
+#define DEBUG_PROCESSES 0x0020 /* Process creation and removal */
+#define DEBUG_MEMORY 0x0040 /* Display results of memory checks */
extern Uint32 verbose;
@@ -88,7 +87,6 @@ extern void erts_check_stack(Process *p);
extern void erts_check_heap(Process *p);
extern void erts_check_memory(Process *p, Eterm *start, Eterm *end);
extern void verify_process(Process *p);
-extern void verify_everything(void);
extern void print_tagged_memory(Eterm *start, Eterm *end);
extern void print_untagged_memory(Eterm *start, Eterm *end);
extern void print_memory(Process *p);
@@ -99,10 +97,4 @@ extern void erts_debug_use_tmp_heap(int, Process *);
extern void erts_debug_unuse_tmp_heap(int, Process *);
#endif
-#ifdef HYBRID
-extern void print_ma_info(void);
-extern void print_message_area(void);
-extern void check_message_area(void);
-#endif
-
#endif /* _ERL_DEBUG_H_ */
diff --git a/erts/emulator/beam/erl_fun.h b/erts/emulator/beam/erl_fun.h
index 6023fa0448..217066ab11 100644
--- a/erts/emulator/beam/erl_fun.h
+++ b/erts/emulator/beam/erl_fun.h
@@ -54,9 +54,7 @@ typedef struct erl_fun_entry {
typedef struct erl_fun_thing {
Eterm thing_word; /* Subtag FUN_SUBTAG. */
ErlFunEntry* fe; /* Pointer to fun entry. */
-#ifndef HYBRID /* FIND ME! */
struct erl_off_heap_header* next;
-#endif
#ifdef HIPE
UWord* native_address; /* Native code for the fun. */
#endif
@@ -81,9 +79,7 @@ ErlFunEntry* erts_put_fun_entry2(Eterm mod, int old_uniq, int old_index,
byte* uniq, int index, int arity);
void erts_erase_fun_entry(ErlFunEntry* fe);
-#ifndef HYBRID /* FIND ME! */
void erts_cleanup_funs(ErlFunThing* funp);
-#endif
void erts_cleanup_funs_on_purge(BeamInstr* start, BeamInstr* end);
void erts_dump_fun_entries(int, void *);
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index f88d485448..d382e421e6 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -34,7 +34,6 @@
#include "erl_binary.h"
#include "dist.h"
#include "erl_mseg.h"
-#include "erl_nmgc.h"
#include "erl_threads.h"
#include "erl_bif_timer.h"
#include "erl_instrument.h"
@@ -209,28 +208,6 @@ Export *erts_delay_trap = NULL;
int erts_use_r9_pids_ports;
-#ifdef HYBRID
-Eterm *global_heap;
-Eterm *global_hend;
-Eterm *global_htop;
-Eterm *global_saved_htop;
-Eterm *global_old_heap;
-Eterm *global_old_hend;
-ErlOffHeap erts_global_offheap;
-Uint global_heap_sz = SH_DEFAULT_SIZE;
-
-#ifndef INCREMENTAL
-Eterm *global_high_water;
-Eterm *global_old_htop;
-#endif
-
-Uint16 global_gen_gcs;
-Uint16 global_max_gen_gcs;
-Uint global_gc_flags;
-
-Uint global_heap_min_sz = SH_DEFAULT_SIZE;
-#endif
-
int ignore_break;
int replace_intr;
@@ -337,7 +314,6 @@ erl_init(int ncpu)
erl_drv_thr_init();
erts_init_async();
init_io();
- init_copy();
init_load();
erts_init_bif();
erts_init_bif_chksum();
@@ -358,45 +334,6 @@ erl_init(int ncpu)
}
static void
-init_shared_memory(int argc, char **argv)
-{
-#ifdef HYBRID
- int arg_size = 0;
-
- global_heap_sz = erts_next_heap_size(global_heap_sz,0);
-
- /* Make sure arguments will fit on the heap, no one else will check! */
- while (argc--)
- arg_size += 2 + strlen(argv[argc]);
- if (global_heap_sz < arg_size)
- global_heap_sz = erts_next_heap_size(arg_size,1);
-
-#ifndef INCREMENTAL
- global_heap = (Eterm *) ERTS_HEAP_ALLOC(ERTS_ALC_T_HEAP,
- sizeof(Eterm) * global_heap_sz);
- global_hend = global_heap + global_heap_sz;
- global_htop = global_heap;
- global_high_water = global_heap;
- global_old_hend = global_old_htop = global_old_heap = NULL;
-#endif
-
- global_gen_gcs = 0;
- global_max_gen_gcs = (Uint16) erts_smp_atomic32_read_nob(&erts_max_gen_gcs);
- global_gc_flags = erts_default_process_flags;
-
- erts_global_offheap.mso = NULL;
-#ifndef HYBRID /* FIND ME! */
- erts_global_offheap.funs = NULL;
-#endif
- erts_global_offheap.overhead = 0;
-#endif
-
-#ifdef INCREMENTAL
- erts_init_incgc();
-#endif
-}
-
-static void
erl_first_process_otp(char* modname, void* code, unsigned size, int argc, char** argv)
{
int i;
@@ -1057,7 +994,6 @@ erl_start(int argc, char **argv)
switch (*ch) {
case 's': verbose |= DEBUG_SYSTEM; break;
case 'g': verbose |= DEBUG_PRIVATE_GC; break;
- case 'h': verbose |= DEBUG_HYBRID_GC; break;
case 'M': verbose |= DEBUG_MEMORY; break;
case 'a': verbose |= DEBUG_ALLOCATION; break;
case 't': verbose |= DEBUG_THREADS; break;
@@ -1070,7 +1006,6 @@ erl_start(int argc, char **argv)
erts_printf("Verbose level: ");
if (verbose & DEBUG_SYSTEM) erts_printf("SYSTEM ");
if (verbose & DEBUG_PRIVATE_GC) erts_printf("PRIVATE_GC ");
- if (verbose & DEBUG_HYBRID_GC) erts_printf("HYBRID_GC ");
if (verbose & DEBUG_MEMORY) erts_printf("PARANOID_MEMORY ");
if (verbose & DEBUG_ALLOCATION) erts_printf("ALLOCATION ");
if (verbose & DEBUG_THREADS) erts_printf("THREADS ");
@@ -1098,12 +1033,6 @@ erl_start(int argc, char **argv)
#ifdef HIPE
strcat(tmp, ",HIPE");
#endif
-#ifdef INCREMENTAL
- strcat(tmp, ",INCREMENTAL_GC");
-#endif
-#ifdef HYBRID
- strcat(tmp, ",HYBRID");
-#endif
erts_fprintf(stderr, "Erlang ");
if (tmp[1]) {
erts_fprintf(stderr, "(%s) ", tmp+1);
@@ -1555,7 +1484,6 @@ erl_start(int argc, char **argv)
erl_init(ncpu);
- init_shared_memory(boot_argc, boot_argv);
load_preloaded();
erts_end_staging_code_ix();
erts_commit_staging_code_ix();
@@ -1644,32 +1572,6 @@ system_cleanup(int flush_async)
#endif
#endif
-#ifdef HYBRID
- if (ma_src_stack) erts_free(ERTS_ALC_T_OBJECT_STACK,
- (void *)ma_src_stack);
- if (ma_dst_stack) erts_free(ERTS_ALC_T_OBJECT_STACK,
- (void *)ma_dst_stack);
- if (ma_offset_stack) erts_free(ERTS_ALC_T_OBJECT_STACK,
- (void *)ma_offset_stack);
- ma_src_stack = NULL;
- ma_dst_stack = NULL;
- ma_offset_stack = NULL;
- erts_cleanup_offheap(&erts_global_offheap);
-#endif
-
-#if defined(HYBRID) && !defined(INCREMENTAL)
- if (global_heap) {
- ERTS_HEAP_FREE(ERTS_ALC_T_HEAP,
- (void*) global_heap,
- sizeof(Eterm) * global_heap_sz);
- }
- global_heap = NULL;
-#endif
-
-#ifdef INCREMENTAL
- erts_cleanup_incgc();
-#endif
-
erts_exit_flush_async();
}
diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c
index b10964da52..241d61b868 100644
--- a/erts/emulator/beam/erl_message.c
+++ b/erts/emulator/beam/erl_message.c
@@ -29,7 +29,6 @@
#include "global.h"
#include "erl_message.h"
#include "erl_process.h"
-#include "erl_nmgc.h"
#include "erl_binary.h"
#include "dtrace-wrapper.h"
@@ -1005,53 +1004,6 @@ erts_send_message(Process* sender,
#endif
);
BM_SWAP_TIMER(send,system);
-#ifdef HYBRID
- } else {
- ErlMessage* mp = message_alloc();
- BM_SWAP_TIMER(send,copy);
-#ifdef INCREMENTAL
- /* TODO: During GC activate processes if the message relies in
- * the fromspace and the sender is active. During major
- * collections add the message to the gray stack if it relies
- * in the old generation and the sender is active and the
- * receiver is inactive.
-
- if (!IS_CONST(message) && (ma_gc_flags & GC_CYCLE) &&
- (ptr_val(message) >= inc_fromspc &&
- ptr_val(message) < inc_fromend) && INC_IS_ACTIVE(sender))
- INC_ACTIVATE(receiver);
- else if (!IS_CONST(message) && (ma_gc_flags & GC_CYCLE) &&
- (ptr_val(message) >= global_old_heap &&
- ptr_val(message) < global_old_hend) &&
- INC_IS_ACTIVE(sender) && !INC_IS_ACTIVE(receiver))
- Mark message in blackmap and add it to the gray stack
- */
-
- if (!IS_CONST(message))
- INC_ACTIVATE(receiver);
-#endif
- LAZY_COPY(sender,message);
- BM_SWAP_TIMER(copy,send);
- DTRACE6(message_send, sender_name, receiver_name,
- size_object(message)msize, tok_label, tok_lastcnt, tok_serial);
- ERL_MESSAGE_TERM(mp) = message;
- ERL_MESSAGE_TOKEN(mp) = NIL;
-#ifdef USE_VM_PROBES
- ERL_MESSAGE_DT_UTAG(mp) = NIL;
-#endif
- mp->next = NULL;
- LINK_MESSAGE(receiver, mp);
- ACTIVATE(receiver);
-
- erts_proc_notify_new_message(receiver);
-
- if (IS_TRACED_FL(receiver, F_TRACE_RECEIVE)) {
- trace_receive(receiver, message);
- }
-
- BM_SWAP_TIMER(send,system);
- return;
-#else
} else if (sender == receiver) {
/* Drop message if receiver has a pending exit ... */
#ifdef ERTS_SMP
@@ -1169,7 +1121,7 @@ erts_send_message(Process* sender,
}
BM_SWAP_TIMER(send,system);
#endif /* #ifndef ERTS_SMP */
-#endif /* HYBRID */
+ return;
}
}
diff --git a/erts/emulator/beam/erl_nmgc.c b/erts/emulator/beam/erl_nmgc.c
deleted file mode 100644
index 2a8c819360..0000000000
--- a/erts/emulator/beam/erl_nmgc.c
+++ /dev/null
@@ -1,1401 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2004-2011. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * %CopyrightEnd%
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-#include "global.h"
-#include "erl_gc.h"
-#include "erl_binary.h"
-#include "erl_nmgc.h"
-#include "erl_debug.h"
-#if HIPE
-#include "hipe_stack.h"
-#endif
-
-
-#ifdef INCREMENTAL
-/***************************************************************************
- * *
- * Incremental Garbage Collector for the Message Area *
- * *
- ***************************************************************************/
-
-/*
- * The heap pointers are declared in erl_init.c
- * global_heap is the nursery
- * global_old_heap is the old generation
- */
-unsigned char *blackmap = NULL;
-INC_Page *inc_used_mem = NULL;
-INC_MemBlock *inc_free_list = NULL;
-Eterm *inc_fromspc;
-Eterm *inc_fromend;
-Eterm *inc_nursery_scn_ptr;
-Eterm **fwdptrs;
-Eterm *inc_alloc_limit;
-Process *inc_active_proc;
-Process *inc_active_last;
-int inc_words_to_go;
-
-static Eterm *inc_last_nursery;
-static int inc_pages = INC_NoPAGES;
-static INC_Page *inc_bibop = NULL;
-static int inc_used_pages;
-
-/* Used when growing the old generation */
-/*
-#define INC_ROOTSAVE 16384
-static Eterm *root_save[INC_ROOTSAVE];
-static int roots_saved = 0;
-*/
-
-INC_STORAGE_DECLARATION(,gray);
-
-static void inc_minor_gc(Process *p, int need, Eterm* objv, int nobj);
-static void inc_major_gc(Process *p, int need, Eterm* objv, int nobj);
-
-#ifdef INC_TIME_BASED
-#if USE_PERFCTR
-
-/*
- * This uses the Linux perfctr extension to virtualise the
- * time-stamp counter.
- */
-#include "libperfctr.h"
-static struct vperfctr *vperfctr;
-static double cpu_khz;
-static double tsc_to_cpu_mult;
-
-static void inc_start_hrvtime(void)
-{
- struct perfctr_info info;
- struct vperfctr_control control;
-
- if( vperfctr != NULL )
- return;
- vperfctr = vperfctr_open();
- if( vperfctr == NULL )
- return;
- if( vperfctr_info(vperfctr, &info) >= 0 ) {
- cpu_khz = (double)info.cpu_khz;
- tsc_to_cpu_mult = (double)(info.tsc_to_cpu_mult ? : 1);
- if( info.cpu_features & PERFCTR_FEATURE_RDTSC ) {
- memset(&control, 0, sizeof control);
- control.cpu_control.tsc_on = 1;
- if( vperfctr_control(vperfctr, &control) >= 0 )
- return;
- }
- }
- vperfctr_close(vperfctr);
- vperfctr = NULL;
-}
-
-#define inc_get_hrvtime() (((double)vperfctr_read_tsc(vperfctr) * tsc_to_cpu_mult) / cpu_khz)
-
-#endif /* USE_PERFCTR */
-#endif /* INC_TIME_BASED */
-
-#ifdef INC_TIME_BASED
-# define timeslice 1 /* milli seconds */
-# define WORK_MORE (inc_get_hrvtime() < start_time + timeslice)
-#else
-//# define inc_min_work 100 /* words */
-# define inc_min_work global_heap_sz + inc_pages * INC_FULLPAGE /* words */
-# define WORK_MORE (inc_words_to_go > 0)
-#endif
-
-void erts_init_incgc(void)
-{
- int i;
- int size = inc_pages * INC_FULLPAGE;
-
- /* Young generation */
- global_heap = (Eterm *)erts_alloc(ERTS_ALC_T_MESSAGE_AREA,
- sizeof(Eterm) * global_heap_sz);
- global_hend = global_heap + global_heap_sz;
- global_htop = global_heap;
- inc_alloc_limit = global_hend;
-
- /* Fromspace */
- inc_last_nursery = (Eterm *) erts_alloc(ERTS_ALC_T_MESSAGE_AREA,
- global_heap_sz * sizeof(Eterm));
- inc_fromspc = inc_fromend = NULL;
-
- /* Forward-pointers */
- fwdptrs = erts_alloc(ERTS_ALC_T_MESSAGE_AREA,
- global_heap_sz * sizeof(Eterm*));
- /* Old generation */
- global_old_heap = (Eterm *)erts_alloc(ERTS_ALC_T_MESSAGE_AREA,
- size * sizeof(Eterm));
- global_old_hend = global_old_heap + size;
-
- /* Pages i BiBOP */
- for (i = 0; i < inc_pages; i++)
- {
- INC_Page *this = (INC_Page*)(global_old_heap + i * INC_FULLPAGE);
- this->next = (INC_Page*)((Eterm*)this + INC_FULLPAGE);
- }
-
- inc_bibop = (INC_Page*)global_old_heap;
- ((INC_Page*)(global_old_heap + (inc_pages - 1) * INC_FULLPAGE))->next =
- NULL;
-
- inc_used_mem = inc_bibop;
- inc_bibop = inc_bibop->next;
- inc_used_mem->next = NULL;
- inc_used_pages = 1;
-
- /* Free-list */
- inc_free_list = (INC_MemBlock*)inc_used_mem->start;
- inc_free_list->size = INC_PAGESIZE;
- inc_free_list->prev = NULL;
- inc_free_list->next = NULL;
-
- /* Blackmap */
- blackmap = (unsigned char*)erts_alloc(ERTS_ALC_T_MESSAGE_AREA,
- INC_FULLPAGE * inc_pages);
- /* Gray stack */
- INC_STORAGE_INIT(gray);
-
- inc_active_proc = NULL;
- inc_active_last = NULL;
-
-#ifdef INC_TIME_BASED
- inc_start_hrvtime();
-#endif
-}
-
-void erts_cleanup_incgc(void)
-{
- INC_STORAGE_ERASE(gray);
-
- if (inc_fromspc)
- inc_last_nursery = inc_fromspc;
-
- erts_free(ERTS_ALC_T_MESSAGE_AREA,(void*)global_heap);
- erts_free(ERTS_ALC_T_MESSAGE_AREA,(void*)inc_last_nursery);
- erts_free(ERTS_ALC_T_MESSAGE_AREA,(void*)global_old_heap);
- erts_free(ERTS_ALC_T_MESSAGE_AREA,(void*)blackmap);
- erts_free(ERTS_ALC_T_MESSAGE_AREA,(void*)fwdptrs);
-}
-
-void erts_incremental_gc(Process* p, int need, Eterm* objv, int nobj)
-{
- int repeat_minor;
-#ifdef INC_TIME_BASED
- double start_time = inc_get_hrvtime();
- int work_left_before = inc_words_to_go;
-#endif
- /* Used when growing the fromspace */
- static char inc_growing_nurs = 0;
-
- BM_STOP_TIMER(system);
- //BM_MMU_READ();
- BM_RESET_TIMER(gc);
- BM_START_TIMER(gc);
-
- VERBOSE(DEBUG_HYBRID_GC,
- ("INCGC: Incremental GC START Caused by: %T Need: %d\n",
- p->id,need));
-
- ma_gc_flags |= GC_GLOBAL;
- ma_gc_flags &= ~GC_CYCLE_START;
-
-#ifndef INC_TIME_BASED
- /* Decide how much work to do this GC stage. The work is meassured
- * in number of words copied from the young generation to the old
- * plus number of work marked in the old generation.
- */
- if (ma_gc_flags & GC_MAJOR) {
- int wm = (need > inc_min_work) ? need : inc_min_work;
- inc_words_to_go = (int)((wm * (((inc_used_pages * INC_PAGESIZE) /
- (double)global_heap_sz) + 1)) + 0.5);
- }
- else
- inc_words_to_go = (need > inc_min_work) ? need : inc_min_work;
-#endif
-
- do {
- if (ma_gc_flags & GC_MAJOR) {
- /* This is a major collection cycle. */
- inc_major_gc(p,need,objv,nobj);
- } else if (ma_gc_flags & GC_CYCLE) {
- /* This is a minor collection cycle. */
- inc_minor_gc(p,need,objv,nobj);
- } else {
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Collection cycle START\n"));
- ma_gc_flags |= (GC_CYCLE | GC_CYCLE_START);
- inc_fromspc = global_heap;
- inc_fromend = global_htop;
- global_heap = global_htop = inc_last_nursery;
- global_hend = global_heap + global_heap_sz;
- inc_nursery_scn_ptr = global_heap;
-#ifdef INC_TIME_BASED
- work_left_before = inc_words_to_go = global_heap_sz;
-#endif
-#ifdef DEBUG
- inc_last_nursery = NULL;
-#endif
- memset(fwdptrs,0,global_heap_sz * sizeof(Eterm));
-
- {
- /* TODO: Alla processer ska v�l egentligen inte aktiveras h�r... */
- int i;
- for (i = 0; i < erts_num_active_procs; i++) {
- Process *cp = erts_active_procs[i];
- INC_ACTIVATE(cp);
- cp->scan_top = cp->high_water;
- }
- }
-
- if (ma_gc_flags & GC_NEED_MAJOR) {
- /* The previous collection cycle caused the old generation to
- * overflow. This collection cycle will therefore be a major
- * one.
- */
- BM_COUNT(major_gc_cycles);
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: MAJOR cycle\n"));
- inc_major_gc(p,need,objv,nobj);
- } else {
- BM_COUNT(minor_gc_cycles);
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: MINOR cycle\n"));
- inc_minor_gc(p,need,objv,nobj);
- }
- }
-
- repeat_minor = 0;
- if (!(ma_gc_flags & GC_CYCLE)) {
- inc_alloc_limit = global_hend;
- inc_last_nursery = inc_fromspc;
- inc_fromspc = inc_fromend = NULL;
- ASSERT(INC_STORAGE_EMPTY(gray));
-
- if (inc_growing_nurs) {
- /*
- * The previous collection cycle caused the nursery to
- * grow, now we have to grow the from-space as well.
- */
- inc_last_nursery =
- (Eterm*) erts_realloc(ERTS_ALC_T_MESSAGE_AREA,
- (void*)inc_last_nursery,
- sizeof(Eterm) * global_heap_sz);
- inc_growing_nurs = 0;
- }
-
- if (global_hend - global_htop <= need) {
- /*
- * Initiate a new GC cycle immediately and, if necessary,
- * enlarge the nursery.
- */
- if (global_heap_sz <= need) {
- VERBOSE(DEBUG_HYBRID_GC,
- ("INCGC: Allocating a larger nursery\n"));
- global_heap_sz = erts_next_heap_size(need * 1.5,0);
- inc_last_nursery =
- (Eterm*) erts_realloc(ERTS_ALC_T_MESSAGE_AREA,
- (void*)inc_last_nursery,
- sizeof(Eterm) * global_heap_sz);
- fwdptrs = erts_realloc(ERTS_ALC_T_MESSAGE_AREA,fwdptrs,
- global_heap_sz * sizeof(Eterm*));
- inc_growing_nurs = 1;
- }
- repeat_minor = 1;
- }
-
-#ifdef DEBUG
- /* Fill the from-space with bad things */
- memset(inc_last_nursery,DEBUG_BAD_BYTE,
- global_heap_sz * sizeof(Eterm));
-#endif
- }
- } while (repeat_minor);
-
-
- /* Clean up after garbage collection ********************************/
-
- if (inc_alloc_limit != global_hend) {
-
-#ifdef INC_TIME_BASED
- if ((work_left_before - inc_words_to_go) == 0) {
- inc_alloc_limit = global_htop + need;
- } else {
- inc_alloc_limit = (global_hend - global_htop) /
- (inc_words_to_go / (work_left_before - inc_words_to_go)) +
- global_htop;
- if (inc_alloc_limit > global_hend)
- inc_alloc_limit = global_hend;
- }
-#else
- inc_alloc_limit = (Eterm*)(global_htop + (need > inc_min_work) ?
- need : inc_min_work);
- if (inc_alloc_limit > global_hend)
- inc_alloc_limit = global_hend;
-#endif
- }
-
- ma_gc_flags &= ~GC_GLOBAL;
-
- /* INC_TIME_BASED: If this fails we have to increase the timeslice! */
- ASSERT(inc_alloc_limit - global_htop > need);
-
- BM_STOP_TIMER(gc);
-#ifdef BM_TIMERS
- minor_global_gc_time += gc_time;
- if (gc_time > max_global_minor_time)
- max_global_minor_time = gc_time;
-
- pause_times[(((gc_time * 1000) < MAX_PAUSE_TIME) ?
- (int)(gc_time * 1000) :
- MAX_PAUSE_TIME - 1)]++;
-#endif
- //BM_MMU_INIT();
- { static long long verif = 0;
- //erts_printf("innan verify: %d\n",++verif);
- if (verif==168) print_memory(NULL);
- verify_everything();
- //erts_printf("efter verify: %d\n",verif);
- }
- BM_START_TIMER(system);
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Incremental GC END\n"));
-}
-
-
-/***************************************************************************
- * *
- * Minor collection - Copy live data from young generation to old *
- * *
- ***************************************************************************/
-
-#define MINOR_SCAN(PTR,END) do { \
- ASSERT(PTR <= END); \
- while (WORK_MORE && PTR < END) { \
- Eterm val = *PTR; \
- Eterm *obj_ptr = ptr_val(val); \
- switch (primary_tag(val)) { \
- case TAG_PRIMARY_LIST: \
- if (ptr_within(obj_ptr,inc_fromspc,inc_fromend)) { \
- if (INC_IS_FORWARDED(obj_ptr)) { \
- *PTR = make_list(INC_FORWARD_VALUE(obj_ptr)); \
- } \
- else { \
- Eterm *hp = erts_inc_alloc(2); \
- INC_STORE(gray,hp,2); \
- INC_COPY_CONS(obj_ptr,hp,PTR); \
- } \
- } \
- break; \
- case TAG_PRIMARY_BOXED: \
- if (ptr_within(obj_ptr,inc_fromspc,inc_fromend)) { \
- if (INC_IS_FORWARDED(obj_ptr)) { \
- *PTR = make_boxed(INC_FORWARD_VALUE(obj_ptr)); \
- } \
- else { \
- Eterm *hp = erts_inc_alloc(BOXED_NEED(obj_ptr,*obj_ptr)); \
- INC_STORE(gray,hp,BOXED_NEED(obj_ptr,*obj_ptr)); \
- INC_COPY_BOXED(obj_ptr,hp,PTR); \
- } \
- } \
- break; \
- case TAG_PRIMARY_HEADER: \
- switch (val & _TAG_HEADER_MASK) { \
- case ARITYVAL_SUBTAG: break; \
- default: PTR += thing_arityval(val); break; \
- } \
- break; \
- } \
- PTR++; \
- } \
-} while(0)
-
-
-/* Returns: TRUE (1) if the need is greater than the available space
- * and the garbage collector needs to be restarted immediately. FALSE
- * (0) otherwise.
- */
-static void inc_minor_gc(Process* p, int need, Eterm* objv, int nobj)
-{
- BM_COUNT(minor_gc_stages);
-
- /* Start with looking at gray objects found in earlier collection
- * stages.
- */
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Rescue gray found from nursery\n"));
- {
- INC_Object *obj = NULL;
- Eterm *ptr;
-
- while (WORK_MORE && !INC_STORAGE_EMPTY(gray)) {
- obj = INC_STORAGE_GET(gray);
- if ((*obj->this & _TAG_HEADER_MASK) == FUN_SUBTAG) {
- ptr = obj->this + thing_arityval(*obj->this) + 1;
- } else {
- ptr = obj->this;
- }
- MINOR_SCAN(ptr,obj->this + obj->size);
- }
- /* TODO: Se f�reg�ende uppdatering av gr� objekt */
- if (!WORK_MORE && obj != NULL)
- INC_STORE(gray,obj->this,obj->size);
- }
-
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Scan root-set\n"));
- while (WORK_MORE && inc_active_proc) {
- Rootset rootset;
- Process *cp = inc_active_proc;
-
- ASSERT(INC_IS_ACTIVE(cp));
-
- /* TODO: Hur dyrt �r det att bygga nytt rootset varje g�ng? */
-
- /* TODO: Fundera p� ordningen! Rootset, Heap, Old heap... */
-
- /* TODO: Scanna stacken fr�n p->send till p->stop! [Brooks84] */
- /* Notera: Vi GC:ar inte de yngsta objekten - de som allokeras
- under GC-cykeln. Detta ger ynglingarna en chans att d� innan
- GC:n b�rjar kopiera dem. [StefanovicMcKinleyMoss@OOPSLA99] */
-
- /* TODO: N�r rootset �r scannat borde processen inte vara
- aktiv mer. Den b�r aktiveras i schedule, endast om en
- process har k�rt beh�ver vi scanna rootset igen. */
-
- /* MT: In a multithreaded system the process cp needs to be
- * locked here.
- */
-
- if (cp == p)
- rootset.n = setup_rootset(cp, objv, nobj, &rootset);
- else
- rootset.n = setup_rootset(cp, cp->arg_reg, cp->arity, &rootset);
-
- //MA_GENSWEEP_NSTACK(cp, old_htop, n_htop, objv, nobj);
-
- while (WORK_MORE && rootset.n--) {
- Eterm *g_ptr = rootset.v[rootset.n];
- Uint g_sz = rootset.sz[rootset.n];
-
- while (WORK_MORE && g_sz--) {
- Eterm gval = *g_ptr;
- switch (primary_tag(gval)) {
- case TAG_PRIMARY_LIST: {
- Eterm *ptr = list_val(gval);
- if (ptr_within(ptr,inc_fromspc,inc_fromend)) {
- if (INC_IS_FORWARDED(ptr)) {
- *g_ptr++ = make_list(INC_FORWARD_VALUE(ptr));
- }
- else {
- Eterm *hp = erts_inc_alloc(2);
- INC_STORE(gray,hp,2);
- INC_COPY_CONS(ptr,hp,g_ptr++);
- }
- }
- else
- ++g_ptr;
- continue;
- }
-
- case TAG_PRIMARY_BOXED: {
- Eterm *ptr = boxed_val(gval);
- if (ptr_within(ptr,inc_fromspc,inc_fromend)) {
- if (INC_IS_FORWARDED(ptr)) {
- *g_ptr++ = make_boxed(INC_FORWARD_VALUE(ptr));
- }
- else {
- Eterm *hp = erts_inc_alloc(BOXED_NEED(ptr,*ptr));
- INC_STORE(gray,hp,BOXED_NEED(ptr,*ptr));
- INC_COPY_BOXED(ptr,hp,g_ptr++);
- }
- }
- else
- ++g_ptr;
- continue;
- }
-
- default:
- g_ptr++;
- continue;
- }
- }
- }
-
- restore_one_rootset(cp, &rootset);
-
- /* MT: cp can be unlocked now. */
-
- /* VERBOSE(DEBUG_HYBRID_GC,("INCGC: Scan private nursery\n")); */
- if (cp->scan_top != HEAP_TOP(cp)) {
- Eterm *ptr = cp->scan_top;
- MINOR_SCAN(ptr,HEAP_TOP(cp));
- /* TODO: F�r att spara scan_top h�r m�ste alla ma-pekare
- * som hittas l�ggas till i cp->rrma.
- */
- //cp->scan_top = ptr;
- }
-
- /* VERBOSE(DEBUG_HYBRID_GC,("INCGC: Scan heap fragments\n")); */
- {
- ErlHeapFragment* bp = MBUF(cp);
-
- while (WORK_MORE && bp) {
- Eterm *ptr = bp->mem;
- if ((ARITH_HEAP(cp) >= bp->mem) &&
- (ARITH_HEAP(cp) < bp->mem + bp->size)) {
- MINOR_SCAN(ptr,ARITH_HEAP(cp));
- } else {
- MINOR_SCAN(ptr,bp->mem + bp->size);
- }
- bp = bp->next;
- }
- }
-
- /* VERBOSE(DEBUG_HYBRID_GC,("INCGC: Scan gray\n")); */
- {
- INC_Object *obj = NULL;
- Eterm *ptr;
- while (WORK_MORE && !INC_STORAGE_EMPTY(gray)) {
- obj = INC_STORAGE_GET(gray);
- if ((*obj->this & _TAG_HEADER_MASK) == FUN_SUBTAG) {
- ptr = obj->this + thing_arityval(*obj->this) + 1;
- } else {
- ptr = obj->this;
- }
- MINOR_SCAN(ptr,obj->this + obj->size);
- }
- /* TODO: INC_STORE(gray,ptr,obj->size-(ptr-obj->this)); Typ.. */
- if (!WORK_MORE && obj != NULL)
- INC_STORE(gray,obj->this,obj->size);
- }
-
- if (WORK_MORE) {
- //printf("Rootset after:\r\n");
- //print_one_rootset(&rootset);
- INC_DEACTIVATE(cp);
- }
- }
-
- /* Update new pointers in the nursery to new copies in old generation. */
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Update nursery\n"));
- {
- Eterm *ptr = inc_nursery_scn_ptr;
- MINOR_SCAN(ptr,global_htop);
- inc_nursery_scn_ptr = ptr;
- }
-
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Rescue gray found from nursery\n"));
- {
- INC_Object *obj = NULL;
- Eterm *ptr;
-
- while (WORK_MORE && !INC_STORAGE_EMPTY(gray)) {
- obj = INC_STORAGE_GET(gray);
- if ((*obj->this & _TAG_HEADER_MASK) == FUN_SUBTAG) {
- ptr = obj->this + thing_arityval(*obj->this) + 1;
- } else {
- ptr = obj->this;
- }
- MINOR_SCAN(ptr,obj->this + obj->size);
- }
- /* TODO: Se f�reg�ende uppdatering av gr� objekt */
- if (!WORK_MORE && obj != NULL)
- INC_STORE(gray,obj->this,obj->size);
- }
-
- /* Atomic phase */
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Update copy stack\n"));
- {
- Uint i;
- for (i = 0; i < ma_dst_top; i++) {
- if (ptr_within(ma_dst_stack[i],inc_fromspc,inc_fromend)) {
- if (INC_IS_FORWARDED(ma_dst_stack[i]))
- ma_dst_stack[i] = INC_FORWARD_VALUE(ma_dst_stack[i]);
- }
- }
- }
-
- if (WORK_MORE) {
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Update offheap-lists\n"));
- {
- ExternalThing **prev = &erts_global_offheap.externals;
- ExternalThing *ptr = erts_global_offheap.externals;
-
- /* Atomic phase */
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Sweep proc externals\n"));
- while (ptr) {
- Eterm *ppt = (Eterm*) ptr;
-
- if (ptr_within(ppt,global_old_heap,global_old_hend)) {
- prev = &ptr->next;
- ptr = ptr->next;
- } else if (ptr_within(ppt, inc_fromspc, inc_fromend) &&
- INC_IS_FORWARDED(ppt)) {
- ExternalThing *ro = (ExternalThing*)INC_FORWARD_VALUE(ppt);
- *prev = ro; /* Patch to moved pos */
- prev = &ro->next;
- ptr = ro->next;
- } else {
- erts_deref_node_entry(ptr->node);
- *prev = ptr = ptr->next;
- }
- }
- ASSERT(*prev == NULL);
- }
-
- {
- ProcBin **prev = &erts_global_offheap.mso;
- ProcBin *ptr = erts_global_offheap.mso;
-
- /* Atomic phase */
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Sweep proc bins\n"));
- while (ptr) {
- Eterm *ppt = (Eterm*)ptr;
-
- if (ptr_within(ppt,global_old_heap,global_old_hend)) {
- prev = &ptr->next;
- ptr = ptr->next;
- } else if (ptr_within(ppt, inc_fromspc, inc_fromend) &&
- INC_IS_FORWARDED(ppt)) {
- ProcBin *ro = (ProcBin*)INC_FORWARD_VALUE(ppt);
- *prev = ro; /* Patch to moved pos */
- prev = &ro->next;
- ptr = ro->next;
- } else {
- Binary *bptr;
- *prev = ptr->next;
- bptr = ptr->val;
- if (erts_refc_dectest(&bptr->refc, 0) == 0)
- erts_bin_free(bptr);
- ptr = *prev;
- }
- }
- ASSERT(*prev == NULL);
- }
-
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Minor collection cycle END\n"));
- ma_gc_flags &= ~GC_CYCLE;
- }
-}
-
-
-
-
-/***************************************************************************
- * *
- * Major collection - CopyMark - Copy young to old, Mark-Sweep old *
- * *
- ***************************************************************************/
-
-#define COPYMARK(PTR,END) do { \
- ASSERT(PTR <= END); \
- while (WORK_MORE && PTR < END) { \
- Eterm val = *PTR; \
- Eterm *obj_ptr = ptr_val(val); \
- switch (primary_tag(val)) { \
- case TAG_PRIMARY_LIST: \
- COPYMARK_CONS(obj_ptr,aging_htop,PTR,aging_end); break; \
- case TAG_PRIMARY_BOXED: \
- COPYMARK_BOXED(obj_ptr,aging_htop,PTR,aging_end); break; \
- case TAG_PRIMARY_HEADER: \
- switch (val & _TAG_HEADER_MASK) { \
- case ARITYVAL_SUBTAG: break; \
- default: \
- PTR += thing_arityval(val); \
- break; \
- } \
- break; \
- default: break; \
- } \
- PTR++; \
- } \
-} while(0);
-/* TODO:
- if (aging_htop + 10 > aging + INC_FULLPAGE) {
- aging->next = inc_used_mem;
- inc_used_mem = aging;
- }
-*/
-
-static void inc_major_gc(Process *p, int need, Eterm* objv, int nobj)
-{
- Eterm *free_start = NULL;
- Uint live = 0;
- Uint old_gen_sz = 0;
- static INC_Page *aging;
- static Eterm *aging_htop;
- static Eterm *aging_end;
- BM_NEW_TIMER(old_gc);
-
- BM_SWAP_TIMER(gc,old_gc);
- BM_COUNT(major_gc_stages);
-
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Major collection START\n"));
-
- ma_gc_flags |= GC_INCLUDE_ALL;
-
- if (ma_gc_flags & GC_NEED_MAJOR)
- {
- INC_Page *page = inc_used_mem;
-
- ma_gc_flags |= GC_MAJOR;
- ma_gc_flags &= ~GC_NEED_MAJOR;
-
- while (page)
- {
- memset(blackmap +
- ((void*)page - (void*)global_old_heap) / sizeof(void*),
- 0, INC_FULLPAGE);
- page = page->next;
- }
-
- if (inc_bibop) {
- aging = inc_bibop;
- inc_bibop = inc_bibop->next;
- aging->next = NULL;
- memset(blackmap +
- ((void*)aging - (void*)global_old_heap) / sizeof(void*),
- 1, INC_FULLPAGE);
- aging_htop = aging->start;
- aging_end = aging->start + INC_PAGESIZE;
- }
- else {
- /* There are no free pages.. Either fragmentation is a
- * problem or we are simply out of memory. Allocation in
- * the old generation will be done through the free-list
- * this GC cycle.
- */
- aging = NULL;
- aging_htop = aging_end = NULL;
- }
- }
-
- /* Start with looking at gray objects found in earlier collection
- * stages.
- */
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Copy-Mark gray\n"));
- {
- INC_Object *obj = NULL;
-
- while (WORK_MORE && !INC_STORAGE_EMPTY(gray)) {
- Eterm *ptr;
-
- obj = INC_STORAGE_GET(gray);
- if ((*obj->this & _TAG_HEADER_MASK) == FUN_SUBTAG) {
- ptr = obj->this + thing_arityval(*obj->this) + 1;
- } else {
- ptr = obj->this;
- }
- COPYMARK(ptr,obj->this + obj->size);
- }
- /* TODO: Titta p� motsvarande i minor. */
- if (!WORK_MORE && obj != NULL)
- INC_STORE(gray,obj->this,obj->size);
- }
-
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Copy-Mark roots\n"));
- while (WORK_MORE && inc_active_proc)
- {
- /* For each process: Scan all areas containing pointers to the
- * message area. When a process is done here, all it's
- * message-pointers should be to the old generation.
- */
- Rootset rootset;
- Process *cp = inc_active_proc;
-
- ASSERT(INC_IS_ACTIVE(cp));
-
- /* MT: In a multithreaded system the process cp needs to be
- * locked here.
- */
- if (cp == p)
- rootset.n = setup_rootset(cp, objv, nobj, &rootset);
- else
- rootset.n = setup_rootset(cp, cp->arg_reg, cp->arity, &rootset);
-
- while (WORK_MORE && rootset.n--)
- {
- Eterm *ptr = rootset.v[rootset.n];
- Eterm *end = ptr + rootset.sz[rootset.n];
-
- while (WORK_MORE && ptr < end) {
- Eterm val = *ptr;
- Eterm *obj_ptr = ptr_val(val);
-
- switch (primary_tag(val)) {
- case TAG_PRIMARY_LIST:
- {
- COPYMARK_CONS(obj_ptr,aging_htop,ptr,aging_end);
- break;
- }
-
- case TAG_PRIMARY_BOXED:
- {
- COPYMARK_BOXED(obj_ptr,aging_htop,ptr,aging_end);
- break;
- }
- }
- ptr++;
- }
- }
-
-#ifdef HIPE
- /* Atomic phase */
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Native stack scan: %T\n",cp->id));
- aging_htop = ma_fullsweep_nstack(cp,aging_htop,aging_end);
-#endif
- restore_one_rootset(cp, &rootset);
-
- /* MT: cp can be unlocked now. But beware!! The message queue
- * might be updated with new pointers to the fromspace while
- * we work below. The send operation can not assume that all
- * active processes will look through their message queue
- * before deactivating as is the case in non-MT incremental
- * collection.
- */
-
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Copy-Mark process heap\n"));
- {
- Eterm *ptr = cp->scan_top;
- COPYMARK(ptr,cp->htop);
- //cp->scan_top = ptr;
- }
-
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Copy-Mark heap fragments\n"));
- {
- ErlHeapFragment* bp = MBUF(cp);
-
- while (WORK_MORE && bp) {
- Eterm *ptr = bp->mem;
- Eterm *end;
-
- if ((ARITH_HEAP(cp) >= bp->mem) &&
- (ARITH_HEAP(cp) < bp->mem + bp->size)) {
- end = ARITH_HEAP(cp);
- } else {
- end = bp->mem + bp->size;
- }
-
- COPYMARK(ptr,end);
- bp = bp->next;
- }
- }
-
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Copy-Mark gray stack\n"));
- {
- INC_Object *obj = NULL;
-
- while (WORK_MORE && !INC_STORAGE_EMPTY(gray)) {
- Eterm *ptr;
-
- obj = INC_STORAGE_GET(gray);
- if ((*obj->this & _TAG_HEADER_MASK) == FUN_SUBTAG) {
- ptr = obj->this + thing_arityval(*obj->this) + 1;
- } else {
- ptr = obj->this;
- }
- COPYMARK(ptr,obj->this + obj->size);
- }
- /* TODO: Titta p� motsvarande i minor. */
- if (!WORK_MORE && obj != NULL)
- INC_STORE(gray,obj->this,obj->size);
- }
-
- if (WORK_MORE) {
- INC_DEACTIVATE(cp);
- }
- }
-
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Copy-Mark nursery\n"));
- {
- Eterm *ptr = inc_nursery_scn_ptr;
- COPYMARK(ptr,global_htop);
- inc_nursery_scn_ptr = ptr;
- }
-
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Copy-Mark gray found in nursery\n"));
- {
- INC_Object *obj = NULL;
-
- while (WORK_MORE && !INC_STORAGE_EMPTY(gray)) {
- Eterm *ptr;
-
- obj = INC_STORAGE_GET(gray);
- if ((*obj->this & _TAG_HEADER_MASK) == FUN_SUBTAG) {
- ptr = obj->this + thing_arityval(*obj->this) + 1;
- } else {
- ptr = obj->this;
- }
- COPYMARK(ptr,obj->this + obj->size);
- }
- /* TODO: Titta p� motsvarande i minor. */
- if (!WORK_MORE && obj != NULL)
- INC_STORE(gray,obj->this,obj->size);
- }
-
-
- /**********************************************************************/
- if (WORK_MORE) {
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Sweep phase\n"));
-
- /* Atomic phase */
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Sweep externals in old generation\n"));
- {
- ExternalThing** prev = &erts_global_offheap.externals;
- ExternalThing* ptr = erts_global_offheap.externals;
-
- while (ptr) {
- Eterm* ppt = (Eterm *) ptr;
-
- if ((ptr_within(ppt, global_old_heap, global_old_hend) &&
- blackmap[ppt - global_old_heap] == 0) ||
- (ptr_within(ppt, inc_fromspc, inc_fromend) &&
- !INC_IS_FORWARDED(ppt)))
- {
- erts_deref_node_entry(ptr->node);
- *prev = ptr = ptr->next;
- } else if (ptr_within(ppt, inc_fromspc, inc_fromend)) {
- ExternalThing* ro = (ExternalThing*)INC_FORWARD_VALUE(ppt);
- *prev = ro; /* Patch to moved pos */
- prev = &ro->next;
- ptr = ro->next;
- } else {
- prev = &ptr->next;
- ptr = ptr->next;
- }
- }
- ASSERT(*prev == NULL);
- }
-
- /* Atomic phase */
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Sweep refc bins in old generation\n"));
- {
- ProcBin** prev = &erts_global_offheap.mso;
- ProcBin* ptr = erts_global_offheap.mso;
-
- while (ptr) {
- Eterm *ppt = (Eterm*)ptr;
-
- if ((ptr_within(ppt, global_old_heap, global_old_hend) &&
- blackmap[ppt - global_old_heap] == 0) ||
- (ptr_within(ppt, inc_fromspc, inc_fromend) &&
- !INC_IS_FORWARDED(ppt)))
- {
- Binary* bptr;
- *prev = ptr->next;
- bptr = ptr->val;
- if (erts_refc_dectest(&bptr->refc, 0) == 0)
- erts_bin_free(bptr);
- ptr = *prev;
- } else if (ptr_within(ppt, inc_fromspc, inc_fromend)) {
- ProcBin* ro = (ProcBin*)INC_FORWARD_VALUE(ppt);
- *prev = ro; /* Patch to moved pos */
- prev = &ro->next;
- ptr = ro->next;
- } else {
- prev = &ptr->next;
- ptr = ptr->next;
- }
- }
- ASSERT(*prev == NULL);
- }
-
- /* TODO: Currently atomic phase - Can not be later of course. */
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Sweep old generation\n"));
- {
- INC_Page *page = inc_used_mem;
- INC_Page *prev = NULL;
- inc_free_list = NULL;
-
- while (page) {
- int scavenging = 0;
- int n = page->start - global_old_heap;
- int stop = n + INC_PAGESIZE;
-
- old_gen_sz += INC_PAGESIZE;
- while (n < stop) {
- if (blackmap[n] != 0) {
- if (scavenging) {
- Eterm *ptr = global_old_heap + n;
- scavenging = 0;
- if ((ptr - free_start) * sizeof(Eterm) >=
- sizeof(INC_MemBlock))
- {
- INC_MemBlock *new = (INC_MemBlock*)free_start;
- new->size = ptr - free_start;
- new->prev = NULL;
- new->next = inc_free_list;
- if (inc_free_list)
- inc_free_list->prev = new;
- inc_free_list = new;
- }
- }
- if (blackmap[n] == 255) {
- unsigned int size =
- *(unsigned int*)(((long)&blackmap[n]+4) & ~3);
- live += size;
- n += size;
- }
- else {
- live += blackmap[n];
- n += blackmap[n];
- }
- }
- else if (!scavenging) {
- free_start = global_old_heap + n;
- scavenging = 1;
- n++;
- }
- else {
- n++;
- }
- }
-
- if (scavenging) {
- if ((global_old_heap + n - free_start) * sizeof(Eterm) >
- sizeof(INC_MemBlock))
- {
- INC_MemBlock *new = (INC_MemBlock*)free_start;
- new->size = global_old_heap + n - free_start;
- new->prev = NULL;
- new->next = inc_free_list;
- if (inc_free_list)
- inc_free_list->prev = new;
- inc_free_list = new;
- }
- else if (free_start == page->start) {
- INC_Page *next = page->next;
-
- if (prev)
- prev->next = page->next;
- else
- inc_used_mem = page->next;
-
- page->next = inc_bibop;
- inc_bibop = page;
- inc_used_pages--;
- page = next;
- continue;
- }
- }
- prev = page;
- page = page->next;
- }
- }
- }
-
- ASSERT(inc_bibop);
- /*
- This code is not expected to work right now.
- if (!inc_bibop) {
- int i;
- int new_pages = inc_pages * 2;
- int size = sizeof(Eterm) * new_pages * INC_FULLPAGE;
- Eterm *new_heap = erts_alloc(ERTS_ALC_T_MESSAGE_AREA,size);
- Eterm *new_hend = new_heap + size;
- Eterm *new_htop;
- Eterm *last_page_end;
- INC_Page *new_used_mem;
- INC_Page *page;
-
- erts_printf("The last page has been allocated..\n");
- erts_printf("We need to copy things!\n");
-
- / * Create new, bigger bag of pages * /
- for (i = 0; i < new_pages; i++)
- {
- INC_Page *this =
- (INC_Page*)(new_heap + i * INC_FULLPAGE);
- this->next = (INC_Page*)((Eterm*)this + INC_FULLPAGE);
- }
- inc_bibop = (INC_Page*)new_heap;
- ((INC_Page*)(new_heap + (new_pages - 1) *
- INC_FULLPAGE))->next = NULL;
-
- new_used_mem = inc_bibop;
- inc_bibop = inc_bibop->next;
- new_used_mem->next = NULL;
-
- / * Move stuff from old bag to new * /
- inc_free_list = NULL;
- new_htop = new_used_mem->start;
- last_page_end = new_htop + INC_PAGESIZE;
- page = inc_used_mem;
- while (page)
- {
- Eterm *ptr = page->start;
- Eterm *page_end = ptr + INC_PAGESIZE;
- int n = offsetof(INC_Page,start) / sizeof(void*) +
- ((Eterm*)page - global_old_heap);
- while (ptr < page_end)
- {
- if (blackmap[n] > 0)
- {
- if (last_page_end - new_htop < blackmap[n])
- {
- INC_Page *new_page = inc_bibop;
- inc_bibop = inc_bibop->next;
- new_page->next = new_used_mem;
- new_used_mem = new_page;
- new_htop = new_page->start;
- last_page_end = new_htop + INC_PAGESIZE;
- }
-
- memcpy(new_htop,ptr,blackmap[n] * sizeof(Eterm));
- for (i = 0; i < blackmap[n]; i++)
- {
- *ptr++ = (Eterm)new_htop++;
- }
- //new_htop += blackmap[n];
- //ptr += blackmap[n];
- / *
- if (blackmap[n] == 255) Do the right thing...
- * /
- n += blackmap[n];
- }
- else
- {
- n++; ptr++;
- }
- }
- page = page->next;
- }
-
- page = inc_used_mem;
- while (page)
- {
- Eterm *ptr = page->start;
- Eterm *page_end = ptr + INC_PAGESIZE;
-
- / * TODO: If inc_used_mem is sorted in address order, this
- * pass can be done at the same time as copying. * /
- while (ptr < page_end)
- {
- if (ptr_within(ptr_val(*ptr),global_old_heap,global_old_hend))
- {
- *ptr = *((Eterm*)ptr_val(*ptr));
- }
- ptr++;
- }
- page = page->next;
- }
-
- printf("Restore rootset after heap move. Roots: %d\r\n",roots_saved);
- while (roots_saved--)
- {
- Eterm *ptr = root_save[roots_saved];
- *ptr = *((Eterm*)ptr_val(*ptr));
- }
-
- erts_free(ERTS_ALC_T_MESSAGE_AREA,(void*)global_old_heap);
-
- global_old_heap = new_heap;
- global_old_hend = new_hend;
- inc_used_mem = new_used_mem;
- inc_pages = new_pages;
-
- if ((last_page_end - new_htop) * sizeof(Eterm) >=
- sizeof(INC_MemBlock))
- {
- inc_free_list = (INC_MemBlock*)(new_htop);
- inc_free_list->size = last_page_end - new_htop;
- inc_free_list->prev = NULL;
- inc_free_list->next = NULL;
- }
- }
- */
-
- /* I vilka l�gen kan vi vilja sl�nga p� en extra sida.. ( < 25% kvar?)
- if ()
- {
- INC_Page *new_page = inc_bibop;
- INC_MemBlock *new_free =
- (INC_MemBlock*)new_page->start;
-
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Fetching new page\n"));
- inc_bibop = inc_bibop->next;
-
- new_page->next = inc_used_mem;
- if (inc_used_mem)
- inc_used_mem->prev = new_page;
- inc_used_mem = new_page;
-
- // kolla detta med normal sidstorlek! old_gen_sz += INC_PAGESIZE;
- //BM_SWAP_TIMER(gc,misc1);
- memset(blackmap +
- ((void*)new_page - (void*)global_old_heap) / sizeof(void*),
- 0, INC_FULLPAGE);
- //BM_SWAP_TIMER(misc1,gc);
-
- new_free->prev = NULL;
- new_free->next = inc_free_list;
- new_free->size = INC_PAGESIZE;
- if (inc_free_list)
- inc_free_list->prev = new_free;
- inc_free_list = new_free;
- //printf("Snatched a new page @ 0x%08x\r\n",(int)new_page);
- //print_free_list();
- found = new_free;
- }
- */
-
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Update copy stack\n"));
- {
- Uint i;
- for (i = 0; i < ma_dst_top; i++) {
- if (ptr_within(ma_dst_stack[i],inc_fromspc,inc_fromend)) {
- if (INC_IS_FORWARDED(ma_dst_stack[i]))
- ma_dst_stack[i] = INC_FORWARD_VALUE(ma_dst_stack[i]);
- }
- }
- }
-
- if (WORK_MORE)
- {
- int size_left = INC_PAGESIZE - (aging_htop - aging->start);
-
- if (size_left > sizeof(INC_MemBlock))
- {
- ((INC_MemBlock*)aging_htop)->size = size_left;
- ((INC_MemBlock*)aging_htop)->prev = NULL;
- ((INC_MemBlock*)aging_htop)->next = inc_free_list;
- if (inc_free_list)
- inc_free_list->prev = (INC_MemBlock*)aging_htop;
- inc_free_list = (INC_MemBlock*)aging_htop;
- }
- aging->next = inc_used_mem;
- inc_used_mem = aging;
- inc_used_pages++;
-
- ma_gc_flags &= ~GC_MAJOR;
- ma_gc_flags &= ~GC_CYCLE;
-
- VERBOSE(DEBUG_HYBRID_GC,("INCGC: Major collection cycle END\n"));
- }
-
- ma_gc_flags &= ~GC_INCLUDE_ALL;
-
- BM_STOP_TIMER(old_gc);
-#ifdef BM_TIMER
- major_global_gc_time += old_gc_time;
- if (old_gc_time > max_global_major_time)
- max_global_major_time = old_gc_time;
-
- if ((old_gc_time * 1000) < MAX_PAUSE_TIME)
- pause_times_old[(int)(old_gc_time * 1000)]++;
- else
- pause_times_old[MAX_PAUSE_TIME - 1]++;
-#endif
- BM_START_TIMER(gc);
-}
-
-
-
-/***************************************************************************
- * *
- * Allocation in the old generation. Used in minor colection and when *
- * copying the rest of a message after a GC. *
- * *
- ***************************************************************************/
-
-
-Eterm *erts_inc_alloc(int need)
-{
- INC_MemBlock *this = inc_free_list;
-
- ASSERT(need < INC_PAGESIZE);
- while (this && (this->size) < need)
- {
- this = this->next;
- }
-
- if (!this)
- {
- /* If a free block large enough is not found, a new page is
- * allocated. GC_NEED_MAJOR is set so that the next garbage
- * collection cycle will be a major one, that is, both
- * generations will be garbage collected.
- */
- INC_Page *new_page = inc_bibop;
- INC_MemBlock *new_free = (INC_MemBlock*)new_page->start;
-
- if (new_page)
- {
- VERBOSE(DEBUG_HYBRID_GC,
- ("INCGC: Allocation grabs a new page\n"));
- inc_bibop = inc_bibop->next;
- new_page->next = inc_used_mem;
- inc_used_mem = new_page;
- inc_used_pages++;
-
- new_free->prev = NULL;
- new_free->next = inc_free_list;
- new_free->size = INC_PAGESIZE;
- if (inc_free_list)
- inc_free_list->prev = new_free;
- inc_free_list = new_free;
-
- this = new_free;
- if (!(ma_gc_flags & GC_MAJOR))
- ma_gc_flags |= GC_NEED_MAJOR;
- }
- else
- {
- erl_exit(-1, "inc_alloc ran out of pages!\n");
- }
- }
-
- if (((this->size) - need) * sizeof(Eterm) >= sizeof(INC_MemBlock))
- {
- INC_MemBlock *rest = (INC_MemBlock*)((Eterm*)this + need);
-
- /* The order here IS important! */
- rest->next = this->next;
-
- if (rest->next)
- rest->next->prev = rest;
-
- rest->prev = this->prev;
-
- if (rest->prev)
- rest->prev->next = rest;
- else
- inc_free_list = rest;
-
- rest->size = this->size - need;
- }
- else
- {
- if (this->prev)
- this->prev->next = this->next;
- else
- inc_free_list = this->next;
-
- if (this->next)
- this->next->prev = this->prev;
- }
-
- if (ma_gc_flags & GC_MAJOR) {
- if (need > 254) {
- blackmap[(Eterm*)this - global_old_heap] = 255;
- *(int*)((UWord)(&blackmap[(Eterm*)this - global_old_heap]+4) & ~3) =
- need;
- } else
- blackmap[(Eterm*)this - global_old_heap] = need;
- }
- return (Eterm*)this;
-}
-#endif /* INCREMENTAL */
diff --git a/erts/emulator/beam/erl_nmgc.h b/erts/emulator/beam/erl_nmgc.h
deleted file mode 100644
index b207dd37fa..0000000000
--- a/erts/emulator/beam/erl_nmgc.h
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2004-2009. All Rights Reserved.
- *
- * The contents of this file are subject to the Erlang Public License,
- * Version 1.1, (the "License"); you may not use this file except in
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * %CopyrightEnd%
- */
-
-#ifndef __ERL_NMGC_H__
-#define __ERL_NMGC_H__
-
-#ifdef INCREMENTAL
-#include <stddef.h> /* offsetof() */
-#include "erl_process.h"
-
-#define INC_FULLPAGE (INC_PAGESIZE + offsetof(INC_Page,start) / sizeof(void*))
-
-#define BOXED_NEED(PTR,HDR) \
- (((HDR) & _HEADER_SUBTAG_MASK) == SUB_BINARY_SUBTAG ? \
- header_arity(HDR) + 2 : \
- ((HDR) & _HEADER_SUBTAG_MASK) == FUN_SUBTAG ? \
- header_arity(HDR) + ((ErlFunThing*)(PTR))->num_free + 2 : \
- header_arity(HDR) + 1)
-
-
-#define INC_DECREASE_WORK(n) inc_words_to_go -= (n);
-
-#define INC_COPY_CONS(FROM,TO,PTR) \
-do { \
- TO[0] = FROM[0]; \
- TO[1] = FROM[1]; \
- INC_MARK_FORWARD(FROM,TO); \
- *(PTR) = make_list(TO); \
- INC_DECREASE_WORK(2); \
- (TO) += 2; \
-} while(0)
-
-#define INC_COPY_BOXED(FROM,TO,PTR) \
-do { \
- Sint nelts; \
- Eterm hdr = *(FROM); \
- \
- ASSERT(is_header(hdr)); \
- INC_MARK_FORWARD(FROM,TO); \
- *(PTR) = make_boxed(TO); \
- *(TO)++ = *(FROM)++; \
- nelts = header_arity(hdr); \
- switch ((hdr) & _HEADER_SUBTAG_MASK) { \
- case SUB_BINARY_SUBTAG: nelts++; break; \
- case FUN_SUBTAG: nelts+=((ErlFunThing*)(FROM-1))->num_free+1; break;\
- } \
- INC_DECREASE_WORK(nelts + 1); \
- while (nelts--) \
- *(TO)++ = *(FROM)++; \
-} while(0)
-
-
-/* Things copied to the old generation are not marked in the blackmap.
- * This is ok since the page they are copied to (aging) is not part of
- * the sweep.
- */
-#define COPYMARK_CONS(FROM,TO,PTR,LIMIT) \
-do { \
- if (ptr_within(FROM,inc_fromspc,inc_fromend)) { \
- if (INC_IS_FORWARDED(FROM)) { \
- *PTR = make_list(INC_FORWARD_VALUE(FROM)); \
- } else if (TO + 2 <= LIMIT) { \
- INC_STORE(gray,TO,2); \
- INC_COPY_CONS(FROM,TO,PTR); \
- } else { \
- Eterm *hp = erts_inc_alloc(2); \
- INC_STORE(gray,hp,2); \
- INC_COPY_CONS(FROM,hp,PTR); \
- } \
- } else if (ptr_within(FROM,global_old_heap,global_old_hend) && \
- (blackmap[FROM - global_old_heap] == 0)) { \
- blackmap[FROM - global_old_heap] = 2; \
- INC_DECREASE_WORK(2); \
- INC_STORE(gray,FROM,2); \
- } \
-} while(0)
-
-#define COPYMARK_BOXED(FROM,TO,PTR,LIMIT) \
-do { \
- if (ptr_within(FROM,inc_fromspc,inc_fromend)) { \
- int size = BOXED_NEED(FROM,*FROM); \
- if (INC_IS_FORWARDED(FROM)) { \
- *PTR = make_boxed(INC_FORWARD_VALUE(FROM)); \
- } else if (TO + size <= LIMIT) { \
- INC_STORE(gray,TO,size); \
- INC_COPY_BOXED(FROM,TO,PTR); \
- } else { \
- Eterm *hp = erts_inc_alloc(size); \
- INC_STORE(gray,hp,size); \
- INC_COPY_BOXED(FROM,hp,PTR); \
- } \
- } else if (ptr_within(FROM,global_old_heap,global_old_hend) && \
- (blackmap[FROM - global_old_heap] == 0)) { \
- int size = BOXED_NEED(FROM,*FROM); \
- if (size > 254) { \
- blackmap[FROM - global_old_heap] = 255; \
- *(int*)((long)(&blackmap[FROM - \
- global_old_heap] + 4) & ~3) = size; \
- } else \
- blackmap[FROM - global_old_heap] = size; \
- INC_DECREASE_WORK(size); \
- INC_STORE(gray,FROM,size); \
- } \
-} while(0)
-
-#define INC_MARK_FORWARD(ptr,dst) fwdptrs[(ptr) - inc_fromspc] = (dst);
-#define INC_IS_FORWARDED(ptr) (fwdptrs[(ptr) - inc_fromspc] != 0)
-#define INC_FORWARD_VALUE(ptr) fwdptrs[(ptr) - inc_fromspc]
-
-/* Note for BM_TIMER: Active timer should always be 'system' when IncAlloc
- * is called!
- */
-#define IncAlloc(p, sz, objv, nobj) \
- (ASSERT_EXPR((sz) >= 0), \
- (((inc_alloc_limit - global_htop) <= (sz)) ? \
- erts_incremental_gc((p),(sz),(objv),(nobj)) : 0), \
- ASSERT_EXPR(global_hend - global_htop > (sz)), \
- global_htop += (sz), global_htop - (sz))
-
-
-/************************************************************************
- * INC_STORAGE, a dynamic circular storage for objects (INC_Object). *
- * Use INC_STORE to add objects to the storage. The storage can then *
- * be used either as a queue, using INC_STORAGE_GET to retreive *
- * values, or as a stack, using INC_STORAGE_POP. It is OK to mix calls *
- * to GET and POP if that is desired. *
- * An iterator can be declared to traverse the storage without removing *
- * any elements, and INC_STORAGE_STEP will then return each element in *
- * turn, oldest first. *
- ***********************************************************************/
-
-/* Declare a new storage; must be in the beginning of a block. Give
- * the storage a name that is used in all later calls to the storage.
- * If this is an external declaration of the storage, pass the keyword
- * external as the first argument, otherwise leave it empty.
- */
-#define INC_STORAGE_DECLARATION(ext,name) \
- ext INC_Storage *name##head; \
- ext INC_Storage *name##tail; \
- ext INC_Object *name##free; \
- ext INC_Object *name##last_free; \
- ext int name##size;
-
-
-/* Initialize the storage. Note that memory allocation is involved -
- * don't forget to erase the storage when you are done.
- */
-#define INC_STORAGE_INIT(name) do { \
- name##head = (INC_Storage*)erts_alloc(ERTS_ALC_T_OBJECT_STACK, \
- sizeof(INC_Storage)); \
- name##head->next = name##head; \
- name##head->prev = name##head; \
- name##tail = name##head; \
- name##free = name##head->data; \
- name##last_free = name##free + INC_STORAGE_SIZE - 1; \
- name##size = 0; \
-} while(0)
-
-
-/*
-#define INC_STORAGE_SWAP(s1,s2) do { \
- INC_Storage *tmphead = s1##head; \
- INC_Storage *tmptail = s1##tail; \
- INC_Object *tmpfree = s1##free; \
- INC_Object *tmplast = s1##last_free; \
- int tmpsize = s1##size; \
- s1##head = s2##head; \
- s1##tail = s2##tail; \
- s1##free = s2##free; \
- s1##last_free = s2##last_free; \
- s1##size = s2##size; \
- s2##head = tmphead; \
- s2##tail = tmptail; \
- s2##free = tmpfree; \
- s2##last_free = tmplast; \
- s2##size = tmpsize; \
-} while(0)
-*/
-
-
-/* Return and remove the youngest element - treat the storage as a
- * stack. Always check that there are elements in the queue before
- * using INC_STORAGE_POP!
- */
-#define INC_STORAGE_POP(name) (ASSERT_EXPR(name##size != 0), \
- name##size--, \
- (--name##free != name##head->data - 1) ? \
- name##free : (name##head = name##head->prev, \
- name##free = name##head->data + INC_STORAGE_SIZE - 1))
-
-
-/* Return and remove the oldest element - treat the storage as a
- * queue. Always check that there are elements in the queue before
- * using INC_STORAGE_GET!
- */
-#define INC_STORAGE_GET(name) (ASSERT_EXPR(name##size != 0), \
- name##size--, \
- (++name##last_free != name##tail->data + INC_STORAGE_SIZE) ? \
- name##last_free : (name##tail = name##tail->next, \
- name##last_free = name##tail->data))
-
-
-/* Advance the head to the next free location. If the storage is full,
- * a new storage is allocated and linked into the list.
- */
-#define INC_STORAGE_NEXT(name) do { \
- if (name##free == name##last_free) { \
- name##tail = (INC_Storage*)erts_alloc(ERTS_ALC_T_OBJECT_STACK, \
- sizeof(INC_Storage)); \
- memcpy(name##tail->data,name##head->data, \
- INC_STORAGE_SIZE * sizeof(INC_Object)); \
- name##tail->next = name##head->next; \
- name##head->next = name##tail; \
- name##tail->prev = name##tail->next->prev; \
- name##tail->next->prev = name##tail; \
- name##last_free = ((void*)name##tail + \
- ((void*)name##last_free - (void*)name##head)); \
- } \
- name##free++; \
- name##size++; \
- if (name##free == name##head->data + INC_STORAGE_SIZE) { \
- name##head = name##head->next; \
- name##free = name##head->data; \
- } \
-} while(0)
-
-
-/* The head of this storage is the next free location. This is where
- * the next element will be stored.
- */
-#define INC_STORAGE_HEAD(name) (name##free)
-
-
-/* Return the top - the youngest element in the storage. */
-/* #define INC_STORAGE_TOP(name) (name##free - 1 with some magic..) */
-
-
-/* True if the storage is empty, false otherwise */
-#define INC_STORAGE_EMPTY(name) (name##size == 0)
-
-
-/* Store a new element in the head of the storage and advance the head
- * to the next free location.
- */
-#define INC_STORE(name,ptr,sz) do { \
- INC_STORAGE_HEAD(name)->this = ptr; \
- INC_STORAGE_HEAD(name)->size = sz; \
- INC_STORAGE_NEXT(name); \
-} while(0)
-
-
-/* An iterator. Use it together with INC_STORAGE_STEP to browse throuh
- * the storage. Please note that it is not possible to remove an entry
- * in the middle of the storage, use GET or POP to remove enties.
- */
-#define INC_STORAGE_ITERATOR(name) \
- INC_Storage *name##iterator_head = name##tail; \
- INC_Object *name##iterator_current = name##last_free; \
- int name##iterator_left = name##size;
-
-
-/* Return the next element in the storage (sorted by age, oldest
- * first) or NULL if the storage is empty or the last element has been
- * returned already.
- */
-#define INC_STORAGE_STEP(name) (name##iterator_left == 0 ? NULL : \
- (name##iterator_left--, \
- (++name##iterator_current != name##iterator_head->data + \
- INC_STORAGE_SIZE) ? name##iterator_current : \
- (name##iterator_head = name##iterator_head->next, \
- name##iterator_current = name##iterator_head->data)))
-
-
-/* Erase the storage. */
-#define INC_STORAGE_ERASE(name)do { \
- name##head->prev->next = NULL; \
- while (name##head != NULL) { \
- name##tail = name##head; \
- name##head = name##head->next; \
- erts_free(ERTS_ALC_T_OBJECT_STACK,(void*)name##tail); \
- } \
- name##tail = NULL; \
- name##free = NULL; \
- name##last_free = NULL; \
- name##size = 0; \
-} while(0)
-
-/*
- * Structures used by the non-moving memory manager
- */
-
-typedef struct
-{
- Eterm *this;
- unsigned long size;
-} INC_Object;
-
-typedef struct inc_storage {
- struct inc_storage *next;
- struct inc_storage *prev;
- INC_Object data[INC_STORAGE_SIZE];
-} INC_Storage;
-
-typedef struct inc_mem_block
-{
- unsigned long size;
- struct inc_mem_block *prev;
- struct inc_mem_block *next;
-} INC_MemBlock;
-
-typedef struct inc_page
-{
- struct inc_page *next;
- Eterm start[1]; /* Has to be last in struct, this is where the data start */
-} INC_Page;
-
-
-/*
- * Heap pointers for the non-moving memory area.
- */
-extern INC_Page *inc_used_mem;
-extern INC_MemBlock *inc_free_list;
-extern unsigned char *blackmap;
-
-extern Eterm **fwdptrs;
-extern Eterm *inc_fromspc;
-extern Eterm *inc_fromend;
-extern Process *inc_active_proc;
-extern Process *inc_active_last;
-extern Eterm *inc_alloc_limit;
-extern int inc_words_to_go;
-
-INC_STORAGE_DECLARATION(extern,gray);
-INC_STORAGE_DECLARATION(extern,root);
-
-void erts_init_incgc(void);
-void erts_cleanup_incgc(void);
-void erts_incremental_gc(Process *p, int sz, Eterm* objv, int nobj);
-Eterm *erts_inc_alloc(int need);
-
-#else
-# define INC_STORE(lst,ptr,sz)
-# define INC_MARK_FORWARD(ptr)
-# define INC_IS_FORWARDED(ptr)
-# define INC_FORWARD_VALUE(ptr)
-#endif /* INCREMENTAL */
-
-#endif /* _ERL_NMGC_H_ */
diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c
index 16367c305d..649be3f454 100644
--- a/erts/emulator/beam/erl_node_tables.c
+++ b/erts/emulator/beam/erl_node_tables.c
@@ -849,9 +849,6 @@ static Eterm AM_dist_references;
static Eterm AM_node_references;
static Eterm AM_system;
static Eterm AM_timer;
-#ifdef HYBRID
-static Eterm AM_processes;
-#endif
static void setup_reference_table(void);
static Eterm reference_table_term(Uint **hpp, Uint *szp);
@@ -936,9 +933,6 @@ erts_get_node_and_dist_references(struct process *proc)
INIT_AM(node_references);
INIT_AM(timer);
INIT_AM(system);
-#ifdef HYBRID
- INIT_AM(processes);
-#endif
references_atoms_need_init = 0;
}
@@ -1301,12 +1295,6 @@ setup_reference_table(void)
SYSTEM_REF,
TUPLE2(&heap[0], AM_system, am_undefined));
-#ifdef HYBRID
- /* Insert Heap */
- insert_offheap(&erts_global_offheap,
- HEAP_REF,
- TUPLE2(&heap[0], AM_processes, am_undefined));
-#endif
UnUseTmpHeapNoproc(3);
/* Insert all processes */
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 7c46a38c9b..bca8fac259 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -28,7 +28,6 @@
#include "erl_vm.h"
#include "global.h"
#include "erl_process.h"
-#include "erl_nmgc.h"
#include "error.h"
#include "bif.h"
#include "erl_db.h"
@@ -404,11 +403,6 @@ struct erts_system_monitor_flags_t erts_system_monitor_flags;
Eterm erts_system_profile;
struct erts_system_profile_flags_t erts_system_profile_flags;
-#ifdef HYBRID
-Uint erts_num_active_procs;
-Process** erts_active_procs;
-#endif
-
#if ERTS_MAX_PROCESSES > 0x7fffffff
#error "Need to store process_count in another type"
#endif
@@ -697,12 +691,6 @@ erts_init_process(int ncpu)
erts_smp_atomic_init_nob(proc_entry, ERTS_AINT_NULL);
proc_entry++;
}
-#ifdef HYBRID
- erts_active_procs = (Process**)
- erts_alloc(ERTS_ALC_T_ACTIVE_PROCS,
- erts_proc.max * sizeof(Process*));
- erts_num_active_procs = 0;
-#endif
erts_smp_rwmtx_init_opt(&erts_proc_tab_rwmtx,
&proc_tab_rwmtx_opts,
@@ -7078,7 +7066,6 @@ Process *schedule(Process *p, int calls)
/* Never run a suspended process */
ASSERT(!(ERTS_PSFLG_SUSPENDED & erts_smp_atomic32_read_nob(&p->state)));
- ACTIVATE(p);
reds = context_reds;
if (IS_TRACED(p)) {
@@ -7114,7 +7101,6 @@ Process *schedule(Process *p, int calls)
}
p->fcalls = reds;
- ASSERT(IS_ACTIVE(p));
ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p);
return p;
}
@@ -7515,9 +7501,7 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
ErtsRunQueue *rq = NULL;
Process *p;
Sint arity; /* Number of arguments. */
-#ifndef HYBRID
Uint arg_size; /* Size of arguments. */
-#endif
Uint sz; /* Needed words on heap. */
Uint heap_need; /* Size needed on heap. */
Eterm res = THE_NON_VALUE;
@@ -7528,17 +7512,6 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
erts_smp_proc_lock(parent, ERTS_PROC_LOCKS_ALL_MINOR);
#endif
-#ifdef HYBRID
- /*
- * Copy the arguments to the global heap
- * Since global GC might occur we want to do this before adding the
- * new process to the erts_proc.tab.
- */
- BM_SWAP_TIMER(system,copy);
- LAZY_COPY(parent,args);
- BM_SWAP_TIMER(copy,system);
- heap_need = 0;
-#endif /* HYBRID */
/*
* Check for errors.
*/
@@ -7577,12 +7550,10 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
#endif
BM_COUNT(processes_spawned);
-#ifndef HYBRID
BM_SWAP_TIMER(system,size);
arg_size = size_object(args);
BM_SWAP_TIMER(size,system);
heap_need = arg_size;
-#endif
p->flags = erts_default_process_flags;
@@ -7627,9 +7598,6 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
p->heap = (Eterm *) ERTS_HEAP_ALLOC(ERTS_ALC_T_HEAP, sizeof(Eterm)*sz);
p->old_hend = p->old_htop = p->old_heap = NULL;
p->high_water = p->heap;
-#ifdef INCREMENTAL
- p->scan_top = p->high_water;
-#endif
p->gen_gcs = 0;
p->stop = p->hend = p->heap + sz;
p->htop = p->heap;
@@ -7655,19 +7623,10 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
BM_STOP_TIMER(system);
BM_MESSAGE(args,p,parent);
BM_START_TIMER(system);
-#ifdef HYBRID
- p->arg_reg[2] = args;
-#ifdef INCREMENTAL
- p->active = 0;
- if (ptr_val(args) >= inc_fromspc && ptr_val(args) < inc_fromend)
- INC_ACTIVATE(p);
-#endif
-#else
BM_SWAP_TIMER(system,copy);
p->arg_reg[2] = copy_struct(args, arg_size, &p->htop, &p->off_heap);
BM_MESSAGE_COPIED(arg_size);
BM_SWAP_TIMER(copy,system);
-#endif
p->arity = 3;
p->fvalue = NIL;
@@ -7724,13 +7683,6 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
#endif
p->parent = parent->id == ERTS_INVALID_PID ? NIL : parent->id;
-#ifdef HYBRID
- p->rrma = NULL;
- p->rrsrc = NULL;
- p->nrr = 0;
- p->rrsz = 0;
-#endif
-
INIT_HOLE_CHECK(p);
#ifdef DEBUG
p->last_old_htop = NULL;
@@ -7799,15 +7751,6 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
so->mref = mref;
}
-#ifdef HYBRID
- /*
- * Add process to the array of active processes.
- */
- ACTIVATE(p);
- p->active_index = erts_num_active_procs++;
- erts_active_procs[p->active_index] = p;
-#endif
-
#ifdef ERTS_SMP
p->scheduler_data = NULL;
p->suspendee = NIL;
@@ -7891,9 +7834,6 @@ void erts_init_empty_process(Process *p)
p->reg = NULL;
p->heap_sz = 0;
p->high_water = NULL;
-#ifdef INCREMENTAL
- p->scan_top = NULL;
-#endif
p->old_hend = NULL;
p->old_htop = NULL;
p->old_heap = NULL;
@@ -7945,14 +7885,6 @@ void erts_init_empty_process(Process *p)
#endif
#endif
- ACTIVATE(p);
-
-#ifdef HYBRID
- p->rrma = NULL;
- p->rrsrc = NULL;
- p->nrr = 0;
- p->rrsz = 0;
-#endif
INIT_HOLE_CHECK(p);
#ifdef DEBUG
p->last_old_htop = NULL;
@@ -7998,9 +7930,6 @@ erts_debug_verify_clean_empty_process(Process* p)
ASSERT(p->reg == NULL);
ASSERT(p->heap_sz == 0);
ASSERT(p->high_water == NULL);
-#ifdef INCREMENTAL
- ASSERT(p->scan_top == NULL);
-#endif
ASSERT(p->old_hend == NULL);
ASSERT(p->old_htop == NULL);
ASSERT(p->old_heap == NULL);
@@ -8148,22 +8077,6 @@ delete_process(Process* p)
ASSERT(!p->suspend_monitors);
p->fvalue = NIL;
-
-#ifdef HYBRID
- erts_active_procs[p->active_index] =
- erts_active_procs[--erts_num_active_procs];
- erts_active_procs[p->active_index]->active_index = p->active_index;
-#ifdef INCREMENTAL
- if (INC_IS_ACTIVE(p))
- INC_DEACTIVATE(p);
-#endif
-
- if (p->rrma != NULL) {
- erts_free(ERTS_ALC_T_ROOTSET,p->rrma);
- erts_free(ERTS_ALC_T_ROOTSET,p->rrsrc);
- }
-#endif
-
}
static ERTS_INLINE erts_aint32_t
@@ -8552,7 +8465,6 @@ send_exit_signal(Process *c_p, /* current process if and only
? rsn
: copy_object(rsn, rp)),
NULL);
- ACTIVATE(rp);
}
#endif
return -1; /* Receiver will exit */
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index 0798697350..e9e5a3365f 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -868,24 +868,6 @@ struct process {
#endif
#endif
-#ifdef HYBRID
- Eterm *rrma; /* Remembered roots to Message Area */
- Eterm **rrsrc; /* The source of the root */
- Uint nrr; /* Number of remembered roots */
- Uint rrsz; /* Size of root array */
-#endif
-
-#ifdef HYBRID
- Uint active; /* Active since last major collection? */
- Uint active_index; /* Index in the active process array */
-#endif
-
-#ifdef INCREMENTAL
- Process *active_next; /* Active processes to scan for roots */
- Process *active_prev; /* in collection of the message area */
- Eterm *scan_top;
-#endif
-
#ifdef CHECK_FOR_HOLES
Eterm* last_htop; /* No need to scan the heap below this point. */
ErlHeapFragment* last_mbuf; /* No need to scan beyond this mbuf. */
@@ -1031,10 +1013,6 @@ Eterm* erts_set_hole_marker(Eterm* ptr, Uint sz);
extern erts_smp_rwmtx_t erts_proc_tab_rwmtx;
extern erts_smp_atomic_t *erts_proc_tab;
-#ifdef HYBRID
-extern Uint erts_num_active_procs;
-extern Process** erts_active_procs;
-#endif
extern Uint erts_default_process_flags;
extern erts_smp_rwmtx_t erts_cpu_bind_rwmtx;
/* If any of the erts_system_monitor_* variables are set (enabled),
diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h
index 5dc307e383..a0e12e57f2 100644
--- a/erts/emulator/beam/erl_vm.h
+++ b/erts/emulator/beam/erl_vm.h
@@ -29,19 +29,10 @@
/* #define FORCE_HEAP_FRAGS */
-#if defined(HYBRID)
-/* # define CHECK_FOR_HOLES */
-#endif
-
#if defined(DEBUG) && !defined(CHECK_FOR_HOLES) && !defined(__WIN32__)
# define CHECK_FOR_HOLES
#endif
-#if defined(HYBRID)
-/* # define INCREMENTAL 1 */ /* Incremental garbage collection */
-/* # define INC_TIME_BASED 1 */ /* Time-based incremental GC (vs Work-based) */
-#endif
-
#define BEAM 1
#define EMULATOR "BEAM"
#define SEQ_TRACE 1
@@ -70,16 +61,6 @@
#define H_DEFAULT_SIZE 233 /* default (heap + stack) min size */
#define VH_DEFAULT_SIZE 32768 /* default virtual (bin) heap min size (words) */
-#ifdef HYBRID
-# define SH_DEFAULT_SIZE 2629425 /* default message area min size */
-#endif
-
-#ifdef INCREMENTAL
-# define INC_NoPAGES 256 /* Number of pages in the old generation */
-# define INC_PAGESIZE 32768 /* The size of each page */
-# define INC_STORAGE_SIZE 1024 /* The size of gray stack and similar */
-#endif
-
#define CP_SIZE 1
#define ErtsHAllocLockCheck(P) \
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index 261a480ebf..feb1740649 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -2626,14 +2626,12 @@ dec_term_atom_common:
}
old_uniq = unsigned_val(temp);
-#ifndef HYBRID /* FIND ME! */
/*
* It is safe to link the fun into the fun list only when
* no more validity tests can fail.
*/
funp->next = off_heap->first;
off_heap->first = (struct erl_off_heap_header*)funp;
-#endif
funp->fe = erts_put_fun_entry2(module, old_uniq, old_index,
uniq, index, arity);
@@ -2704,14 +2702,12 @@ dec_term_atom_common:
goto error;
}
-#ifndef HYBRID /* FIND ME! */
/*
* It is safe to link the fun into the fun list only when
* no more validity tests can fail.
*/
funp->next = off_heap->first;
off_heap->first = (struct erl_off_heap_header*)funp;
-#endif
old_uniq = unsigned_val(temp);
funp->fe = erts_put_fun_entry(module, old_uniq, old_index);
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 12fea779da..9e387c550f 100755
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -570,92 +570,6 @@ extern erts_smp_atomic32_t erts_max_gen_gcs;
extern int erts_disable_tolerant_timeofday;
-#ifdef HYBRID
-
-/* Message Area heap pointers */
-extern Eterm *global_heap; /* Heap start */
-extern Eterm *global_hend; /* Heap end */
-extern Eterm *global_htop; /* Heap top (heap pointer) */
-extern Eterm *global_saved_htop; /* Saved heap top (heap pointer) */
-extern Uint global_heap_sz; /* Heap size, in words */
-extern Eterm *global_old_heap; /* Old generation */
-extern Eterm *global_old_hend;
-extern ErlOffHeap erts_global_offheap; /* Global MSO (OffHeap) list */
-
-extern Uint16 global_gen_gcs;
-extern Uint16 global_max_gen_gcs;
-extern Uint global_gc_flags;
-
-#ifdef INCREMENTAL
-#define ACTIVATE(p)
-#define DEACTIVATE(p)
-#define IS_ACTIVE(p) 1
-
-#define INC_ACTIVATE(p) do { \
- if ((p)->active) { \
- if ((p)->active_next != NULL) { \
- (p)->active_next->active_prev = (p)->active_prev; \
- if ((p)->active_prev) { \
- (p)->active_prev->active_next = (p)->active_next; \
- } else { \
- inc_active_proc = (p)->active_next; \
- } \
- inc_active_last->active_next = (p); \
- (p)->active_next = NULL; \
- (p)->active_prev = inc_active_last; \
- inc_active_last = (p); \
- } \
- } else { \
- (p)->active_next = NULL; \
- (p)->active_prev = inc_active_last; \
- if (inc_active_last) { \
- inc_active_last->active_next = (p); \
- } else { \
- inc_active_proc = (p); \
- } \
- inc_active_last = (p); \
- (p)->active = 1; \
- } \
-} while(0);
-
-#define INC_DEACTIVATE(p) do { \
- ASSERT((p)->active == 1); \
- if ((p)->active_next == NULL) { \
- inc_active_last = (p)->active_prev; \
- } else { \
- (p)->active_next->active_prev = (p)->active_prev; \
- } \
- if ((p)->active_prev == NULL) { \
- inc_active_proc = (p)->active_next; \
- } else { \
- (p)->active_prev->active_next = (p)->active_next; \
- } \
- (p)->active = 0; \
-} while(0);
-
-#define INC_IS_ACTIVE(p) ((p)->active != 0)
-
-#else
-extern Eterm *global_old_htop;
-extern Eterm *global_high_water;
-#define ACTIVATE(p) (p)->active = 1;
-#define DEACTIVATE(p) (p)->active = 0;
-#define IS_ACTIVE(p) ((p)->active != 0)
-#define INC_ACTIVATE(p)
-#define INC_IS_ACTIVE(p) 1
-#endif /* INCREMENTAL */
-
-#else
-# define ACTIVATE(p)
-# define DEACTIVATE(p)
-# define IS_ACTIVE(p) 1
-# define INC_ACTIVATE(p)
-#endif /* HYBRID */
-
-#ifdef HYBRID
-extern Uint global_heap_min_sz;
-#endif
-
extern int bif_reductions; /* reductions + fcalls (when doing call_bif) */
extern int stackdump_on_exit;
@@ -922,7 +836,6 @@ __decl_noreturn void __noreturn erl_exit_flush_async(int n, char*, ...);
void erl_error(char*, va_list);
/* copy.c */
-void init_copy(void);
Eterm copy_object(Eterm, Process*);
#if HALFWORD_HEAP
@@ -952,116 +865,6 @@ Eterm copy_shallow(Eterm*, Uint, Eterm**, ErlOffHeap*);
void move_multi_frags(Eterm** hpp, ErlOffHeap*, ErlHeapFragment* first,
Eterm* refs, unsigned nrefs);
-#ifdef HYBRID
-#define RRMA_DEFAULT_SIZE 256
-#define RRMA_STORE(p,ptr,src) do { \
- ASSERT((p)->rrma != NULL); \
- ASSERT((p)->rrsrc != NULL); \
- (p)->rrma[(p)->nrr] = (ptr); \
- (p)->rrsrc[(p)->nrr++] = (src); \
- if ((p)->nrr == (p)->rrsz) \
- { \
- (p)->rrsz *= 2; \
- (p)->rrma = (Eterm *) erts_realloc(ERTS_ALC_T_ROOTSET, \
- (void*)(p)->rrma, \
- sizeof(Eterm) * (p)->rrsz); \
- (p)->rrsrc = (Eterm **) erts_realloc(ERTS_ALC_T_ROOTSET, \
- (void*)(p)->rrsrc, \
- sizeof(Eterm) * (p)->rrsz); \
- } \
-} while(0)
-
-/* Note that RRMA_REMOVE decreases the given index after deletion.
- * This is done so that a loop with an increasing index can call
- * remove without having to decrease the index to see the element
- * placed in the hole after the deleted element.
- */
-#define RRMA_REMOVE(p,index) do { \
- p->rrsrc[index] = p->rrsrc[--p->nrr]; \
- p->rrma[index--] = p->rrma[p->nrr]; \
- } while(0);
-
-
-/* The MessageArea STACKs are used while copying messages to the
- * message area.
- */
-#define MA_STACK_EXTERNAL_DECLARE(type,_s_) \
- typedef type ma_##_s_##_type; \
- extern ma_##_s_##_type *ma_##_s_##_stack; \
- extern Uint ma_##_s_##_top; \
- extern Uint ma_##_s_##_size;
-
-#define MA_STACK_DECLARE(_s_) \
- ma_##_s_##_type *ma_##_s_##_stack; Uint ma_##_s_##_top; Uint ma_##_s_##_size;
-
-#define MA_STACK_ALLOC(_s_) do { \
- ma_##_s_##_top = 0; \
- ma_##_s_##_size = 512; \
- ma_##_s_##_stack = (ma_##_s_##_type*)erts_alloc(ERTS_ALC_T_OBJECT_STACK, \
- sizeof(ma_##_s_##_type) * ma_##_s_##_size); \
-} while(0)
-
-
-#define MA_STACK_PUSH(_s_,val) do { \
- ma_##_s_##_stack[ma_##_s_##_top++] = (val); \
- if (ma_##_s_##_top == ma_##_s_##_size) \
- { \
- ma_##_s_##_size *= 2; \
- ma_##_s_##_stack = \
- (ma_##_s_##_type*) erts_realloc(ERTS_ALC_T_OBJECT_STACK, \
- (void*)ma_##_s_##_stack, \
- sizeof(ma_##_s_##_type) * ma_##_s_##_size); \
- } \
-} while(0)
-
-#define MA_STACK_POP(_s_) (ma_##_s_##_top != 0 ? ma_##_s_##_stack[--ma_##_s_##_top] : 0)
-#define MA_STACK_TOP(_s_) (ma_##_s_##_stack[ma_##_s_##_top - 1])
-#define MA_STACK_UPDATE(_s_,offset,value) \
- *(ma_##_s_##_stack[ma_##_s_##_top - 1] + (offset)) = (value)
-#define MA_STACK_SIZE(_s_) (ma_##_s_##_top)
-#define MA_STACK_ELM(_s_,i) ma_##_s_##_stack[i]
-
-MA_STACK_EXTERNAL_DECLARE(Eterm,src);
-MA_STACK_EXTERNAL_DECLARE(Eterm*,dst);
-MA_STACK_EXTERNAL_DECLARE(Uint,offset);
-
-
-#ifdef INCREMENTAL
-extern Eterm *ma_pending_stack;
-extern Uint ma_pending_top;
-extern Uint ma_pending_size;
-
-#define NO_COPY(obj) (IS_CONST(obj) || \
- (((ptr_val(obj) >= global_heap) && \
- (ptr_val(obj) < global_htop)) || \
- ((ptr_val(obj) >= inc_fromspc) && \
- (ptr_val(obj) < inc_fromend)) || \
- ((ptr_val(obj) >= global_old_heap) && \
- (ptr_val(obj) < global_old_hend))))
-
-#else
-
-#define NO_COPY(obj) (IS_CONST(obj) || \
- (((ptr_val(obj) >= global_heap) && \
- (ptr_val(obj) < global_htop)) || \
- ((ptr_val(obj) >= global_old_heap) && \
- (ptr_val(obj) < global_old_hend))))
-
-#endif /* INCREMENTAL */
-
-#define LAZY_COPY(from,obj) do { \
- if (!NO_COPY(obj)) { \
- BM_LAZY_COPY_START; \
- BM_COUNT(messages_copied); \
- obj = copy_struct_lazy(from,obj,0); \
- BM_LAZY_COPY_STOP; \
- } \
-} while(0)
-
-Eterm copy_struct_lazy(Process*, Eterm, Uint);
-
-#endif /* HYBRID */
-
/* Utilities */
extern void erts_delete_nodes_monitors(Process *, ErtsProcLocks);
extern Eterm erts_monitor_nodes(Process *, Eterm, Eterm);
@@ -1155,10 +958,6 @@ void erts_offset_heap_ptr(Eterm*, Uint, Sint, Eterm*, Eterm*);
void erts_offset_heap(Eterm*, Uint, Sint, Eterm*, Eterm*);
void erts_free_heap_frags(Process* p);
-#ifdef HYBRID
-int erts_global_garbage_collect(Process*, int, Eterm*, int);
-#endif
-
/* io.c */
struct erl_drv_port_data_lock {