diff --git a/vm/src/image_readers/squeak_image_reader.cpp b/vm/src/image_readers/squeak_image_reader.cpp index 41a54e70..d4011f34 100644 --- a/vm/src/image_readers/squeak_image_reader.cpp +++ b/vm/src/image_readers/squeak_image_reader.cpp @@ -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(); + } } @@ -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() { diff --git a/vm/src/image_readers/squeak_image_reader.h b/vm/src/image_readers/squeak_image_reader.h index c346bc4d..03c7a62f 100644 --- a/vm/src/image_readers/squeak_image_reader.h +++ b/vm/src/image_readers/squeak_image_reader.h @@ -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(); @@ -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; }; diff --git a/vm/src/objects/object.h b/vm/src/objects/object.h index 40fc0221..76b0558f 100644 --- a/vm/src/objects/object.h +++ b/vm/src/objects/object.h @@ -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)); } diff --git a/vm/src/objects/object.inline.h b/vm/src/objects/object.inline.h index dafa6974..bf9e2ced 100644 --- a/vm/src/objects/object.inline.h +++ b/vm/src/objects/object.inline.h @@ -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; }