Description: fix for Solaris/amd64 memory layout This patch: 1. Fixes C++ classes 2. Disables JIT and enables LLInt 3. Fixes LLInt TODO: Fix JIT Index: qt5webkit/Source/WTF/wtf/Platform.h =================================================================== --- qt5webkit.orig/Source/WTF/wtf/Platform.h +++ qt5webkit/Source/WTF/wtf/Platform.h @@ -409,6 +409,10 @@ #define WTF_OS_SOLARIS 1 #endif +#if CPU(X86_64) && OS(SOLARIS) +# define WTF_OS_SOLARIS_AMD64 1 +#endif + /* OS(WINDOWS) - Any version of Windows */ #if defined(WIN32) || defined(_WIN32) #define WTF_OS_WINDOWS 1 Index: qt5webkit/Source/JavaScriptCore/runtime/JSCJSValue.h =================================================================== --- qt5webkit.orig/Source/JavaScriptCore/runtime/JSCJSValue.h +++ qt5webkit/Source/JavaScriptCore/runtime/JSCJSValue.h @@ -427,6 +427,14 @@ public: // alignment for a GC cell, and in the zero page). #define ValueEmpty 0x0ll #define ValueDeleted 0x4ll +#if OS(SOLARIS_AMD64) +// https://bugzilla.mozilla.org/show_bug.cgi?id=577056 +// Memory layout for 64-bit Solaris is different than other 64-bit systems. +// User space memory may locate on PART-A (0xFFFFFD80.00000000 - 0xFFFF8000.00000000) +// and PART-B (0x00008000.00000000 - 0x00000000.04000000). + bool isSolarisAMD64StackPointer() const; +#endif + #endif private: Index: qt5webkit/Source/JavaScriptCore/runtime/JSCJSValueInlines.h =================================================================== --- qt5webkit.orig/Source/JavaScriptCore/runtime/JSCJSValueInlines.h +++ qt5webkit/Source/JavaScriptCore/runtime/JSCJSValueInlines.h @@ -341,6 +341,13 @@ inline bool JSValue::asBoolean() const #else // !USE(JSVALUE32_64) i.e. USE(JSVALUE64) +#if OS(SOLARIS_AMD64) +inline bool JSValue::isSolarisAMD64StackPointer() const +{ + return ((u.asInt64 & 0xFFFF800000000000LL) == 0xFFFF800000000000LL); +} +#endif + // 0x0 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x0, which is in the (invalid) zero page. inline JSValue::JSValue() { @@ -417,6 +424,10 @@ inline int32_t JSValue::asInt32() const inline bool JSValue::isDouble() const { +#if OS(SOLARIS_AMD64) + if (isSolarisAMD64StackPointer()) + return false; +#endif return isNumber() && !isInt32(); } @@ -442,22 +453,38 @@ inline JSValue::JSValue(JSFalseTag) inline bool JSValue::isUndefinedOrNull() const { +#if OS(SOLARIS_AMD64) + if (isSolarisAMD64StackPointer()) + return false; +#endif // Undefined and null share the same value, bar the 'undefined' bit in the extended tag. return (u.asInt64 & ~TagBitUndefined) == ValueNull; } inline bool JSValue::isBoolean() const { +#if OS(SOLARIS_AMD64) + if (isSolarisAMD64StackPointer()) + return false; +#endif return (u.asInt64 & ~1) == ValueFalse; } inline bool JSValue::isCell() const { +#if OS(SOLARIS_AMD64) + if (isSolarisAMD64StackPointer()) + return true; // TRUE! +#endif return !(u.asInt64 & TagMask); } inline bool JSValue::isInt32() const { +#if OS(SOLARIS_AMD64) + if (isSolarisAMD64StackPointer()) + return false; +#endif return (u.asInt64 & TagTypeNumber) == TagTypeNumber; } @@ -489,6 +516,10 @@ inline double JSValue::asDouble() const inline bool JSValue::isNumber() const { +#if OS(SOLARIS_AMD64) + if (isSolarisAMD64StackPointer()) + return false; +#endif return u.asInt64 & TagTypeNumber; } Index: qt5webkit/Source/JavaScriptCore/jit/JITInlines.h =================================================================== --- qt5webkit.orig/Source/JavaScriptCore/jit/JITInlines.h +++ qt5webkit/Source/JavaScriptCore/jit/JITInlines.h @@ -1241,7 +1241,14 @@ ALWAYS_INLINE void JIT::emitInitRegister ALWAYS_INLINE JIT::Jump JIT::emitJumpIfJSCell(RegisterID reg) { +#if OS(SOLARIS_AMD64) + // Does "reg" hold solaris 64-bit stack pointer? + move(TrustedImm64(static_cast(0xFFFF800000000000)), scratchRegister); + and64(reg, scratchRegister); + return branch64(Equal, scratchRegister, TrustedImm64(static_cast(0xFFFF800000000000))); +#else return branchTest64(Zero, reg, tagMaskRegister); +#endif } ALWAYS_INLINE JIT::Jump JIT::emitJumpIfBothJSCells(RegisterID reg1, RegisterID reg2, RegisterID scratch) Index: qt5webkit/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm =================================================================== --- qt5webkit.orig/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm +++ qt5webkit/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm @@ -389,12 +389,21 @@ end macro loadConstantOrVariableInt32(index, value, slow) loadConstantOrVariable(index, value) +if SOLARIS_AMD64 + bqaeq value, solarisAMD64StackBottom, slow +end bqb value, tagTypeNumber, slow end macro loadConstantOrVariableCell(index, value, slow) loadConstantOrVariable(index, value) +if SOLARIS_AMD64 + bqaeq value, solarisAMD64StackBottom, .done +end btqnz value, tagMask, slow +if SOLARIS_AMD64 +.done: +end end macro writeBarrierOnOperand(cellOperand) @@ -715,7 +724,13 @@ _llint_op_neq: macro equalNullComparison() loadisFromInstruction(2, t0) loadq [cfr, t0, 8], t0 +if SOLARIS_AMD64 + bqaeq t0, solarisAMD64StackBottom, .solarisAMD64StackPointer +end btqnz t0, tagMask, .immediate +if SOLARIS_AMD64 +.solarisAMD64StackPointer: +end btbnz JSCell::m_flags[t0], MasqueradesAsUndefined, .masqueradesAsUndefined move 0, t0 jmp .done @@ -755,6 +770,10 @@ macro strictEq(equalityOperation, slowPa loadisFromInstruction(2, t2) loadConstantOrVariable(t0, t1) loadConstantOrVariable(t2, t0) +if SOLARIS_AMD64 + bqaeq t0, solarisAMD64StackBottom, .slow + bqaeq t1, solarisAMD64StackBottom, .slow +end move t0, t2 orq t1, t2 btqz t2, tagMask, .slow @@ -791,6 +810,9 @@ macro preOp(arithmeticOperation, slowPat traceExecution() loadisFromInstruction(1, t0) loadq [cfr, t0, 8], t1 +if SOLARIS_AMD64 + bqaeq t1, solarisAMD64StackBottom, .slow +end bqb t1, tagTypeNumber, .slow arithmeticOperation(t1, .slow) orq tagTypeNumber, t1 @@ -819,6 +841,9 @@ _llint_op_to_number: loadisFromInstruction(2, t0) loadisFromInstruction(1, t1) loadConstantOrVariable(t0, t2) +if SOLARIS_AMD64 + bqaeq t2, solarisAMD64StackBottom, .opToNumberSlow +end bqaeq t2, tagTypeNumber, .opToNumberIsImmediate btqz t2, tagTypeNumber, .opToNumberSlow .opToNumberIsImmediate: @@ -851,6 +876,9 @@ _llint_op_negate: loadisFromInstruction(2, t0) loadisFromInstruction(1, t1) loadConstantOrVariable(t0, t2) +if SOLARIS_AMD64 + bqaeq t2, solarisAMD64StackBottom, .opNegateSlow +end bqb t2, tagTypeNumber, .opNegateNotInt btiz t2, 0x7fffffff, .opNegateSlow negi t2 @@ -873,7 +901,13 @@ macro binaryOpCustomStore(integerOperati loadisFromInstruction(2, t2) loadConstantOrVariable(t0, t1) loadConstantOrVariable(t2, t0) +if SOLARIS_AMD64 + bqaeq t0, solarisAMD64StackBottom, .slow +end bqb t0, tagTypeNumber, .op1NotInt +if SOLARIS_AMD64 + bqaeq t1, solarisAMD64StackBottom, .op2NotInt +end bqb t1, tagTypeNumber, .op2NotInt loadisFromInstruction(1, t2) integerOperationAndStore(t1, t0, .slow, t2) @@ -882,6 +916,9 @@ macro binaryOpCustomStore(integerOperati .op1NotInt: # First operand is definitely not an int, the second operand could be anything. btqz t0, tagTypeNumber, .slow +if SOLARIS_AMD64 + bqaeq t1, solarisAMD64StackBottom, .slow +end bqaeq t1, tagTypeNumber, .op1NotIntOp2Int btqz t1, tagTypeNumber, .slow addq tagTypeNumber, t1 @@ -902,6 +939,9 @@ macro binaryOpCustomStore(integerOperati .op2NotInt: # First operand is definitely an int, the second is definitely not. loadisFromInstruction(1, t2) +if SOLARIS_AMD64 + bqaeq t1, solarisAMD64StackBottom, .slow +end btqz t1, tagTypeNumber, .slow ci2d t0, ft0 addq tagTypeNumber, t1 @@ -996,6 +1036,10 @@ macro bitOp(operation, slowPath, advance loadisFromInstruction(1, t3) loadConstantOrVariable(t0, t1) loadConstantOrVariable(t2, t0) +if SOLARIS_AMD64 + bqaeq t0, solarisAMD64StackBottom, .slow + bqaeq t1, solarisAMD64StackBottom, .slow +end bqb t0, tagTypeNumber, .slow bqb t1, tagTypeNumber, .slow operation(t1, t0) @@ -1107,6 +1151,9 @@ _llint_op_instanceof: loadStructureAndClobberFirstArg(t2, t3) loadq Structure::m_prototype[t3], t2 bqeq t2, t1, .opInstanceofDone +if SOLARIS_AMD64 + bqaeq t2, solarisAMD64StackBottom, .opInstanceofLoop +end btqz t2, tagMask, .opInstanceofLoop move 0, t0 @@ -1130,6 +1177,9 @@ _llint_op_is_undefined: loadisFromInstruction(2, t1) loadisFromInstruction(1, t2) loadConstantOrVariable(t1, t0) +if SOLARIS_AMD64 + bqaeq t0, solarisAMD64StackBottom, .opIsUndefinedCell +end btqz t0, tagMask, .opIsUndefinedCell cqeq t0, ValueUndefined, t3 orq ValueFalse, t3 @@ -1167,6 +1217,12 @@ _llint_op_is_number: loadisFromInstruction(2, t1) loadisFromInstruction(1, t2) loadConstantOrVariable(t1, t0) +if SOLARIS_AMD64 + bqb t0, solarisAMD64StackBottom, .opIsNumberNotSolarisAMD64StackPointer + storeq ValueFalse, [cfr, t2, 8] + dispatch(3) +.opIsNumberNotSolarisAMD64StackPointer: +end tqnz t0, tagTypeNumber, t1 orq ValueFalse, t1 storeq t1, [cfr, t2, 8] @@ -1178,7 +1234,13 @@ _llint_op_is_string: loadisFromInstruction(2, t1) loadisFromInstruction(1, t2) loadConstantOrVariable(t1, t0) +if SOLARIS_AMD64 + bqaeq t0, solarisAMD64StackBottom, .opIsStringSolarisAMD64StackPointer +end btqnz t0, tagMask, .opIsStringNotCell +if SOLARIS_AMD64 +.opIsStringSolarisAMD64StackPointer: +end cbeq JSCell::m_type[t0], StringType, t1 orq ValueFalse, t1 storeq t1, [cfr, t2, 8] @@ -1504,6 +1566,9 @@ macro putByVal(slowPath) contiguousPutByVal( macro (operand, scratch, address) loadConstantOrVariable(operand, scratch) +if SOLARIS_AMD64 + bqaeq scratch, solarisAMD64StackBottom, .opPutByValSlow +end bpb scratch, tagTypeNumber, .opPutByValSlow storep scratch, address end) @@ -1513,6 +1578,9 @@ macro putByVal(slowPath) contiguousPutByVal( macro (operand, scratch, address) loadConstantOrVariable(operand, scratch) +if SOLARIS_AMD64 + bqaeq scratch, solarisAMD64StackBottom, .notInt +end bqb scratch, tagTypeNumber, .notInt ci2d scratch, ft0 jmp .ready @@ -1592,7 +1660,13 @@ macro equalNull(cellHandler, immediateHa loadisFromInstruction(1, t0) assertNotConstant(t0) loadq [cfr, t0, 8], t0 +if SOLARIS_AMD64 + bqaeq t0, solarisAMD64StackBottom, .solarisAMD64StackPointer +end btqnz t0, tagMask, .immediate +if SOLARIS_AMD64 +.solarisAMD64StackPointer: +end loadStructureWithScratch(t0, t2, t1) cellHandler(t2, JSCell::m_flags[t0], .target) dispatch(3) @@ -1650,6 +1724,10 @@ macro compare(integerCompare, doubleComp loadisFromInstruction(2, t3) loadConstantOrVariable(t2, t0) loadConstantOrVariable(t3, t1) +if SOLARIS_AMD64 + bqaeq t0, solarisAMD64StackBottom, .slow + bqaeq t1, solarisAMD64StackBottom, .slow +end bqb t0, tagTypeNumber, .op1NotInt bqb t1, tagTypeNumber, .op2NotInt integerCompare(t0, t1, .jumpTarget) @@ -1697,6 +1775,9 @@ _llint_op_switch_imm: muli sizeof SimpleJumpTable, t3 # FIXME: would be nice to peephole this! loadp CodeBlock::RareData::m_switchJumpTables + VectorBufferOffset[t2], t2 addp t3, t2 +if SOLARIS_AMD64 + bqaeq t1, solarisAMD64StackBottom, .opSwitchImmFallThrough +end bqb t1, tagTypeNumber, .opSwitchImmNotInt subi SimpleJumpTable::min[t2], t1 biaeq t1, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchImmFallThrough @@ -1725,7 +1806,13 @@ _llint_op_switch_char: muli sizeof SimpleJumpTable, t3 loadp CodeBlock::RareData::m_switchJumpTables + VectorBufferOffset[t2], t2 addp t3, t2 +if SOLARIS_AMD64 + bqaeq t1, solarisAMD64StackBottom, .opSwitchCharSolarisAMD64StackPointer +end btqnz t1, tagMask, .opSwitchCharFallThrough +if SOLARIS_AMD64 +.opSwitchCharSolarisAMD64StackPointer: +end bbneq JSCell::m_type[t1], StringType, .opSwitchCharFallThrough bineq JSString::m_length[t1], 1, .opSwitchCharFallThrough loadp JSString::m_value[t1], t0 @@ -1756,7 +1843,13 @@ macro arrayProfileForCall() loadisFromInstruction(4, t3) negp t3 loadq ThisArgumentOffset[cfr, t3, 8], t0 +if SOLARIS_AMD64 + bqaeq t0, solarisAMD64StackBottom, .solarisAMD64StackPointer +end btqnz t0, tagMask, .done +if SOLARIS_AMD64 +.solarisAMD64StackPointer: +end loadpFromInstruction((CallOpCodeSize - 2), t1) loadi JSCell::m_structureID[t0], t3 storei t3, ArrayProfile::m_lastSeenStructureID[t1] @@ -1798,7 +1891,13 @@ _llint_op_to_primitive: loadisFromInstruction(2, t2) loadisFromInstruction(1, t3) loadConstantOrVariable(t2, t0) +if SOLARIS_AMD64 + bqaeq t0, solarisAMD64StackBottom, .opToPrimitiveSolarisAMD64StackPointer +end btqnz t0, tagMask, .opToPrimitiveIsImm +if SOLARIS_AMD64 +.opToPrimitiveSolarisAMD64StackPointer: +end bbaeq JSCell::m_type[t0], ObjectType, .opToPrimitiveSlowCase .opToPrimitiveIsImm: storeq t0, [cfr, t3, 8] Index: qt5webkit/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h =================================================================== --- qt5webkit.orig/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h +++ qt5webkit/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h @@ -143,6 +143,12 @@ #define OFFLINE_ASM_JSVALUE64 0 #endif +#if OS(SOLARIS_AMD64) +#define OFFLINE_ASM_SOLARIS_AMD64 1 +#else +#define OFFLINE_ASM_SOLARIS_AMD64 0 +#endif + #if !ASSERT_DISABLED #define OFFLINE_ASM_ASSERT_ENABLED 1 #else Index: qt5webkit/Source/JavaScriptCore/llint/LowLevelInterpreter.asm =================================================================== --- qt5webkit.orig/Source/JavaScriptCore/llint/LowLevelInterpreter.asm +++ qt5webkit/Source/JavaScriptCore/llint/LowLevelInterpreter.asm @@ -191,6 +191,9 @@ if JSVALUE64 const ValueTrue = TagBitTypeOther | TagBitBool | 1 const ValueUndefined = TagBitTypeOther | TagBitUndefined const ValueNull = TagBitTypeOther +if SOLARIS_AMD64 + const solarisAMD64StackBottom = 0xFFFF800000000000 +end const TagTypeNumber = 0xffff000000000000 const TagMask = TagTypeNumber | TagBitTypeOther else