Skip to content

Commit

Permalink
Added support for loading images saved with the CogVM
Browse files Browse the repository at this point in the history
- the CogVM stores floats in platform order which is not supported by the standard squeak interpreter and similarly not by the RoarVM
- this patch restores normalized order for images with the version 6505, might be problematic on big-endien machines, where the normalized encoding is identical to the platform encoding

This change is inspired by David T. Lewis's change for the standard interpreter:
http://forum.world.st/VM-Maker-VMMaker-dtl-189-mcz-td2964230.html
http://forum.world.st/attachment/2964255/0/ReadCogImageStandardVM-dtl.1.cs.gz

Signed-off-by: Stefan Marr <git@stefan-marr.de>
  • Loading branch information
smarr committed Jul 16, 2011
1 parent 467efa3 commit c565232
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 3 deletions.
36 changes: 33 additions & 3 deletions vm/src/image_readers/squeak_image_reader.cpp
Expand Up @@ -102,10 +102,36 @@ readImageFromFile: f HeapSize: desiredHeapSize StartingAt: imageOffset

// "Second, return the bytes of bytes-type objects to their orginal order."
if (swap_bytes) byteSwapByteObjects();

Safepoint_Ability sa(false); // for distributing objects and putting image name
distribute_objects();
imageNamePut_on_all_cores(file_name, strlen(file_name));

// we need to reoder floats if the image was a Cog image
if (is_cog_image_with_reodered_floats()) {
normalize_float_ordering_in_image();
}
}


/** Inspired by:
!Interpreter methodsFor: 'image save/restore' stamp: 'dtl 10/5/2010 23:54'!
normalizeFloatOrderingInImage
"Float objects were saved in platform word ordering. Reorder them into the
traditional object format."
*/
void Squeak_Image_Reader::normalize_float_ordering_in_image() {
Squeak_Interpreter* const interp = The_Squeak_Interpreter();
Memory_System* const mem_sys = The_Memory_System();

Oop cls = interp->splObj(Special_Indices::ClassFloat);
for (Oop floatInstance = mem_sys->initialInstanceOf(cls);
floatInstance != interp->roots.nilObj;
floatInstance = mem_sys->nextInstanceAfter(floatInstance) ) {
/* Swap words within Float objects, taking them out of native platform ordering */
floatInstance.as_object()->swapFloatParts_for_cog_compatibility();
}
}


Expand Down Expand Up @@ -167,10 +193,14 @@ bool Squeak_Image_Reader::readable_format(int32 version) {
/* Check against a magic constant that changes when the image format
changes. Since the image reading code uses this to detect byte ordering,
one must avoid version numbers that are invariant under byte reversal. */
return version == Pre_Closure_32_Bit_Image_Version || version == Post_Closure_32_Bit_Image_Version;
return version == Pre_Closure_32_Bit_Image_Version
|| version == Post_Closure_32_Bit_Image_Version
|| version == Post_Closure_With_Reordered_Floats_32_Bit_Image_Version;
}


bool Squeak_Image_Reader::is_cog_image_with_reodered_floats() {
return interpreter->image_version == Post_Closure_With_Reordered_Floats_32_Bit_Image_Version;
}


void Squeak_Image_Reader::byteSwapByteObjects() {
Expand Down
3 changes: 3 additions & 0 deletions vm/src/image_readers/squeak_image_reader.h
Expand Up @@ -37,10 +37,12 @@ class Squeak_Image_Reader {
void check_image_version();
int32 get_long();
static bool readable_format(int32);
bool is_cog_image_with_reodered_floats();
static int32 image_format_version();
void read_header();

void byteSwapByteObjects();
void normalize_float_ordering_in_image();
void distribute_objects();


Expand All @@ -61,5 +63,6 @@ class Squeak_Image_Reader {

static const int Pre_Closure_32_Bit_Image_Version = 6502;
static const int Post_Closure_32_Bit_Image_Version = 6504;
static const int Post_Closure_With_Reordered_Floats_32_Bit_Image_Version = 6505;
};

9 changes: 9 additions & 0 deletions vm/src/objects/object.h
Expand Up @@ -525,6 +525,15 @@ class Object
bool isEmptyList();
inline static Oop floatObject(double);
inline void storeFloat(double);

/** Floats are stored in platform order in Cog images.
This function here is used during image load to make sure that
the floats are stored in normalized, i.e., swaped order, since
the standard interpreter and the RoarVM do not use platform order.
REM: should NOT be called in normal operation. */
inline void swapFloatParts_for_cog_compatibility();

void storeStackPointerValue(oop_int_t v) {
storePointerUnchecked(Object_Indices::StackPointerIndex, Oop::from_int(v));
}
Expand Down
14 changes: 14 additions & 0 deletions vm/src/objects/object.inline.h
Expand Up @@ -540,6 +540,20 @@ inline void Object::storeFloat(double d) {
&as_int32_p()[0 + BaseHeaderSize/sizeof(int32)], ((int32*)&d)[1],((int32*)&d)[0], (Object_p)this);
}

/** Floats are stored in platform order in Cog images.
This function here is used during image load to make sure that
the floats are stored in normalized, i.e., swaped order, since
the standard interpreter and the RoarVM do not use platform order.
REM: should NOT be called in normal operation. */
inline void Object::swapFloatParts_for_cog_compatibility() {
int32* data = &as_int32_p()[0 + BaseHeaderSize/sizeof(int32)];

The_Memory_System()->store_2_enforcing_coherence(
data, data[1], data[0], (Object_p)this);
}


inline bool Object::equals_string(const char* s) {
return strlen(s) == lengthOf() && strncmp(s, first_byte_address(), lengthOf()) == 0;
}
Expand Down

0 comments on commit c565232

Please sign in to comment.