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; }
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; }