Example #1
0
oop slotsMap::copy_add_method_slot( slotsOop obj,
                                    stringOop name, 
                                    slotType type, 
                                    oop contents,
                                    oop anno,
                                    bool mustAllocate) {

  if (type->is_vm_slot()) {
    // skip all the checks and do not try to remove it, since
    // vm slots do not change from obj to map, and rm will fetch anyway
    slotDesc* sd = obj->find_slot(name);
    return sd != NULL
     ? change_slot      (obj, sd,   type, contents, anno, mustAllocate)
     : copy_add_new_slot(obj, name, type, contents, anno, mustAllocate);
  }
  if ( contents->arg_count() != name->arg_count() )
    return ErrorCodes::vmString_prim_error(ARGUMENTCOUNTERROR);

  if (obj->is_method_like())
    return ErrorCodes::vmString_prim_error(BADTYPEERROR); // cannot add methods to methods

  slotDesc *old= find_slot(name);
  if (old && old->is_map_slot())
    // change in situ
    return change_slot(obj, old, type, contents, anno, mustAllocate);

  slotsOop result;
  if (old) {
    // remove the old slot, then add in a new one
    result= (slotsOop)copy_remove_one_slot(obj, old, mustAllocate);
    if (oop(result) == failedAllocationOop) return failedAllocationOop;

    if (old->is_assignment_slot_name(name)) {
      // replace the data slot as a map slot
      result= ((slotsMap*)result->map())->
        copy_add_new_slot(result, old->name, MAP_SLOT(old->type),
                          obj->get_slot(old), old->annotation, mustAllocate);
      if (oop(result) == failedAllocationOop) return failedAllocationOop;
    }
  } else
    result= obj;

  return ((slotsMap*)result->map())->
    copy_add_new_slot(result, name, MAP_SLOT(type), contents, anno,
                      mustAllocate);
}