Commit 31f7002a authored by Kevin Modzelewski's avatar Kevin Modzelewski

Some small independent changes

Can emit add/sub/etc instructions with 32-bit operands in addition to 8-bit now
Can get the RSP and RBP in rewriter1, for accessing scratch space
Change some debugging output

Fix a gc bug: if an object gets new'd, and takes a parameter that gets new'd, the sequence is
1) object space gets allocated
2) parameter space gets allocated
3) parameter gets constructed
4) object gets constructed
The bug is that the object construction is what initializes the GC header,
so if step #3 causes a collection, it can see that the allocation from step #1
has an invalid header.
As a workaround, always zero out the header in allocation, and skip blocks with
zeroed headers.
The real solution is probably to have the GC manage the header itself rather than
expecting the user to; this would mean that gc_alloc would take the allocation kind,
put that into the header, and then return a pointer to the post-header data section
of the allocation.
parent 138e4546
......@@ -289,8 +289,9 @@ private:
CompilerType* rtn_type = func->callType(ArgPassSpec(arg_types.size()), arg_types, NULL);
// Should be unboxing things before getting here:
ASSERT(rtn_type == unboxedType(rtn_type->getConcreteType()), "%s", rtn_type->debugName().c_str());
// Should be unboxing things before getting here; would like to assert, though
// we haven't specialized all of the stdlib.
// ASSERT(rtn_type == unboxedType(rtn_type->getConcreteType()), "%s", rtn_type->debugName().c_str());
rtn_type = unboxedType(rtn_type->getConcreteType());
if (speculation != TypeAnalysis::NONE) {
......
......@@ -73,7 +73,7 @@ void Assembler::emitArith(Immediate imm, Register r, int opcode) {
// assert(r != RSP && "This breaks unwinding, please don't use.");
int64_t amount = imm.val;
RELEASE_ASSERT(-0x80 <= amount && amount < 0x80 && "unsupported", "");
RELEASE_ASSERT((-1L << 31) <= amount && amount < (1L << 31) - 1, "");
assert(0 <= opcode && opcode < 8);
int rex = REX_W;
......@@ -85,9 +85,15 @@ void Assembler::emitArith(Immediate imm, Register r, int opcode) {
}
emitRex(rex);
emitByte(0x83);
emitModRM(0b11, opcode, reg_idx);
emitByte(amount);
if (-0x80 <= amount && amount < 0x80) {
emitByte(0x83);
emitModRM(0b11, opcode, reg_idx);
emitByte(amount);
} else {
emitByte(0x81);
emitModRM(0b11, opcode, reg_idx);
emitInt(amount, 4);
}
}
......
......@@ -27,6 +27,10 @@ using namespace pyston::assembler;
Register fromArgnum(int argnum) {
switch (argnum) {
case -5:
return RBP;
case -4:
return RSP;
case -3:
return R11;
case -2:
......@@ -234,6 +238,17 @@ RewriterVar RewriterVar::toBool(int dest) {
return RewriterVar(rewriter, dest, version);
}
RewriterVar RewriterVar::add(int64_t amount) {
assertValid();
if (amount > 0)
rewriter->assembler->add(assembler::Immediate(amount), fromArgnum(this->argnum));
else
rewriter->assembler->sub(assembler::Immediate(-amount), fromArgnum(this->argnum));
int new_version = rewriter->mutate(this->argnum);
return RewriterVar(rewriter, this->argnum, new_version);
}
Rewriter* Rewriter::createRewriter(void* ic_rtn_addr, int num_orig_args, int num_temp_regs, const char* debug_name) {
assert(num_temp_regs <= 2 && "unsupported");
......@@ -267,7 +282,7 @@ Rewriter::Rewriter(ICSlotRewrite* rewrite, int num_orig_args, int num_temp_regs)
//}
#ifndef NDEBUG
for (int i = -3; i < MAX_ARGS; i++) {
for (int i = -5; i < MAX_ARGS; i++) {
versions[i] = next_version++;
}
#endif
......@@ -297,17 +312,39 @@ RewriterVar Rewriter::getArg(int argnum) {
#ifndef NDEBUG
int version = versions[argnum];
assert(version);
assert(version == argnum + 5);
assert(version == argnum + 7);
#else
int version = 0;
#endif
return RewriterVar(this, argnum, version);
}
RewriterVar Rewriter::getRsp() {
int argnum = -4;
#ifndef NDEBUG
int version = versions[argnum];
#else
int version = 0;
#endif
assert(version);
return RewriterVar(this, argnum, version);
}
RewriterVar Rewriter::getRbp() {
int argnum = -5;
#ifndef NDEBUG
int version = versions[argnum];
#else
int version = 0;
#endif
assert(version);
return RewriterVar(this, argnum, version);
}
#ifndef NDEBUG
void Rewriter::checkArgsValid() {
for (int i = 0; i < num_orig_args; i++)
checkVersion(i, i + 5);
checkVersion(i, i + 7);
}
int Rewriter::mutate(int argnum) {
......
......@@ -71,6 +71,7 @@ public:
void push();
RewriterVar cmp(AST_TYPE::AST_TYPE cmp_type, const RewriterVar& val, int dest);
RewriterVar toBool(int dest);
RewriterVar add(int64_t amount);
friend class Rewriter;
};
......@@ -117,6 +118,12 @@ public:
inline void checkArgsValid() {}
#endif
int getFuncStackSize() { return rewrite->getFuncStackSize(); }
int getScratchRbpOffset() { return rewrite->getScratchRbpOffset(); }
int getScratchBytes() { return rewrite->getScratchBytes(); }
RewriterVar getRbp();
RewriterVar getRsp();
void addDecision(int way);
RewriterVar alloca_(int bytes, int dest_argnum);
......
......@@ -1400,6 +1400,7 @@ bool PrintVisitor::visit_return(AST_Return* node) {
}
bool PrintVisitor::visit_slice(AST_Slice* node) {
printf("<slice>(");
if (node->lower)
node->lower->accept(this);
if (node->upper || node->step)
......@@ -1410,6 +1411,7 @@ bool PrintVisitor::visit_slice(AST_Slice* node) {
putchar(':');
node->step->accept(this);
}
printf(")");
return true;
}
......
......@@ -145,7 +145,7 @@ private:
AST_expr* remapped_iter = remapExpr(c->iter);
AST_expr* iter_attr = makeLoadAttribute(remapped_iter, "__iter__", true);
AST_expr* iter_call = makeCall(iter_attr);
std::string iter_name = nodeName(node, "iter", i);
std::string iter_name = nodeName(node, "lc_iter", i);
AST_stmt* iter_assign = makeAssign(iter_name, iter_call);
push_back(iter_assign);
......
......@@ -121,6 +121,10 @@ static void markPhase() {
setMark(header);
// is being made
if (header->kind_id == 0)
continue;
ASSERT(KIND_OFFSET <= header->kind_id && header->kind_id < KIND_OFFSET + num_kinds, "%p %d", header,
header->kind_id);
......
......@@ -24,14 +24,6 @@ namespace gc {
#define MARK_BIT 0x1
inline GCObjectHeader* headerFromObject(void* obj) {
#ifndef NVALGRIND
return static_cast<GCObjectHeader*>((void*)((char*)obj + 0));
#else
return static_cast<GCObjectHeader*>(obj);
#endif
}
inline void setMark(GCObjectHeader* header) {
header->gc_flags |= MARK_BIT;
}
......
......@@ -22,6 +22,14 @@
namespace pyston {
namespace gc {
inline GCObjectHeader* headerFromObject(void* obj) {
#ifndef NVALGRIND
return static_cast<GCObjectHeader*>((void*)((char*)obj + 0));
#else
return static_cast<GCObjectHeader*>(obj);
#endif
}
#define BLOCK_SIZE 4096
#define ATOM_SIZE 16
static_assert(BLOCK_SIZE % ATOM_SIZE == 0, "");
......@@ -78,24 +86,28 @@ public:
void* realloc(void* ptr, size_t bytes);
void* alloc(size_t bytes) {
void* rtn;
// assert(bytes >= 16);
if (bytes <= 16)
return allocSmall(16, &heads[0], &full_heads[0]);
if (bytes <= 32)
return allocSmall(32, &heads[1], &full_heads[1]);
if (bytes > sizes[NUM_BUCKETS - 1]) {
return allocLarge(bytes);
}
for (int i = 2; i < NUM_BUCKETS; i++) {
if (sizes[i] >= bytes) {
return allocSmall(sizes[i], &heads[i], &full_heads[i]);
rtn = allocSmall(16, &heads[0], &full_heads[0]);
else if (bytes <= 32)
rtn = allocSmall(32, &heads[1], &full_heads[1]);
else if (bytes > sizes[NUM_BUCKETS - 1])
rtn = allocLarge(bytes);
else {
rtn = NULL;
for (int i = 2; i < NUM_BUCKETS; i++) {
if (sizes[i] >= bytes) {
rtn = allocSmall(sizes[i], &heads[i], &full_heads[i]);
break;
}
}
}
// unreachable
abort();
// assert(rtn);
GCObjectHeader* header = headerFromObject(rtn);
*reinterpret_cast<intptr_t*>(header) = 0;
return rtn;
}
void free(void* ptr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment