Skip to content

Commit

Permalink
[cgen] make GC work: record assignments in assignment table; fill spa…
Browse files Browse the repository at this point in the history
…ce for temporaries in the stack frame with zeroes
  • Loading branch information
tanhevg committed Aug 4, 2016
1 parent 7ef4c46 commit 836febd
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 35 deletions.
25 changes: 19 additions & 6 deletions asm/trap/trap.handler.asm
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ _sabort_msg3: .asciiz "Length to substr too long\n"
_sabort_msg4: .asciiz "Length to substr is negative\n"
_sabort_msg: .asciiz "Execution aborted.\n"
_objcopy_msg: .asciiz "Object.copy: Invalid object size.\n"
_gc_abort_msg: .asciiz "GC bug!\n"
_gc_abort_msg: .asciiz "GC bug at address "

# Exception Handler Message:
_uncaught_msg1: .asciiz "Uncaught Exception of Class "
Expand Down Expand Up @@ -1276,8 +1276,8 @@ _MemMgr_Test_end:
#
# The assignment table is implemented as a stack growing towards the
# allocation pointer ($gp) in the work area. If they cross, a minor
# collection is then carried out. This allows the garbage collector to
# to have to keep a fixed table of assignments. As a result, programs
# collection is then carried out. This allows the garbage collector
# to keep a fixed table of assignments. As a result, programs
# with many assignments will tend not to be bogged down with extra
# garbage collections.
#
Expand All @@ -1302,11 +1302,11 @@ _MemMgr_Test_end:
# first L4 is checked to see if any of the unused memory between L3
# and L4 is enough to satisfy this requirement. If not, then the
# heap will be expanded. If it is, the appropriate amount will be
# transfered from the unused area to the work/reserve area.
# transferred from the unused area to the work/reserve area.
#
# 2) During a major collection, if the live objects in the old area
# do not fit within the new area, the heap is expanded and $s7
# is updated to reflact this. This value later gets stored back
# is updated to reflect this. This value later gets stored back
# into L4.
#
# During a normal allocation and minor collections, the heap has the
Expand Down Expand Up @@ -1612,10 +1612,17 @@ _gc_check:
_gc_ok:
jr $ra

_gc_abort:
_gc_abort:
move $t0 $a0
la $a0 _gc_abort_msg
li $v0 4
syscall # print gc message
move $a0 $t0
li $v0 1
syscall # print the offending address
la $a0 _nl
li $v0 4
syscall # print newline
li $v0 10
syscall # exit

Expand Down Expand Up @@ -1661,10 +1668,13 @@ _GenGC_Collect:
sw $ra 12($sp) # save return address
sw $a0 8($sp) # save stack end
sw $a1 4($sp) # save size
lw $t0 _MemMgr_DEBUG
beqz $t0 _GenGC_COLLECT_skip
la $a0 _GenGC_COLLECT # print collection message
li $v0 4
syscall
lw $a0 8($sp) # restore stack end
_GenGC_COLLECT_skip:
jal _GenGC_MinorC # minor collection
la $a1 heap_start
lw $t1 GenGC_HDRMINOR1($a1)
Expand Down Expand Up @@ -1711,9 +1721,12 @@ _GenGC_Collect_nomajor:
lw $s7 GenGC_HDRL3($a1) # load limit into $s7
b _GenGC_Collect_done
_GenGC_Collect_major:
lw $t0 _MemMgr_DEBUG
beqz $t0 _CgenGC_Major_skip
la $a0 _GenGC_Major # print collection message
li $v0 4
syscall
_CgenGC_Major_skip:
lw $a0 8($sp) # restore stack end
jal _GenGC_MajorC # major collection
la $a1 heap_start
Expand Down
6 changes: 5 additions & 1 deletion cgen/cgen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -264,14 +264,18 @@ void code_select_gc(ostream &str) {
//
// Generate GC choice constants (pointers to GC functions)
//
str << GLOBAL << "_MemMgr_INITIALIZER" << endl; str << "_MemMgr_INITIALIZER:" << endl;
str << GLOBAL << "_MemMgr_INITIALIZER" << endl;
str << "_MemMgr_INITIALIZER:" << endl;
str << WORD << gc_init_names[cgen_Memmgr] << endl;
str << GLOBAL << "_MemMgr_COLLECTOR" << endl;
str << "_MemMgr_COLLECTOR:" << endl;
str << WORD << gc_collect_names[cgen_Memmgr] << endl;
str << GLOBAL << "_MemMgr_TEST" << endl;
str << "_MemMgr_TEST:" << endl;
str << WORD << (cgen_Memmgr_Test == GC_TEST) << endl;
str << GLOBAL << "_MemMgr_DEBUG" << endl;
str << "_MemMgr_DEBUG:" << endl;
str << WORD << (cgen_Memmgr_Debug == GC_DEBUG) << endl;
}


19 changes: 14 additions & 5 deletions cgen/cgen.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
#include "cgen_helpers.h"


enum Basicness {
Basic, NotBasic
};
#define TRUE 1
#define FALSE 0

