00001
00002
00003
00004 #include "slate.hpp"
00005
00006
00007
00008 void object_zero_pin_count(struct Object* xxx) {
00009 xxx->header &= ~(PINNED_MASK << PINNED_OFFSET);
00010 }
00011
00012
00013 void object_set_mark(struct object_heap* oh, struct Object* xxx) {
00014 xxx->header &= ~MARK_MASK;
00015 xxx->header|=oh->mark_color & MARK_MASK;
00016 }
00017 void object_unmark(struct object_heap* oh, struct Object* xxx) {
00018 xxx->header &= ~MARK_MASK;
00019 xxx->header|= ((~oh->mark_color)&MARK_MASK);
00020 }
00021
00022 void object_set_format(struct Object* xxx, word_t type) {
00023 xxx->header &= ~(3<<30);
00024 xxx->header |= (type&3) << 30;
00025 }
00026 void object_set_size(struct Object* xxx, word_t size) {
00027 assert((size_t)size >= HEADER_SIZE_WORDS+1);
00028 xxx->objectSize = size;
00029 }
00030 void object_set_idhash(struct Object* xxx, word_t hash) {
00031 xxx->header &= ~(ID_HASH_MAX<<1);
00032 xxx->header |= (hash&ID_HASH_MAX) << 1;
00033 }
00034 void payload_set_size(struct Object* xxx, word_t size) {
00035 xxx->payloadSize = size;
00036 }
00037
00038
00039
00040 word_t heap_new_hash(struct object_heap* oh) {
00041 word_t hash;
00042 do {
00043 hash = (oh->lastHash = 13849 + (27181 * oh->lastHash)) & ID_HASH_MAX;
00044 } while (hash >= ID_HASH_RESERVED);
00045
00046 return hash;
00047 }
00048
00049
00050
00051
00052
00053
00054
00055
00056 word_t smallint_fits_object(word_t i) { return (i ^ (i << 1)) >= 0;}
00057
00058
00059
00060
00061
00062 word_t object_is_immutable(struct Object* o) {return ((word_t)o->map->flags & MAP_FLAG_IMMUTABLE) != 0; }
00063
00064 bool_t object_is_special(struct object_heap* oh, struct Object* obj) {
00065 word_t i;
00066 for (i = 0; i < SPECIAL_OOP_COUNT; i++) {
00067 if (obj == oh->special_objects_oop->elements[i]) return 1;
00068 }
00069 return 0;
00070 }
00071
00072
00073
00074 word_t object_array_offset(struct Object* o) {
00075 return object_size((struct Object*)o) * sizeof(word_t);
00076 }
00077
00078 byte_t* byte_array_elements(struct ByteArray* o) {
00079 byte_t* elements = (byte_t*)inc_ptr((struct Object*)o, object_array_offset((struct Object*)o));
00080 return elements;
00081 }
00082
00083 byte_t byte_array_get_element(struct Object* o, word_t i) {
00084 return byte_array_elements((struct ByteArray*)o)[i];
00085 }
00086
00087 byte_t byte_array_set_element(struct ByteArray* o, word_t i, byte_t val) {
00088 return byte_array_elements(o)[i] = val;
00089 }
00090
00091
00092 struct Object* object_array_get_element(struct Object* o, word_t i) {
00093 struct Object** elements = (struct Object**)inc_ptr(o, object_array_offset(o));
00094 return elements[i];
00095 }
00096
00097 struct Object* object_array_set_element(struct object_heap* oh, struct Object* o, word_t i, struct Object* val) {
00098 struct Object** elements = (struct Object**)inc_ptr(o, object_array_offset(o));
00099 heap_store_into(oh, o, val);
00100 return elements[i] = val;
00101 }
00102
00103 struct Object** object_array_elements(struct Object* o) {
00104 return (struct Object**)inc_ptr(o, object_array_offset(o));
00105 }
00106
00107 struct Object** array_elements(struct OopArray* o) {
00108 return object_array_elements((struct Object*) o);
00109 }
00110
00111 float_type* float_part(struct ByteArray* o) {
00112 return (float_type*)object_array_elements((struct Object*) o);
00113 }
00114
00115
00116 word_t slot_table_capacity(struct SlotTable* roles) {
00117 return object_array_size((struct Object*)roles) / ((sizeof(struct SlotEntry) + (sizeof(word_t) - 1)) / sizeof(word_t));
00118 }
00119
00120 word_t role_table_capacity(struct RoleTable* roles) {
00121 return object_array_size((struct Object*)roles) / ((sizeof(struct RoleEntry) + (sizeof(word_t) - 1)) / sizeof(word_t));
00122 }
00123
00124
00125 word_t object_first_slot_offset(struct Object* o) {
00126
00127 return sizeof(struct Object);
00128
00129 }
00130
00131 word_t object_last_slot_offset(struct Object* o) {
00132 return object_size(o) * sizeof(word_t) - sizeof(word_t);
00133 }
00134
00135
00136 word_t object_last_oop_offset(struct Object* o) {
00137
00138 if (object_type(o) == TYPE_OOP_ARRAY) {
00139 return object_last_slot_offset(o) + payload_size(o);
00140 }
00141 return object_last_slot_offset(o);
00142 }
00143
00144
00145 struct Object* object_slot_value_at_offset_put(struct object_heap* oh, struct Object* o, word_t offset, struct Object* value) {
00146
00147 heap_store_into(oh, o, value);
00148 return (struct Object*)((*((word_t*)inc_ptr(o, offset))) = (word_t)value);
00149
00150 }
00151
00152
00153 struct RoleEntry* role_table_entry_for_name(struct object_heap* oh, struct RoleTable* roles, struct Symbol* name) {
00154
00155 word_t tableSize, hash, index;
00156 struct RoleEntry* role;
00157
00158 tableSize = role_table_capacity(roles);
00159 if (tableSize == 0) return NULL;
00160 hash = object_hash((struct Object*)name) & (tableSize-1);
00161
00162
00163 for (index = hash; index < tableSize; index++) {
00164
00165 role = &roles->roles[index];
00166 if (role->name == name) return role;
00167 if (role->name == (struct Symbol*)oh->cached.nil) return NULL;
00168 }
00169 for (index = 0; index < hash; index++) {
00170 role = &roles->roles[index];
00171 if (role->name == name) return role;
00172 if (role->name == (struct Symbol*)oh->cached.nil) return NULL;
00173 }
00174
00175 return NULL;
00176 }
00177
00178
00179 struct RoleEntry* role_table_entry_for_inserting_name(struct object_heap* oh, struct RoleTable* roles, struct Symbol* name) {
00180
00181 word_t tableSize, hash, index;
00182 struct RoleEntry* role;
00183
00184 tableSize = role_table_capacity(roles);
00185 if (tableSize == 0) return NULL;
00186 hash = object_hash((struct Object*)name) & (tableSize-1);
00187
00188
00189 for (index = hash; index < tableSize; index++) {
00190
00191 role = &roles->roles[index];
00192 if (role->name == (struct Symbol*)oh->cached.nil) return role;
00193 }
00194 for (index = 0; index < hash; index++) {
00195 role = &roles->roles[index];
00196 if (role->name == (struct Symbol*)oh->cached.nil) return role;
00197 }
00198
00199 return NULL;
00200 }
00201
00202
00203 struct RoleEntry* role_table_insert(struct object_heap* oh, struct RoleTable* roles, struct Symbol* name) {
00204 struct RoleEntry* chain = role_table_entry_for_name(oh, roles, name);
00205 struct RoleEntry* role = role_table_entry_for_inserting_name(oh, roles, name);
00206 heap_store_into(oh, (struct Object*)roles, (struct Object*)name);
00207 if (chain != NULL) {
00208 while (chain->nextRole != oh->cached.nil) {
00209 chain = & roles->roles[object_to_smallint(chain->nextRole)];
00210 }
00211 chain->nextRole = smallint_to_object(role - roles->roles);
00212 }
00213
00214 return role;
00215 }
00216
00217
00218 struct SlotEntry* slot_table_entry_for_name(struct object_heap* oh, struct SlotTable* slots, struct Symbol* name) {
00219
00220 word_t tableSize, hash, index;
00221 struct SlotEntry* slot;
00222
00223 tableSize = slot_table_capacity(slots);
00224 if (tableSize == 0) return NULL;
00225 hash = object_hash((struct Object*)name) & (tableSize-1);
00226
00227
00228 for (index = hash; index < tableSize; index++) {
00229
00230 slot = &slots->slots[index];
00231 if (slot->name == name) return slot;
00232 if (slot->name == (struct Symbol*)oh->cached.nil) return NULL;
00233 }
00234 for (index = 0; index < hash; index++) {
00235 slot = &slots->slots[index];
00236 if (slot->name == name) return slot;
00237 if (slot->name == (struct Symbol*)oh->cached.nil) return NULL;
00238 }
00239
00240 return NULL;
00241 }
00242
00243
00244 struct SlotEntry* slot_table_entry_for_inserting_name(struct object_heap* oh, struct SlotTable* slots, struct Symbol* name) {
00245
00246 word_t tableSize, hash, index;
00247 struct SlotEntry* slot;
00248
00249 tableSize = slot_table_capacity(slots);
00250 if (tableSize == 0) return NULL;
00251 hash = object_hash((struct Object*)name) & (tableSize-1);
00252
00253
00254 for (index = hash; index < tableSize; index++) {
00255 slot = &slots->slots[index];
00256 if (slot->name == (struct Symbol*)oh->cached.nil) return slot;
00257 }
00258 for (index = 0; index < hash; index++) {
00259 slot = &slots->slots[index];
00260 if (slot->name == (struct Symbol*)oh->cached.nil) return slot;
00261 }
00262
00263 return NULL;
00264 }
00265
00266
00267
00268 word_t role_table_accommodate(struct RoleTable* roles, word_t n) {
00269
00270 word_t tableSize, requested;
00271
00272 tableSize = role_table_capacity(roles);
00273 assert(tableSize + n >= 0);
00274 requested = tableSize + n;
00275 while (tableSize > requested)
00276 tableSize >>= 1;
00277 if (tableSize ==0 && requested > 1)
00278 tableSize = 1;
00279 while (tableSize < requested)
00280 tableSize <<= 1;
00281
00282 return tableSize;
00283 }
00284
00285 word_t slot_table_accommodate(struct SlotTable* roles, word_t n) {
00286
00287 word_t tableSize, requested;
00288
00289 tableSize = slot_table_capacity(roles);
00290 assert(tableSize + n >= 0);
00291 requested = tableSize + n;
00292 while (tableSize > requested)
00293 tableSize >>= 1;
00294 if (tableSize ==0 && requested > 1)
00295 tableSize = 1;
00296 while (tableSize < requested)
00297 tableSize <<= 1;
00298
00299 return tableSize;
00300 }
00301
00302
00303 word_t role_table_empty_space(struct object_heap* oh, struct RoleTable* roles) {
00304
00305 word_t space = 0, i;
00306
00307 for (i = 0; i < role_table_capacity(roles); i++) {
00308 if (roles->roles[i].name == (struct Symbol*)oh->cached.nil) space++;
00309 }
00310
00311 return space;
00312 }
00313
00314 word_t slot_table_empty_space(struct object_heap* oh, struct SlotTable* slots) {
00315
00316 word_t space = 0, i;
00317
00318 for (i = 0; i < slot_table_capacity(slots); i++) {
00319 if (slots->slots[i].name == (struct Symbol*)oh->cached.nil) space++;
00320 }
00321
00322 return space;
00323 }
00324
00325
00326 struct RoleTable* role_table_grow_excluding(struct object_heap* oh, struct RoleTable* roles, word_t n, struct MethodDefinition* method) {
00327 word_t oldSize, newSize, i;
00328 Pinned<struct RoleTable> newRoles(oh);
00329 Pinned<struct Symbol> roleName(oh);
00330 oldSize = role_table_capacity(roles);
00331 newSize = role_table_accommodate(roles, (oldSize / 3 - role_table_empty_space(oh, roles)) + n);
00332 newRoles = (struct RoleTable*) heap_clone_oop_array_sized(oh, get_special(oh, SPECIAL_OOP_ARRAY_PROTO), newSize * ROLE_ENTRY_WORD_SIZE);
00333
00334 for (i = 0; i < oldSize; i++) {
00335 roleName = (struct Symbol*)roles->roles[i].name;
00336 if (roleName != (struct Symbol*)oh->cached.nil && roles->roles[i].methodDefinition != method) {
00337 struct RoleEntry * role = role_table_insert(oh, newRoles, roleName);
00338 *role = roles->roles[i];
00339 role->nextRole = oh->cached.nil;
00340 }
00341
00342 }
00343
00344 return newRoles;
00345
00346 }
00347
00348
00349 struct SlotTable* slot_table_grow_excluding(struct object_heap* oh, struct SlotTable* slots, word_t n, struct Symbol* excluding) {
00350 word_t oldSize, newSize, i;
00351 Pinned<struct SlotTable> newSlots(oh);
00352
00353 oldSize = slot_table_capacity(slots);
00354 newSize = slot_table_accommodate(slots, (oldSize / 3 - slot_table_empty_space(oh, slots)) + n);
00355 newSlots = (struct SlotTable*) heap_clone_oop_array_sized(oh, get_special(oh, SPECIAL_OOP_ARRAY_PROTO), newSize * SLOT_ENTRY_WORD_SIZE);
00356
00357 for (i = 0; i < oldSize; i++) {
00358 struct Symbol* slotName = (struct Symbol*)slots->slots[i].name;
00359 if (slotName != (struct Symbol*)oh->cached.nil && slotName != excluding) {
00360 struct SlotEntry * slot = slot_table_entry_for_inserting_name(oh, newSlots, slotName);
00361 *slot = slots->slots[i];
00362 }
00363
00364 }
00365
00366 return newSlots;
00367
00368 }
00369
00370 void slot_table_relocate_by(struct object_heap* oh, struct SlotTable* slots, word_t offset, word_t amount) {
00371
00372 word_t i;
00373
00374 for (i = 0; i < slot_table_capacity(slots); i++) {
00375 if (slots->slots[i].name != (struct Symbol*)oh->cached.nil
00376 && object_to_smallint(slots->slots[i].offset) >= offset) {
00377 slots->slots[i].offset = smallint_to_object(object_to_smallint(slots->slots[i].offset) + amount);
00378 }
00379 }
00380 }
00381
00382
00383
00384
00385 struct MethodDefinition* object_has_role_named_at(struct Object* obj, struct Symbol* selector, word_t position, struct Object* method) {
00386
00387 word_t i;
00388
00389 for (i = 0; i < role_table_capacity(obj->map->roleTable); i++) {
00390 struct RoleEntry* role = &obj->map->roleTable->roles[i];
00391 if (role->name == selector
00392 && (object_to_smallint(role->rolePositions) & position) == position
00393 && role->methodDefinition->method == method) {
00394 return role->methodDefinition;
00395 }
00396
00397 }
00398
00399 return NULL;
00400
00401 }
00402
00403 void object_change_map(struct object_heap* oh, struct Object* obj, struct Map* map) {
00404 if (obj->map->representative == obj) obj->map->representative = oh->cached.nil;
00405 heap_store_into(oh, obj, (struct Object*)map);
00406 obj->map = map;
00407 }
00408
00409 void object_represent(struct object_heap* oh, struct Object* obj, struct Map* map) {
00410 object_change_map(oh, obj, map);
00411 heap_store_into(oh, (struct Object*)map, obj);
00412 map->representative = obj;
00413 }
00414
00415 word_t object_add_role_at(struct object_heap* oh, struct Object* obj, struct Symbol* selector, word_t position, struct MethodDefinition* method) {
00416
00417 Pinned<struct Map> map(oh);
00418 Pinned<struct Map> objMap(oh);
00419 Pinned<struct RoleTable> objMapRoleTable(oh);
00420 Pinned<struct RoleTable> mapRoleTable(oh);
00421 struct RoleEntry *entry, *chain;
00422
00423 objMap = obj->map;
00424 objMapRoleTable = obj->map->roleTable;
00425 map = heap_clone_map(oh, objMap);
00426 mapRoleTable = map->roleTable;
00427 chain = role_table_entry_for_name(oh, objMapRoleTable, selector);
00428 object_represent(oh, obj, map);
00429
00430 while (chain != NULL) {
00431
00432 if (chain->methodDefinition == method) {
00433
00434
00435 map->roleTable = role_table_grow_excluding(oh, mapRoleTable, 0, NULL);
00436 mapRoleTable = map->roleTable;
00437 heap_store_into(oh, (struct Object*)map, (struct Object*)map->roleTable);
00438
00439
00440 entry = role_table_entry_for_name(oh, map->roleTable, selector);
00441 while (entry != NULL) {
00442 if (entry->methodDefinition == method) {
00443 entry->rolePositions = smallint_to_object(object_to_smallint(entry->rolePositions) | position);
00444 return FALSE;
00445 }
00446 if (entry->nextRole == oh->cached.nil) {
00447 entry = NULL;
00448 } else {
00449 entry = &map->roleTable->roles[object_to_smallint(entry->nextRole)];
00450 }
00451 }
00452
00453 }
00454
00455 if (chain->nextRole == oh->cached.nil) {
00456 chain = NULL;
00457 } else {
00458 chain = &map->roleTable->roles[object_to_smallint(chain->nextRole)];
00459 }
00460 }
00461
00462
00463 mapRoleTable = map->roleTable;
00464 map->roleTable = role_table_grow_excluding(oh, mapRoleTable, 1, NULL);
00465 mapRoleTable = map->roleTable;
00466 heap_store_into(oh, (struct Object*)map, (struct Object*)map->roleTable);
00467
00468 entry = role_table_insert(oh, mapRoleTable, selector);
00469 entry->name = selector;
00470 entry->nextRole = oh->cached.nil;
00471 entry->rolePositions = smallint_to_object(position);
00472 entry->methodDefinition = method;
00473 return TRUE;
00474
00475 }
00476
00477 word_t object_remove_role(struct object_heap* oh, struct Object* obj, struct Symbol* selector, struct MethodDefinition* method) {
00478
00479 Pinned<struct Map> map(oh);
00480 Pinned<struct RoleTable> roles(oh);
00481 roles = obj->map->roleTable;
00482 word_t i, matches = 0;
00483
00484 for (i = 0; i< role_table_capacity(roles); i++) {
00485
00486 if (roles->roles[i].methodDefinition == method) {
00487 matches++;
00488 }
00489
00490 }
00491
00492 if (matches == 0) return FALSE;
00493 map = heap_clone_map(oh, obj->map);
00494 map->roleTable = role_table_grow_excluding(oh, roles, matches, method);
00495 heap_store_into(oh, (struct Object*)map, (struct Object*)map->roleTable);
00496 object_represent(oh, obj, map);
00497 return TRUE;
00498
00499 }
00500
00501
00502
00503
00504
00505 struct Object* object_add_slot_named_at(struct object_heap* oh, struct Object* obj, struct Symbol* name, struct Object* value, word_t offset) {
00506
00507 Pinned<struct Map> map(oh);
00508 Pinned<struct Object> newObj(oh);
00509 Pinned<struct SlotTable> slotTable(oh);
00510 struct SlotEntry* entry;
00511
00512 entry = slot_table_entry_for_name(oh, obj->map->slotTable, name);
00513 if ((struct Object*)entry != NULL) return NULL;
00514 map = heap_clone_map(oh, obj->map);
00515 slotTable = map->slotTable;
00516 map->slotTable = slot_table_grow_excluding(oh, slotTable, 1, (struct Symbol*)oh->cached.nil);
00517 slotTable = map->slotTable;
00518 slot_table_relocate_by(oh, slotTable, offset, sizeof(word_t));
00519 entry = slot_table_entry_for_inserting_name(oh, slotTable, name);
00520 entry->name = name;
00521 entry->offset = smallint_to_object(offset);
00522
00523 if (object_type(obj) == TYPE_OBJECT) {
00524 newObj = heap_allocate(oh, object_size(obj) + 1);
00525 } else {
00526 newObj = heap_allocate_with_payload(oh, object_size(obj) + 1, payload_size(obj));
00527 }
00528 object_set_format(newObj, object_type(obj));
00529
00530
00531
00532 object_set_idhash(newObj, heap_new_hash(oh));
00533 copy_bytes_into((byte_t*)obj+ object_first_slot_offset(obj),
00534 offset-object_first_slot_offset(obj),
00535 (byte_t*)newObj + object_first_slot_offset(newObj));
00536 object_slot_value_at_offset_put(oh, newObj, offset, value);
00537
00538 copy_bytes_into((byte_t*)obj+offset, object_total_size(obj) - offset, (byte_t*)newObj + offset + sizeof(word_t));
00539 newObj->map = map;
00540 map->representative = newObj;
00541 heap_store_into(oh, (struct Object*)map, (struct Object*)map->representative);
00542
00543 return newObj;
00544 }
00545
00546
00547 struct Object* object_add_slot_named(struct object_heap* oh, struct Object* obj, struct Symbol* name, struct Object* value) {
00548
00549
00550 struct Object* newObj =
00551 object_add_slot_named_at(oh, obj, name, value,
00552 object_first_slot_offset(obj) + object_to_smallint(obj->map->slotCount) * sizeof(word_t));
00553
00554 if (newObj == NULL) return obj;
00555
00556 newObj->map->slotCount = smallint_to_object(object_to_smallint(newObj->map->slotCount) + 1);
00557
00558 return newObj;
00559 }
00560
00561 struct Object* object_remove_slot(struct object_heap* oh, struct Object* obj, struct Symbol* name) {
00562 word_t offset;
00563 Pinned<struct Object> newObj(oh);
00564 Pinned<struct Map> map(oh);
00565 Pinned<struct SlotTable> slotTable(oh);
00566 struct SlotEntry* se;
00567 se = slot_table_entry_for_name(oh, obj->map->slotTable, name);
00568 if ((struct Object*)se == NULL) return obj;
00569
00570 offset = object_to_smallint(se->offset);
00571 map = heap_clone_map(oh, obj->map);
00572 map->slotCount = smallint_to_object(object_to_smallint(map->slotCount) - 1);
00573 slotTable = map->slotTable;
00574 map->slotTable = slot_table_grow_excluding(oh, slotTable, -1, se->name);
00575 slotTable = map->slotTable;
00576 slot_table_relocate_by(oh, slotTable, offset, -sizeof(word_t));
00577
00578 if (object_type(obj) == TYPE_OBJECT) {
00579 newObj = heap_allocate(oh, object_size(obj)-1);
00580 object_set_format(newObj, TYPE_OBJECT);
00581 } else {
00582 newObj = heap_allocate_with_payload(oh, object_size(obj) -1 , payload_size(obj));
00583 object_set_format(newObj, object_type(obj));
00584 }
00585
00586
00587 object_set_idhash(newObj, heap_new_hash(oh));
00588 copy_bytes_into((byte_t*) obj + object_first_slot_offset(obj),
00589 offset - object_first_slot_offset(obj),
00590 (byte_t*) newObj + object_first_slot_offset(newObj));
00591
00592 copy_bytes_into((byte_t*) obj + object_first_slot_offset(obj) + sizeof(word_t),
00593 object_total_size(obj) - offset - sizeof(word_t),
00594 (byte_t*) newObj + offset);
00595 newObj->map = map;
00596 map->representative = newObj;
00597 heap_store_into(oh, (struct Object*)map, map->representative);
00598 return newObj;
00599 }
00600
00601
00602
00603 struct ForwardPointerEntry* forward_pointer_hash_get(struct ForwardPointerEntry* table,
00604 word_t forwardPointerEntryCount,
00605 struct Object* fromObj) {
00606 word_t index;
00607 word_t hash = (uword_t)fromObj % forwardPointerEntryCount;
00608 struct ForwardPointerEntry* entry;
00609
00610 for (index = hash; index < forwardPointerEntryCount; index++) {
00611 entry = &table[index];
00612 if (entry->fromObj == fromObj || entry->fromObj == NULL) return entry;
00613 }
00614 for (index = 0; index < hash; index++) {
00615 entry = &table[index];
00616 if (entry->fromObj == fromObj || entry->fromObj == NULL) return entry;
00617 }
00618
00619 return NULL;
00620
00621
00622 }
00623
00624 struct ForwardPointerEntry* forward_pointer_hash_add(struct ForwardPointerEntry* table,
00625 word_t forwardPointerEntryCount,
00626 struct Object* fromObj, struct Object* toObj) {
00627
00628 struct ForwardPointerEntry* entry = forward_pointer_hash_get(table, forwardPointerEntryCount, fromObj);
00629 if (NULL == entry) return NULL;
00630 assert(entry->fromObj == NULL || entry->fromObj == fromObj);
00631 entry->fromObj = fromObj;
00632 entry->toObj = toObj;
00633 return entry;
00634
00635 }
00636
00637
00638 void copy_used_objects(struct object_heap* oh, struct Object** writeObject, byte_t* memoryStart, word_t memorySize,
00639 struct ForwardPointerEntry* table, word_t forwardPointerEntryCount) {
00640 struct Object* readObject = (struct Object*) memoryStart;
00641 while (object_in_memory(oh, readObject, memoryStart, memorySize)) {
00642 if (!object_is_free(readObject)) {
00643 assert(NULL != forward_pointer_hash_add(table, forwardPointerEntryCount, readObject, *writeObject));
00644 copy_words_into((word_t*)readObject, object_word_size(readObject), (word_t*)*writeObject);
00645 *writeObject = object_after(oh, *writeObject);
00646 }
00647 readObject = object_after(oh, readObject);
00648 }
00649
00650 }
00651
00652 void adjust_object_fields_with_table(struct object_heap* oh, byte_t* memory, word_t memorySize,
00653 struct ForwardPointerEntry* table, word_t forwardPointerEntryCount) {
00654
00655 struct Object* o = (struct Object*) memory;
00656
00657 while (object_in_memory(oh, o, memory, memorySize)) {
00658 word_t offset, limit;
00659 o->map = (struct Map*)forward_pointer_hash_get(table, forwardPointerEntryCount, (struct Object*)o->map)->toObj;
00660 offset = object_first_slot_offset(o);
00661 limit = object_last_oop_offset(o) + sizeof(word_t);
00662 for (; offset != limit; offset += sizeof(word_t)) {
00663 struct Object* val = object_slot_value_at_offset(o, offset);
00664 if (!object_is_smallint(val)) {
00665 object_slot_value_at_offset_put(oh, o, offset,
00666 forward_pointer_hash_get(table, forwardPointerEntryCount, val)->toObj);
00667 }
00668 }
00669 o = object_after(oh, o);
00670 }
00671
00672 }
00673
00674
00675 void adjust_fields_by(struct object_heap* oh, struct Object* o, word_t shift_amount) {
00676
00677 word_t offset, limit;
00678 o->map = (struct Map*) inc_ptr((struct Object*)o->map, shift_amount);
00679 offset = object_first_slot_offset(o);
00680 limit = object_last_oop_offset(o) + sizeof(word_t);
00681 for (; offset != limit; offset += sizeof(word_t)) {
00682 struct Object* val = object_slot_value_at_offset(o, offset);
00683 if (!object_is_smallint(val)) {
00684
00685 (*((word_t*)inc_ptr(o, offset))) = (word_t)inc_ptr(val, shift_amount);
00686
00687 }
00688 }
00689
00690 }
00691
00692
00693 void adjust_oop_pointers_from(struct object_heap* oh, word_t shift_amount, byte_t* memory, word_t memorySize) {
00694
00695 struct Object* o = (struct Object*)memory;
00696 #ifdef PRINT_DEBUG
00697 printf("First object: "); print_object(o);
00698 #endif
00699 while (object_in_memory(oh, o, memory, memorySize)) {
00700
00701 if (!object_is_free(o)) {
00702 adjust_fields_by(oh, o, shift_amount);
00703 }
00704 o = object_after(oh, o);
00705 }
00706
00707
00708 }