Bug#642750: [PATCH] epiphany-browser: *HIGHLY* unstable on ia64 (IA-64/IPF/Itanium) platform

Stephan Schreiber info at fs-driver.org
Sun Dec 2 19:28:00 UTC 2012


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



-------------- next part --------------
A non-text attachment was scrubbed...
Name: ia64-wide-ptr.patch
Type: application/octet-stream
Size: 24380 bytes
Desc: ia64-wide-ptr.patch
URL: <http://lists.alioth.debian.org/pipermail/pkg-webkit-maintainers/attachments/20121202/3868a04f/attachment-0001.obj>


More information about the Pkg-webkit-maintainers mailing list