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