oop slotsMap::copy_add_argument_slot(slotsOop obj, stringOop name, slotType type, oop contents, oop anno, bool mustAllocate) { assert_smi(contents, "arg data must be position"); if (!name->is_unary()) return ErrorCodes::vmString_prim_error(ARGUMENTCOUNTERROR); slotDesc* old = find_slot(name); slotsOop result; if (old == NULL) result= obj; else if (old->is_arg_slot()) { // No need to remove and reinsert because order is the same. // Only the annotation might be really different. // The index will be off by one (assumes that added slot is new) assert(smiOop(contents)->value() == smiOop(old->data)->value() + 1, "arg index wrong"); return change_slot(obj, old, type, old->data, anno, mustAllocate); } else { result= (slotsOop)copy_remove_slot(obj, name, mustAllocate); if (oop(result) == failedAllocationOop || result->is_mark()) return result; assert(result->is_slots(), "just checking"); } assert(smiOop(contents)->value() == arg_count(), "arg index wrong"); return ((slotsMap*)result->map())->copy_add_new_slot(result, name, type, contents, anno, mustAllocate); }
oop slotsMap::copy_add_data_slot(slotsOop obj, stringOop name, slotType type, oop contents, oop anno, bool mustAllocate) { if (!name->is_unary()) { return ErrorCodes::vmString_prim_error(SLOTNAMEERROR); } slotDesc* old = find_slot(name); if (!old) return copy_add_new_slot(obj, name, type, contents, anno, mustAllocate); if (old->is_obj_slot()) // change in place; if type is map_slot, just changes value return (slotsOop)change_slot(obj, old, OBJ_SLOT(type), contents, anno, mustAllocate); // remove then add obj slot slotsOop result= copy_remove_one_slot(obj, old, mustAllocate); if (oop(result) == failedAllocationOop) return result; slotsMap *new_map= (slotsMap*)result->map(); return new_map->copy_add_new_slot(result, name, type, contents, anno, mustAllocate); }