예제 #1
0
파일: slotsMap.cpp 프로젝트: AdamSpitz/self
oop slotsMap::change_slot(oop obj,
                          slotDesc* slot,
                          slotType type, 
                          oop contents,
                          oop anno,
                          bool mustAllocate) {
  assert(slot != NULL, "cannot change the contents of a non-existent slot");
  assert(!obj->is_string(), "cannot clone strings!");
  assert_slots(obj, "object isn't a slotsOop");

  slotsOop new_obj= slotsOop(obj->clone(mustAllocate));
  if (oop(new_obj) == failedAllocationOop) return failedAllocationOop;
  switch (slot->type->slot_type()) {
   case obj_slot_type:
    assert(NakedMethods || !contents->has_code() || slot->type->is_vm_slot(),
           "adding an assignable slot with code");
    assert_smi(slot->data, "data slot contents isn't an offset");
    new_obj->at_put(smiOop(slot->data)->value(), contents);
    break;
   case map_slot_type:
    break;
   case arg_slot_type:
    assert_smi(contents, "argument index isn't a smiOop");
    break;
   default:
    ShouldNotReachHere(); // unexpected slot type
  }

  if (    slot->data == contents
      &&  slot->type == type
      &&  slot->get_annotation() == anno) {
    // no change (to the map, at least)!
    return new_obj;
  }
  
  // create a new map for this object
  slotsMap* new_map= copy_for_changing(mustAllocate);
  if (new_map == NULL) return failedAllocationOop;
  slot = slot->shift(this, new_map);
  slot->type = type;
  slot->set_annotation(anno);
  if (!slot->is_obj_slot()) {
    Memory->store(&slot->data, contents);
  }

  new_obj->set_canonical_map(new_map);
  
  return new_obj;
}
예제 #2
0
파일: slotsMap.cpp 프로젝트: AdamSpitz/self
slotsOop slotsMap::copy_add_new_slot(slotsOop  obj, 
                                     stringOop name,
                                     slotType  slot_type,
                                     oop       contents,
                                     oop       anno,
                                     bool      mustAllocate) {
  assert_slots(obj, "object isn't a slotsOop");
  assert(!obj->is_string(), "cannot clone strings!");

  bool found;
  fint newIndex= find_slot_index_for(name, found);
  assert(!found, "I only add new slots");
  slotsMap* new_map= (slotsMap*) insert(newIndex, mustAllocate);
  if (new_map == NULL) return slotsOop(failedAllocationOop);

  slotDesc* s= new_map->slot(newIndex);
  new_map->slots_length= new_map->slots_length->increment();
  mapOop new_moop= new_map->enclosing_mapOop();
  new_moop->init_mark();
  new_map->init_dependents();

  slotsOop new_obj;
  switch (slot_type->slot_type()) {
   case obj_slot_type: {
    assert(NakedMethods || !contents->has_code() || slot_type->is_vm_slot(),
           "adding an assignable slot with code");
    // find which offset this slot should be at
    fint offset= empty_object_size();
    for (fint i= newIndex - 1; i >= 0; --i)
      if (slot(i)->is_obj_slot()) {
        offset= smiOop(slot(i)->data)->value() + 1;
        break;
      }
    new_obj= obj->is_byteVector()
              ? (slotsOop) byteVectorOop(obj) ->
                  insert(object_size(obj), offset, 1, mustAllocate, true)
              : (slotsOop) slotsOop(obj) ->
                  insert(object_size(obj), offset, 1, mustAllocate, true);
    if (oop(new_obj) == failedAllocationOop)
      return slotsOop(failedAllocationOop);
    new_map->shift_obj_slots(as_smiOop(offset), 1);
    new_map->object_length = new_map->object_length->increment();
    new_obj->at_put(offset, contents, false);
    new_obj->fix_generation(new_map->object_size(new_obj));
    contents= as_smiOop(offset);   // tagged index of slot data
    break; }
   case map_slot_type:
    new_obj= slotsOop(obj->clone(mustAllocate));
    break;
   case arg_slot_type:
    assert_smi(contents, "argument index isn't a smiOop");
    new_obj= slotsOop(obj->clone(mustAllocate));
    break;
   default:
    ShouldNotReachHere(); // unexpected slot type
  }
  if (oop(new_obj) == failedAllocationOop)
    return slotsOop(failedAllocationOop);
  s->init(name, slot_type, contents, anno, false);
  new_moop->fix_generation(new_moop->size());
  new_obj->set_canonical_map(new_map);
  
  return new_obj;
}