1.1 --- a/jitcraft/BytecodeCompiler.cpp Tue Jul 03 13:53:34 2012 -0400
1.2 +++ b/jitcraft/BytecodeCompiler.cpp Wed Jul 04 19:39:00 2012 -0400
1.3 @@ -33,6 +33,7 @@
1.4 BytecodeCompiler::BytecodeCompiler(Zone *zone, ParseTree *tree, Module *module)
1.5 : zone_(zone),
1.6 tree_(tree),
1.7 + emitter_(zone->pool()),
1.8 module_(module),
1.9 locals_(NULL),
1.10 scope_(NULL),
1.11 @@ -134,11 +135,11 @@
1.12 Variable *var = name->binding()->toVariable();
1.13
1.14 if (var->location() == Variable::STACK) {
1.15 - __ getlocal(var->slot());
1.16 + __ getlocal(var);
1.17 assert(!name->type()->isReference());
1.18 } else {
1.19 assert(var->location() == Variable::PARAMETER);
1.20 - __ getarg(var->slot());
1.21 + __ getarg(var);
1.22
1.23 // If this argument is actually a reference, dereference it now.
1.24 if (var->type()->isReference())
1.25 @@ -582,7 +583,7 @@
1.26 __ int_(0);
1.27 }
1.28 }
1.29 - __ setlocal(var->slot());
1.30 + __ setlocal(var);
1.31 __ pop();
1.32
1.33 locals_->set(zone_, var->slot(), var->type());
1.34 @@ -705,7 +706,38 @@
1.35 for (size_t i = 0; i < __ objects()->size(); i++)
1.36 objects->set(zone_, i, *(__ objects()->at(i)));
1.37
1.38 - Local<Code> code(zone_, Code::New(zone_, bytes, locals_, objects, __ maxStackDepth(), module_));
1.39 + Local<ByteArray> safepoints(zone_);
1.40 +
1.41 + // If any stack slots hold gc pointers at potential failure points in the
1.42 + // bytecode, record them now. We do this by building a list of tuples;
1.43 + // each tuple contains the pc offset, and a bitset containing which stack
1.44 + // slots must be scanned by the gc.
1.45 + if (__ oopRecords()->size()) {
1.46 + size_t bytesPerSafepoint = Code::BytesPerSafepoint(__ maxStackDepth());
1.47 + size_t gcmapSize = bytesPerSafepoint * __ oopRecords()->size();
1.48 + safepoints = ByteArray::New(zone_, gcmapSize, Heap::Tenure_Old);
1.49 + if (!safepoints)
1.50 + return NULL;
1.51 +
1.52 + Address cursor = safepoints->raw();
1.53 + for (size_t i = 0; i < __ oopRecords()->size(); i++) {
1.54 + OopRecord *record = __ oopRecords()->at(i);
1.55 + assert(record->depth <= __ maxStackDepth());
1.56 +
1.57 + *reinterpret_cast<unsigned *>(cursor) = record->offset;
1.58 +
1.59 + unsigned char *bits = reinterpret_cast<unsigned char *>(cursor + sizeof(unsigned));
1.60 + for (unsigned i = 0; i < record->depth; i++)
1.61 + bits[i / 8] |= (1 << (i % 8));
1.62 +
1.63 + cursor += bytesPerSafepoint;
1.64 + }
1.65 +
1.66 + assert(cursor == safepoints->raw() + gcmapSize);
1.67 + }
1.68 +
1.69 + Local<Code> code(zone_, Code::New(zone_, bytes, locals_, objects, __ maxStackDepth(), module_,
1.70 + safepoints));
1.71 if (!code)
1.72 return NULL;
1.73