64-bit builds and passes trace tests on OS X with --disable-tracejit. reftests has failures, but these also show up on tm and should be fixed by a rebase

This commit is contained in:
Luke Wagner 2010-06-23 16:58:32 -07:00
parent 50d922350a
commit ed28dae403
7 changed files with 468 additions and 284 deletions

View File

@ -196,7 +196,7 @@ JSVAL_IS_BOOLEAN(jsval v)
{
jsval_layout l;
l.asBits = v;
return l.s.tag == JSVAL_TAG_BOOLEAN;
return JSVAL_IS_BOOLEAN_IMPL(l);
}
static JS_ALWAYS_INLINE JSBool
@ -205,7 +205,7 @@ JSVAL_TO_BOOLEAN(jsval v)
jsval_layout l;
JS_ASSERT(JSVAL_IS_BOOLEAN(v));
l.asBits = v;
return l.s.payload.boo;
return JSVAL_TO_BOOLEAN_IMPL(l);
}
static JS_ALWAYS_INLINE jsval
@ -3198,9 +3198,11 @@ class Value
* break this encapsulation should be listed as friends below. Also see
* uses of public jsval members in jsapi.h/jspubtd.h.
*/
#ifdef JS_TRACER
friend jsdouble UnboxDoubleHelper(uint32 mask, uint32 payload);
friend void NonDoubleNativeToValue(JSValueType type, double *slot, Value *vp);
friend void NonNumberValueToSlot(const Value &v, JSValueType type, double *slot);
#endif
protected:
/* Type masks */
@ -3212,7 +3214,6 @@ class Value
JS_STATIC_ASSERT(sizeof(JSValueTag) == 4);
JS_STATIC_ASSERT(sizeof(JSBool) == 4);
JS_STATIC_ASSERT(sizeof(JSWhyMagic) <= 4);
JS_STATIC_ASSERT(sizeof(((jsval_layout *)0)->s.payload) == 4);
JS_STATIC_ASSERT(sizeof(jsval) == 8);
}
@ -3328,7 +3329,7 @@ class Value
JSValueType type = arg ? JS_OBJ_IS_FUN_IMPL(arg) ? JSVAL_TYPE_FUNOBJ
: JSVAL_TYPE_NONFUNOBJ
: JSVAL_TYPE_NULL;
data = OBJECT_TO_JSVAL_IMPL(type, arg);
data = OBJECT_TO_JSVAL_IMPL(type, arg);
}
inline void setObjectOrUndefined(JSObject *arg) {
@ -3447,7 +3448,7 @@ class Value
int32 asInt32() const {
JS_ASSERT(isInt32());
return data.s.payload.i32;
return JSVAL_TO_INT32_IMPL(data);
}
double asDouble() const {
@ -3492,7 +3493,7 @@ class Value
bool asBoolean() const {
JS_ASSERT(isBoolean());
return data.s.payload.boo;
return JSVAL_TO_BOOLEAN_IMPL(data);
}
uint32 asRawUint32() const {
@ -3508,9 +3509,11 @@ class Value
return JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(data);
}
#if JS_BITS_PER_WORD == 32
JSValueTag extractNonDoubleTag() const {
return JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(data);
}
#endif
/* Swap two Values */
@ -3538,12 +3541,12 @@ class Value
}
void setPrivate(void *ptr) {
data = PRIVATE_PTR_TO_JSVAL_IMPL(ptr);
data = PRIVATE_PTR_TO_JSVAL_IMPL(ptr);
}
void *asPrivate() const {
JS_ASSERT(JSVAL_IS_UNDERLYING_TYPE_OF_PRIVATE_IMPL(data));
return JSVAL_TO_PRIVATE_PTR_IMPL(data);
JS_ASSERT(JSVAL_IS_UNDERLYING_TYPE_OF_PRIVATE_IMPL(data));
return JSVAL_TO_PRIVATE_PTR_IMPL(data);
}
void setPrivateUint32(uint32 ui) {
@ -3551,13 +3554,13 @@ class Value
}
uint32 asPrivateUint32() const {
JS_ASSERT(JSVAL_IS_UNDERLYING_TYPE_OF_PRIVATE_IMPL(data));
return JSVAL_TO_PRIVATE_UINT32_IMPL(data);
JS_ASSERT(JSVAL_IS_UNDERLYING_TYPE_OF_PRIVATE_IMPL(data));
return JSVAL_TO_PRIVATE_UINT32_IMPL(data);
}
uint32 &asPrivateUint32Ref() {
JS_ASSERT(isDouble());
return data.s.payload.u32;
JS_ASSERT(isDouble());
return data.s.payload.u32;
}
/* Tracing support API.

View File

@ -315,7 +315,9 @@ JSObject::resizeDenseArrayElements(JSContext *cx, uint32 oldcap, uint32 newcap,
return JS_TRUE;
}
if (newcap > MAX_DSLOTS_LENGTH) {
/* Silence warning */
size_t newcapBig = newcap;
if (newcapBig > MAX_DSLOTS_LENGTH) {
js_ReportAllocationOverflow(cx);
return JS_FALSE;
}
@ -1446,7 +1448,7 @@ InitArrayElements(JSContext *cx, JSObject *obj, jsuint start, jsuint count, Valu
if (newlen > obj->getArrayLength())
obj->setDenseArrayLength(newlen);
JS_ASSERT(count < size_t(-1) / sizeof(Value));
JS_ASSERT(count < uint32(-1) / sizeof(Value));
if (targetType == TargetElementsMayContainValues) {
jsuint valueCount = 0;
for (jsuint i = 0; i < count; i++) {

View File

@ -35,10 +35,6 @@
#include "jstypes.h"
#include "jsstdint.h"
#include "jsgcchunk.h"
#ifdef JS_64BIT
# include "jsstr.h"
#endif
#ifdef XP_WIN
# include <windows.h>
@ -144,47 +140,6 @@ UnmapPages(void *p, size_t size)
# else /* WINCE */
# ifdef _M_X64
typedef long (*ntavm_fun)(HANDLE handle, void **addr, ULONG zbits,
size_t *size, ULONG alloctype, ULONG prot);
typedef long (*ntfvm_fun)(HANDLE handle, void **addr, size_t *size,
ULONG freetype);
static ntavm_fun NtAllocateVirtualMemory;
static ntfvm_fun NtFreeVirtualMemory;
bool
js::InitNtAllocAPIs()
{
HMODULE h = GetModuleHandle("ntdll.dll");
if (!h)
return false;
NtAllocateVirtualMemory = ntavm_fun(GetProcAddress(h, "NtAllocateVirtualMemory"));
if (!NtAllocateVirtualMemory)
return false;
NtFreeVirtualMemory = ntfvm_fun(GetProcAddress(h, "NtFreeVirtualMemory"));
if (!NtFreeVirtualMemory)
return false;
}
// Allocate pages with 32-bit addresses (i.e., top 16 bits are all 0).
static void *
MapPages(void *addr, size_t size)
{
long rc = NtAllocateVirtualMemory(INVALID_HANDLE_VALUE, &addr, 1, &size,
MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
return rc ? NULL : addr;
}
static void
UnmapPages(void *addr, size_t size)
{
NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &addr, &size, MEM_RELEASE);
}
# else /* _M_X64 */
static void *
MapPages(void *addr, size_t size)
{
@ -199,8 +154,6 @@ UnmapPages(void *addr, size_t size)
JS_ALWAYS_TRUE(VirtualFree(addr, 0, MEM_RELEASE));
}
# endif /* _M_X64 */
# endif /* !WINCE */
#elif defined(XP_MACOSX) || defined(DARWIN)
@ -249,7 +202,6 @@ MapAlignedPages(size_t size, size_t alignment)
* We don't use MAP_FIXED here, because it can cause the *replacement*
* of existing mappings, and we only want to create new mappings.
*/
// TODO: this is totally a hack for now; need to replace
void *p = mmap((caddr_t) alignment, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_NOSYNC | MAP_ALIGN | MAP_ANON, -1, 0);
if (p == MAP_FAILED)
@ -259,53 +211,6 @@ MapAlignedPages(size_t size, size_t alignment)
# else /* JS_GC_HAS_MAP_ALIGN */
# if defined(__MACH__) && defined(__APPLE__) && defined(__x86_64__)
// Make sure the result is in the 32-bit address region.
static void *
MapPages(void *addr, size_t size)
{
void * const start = (void *) 0x10000;
void * const end = (void *) 0x100000000;
// If an addr is given, try once there.
if (addr) {
JS_ASSERT(addr < end);
void *p = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (p == MAP_FAILED)
return NULL;
if (p != addr) {
JS_ALWAYS_TRUE(munmap(p, size) == 0);
return NULL;
}
return p;
}
// FIXME: this depends on implementation details of OSX mmap, namely
// that it searches for free memory starting from the hint,
// so that it will find free memory addresses in 32-bit space
// if it exists.
static void *base = start;
while (true) {
void *p = mmap(base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (p == MAP_FAILED)
return NULL;
// Got a region in range, so return it.
if (start <= p && p < end) {
base = (void *) (uintptr_t(p) + size);
return p;
}
// Out of range. If we started past 'start', then we can try
// again from there.
munmap(p, size);
if (base != start)
return NULL;
base = start;
}
}
# else /* DARWIN && __x86_64__ */
static void *
MapPages(void *addr, size_t size)
{
@ -313,7 +218,6 @@ MapPages(void *addr, size_t size)
* We don't use MAP_FIXED here, because it can cause the *replacement*
* of existing mappings, and we only want to create new mappings.
*/
// TODO: this is totally a hack for now; need to replace
void *p = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON,
-1, 0);
if (p == MAP_FAILED)
@ -326,8 +230,6 @@ MapPages(void *addr, size_t size)
return p;
}
# endif /* DARWIN && __x86_64__ */
# endif /* !JS_GC_HAS_MAP_ALIGN */
static void
@ -338,29 +240,6 @@ UnmapPages(void *addr, size_t size)
#endif
#ifdef JS_64BIT
bool
JSString::initStringTables()
{
char *p = (char *) MapPages(NULL, unitStringTableSize + intStringTableSize);
if (!p)
return false;
unitStringTable = (JSString*) memcpy(p, staticUnitStringTable, unitStringTableSize);
intStringTable = (JSString*) memcpy(p + unitStringTableSize,
staticIntStringTable, intStringTableSize);
return true;
}
void
JSString::freeStringTables()
{
UnmapPages(unitStringTable, unitStringTableSize + intStringTableSize);
unitStringTable = NULL;
intStringTable = NULL;
}
#endif
namespace js {
GCChunkAllocator defaultGCChunkAllocator;

View File

@ -1312,10 +1312,6 @@ js_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, const js::Value &
/*
* Precondition: obj must be locked.
*/
extern JSBool
js_ReallocSlots(JSContext *cx, JSObject *obj, uint32 nslots,
JSBool exactAllocation);
extern JSObject *
js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller);

View File

@ -174,11 +174,9 @@ typedef struct JSCompartment JSCompartment;
# error "Need to add compiler support"
#endif
#define JSVAL_NAN_PATTERN ((uint16)0xFFFF)
/*
* When we can ensure that the underlying type is uint32, use an enum so that
* symbolic type names show up in the debugger.
* symbolic type names show up in the debugger. Otherwise, use #defines.
*/
#ifdef __cplusplus
@ -194,75 +192,137 @@ typedef struct JSCompartment JSCompartment;
# define JS_ENUM_FOOTER(id) __attribute__((packed))
#endif
/* Remember to propagate changes to #else case below. */
/* Remember to propagate changes to the C defines below. */
JS_ENUM_HEADER(JSValueType, uint8)
{
JSVAL_TYPE_DOUBLE = 0x0,
JSVAL_TYPE_INT32 = 0x1,
JSVAL_TYPE_UNDEFINED = 0x2,
JSVAL_TYPE_STRING = 0x3,
JSVAL_TYPE_BOOLEAN = 0x4,
JSVAL_TYPE_MAGIC = 0x5,
JSVAL_TYPE_NULL = 0x6,
JSVAL_TYPE_NONFUNOBJ = 0x7,
JSVAL_TYPE_FUNOBJ = 0xF,
JSVAL_TYPE_DOUBLE = 0x0,
JSVAL_TYPE_INT32 = 0x1,
JSVAL_TYPE_UNDEFINED = 0x2,
JSVAL_TYPE_STRING = 0x3,
JSVAL_TYPE_BOOLEAN = 0x4,
JSVAL_TYPE_MAGIC = 0x5,
JSVAL_TYPE_NULL = 0x6,
JSVAL_TYPE_NONFUNOBJ = 0x7,
JSVAL_TYPE_FUNOBJ = 0xF,
/* Cannot not appear in any jsval ever; trace-jit only. */
JSVAL_TYPE_BOXED = 0x99,
JSVAL_TYPE_UNINITIALIZED = 0xcd
JSVAL_TYPE_BOXED = 0x99,
JSVAL_TYPE_UNINITIALIZED = 0xcd
} JS_ENUM_FOOTER(JSValueType);
/* Remember to propagate changes to #else case below. */
#if JS_BITS_PER_WORD == 32
/* Remember to propagate changes to the C defines below. */
JS_ENUM_HEADER(JSValueTag, uint32)
{
JSVAL_TAG_CLEAR = (uint32)(0xFFFF0000),
JSVAL_TAG_INT32 = (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32),
JSVAL_TAG_UNDEFINED = (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED),
JSVAL_TAG_STRING = (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING),
JSVAL_TAG_BOOLEAN = (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN),
JSVAL_TAG_MAGIC = (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC),
JSVAL_TAG_NULL = (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL),
JSVAL_TAG_NONFUNOBJ = (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NONFUNOBJ),
JSVAL_TAG_FUNOBJ = (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_FUNOBJ)
JSVAL_TAG_CLEAR = 0xFFFF0000,
JSVAL_TAG_INT32 = JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32,
JSVAL_TAG_UNDEFINED = JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED,
JSVAL_TAG_STRING = JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING,
JSVAL_TAG_BOOLEAN = JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN,
JSVAL_TAG_MAGIC = JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC,
JSVAL_TAG_NULL = JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL,
JSVAL_TAG_NONFUNOBJ = JSVAL_TAG_CLEAR | JSVAL_TYPE_NONFUNOBJ,
JSVAL_TAG_FUNOBJ = JSVAL_TAG_CLEAR | JSVAL_TYPE_FUNOBJ
} JS_ENUM_FOOTER(JSValueType);
#elif JS_BITS_PER_WORD == 64
/* Remember to propagate changes to the C defines below. */
JS_ENUM_HEADER(JSValueTag, uint32)
{
JSVAL_TAG_MAX_DOUBLE = 0x1FFF0,
JSVAL_TAG_INT32 = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32,
JSVAL_TAG_UNDEFINED = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED,
JSVAL_TAG_STRING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING,
JSVAL_TAG_BOOLEAN = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN,
JSVAL_TAG_MAGIC = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC,
JSVAL_TAG_NULL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL,
JSVAL_TAG_NONFUNOBJ = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NONFUNOBJ,
JSVAL_TAG_FUNOBJ = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_FUNOBJ
} JS_ENUM_FOOTER(JSValueType);
#else
# error "Unsupported"
#endif
#else /* defined(__cplusplus) */
typedef uint8 JSValueType;
#define JSVAL_TYPE_DOUBLE ((uint8)0x0)
#define JSVAL_TYPE_INT32 ((uint8)0x1)
#define JSVAL_TYPE_UNDEFINED ((uint8)0x2)
#define JSVAL_TYPE_STRING ((uint8)0x3)
#define JSVAL_TYPE_BOOLEAN ((uint8)0x4)
#define JSVAL_TYPE_MAGIC ((uint8)0x5)
#define JSVAL_TYPE_NULL ((uint8)0x6)
#define JSVAL_TYPE_NONFUNOBJ ((uint8)0x7)
#define JSVAL_TYPE_FUNOBJ ((uint8)0xF)
#define JSVAL_TYPE_BOXED ((uint8)0x99)
#define JSVAL_TYPE_UNINITIALIZED ((uint8)0xcd)
#define JSVAL_TYPE_DOUBLE ((uint8)0x0)
#define JSVAL_TYPE_INT32 ((uint8)0x1)
#define JSVAL_TYPE_UNDEFINED ((uint8)0x2)
#define JSVAL_TYPE_STRING ((uint8)0x3)
#define JSVAL_TYPE_BOOLEAN ((uint8)0x4)
#define JSVAL_TYPE_MAGIC ((uint8)0x5)
#define JSVAL_TYPE_NULL ((uint8)0x6)
#define JSVAL_TYPE_NONFUNOBJ ((uint8)0x7)
#define JSVAL_TYPE_FUNOBJ ((uint8)0xF)
#define JSVAL_TYPE_BOXED ((uint8)0x99)
#define JSVAL_TYPE_UNINITIALIZED ((uint8)0xcd)
#ifdef JS_BITS_PER_WORD == 32
typedef uint32 JSValueTag;
#define JSVAL_TAG_CLEAR ((uint32)(0xFFFF0000))
#define JSVAL_TAG_INT32 ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32))
#define JSVAL_TAG_UNDEFINED ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED))
#define JSVAL_TAG_STRING ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING))
#define JSVAL_TAG_BOOLEAN ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN))
#define JSVAL_TAG_MAGIC ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC))
#define JSVAL_TAG_NULL ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL))
#define JSVAL_TAG_NONFUNOBJ ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NONFUNOBJ))
#define JSVAL_TAG_FUNOBJ ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_FUNOBJ))
#define JSVAL_TAG_CLEAR ((uint32)(0xFFFF0000))
#define JSVAL_TAG_INT32 ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32))
#define JSVAL_TAG_UNDEFINED ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED))
#define JSVAL_TAG_STRING ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING))
#define JSVAL_TAG_BOOLEAN ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN))
#define JSVAL_TAG_MAGIC ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC))
#define JSVAL_TAG_NULL ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL))
#define JSVAL_TAG_NONFUNOBJ ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NONFUNOBJ))
#define JSVAL_TAG_FUNOBJ ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_FUNOBJ))
#elif JS_BITS_PER_WORD == 64
typedef uint32 JSValueTag;
#define JSVAL_TAG_MAX_DOUBLE ((uint32)(0x1FFF0))
#define JSVAL_TAG_INT32 (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32)
#define JSVAL_TAG_UNDEFINED (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED)
#define JSVAL_TAG_STRING (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING)
#define JSVAL_TAG_BOOLEAN (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN)
#define JSVAL_TAG_MAGIC (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC)
#define JSVAL_TAG_NULL (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL)
#define JSVAL_TAG_NONFUNOBJ (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NONFUNOBJ)
#define JSVAL_TAG_FUNOBJ (uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_FUNOBJ)
#else
# error "Unsupported"
#endif /* JS_BITS_PER_WORD */
#endif /* defined(__cplusplus) */
/* Avoid ordering dependencies on the set { null, funobj, nonfunobj } */
#define JSVAL_LOWER_TYPE_OF_OBJ_OR_NULL_SET JSVAL_TYPE_NULL
#define JSVAL_LOWER_TYPE_OF_OBJ_SET JSVAL_TYPE_NONFUNOBJ
#define JSVAL_UPPER_TYPE_OF_OBJ_SET JSVAL_TYPE_FUNOBJ
#define JSVAL_LOWER_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL
#define JSVAL_LOWER_TAG_OF_OBJ_SET JSVAL_TAG_NONFUNOBJ
#define JSVAL_UPPER_TAG_OF_OBJ_SET JSVAL_TAG_FUNOBJ
#define JSVAL_LOWER_INCL_TYPE_OF_OBJ_OR_NULL_SET JSVAL_TYPE_NULL
#define JSVAL_LOWER_INCL_TYPE_OF_OBJ_SET JSVAL_TYPE_NONFUNOBJ
#define JSVAL_UPPER_INCL_TYPE_OF_OBJ_SET JSVAL_TYPE_FUNOBJ
#if JS_BITS_PER_WORD == 32
#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL
#define JSVAL_LOWER_INCL_TAG_OF_OBJ_SET JSVAL_TAG_NONFUNOBJ
#define JSVAL_UPPER_INCL_TAG_OF_OBJ_SET JSVAL_TAG_FUNOBJ
#define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32
#elif JS_BITS_PER_WORD == 64
#define JSVAL_TAG_SHIFT 47
#define JSVAL_PAYLOAD_MASK 0x00007FFFFFFFFFFFLL
#define JSVAL_SHIFTED_TAG_MAX_DOUBLE (((uint64)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT)
#define JSVAL_SHIFTED_TAG_INT32 (((uint64)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT)
#define JSVAL_SHIFTED_TAG_UNDEFINED (((uint64)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT)
#define JSVAL_SHIFTED_TAG_STRING (((uint64)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT)
#define JSVAL_SHIFTED_TAG_BOOLEAN (((uint64)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT)
#define JSVAL_SHIFTED_TAG_MAGIC (((uint64)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT)
#define JSVAL_SHIFTED_TAG_NULL (((uint64)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT)
#define JSVAL_SHIFTED_TAG_NONFUNOBJ (((uint64)JSVAL_TAG_NONFUNOBJ) << JSVAL_TAG_SHIFT)
#define JSVAL_SHIFTED_TAG_FUNOBJ (((uint64)JSVAL_TAG_FUNOBJ) << JSVAL_TAG_SHIFT)
#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET JSVAL_SHIFTED_TAG_NULL
#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_SET JSVAL_SHIFTED_TAG_NONFUNOBJ
#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET JSVAL_SHIFTED_TAG_UNDEFINED
#endif /* JS_BITS_PER_WORD */
typedef enum JSWhyMagic
{
@ -277,6 +337,7 @@ typedef enum JSWhyMagic
} JSWhyMagic;
#if defined(IS_LITTLE_ENDIAN)
#if JS_BITS_PER_WORD == 32
typedef union jsval_layout
{
@ -285,15 +346,9 @@ typedef union jsval_layout
int32 i32;
uint32 u32;
JSBool boo;
#if JS_BITS_PER_WORD == 32
JSString *str;
JSObject *obj;
void *ptr;
#elif JS_BITS_PER_WORD == 64
uint32 ptr;
#else
# error "Unsupported configuration"
#endif
JSWhyMagic why;
} payload;
JSValueTag tag;
@ -302,16 +357,35 @@ typedef union jsval_layout
uint64 asBits;
} jsval_layout;
#else /* defined(IS_LITTLE_ENDIAN) */
# error "Unsupported configuration"
#endif
#elif JS_BITS_PER_WORD == 64
typedef union jsval_layout
{
struct {
uint64 payload : 47;
JSValueTag tag : 17;
} debugView;
struct {
union {
int32 i32;
uint32 u32;
JSWhyMagic why;
} payload;
} s;
double asDouble;
uint64 asBits;
} jsval_layout;
#endif /* JS_BITS_PER_WORD */
#endif /* IS_LITTLE_ENDIAN */
typedef VALUE_ALIGNMENT uint64 jsval;
#define BUILD_JSVAL(tag, payload) ((jsval)((((uint64)(uint32)(tag)) << 32) | (uint32)(payload)))
#if JS_BITS_PER_WORD == 32
#define BUILD_JSVAL(tag, payload) \
((jsval)((((uint64)(uint32)(tag)) << 32) | (uint32)(payload)))
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_DOUBLE_IMPL(jsval_layout l)
{
@ -339,7 +413,7 @@ JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32 i32)
return l.s.tag == JSVAL_TAG_INT32 && l.s.payload.i32 == i32;
}
static JS_ALWAYS_INLINE JSBool
static JS_ALWAYS_INLINE jsint
JSVAL_TO_INT32_IMPL(jsval_layout l)
{
return l.s.payload.i32;
@ -354,6 +428,14 @@ INT32_TO_JSVAL_IMPL(int32 i)
return l;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_NUMBER_IMPL(jsval_layout l)
{
JSValueTag tag = l.s.tag;
JS_ASSERT(tag != JSVAL_TAG_CLEAR);
return tag <= JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_UNDEFINED_IMPL(jsval_layout l)
{
@ -387,6 +469,12 @@ JSVAL_IS_BOOLEAN_IMPL(jsval_layout l)
return l.s.tag == JSVAL_TAG_BOOLEAN;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_TO_BOOLEAN_IMPL(jsval_layout l)
{
return l.s.payload.boo;
}
static JS_ALWAYS_INLINE jsval_layout
BOOLEAN_TO_JSVAL_IMPL(JSBool b)
{
@ -417,6 +505,37 @@ MAGIC_TO_JSVAL_IMPL(JSWhyMagic why)
return l;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_NONFUNOBJ_IMPL(jsval_layout l)
{
return l.s.tag == JSVAL_TAG_NONFUNOBJ;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_FUNOBJ_IMPL(jsval_layout l)
{
return l.s.tag == JSVAL_TAG_FUNOBJ;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l)
{
JSValueTag tag = l.s.tag;
return tag < JSVAL_LOWER_INCL_TAG_OF_OBJ_SET;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_OBJECT_IMPL(jsval_layout l)
{
return l.s.tag >= JSVAL_LOWER_INCL_TAG_OF_OBJ_SET;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l)
{
return l.s.tag >= JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET;
}
static JS_ALWAYS_INLINE JSObject *
JSVAL_TO_OBJECT_IMPL(jsval_layout l)
{
@ -470,12 +589,12 @@ JSVAL_SAME_PRIMITIVE_TYPE_OR_BOTH_OBJECTS_IMPL(jsval_layout lhs, jsval_layout rh
{
/*
* The second disjunct uses the fact that the funobj and nonfunobj tags
* differ only in bit 3 and any other pair of tags will differ in at least
* one other bit.
* differ in only 1 type bit and any other pair of tags will differ in at
* least one other bit.
*/
JSValueTag ltag = lhs.s.tag, rtag = rhs.s.tag;
JSValueTag clear = JSVAL_TAG_CLEAR;
return (ltag < clear && rtag < clear) || (((ltag ^ rtag) & 0xFFFFFFF7) == 0);
return (ltag < JSVAL_TAG_CLEAR && rtag < JSVAL_TAG_CLEAR) ||
(((ltag ^ rtag) & 0xFFFFFFF7) == 0);
}
static JS_ALWAYS_INLINE JSValueType
@ -483,7 +602,7 @@ JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l)
{
JS_ASSERT(!JSVAL_IS_DOUBLE_IMPL(l));
JSValueType t = (JSValueType)(l.s.tag & 0xF);
JS_ASSERT(t >= JSVAL_TYPE_INT32 && t <= JSVAL_UPPER_TYPE_OF_OBJ_SET);
JS_ASSERT(t >= JSVAL_TYPE_INT32 && t <= JSVAL_UPPER_INCL_TYPE_OF_OBJ_SET);
return t;
}
@ -492,71 +611,10 @@ JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(jsval_layout l)
{
JS_ASSERT(!JSVAL_IS_DOUBLE_IMPL(l));
JSValueTag t = l.s.tag;
JS_ASSERT(t >= JSVAL_TAG_INT32 && t <= JSVAL_UPPER_TAG_OF_OBJ_SET);
JS_ASSERT(t >= JSVAL_TAG_INT32 && t <= JSVAL_UPPER_INCL_TAG_OF_OBJ_SET);
return t;
}
#elif JS_BITS_PER_WORD == 64
# error "TODO"
#else
# error "Unsupported configuration"
#endif
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_NUMBER_IMPL(jsval_layout l)
{
JSValueTag tag = l.s.tag;
JS_ASSERT(tag != JSVAL_TAG_CLEAR);
return tag <= JSVAL_TAG_INT32;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_NONFUNOBJ_IMPL(jsval_layout l)
{
return l.s.tag == JSVAL_TAG_NONFUNOBJ;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_FUNOBJ_IMPL(jsval_layout l)
{
return l.s.tag == JSVAL_TAG_FUNOBJ;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_OBJECT_IMPL(jsval_layout l)
{
JSValueTag tag = l.s.tag;
return tag >= JSVAL_LOWER_TAG_OF_OBJ_SET;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l)
{
JSValueTag tag = l.s.tag;
return tag >= JSVAL_LOWER_TAG_OF_OBJ_OR_NULL_SET;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l)
{
JSValueTag tag = l.s.tag;
return tag < JSVAL_TAG_NONFUNOBJ;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_GCTHING_IMPL(jsval_layout l)
{
return JSVAL_IS_OBJECT_IMPL(l) || JSVAL_IS_STRING_IMPL(l);
}
static JS_ALWAYS_INLINE uint32
JSVAL_TRACE_KIND_IMPL(jsval_layout l)
{
return (uint32)(l.s.tag == JSVAL_TAG_STRING);
}
static JS_ALWAYS_INLINE jsval_layout
PRIVATE_UINT32_TO_JSVAL_IMPL(uint32 ui)
{
@ -573,6 +631,263 @@ JSVAL_TO_PRIVATE_UINT32_IMPL(jsval_layout l)
return l.s.payload.u32;
}
#elif JS_BITS_PER_WORD == 64
#define BUILD_JSVAL(tag, payload) \
((jsval)((((uint64)(uint32)(tag)) << JSVAL_TAG_SHIFT) | (payload)))
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_DOUBLE_IMPL(jsval_layout l)
{
return l.asBits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE;
}
static JS_ALWAYS_INLINE jsval_layout
DOUBLE_TO_JSVAL_IMPL(jsdouble d)
{
jsval_layout l;
l.asDouble = d;
JS_ASSERT(l.asBits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE);
return l;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_INT32_IMPL(jsval_layout l)
{
return (uint32)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_INT32;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32 i32)
{
return l.asBits == (((uint64)(uint32)i32) | JSVAL_SHIFTED_TAG_INT32);
}
static JS_ALWAYS_INLINE jsint
JSVAL_TO_INT32_IMPL(jsval_layout l)
{
return (int32)l.asBits;
}
static JS_ALWAYS_INLINE jsval_layout
INT32_TO_JSVAL_IMPL(int32 i32)
{
jsval_layout l;
l.asBits = ((uint64)(uint32)i32) | JSVAL_SHIFTED_TAG_INT32;
return l;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_NUMBER_IMPL(jsval_layout l)
{
return l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_UNDEFINED_IMPL(jsval_layout l)
{
return l.asBits == JSVAL_SHIFTED_TAG_UNDEFINED;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_STRING_IMPL(jsval_layout l)
{
return (uint32)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_STRING;
}
static JS_ALWAYS_INLINE jsval_layout
STRING_TO_JSVAL_IMPL(JSString *str)
{
jsval_layout l;
uint64 strBits = (uint64)str;
JS_ASSERT((strBits >> JSVAL_TAG_SHIFT) == 0);
l.asBits = strBits | JSVAL_SHIFTED_TAG_STRING;
return l;
}
static JS_ALWAYS_INLINE JSString *
JSVAL_TO_STRING_IMPL(jsval_layout l)
{
return (JSString *)(l.asBits & JSVAL_PAYLOAD_MASK);
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_BOOLEAN_IMPL(jsval_layout l)
{
return (uint32)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_BOOLEAN;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_TO_BOOLEAN_IMPL(jsval_layout l)
{
return (JSBool)l.asBits;
}
static JS_ALWAYS_INLINE jsval_layout
BOOLEAN_TO_JSVAL_IMPL(JSBool b)
{
jsval_layout l;
l.asBits = ((uint64)(uint32)b) | JSVAL_SHIFTED_TAG_BOOLEAN;
return l;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b)
{
return l.asBits == (((uint64)(uint32)b) | JSVAL_SHIFTED_TAG_BOOLEAN);
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_MAGIC_IMPL(jsval_layout l)
{
return (l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_MAGIC;
}
static JS_ALWAYS_INLINE jsval_layout
MAGIC_TO_JSVAL_IMPL(JSWhyMagic why)
{
jsval_layout l;
l.asBits = ((uint64)(uint32)why) | JSVAL_SHIFTED_TAG_MAGIC;
return l;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_NONFUNOBJ_IMPL(jsval_layout l)
{
return (l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_NONFUNOBJ;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_FUNOBJ_IMPL(jsval_layout l)
{
return (l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_FUNOBJ;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l)
{
return l.asBits < JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_SET;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_OBJECT_IMPL(jsval_layout l)
{
return l.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_SET;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l)
{
return l.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET;
}
static JS_ALWAYS_INLINE JSObject *
JSVAL_TO_OBJECT_IMPL(jsval_layout l)
{
uint64 ptrBits = l.asBits & JSVAL_PAYLOAD_MASK;
JS_ASSERT((ptrBits & 0x7) == 0);
return (JSObject *)ptrBits;
}
static JS_ALWAYS_INLINE jsval_layout
OBJECT_TO_JSVAL_IMPL(JSValueType type, JSObject *obj)
{
jsval_layout l;
uint64 objBits = (uint64)obj;
JS_ASSERT(type >= JSVAL_LOWER_INCL_TYPE_OF_OBJ_OR_NULL_SET);
JS_ASSERT((objBits >> JSVAL_TAG_SHIFT) == 0);
l.asBits = objBits | (((uint64)(JSVAL_TAG_MAX_DOUBLE | type)) << JSVAL_TAG_SHIFT);
return l;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_NULL_IMPL(jsval_layout l)
{
return l.asBits == JSVAL_SHIFTED_TAG_NULL;
}
static JS_ALWAYS_INLINE void *
JSVAL_TO_GCTHING_IMPL(jsval_layout l)
{
uint64 ptrBits = l.asBits & JSVAL_PAYLOAD_MASK;
JS_ASSERT((ptrBits & 0x7) == 0);
return (void *)ptrBits;
}
static JS_ALWAYS_INLINE jsval_layout
PRIVATE_PTR_TO_JSVAL_IMPL(void *ptr)
{
jsval_layout l;
uint64 ptrBits = (uint64)ptr;
JS_ASSERT((ptrBits & 1) == 0);
l.asBits = ptrBits >> 1;
JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l));
return l;
}
static JS_ALWAYS_INLINE void *
JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l)
{
JS_ASSERT((l.asBits & 0x8000000000000000LL) == 0);
return (void *)(l.asBits << 1);
}
#ifdef __cplusplus
JS_STATIC_ASSERT((JSVAL_SHIFTED_TAG_FUNOBJ ^ JSVAL_SHIFTED_TAG_NONFUNOBJ) == 0x0004000000000000LL);
#endif
static JS_ALWAYS_INLINE JSBool
JSVAL_SAME_PRIMITIVE_TYPE_OR_BOTH_OBJECTS_IMPL(jsval_layout lhs, jsval_layout rhs)
{
/*
* The second disjunct uses the fact that the funobj and nonfunobj tags
* differ in only 1 type bit and any other pair of tags will differ in at
* least one other bit.
*/
uint64 lbits = lhs.asBits, rbits = rhs.asBits;
return (lbits < JSVAL_TAG_MAX_DOUBLE && rbits < JSVAL_TAG_MAX_DOUBLE) ||
(((lbits ^ rbits) & 0xFFFB800000000000LL) == 0);
}
static JS_ALWAYS_INLINE JSValueType
JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l)
{
return (JSValueType)((l.asBits >> JSVAL_TAG_SHIFT) & 0xF);
}
static JS_ALWAYS_INLINE jsval_layout
PRIVATE_UINT32_TO_JSVAL_IMPL(uint32 ui)
{
jsval_layout l;
l.asBits = (uint64)ui;
JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l));
return l;
}
static JS_ALWAYS_INLINE uint32
JSVAL_TO_PRIVATE_UINT32_IMPL(jsval_layout l)
{
JS_ASSERT((l.asBits >> 32) == 0);
return (uint32)l.asBits;
}
#else
# error "Unsupported configuration"
#endif
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_GCTHING_IMPL(jsval_layout l)
{
return JSVAL_IS_OBJECT_IMPL(l) || JSVAL_IS_STRING_IMPL(l);
}
static JS_ALWAYS_INLINE uint32
JSVAL_TRACE_KIND_IMPL(jsval_layout l)
{
JS_ASSERT(JSVAL_IS_GCTHING_IMPL(l));
return (uint32)(JSBool)JSVAL_IS_STRING_IMPL(l);
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_UNDERLYING_TYPE_OF_PRIVATE_IMPL(jsval_layout l)
{

View File

@ -2725,7 +2725,7 @@ JS_ALWAYS_INLINE void
NonDoubleNativeToValue(JSValueType type, double *slot, Value *vp)
{
JS_ASSERT(type > JSVAL_TYPE_DOUBLE);
if (JS_LIKELY(type <= JSVAL_UPPER_TYPE_OF_OBJ_SET)) {
if (JS_LIKELY(type <= JSVAL_UPPER_INCL_TYPE_OF_OBJ_SET)) {
vp->data.s.payload.u32 = *(uint32_t *)slot;
vp->data.s.tag = (JSValueTag)(JSVAL_TAG_CLEAR | type);
return;
@ -9416,7 +9416,7 @@ JS_REQUIRES_STACK LIns*
TraceRecorder::is_boxed_object(LIns *vaddr_ins)
{
LIns *mask_ins = lir->insLoad(LIR_ldi, vaddr_ins, sTagOffset, ACC_OTHER);
return lir->ins2(LIR_geui, mask_ins, INS_CONSTU(JSVAL_LOWER_TAG_OF_OBJ_SET));
return lir->ins2(LIR_geui, mask_ins, INS_CONSTU(JSVAL_LOWER_INCL_TAG_OF_OBJ_SET));
}
JS_REQUIRES_STACK LIns*

View File

@ -321,17 +321,6 @@ public:
}
};
#if defined(_MSC_VER) && _MSC_VER >= 1400 || (defined(__GNUC__) && __GNUC__ >= 4)
#define USE_TRACE_TYPE_ENUM
#endif
/*
* This indicates an invalid type or error. Note that it should not be used in typemaps,
* because it is the wrong size. It can only be used as a uint32, for example as the
* return value from a function that returns a type as a uint32.
*/
const uint32 TT_INVALID = uint32(-1);
typedef Queue<uint16> SlotList;
class TypeMap : public Queue<JSValueType> {