severity 642750 grave tags 642750 + patch block 582774 by 642750 thanks
While working on this bug I realized that webkit has yet another bug that prevents it from working on ia64. I filed the separate bug#694971 for that.
I built the libwebkitgtk-3.0-0 package which was configured with --enable-debug. (Wasn't possible with the initial 4GB of memory at all. After a memory upgrade to 16GB it took eleven-and-a-half hour on my box with the -j2 option.)
Just starting epiphany-browser showed a first hint what is going on: ASSERTION FAILED: isCell()../Source/JavaScriptCore/runtime/JSValueInlineMethods.h(491) : JSC::JSCell* JSC::JSValue::asCell() const
Webkit uses a variant data type JSValue, which it uses for anything that can be a thing on Java script. It can contain an integer number, a float number or a pointer to an object - this is 'cell'.
It turned out that the 'isCell()' assertion failed for a JSValue that just has been initialized as a pointer.
The arch determines how the JSValue is defined; there are two options (yet), one for any 32-bits arch, the other one for 64-bits archs.
You can see this in Source/JavaScriptCore/runtime/JSValue.h - JSValue defines an embedded data type 'EncodedValueDescriptor' for that:
#if USE(JSVALUE32_64) typedef int64_t EncodedJSValue; #else typedef void* EncodedJSValue; #endif union EncodedValueDescriptor { int64_t asInt64; #if USE(JSVALUE32_64) double asDouble; #elif USE(JSVALUE64) JSCell* ptr; #endif #if CPU(BIG_ENDIAN) struct { int32_t tag; int32_t payload; } asBits; #else struct { int32_t payload; int32_t tag; } asBits; #endif }; .... #if USE(JSVALUE32_64) /** On 32-bit platforms USE(JSVALUE32_64) should be defined, and we use a NaN-encoded
* form for immediates. ** The encoding makes use of unused NaN space in the IEEE754 representation. Any value * with the top 13 bits set represents a QNaN (with the sign bit set). QNaN values * can encode a 51-bit payload. Hardware produced and C-library payloads typically * have a payload of zero. We assume that non-zero payloads are available to encode * pointer and integer values. Since any 64-bit bit pattern where the top 15 bits are * all set represents a NaN with a non-zero payload, we can use this space in the NaN * ranges to encode other values (however there are also other ranges of NaN space that
* could have been selected). ** For JSValues that do not contain a double value, the high 32 bits contain the tag * values listed in the enums below, which all correspond to NaN-space. In the case of * cell, integer and bool values the lower 32 bits (the 'payload') contain the pointer * integer or boolean value; in the case of all other tags the payload is 0.
*/ enum { Int32Tag = 0xffffffff }; enum { BooleanTag = 0xfffffffe }; enum { NullTag = 0xfffffffd }; enum { UndefinedTag = 0xfffffffc }; enum { CellTag = 0xfffffffb }; enum { EmptyValueTag = 0xfffffffa }; enum { DeletedValueTag = 0xfffffff9 }; enum { LowestTag = DeletedValueTag }; uint32_t tag() const; int32_t payload() const; #elif USE(JSVALUE64) /** On 64-bit platforms USE(JSVALUE64) should be defined, and we use a NaN-encoded
* form for immediates. ** The encoding makes use of unused NaN space in the IEEE754 representation. Any value * with the top 13 bits set represents a QNaN (with the sign bit set). QNaN values * can encode a 51-bit payload. Hardware produced and C-library payloads typically * have a payload of zero. We assume that non-zero payloads are available to encode * pointer and integer values. Since any 64-bit bit pattern where the top 15 bits are * all set represents a NaN with a non-zero payload, we can use this space in the NaN * ranges to encode other values (however there are also other ranges of NaN space that
* could have been selected). ** This range of NaN space is represented by 64-bit numbers begining with the 16-bit * hex patterns 0xFFFE and 0xFFFF - we rely on the fact that no valid double-precision
* numbers will begin fall in these ranges. * * The top 16-bits denote the type of the encoded JSValue: * * Pointer { 0000:PPPP:PPPP:PPPP * / 0001:****:****:**** * Double { ... * \ FFFE:****:****:**** * Integer { FFFF:0000:IIII:IIII ** The scheme we have implemented encodes double precision values by performing a * 64-bit integer addition of the value 2^48 to the number. After this manipulation * no encoded double-precision value will begin with the pattern 0x0000 or 0xFFFF. * Values must be decoded by reversing this operation before subsequent floating point
* operations my be peformed. * * 32-bit signed integers are marked with the 16-bit tag 0xFFFF. ** The tag 0x0000 denotes a pointer, or another form of tagged immediate. Boolean, * null and undefined values are represented by specific, invalid pointer values:
* * False: 0x06 * True: 0x07 * Undefined: 0x0a * Null: 0x02 * * These values have the following properties:* - Bit 1 (TagBitTypeOther) is set for all four values, allowing real pointers to be * quickly distinguished from all immediate values, including these invalid pointers. * - With bit 3 is masked out (TagBitUndefined) Undefined and Null share the
* same value, allowing null & undefined to be quickly detected. ** No valid JSValue will have the bit pattern 0x0, this is used to represent array * holes, and as a C++ 'no value' result (e.g. JSValue() has an internal value of 0).
*/// These values are #defines since using static const integers here is a ~1% regression!
// This value is 2^48, used to encode doubles such that the encoded value will begin
// with a 16-bit pattern within the range 0x0001..0xFFFE. #define DoubleEncodeOffset 0x1000000000000ll // If all bits in the mask are set, this indicates an integer number, // if any but not all are set this value is a double precision number. #define TagTypeNumber 0xffff000000000000ll // All non-numeric (bool, null, undefined) immediates have bit 2 set. #define TagBitTypeOther 0x2ll #define TagBitBool 0x4ll #define TagBitUndefined 0x8ll // Combined integer value for non-numeric immediates. #define ValueFalse (TagBitTypeOther | TagBitBool | false) #define ValueTrue (TagBitTypeOther | TagBitBool | true) #define ValueUndefined (TagBitTypeOther | TagBitUndefined) #define ValueNull (TagBitTypeOther)// TagMask is used to check for all types of immediate values (either number or 'other').
#define TagMask (TagTypeNumber | TagBitTypeOther)// These special values are never visible to JavaScript code; Empty is used to represent // Array holes, and for uninitialized JSValues. Deleted is used in hash table code. // These values would map to cell types in the JSValue encoding, but not valid GC cell // pointer should have either of these values (Empty is null, deleted is at an invalid
// alignment for a GC cell, and in the zero page). #define ValueEmpty 0x0ll #define ValueDeleted 0x4ll #endif USE(JSVALUE64) is true on ia64; USE(JSVALUE32_64) is false.The code on a true USE(JSVALUE64) uses some sophisticated tricks in order to get everything in a 64-bits wide data type. If you read the comment of the webkit source, you realize that this works as long the high 16-bits of the addresses of any allocated memory are cleared. But when you look at the crash dumps above, you see a lot of addresses which have some upper bits set. This is the reason why decoding of the variant data type fails - the mentioned failed assertion.
(If you think you have a Déjà vu, it is because the Mozilla Java script engine uses a similar trick on 64-bit archs, and has a similar problem on ia64, for example, see the archived bug#659186.)
The proposed patch defines a third option USE(JSVALUE64W) which we use *only* on ia64.It uses an encapsulated union without any trick for the variant data type. This is portable but
- the data type is 128-bits wide,- Enabling JIT compiler isn't possible - that's not that bad; ia64 doesn't have a JIT compiler.
The patch is for the most recent libwebkitgtk-3.0-0 package of Wheezy. The patch doesn't change anything on archs other than ia64.The packages which were built with the patch of this bug report and the one of bug#694971 is here; the tar contains all debs which are created by the libwebkitgtk-3.0-0 source:
http://www.fs-driver.org/debian-ia64/webkitgtk-debs.tar The patches also fix bug#582774 (seed FTBFS on ia64). Stephan
ia64-wide-ptr.patch
Description: ia64-wide-ptr.patch