jitcraft/BytecodeCompiler.cpp
changeset 47 050939c6181e
parent 46 735503e448a0
child 54 8e22792a3921
     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