Expand All @@ -18,11 +15,18 @@ class ObjectEnvRecord {
Symbol declaring_type;
char *reg;
int offset;
bool code_gc_assign;
public:
ObjectEnvRecord(Symbol _declaring_type, char *_reg, int _offset) :
declaring_type(_declaring_type),
reg(_reg),
offset(_offset) { }
offset(_offset),
code_gc_assign(false){ }
ObjectEnvRecord(Symbol _declaring_type, char *_reg, int _offset, bool _code_gc_assign) :
declaring_type(_declaring_type),
reg(_reg),
offset(_offset),
code_gc_assign(_code_gc_assign){ }

Symbol get_declaring_type() { return declaring_type; }

Expand All @@ -32,7 +36,12 @@ class ObjectEnvRecord {

template<typename... Ts>
ostream &code_store(ostream &str, int line_no, Ts... logs) {
return emit_store(ACC, offset, reg, str, line_no, logs...);
emit_store(ACC, offset, reg, str, line_no, logs...);
if (code_gc_assign) {
emit_addiu(A1, reg, offset * WORD_SIZE, str, line_no, "Argument for _GenGC_Assign");
emit_jal("_GenGC_Assign", str, line_no, "Notify GC of attribute assignment");
}
return str;
}

template<typename... Ts>
Expand Down
8 changes: 6 additions & 2 deletions cgen/cgen_expressions.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <cool-tree.h>
#include <extern_symbols.h>
#include <string>
#include <cgen_gc.h>
#include "cgen.h"
#include "string_util.h"

Expand All @@ -10,13 +10,14 @@ using std::to_string;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#pragma clang diagnostic ignored "-Wwritable-strings"

static ObjectEnvRecord *stack_entry(Symbol declaring_type, int offset) {
return new ObjectEnvRecord(declaring_type, FP, offset);
}

static ObjectEnvRecord *heap_entry(Symbol declaring_type,
int offset) {
return new ObjectEnvRecord(declaring_type, SELF, offset);
return new ObjectEnvRecord(declaring_type, SELF, offset, cgen_Memmgr != GC_NOGC);
}

/**
Expand Down Expand Up @@ -320,6 +321,9 @@ void CodeGenerator::emit_function_entry(int tmp_count, int line_no) {
emit_move(SELF, ACC, str) << endl;
if (tmp_count > 0) {
emit_addiu(SP, SP, -4 * tmp_count, str, line_no, "push ", tmp_count, " temporaries");
for(int i = tmp_count; i > 0; i--) {
emit_store(ZERO, i, SP, str, line_no, "clear the space reserved for temporaries");
}
}

}
Expand Down
Binary file added doc/bison.pdf
Binary file not shown.
37 changes: 27 additions & 10 deletions doc/cgen_notes.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
- Operators dealing with Int's and Bool's deal with them in object form; temporary objects are created on heap for result of each expression
- Initialisation with constants should load the appropriate label to $a0, and then store $a0 in the right place in memory (heap or stack)

- self should be passed in $a0 for coolaid. we store it in $s0; need to also store self in AR and put it back in $s0 on method return (callee responsibility)
- use a scoped symbol table to figure out whether a symbol is a local variable (that includes method parameters) or an object attribute - object environment
- the value in the symbol table is a record that has a register name ($t9 for attributes, $fp for variables and parameters) and an offset
- each let expression creates a new temporary that is visible in the body; so the variable's offset from $fp can be either positive (parameters) or negative (let bindings)
- Operators dealing with Int's and Bool's deal with them in object form;
temporary objects are created on heap for result of each expression
- Initialisation with constants should load the appropriate label to $a0,
and then store $a0 in the right place in memory (heap or stack)
- self should be passed in $a0 for coolaid. we store it in $s0;
need to also store self in the frame and put it back in $s0 on method return (callee responsibility)
- use a scoped symbol table - object environment - to figure out whether a symbol is a local variable
(that includes method parameters) or an object attribute - object environment
- object environment usage:
-- add all class attributes to the top scope before visiting class; pop after
-- add method parameter to the next scope before visitin method; pop after
-- add method parameter to the next scope before visiting method; pop after
-- each let binding adds its variable to the new scope
- the value in the object environment is a record that has a register name -
$s0 for attributes, $fp for variables and parameters - and an offset
- each let expression creates a new temporary that is visible in the body;
so the variable's offset from $fp can be either positive (parameters) or negative (let bindings)
- when the space is allocated for temporaries on method entry, we need to fill it with zeros;
otherwise we might get some old rubbish there, which will upset GC
- popping the frame off the stack is callee responsibility (i.e the method itself):
it knows about the argument count and temporary count

- Activation record layout:
- Frame layout:

|----------------|
| old $fp |
Expand All @@ -22,4 +31,12 @@
| temp 1 |
| .... |
| temp N |
|----------------| <---- $sp points here after AR is fully formed
|----------------| <---- $sp points here after the frame is fully formed

- cases
-- there is a case subroutine, defined in emit.h
-- it traverses the "branch table" (passed as an argument), and looks for the tag
of case expression (also passed as an argument)
-- the branch table is generated for each case expression
-- each entry is 2 words: tag of the result, followed by address of the branch expression (label)

2 changes: 1 addition & 1 deletion run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

FILE=$1

output/Debug/cool-compiler -o "output/$FILE" "test/$FILE.cl"
output/Debug/cool-compiler -gTo "output/$FILE" "test/$FILE.cl"
spim -exception_file asm/trap/trap.handler.asm -file "output/$FILE.asm"

# output/Debug/cool-compiler -o output/primes test/primes.cl
Expand Down
10 changes: 0 additions & 10 deletions tree/handle_flags.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,6 @@ void handle_flags(int argc, char *argv[]) {
case 'r':
disable_reg_alloc = 1;
break;
//#else
// case 'l':
// case 'p':
// case 's':
// case 'c':
// case 'v':
// case 'r':
// cerr << "No debugging available\n";
// break;
//#endif
case 'g': // enable garbage collection
cgen_Memmgr = GC_GENGC;
break;
Expand Down

0 comments on commit 836febd

Please sign in to comment.