Bug 587962 - [JAEGER] JaegerMonkey build and check failed on Solaris x86 with Sun Studio 12. r=dvander
authorLeon Sha <leon.sha@sun.com>
Fri, 20 Aug 2010 01:09:34 -0700
changeset 53468 c2f1e5150e18688ebede3eadc968d3bf082f9a5b
parent 53467 8a0513a5c024cdcaa92742f25861a8ce1fa7ac6f
child 53469 1fe4f48205b7bc884900fe9414b8ce3c4c739edd
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs587962
milestone2.0b5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 587962 - [JAEGER] JaegerMonkey build and check failed on Solaris x86 with Sun Studio 12. r=dvander
js/src/assembler/wtf/Platform.h
js/src/jscntxt.h
js/src/methodjit/StubCalls.cpp
js/src/methodjit/TrampolineCompiler.cpp
js/src/methodjit/TrampolineCompiler.h
js/src/methodjit/TrampolineSUNWX86.s
js/src/yarr/pcre/pcre_exec.cpp
js/src/yarr/yarr/RegexJIT.cpp
js/src/yarr/yarr/RegexJIT.h
--- a/js/src/assembler/wtf/Platform.h
+++ b/js/src/assembler/wtf/Platform.h
@@ -95,16 +95,20 @@
 #define WTF_COMPILER_MINGW 1
 #endif
 
 /* COMPILER(WINSCW) - CodeWarrior for Symbian emulator */
 #if defined(__WINSCW__)
 #define WTF_COMPILER_WINSCW 1
 #endif
 
+/* COMPILER(SUNPRO) - Sun Studio for Solaris */
+#if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+#define WTF_COMPILER_SUNPRO 1
+#endif
 
 
 /* ==== CPU() - the target CPU architecture ==== */
 
 /* This also defines CPU(BIG_ENDIAN) or CPU(MIDDLE_ENDIAN) or neither, as appropriate. */
 
 
 /* CPU(ALPHA) - DEC Alpha */
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -230,16 +230,20 @@ struct TracerState
 };
 
 #ifdef JS_METHODJIT
 namespace mjit {
     struct Trampolines
     {
         void (* forceReturn)();
         JSC::ExecutablePool *forceReturnPool;
+#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
+        void (* forceReturnFast)();
+        JSC::ExecutablePool *forceReturnFastPool;
+#endif
     };
 
     struct ThreadData
     {
         JSC::ExecutableAllocator *execPool;
 
         // Trampolines for JIT code.
         Trampolines trampolines;
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -1360,17 +1360,21 @@ stubs::Debugger(VMFrame &f, jsbytecode *
             f.cx->throwing = JS_TRUE;
             f.cx->exception = rval;
             THROW();
 
           case JSTRAP_RETURN:
             f.cx->throwing = JS_FALSE;
             f.cx->fp->setReturnValue(rval);
             *f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
+#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
+                                         JS_METHODJIT_DATA(f.cx).trampolines.forceReturnFast);
+#else
                                          JS_METHODJIT_DATA(f.cx).trampolines.forceReturn);
+#endif
             break;
 
           case JSTRAP_ERROR:
             f.cx->throwing = JS_FALSE;
             THROW();
 
           default:
             break;
@@ -1395,17 +1399,21 @@ stubs::Trap(VMFrame &f, jsbytecode *pc)
         f.cx->throwing = JS_TRUE;
         f.cx->exception = rval;
         THROW();
 
       case JSTRAP_RETURN:
         f.cx->throwing = JS_FALSE;
         f.cx->fp->setReturnValue(rval);
         *f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
+#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
+                                     JS_METHODJIT_DATA(f.cx).trampolines.forceReturnFast);
+#else
                                      JS_METHODJIT_DATA(f.cx).trampolines.forceReturn);
+#endif
         break;
 
       case JSTRAP_ERROR:
         f.cx->throwing = JS_FALSE;
         THROW();
 
       default:
         break;
--- a/js/src/methodjit/TrampolineCompiler.cpp
+++ b/js/src/methodjit/TrampolineCompiler.cpp
@@ -57,24 +57,30 @@ JS_END_MACRO
 bool
 TrampolineCompiler::compile()
 {
 #ifdef JS_METHODJIT_SPEW
     JMCheckLogging();
 #endif
 
     COMPILE(trampolines->forceReturn, trampolines->forceReturnPool, generateForceReturn);
+#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
+    COMPILE(trampolines->forceReturnFast, trampolines->forceReturnFastPool, generateForceReturnFast);
+#endif
 
     return true;
 }
 
 void
 TrampolineCompiler::release(Trampolines *tramps)
 {
     RELEASE(tramps->forceReturn, tramps->forceReturnPool);
+#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
+    RELEASE(tramps->forceReturnFast, tramps->forceReturnFastPool);
+#endif
 }
 
 bool
 TrampolineCompiler::compileTrampoline(void **where, JSC::ExecutablePool **pool,
                                       TrampolineGenerator generator)
 {
     Assembler masm;
 
@@ -99,21 +105,16 @@ TrampolineCompiler::compileTrampoline(vo
  * - There was always at least one inline call.
  * - We don't know if there is a call object, so we always check.
  * - We don't know where we came from, so we don't know frame depth or PC.
  * - There is no stub buffer.
  */
 bool
 TrampolineCompiler::generateForceReturn(Assembler &masm)
 {
-#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
-    // In case of no fast call, when we change the return address,
-    // we need to make sure add esp by 8.
-    masm.addPtr(Imm32(8), Registers::StackPointer);
-#endif
     /* if (!callobj) stubs::PutCallObject */
     Jump noCallObj = masm.branchPtr(Assembler::Equal,
                                     Address(JSFrameReg, JSStackFrame::offsetCallObj()),
                                     ImmPtr(0));
     masm.stubCall(stubs::PutCallObject, NULL, 0);
     noCallObj.linkTo(masm.label(), &masm);
 
     /* if (arguments) stubs::PutArgsObject */
@@ -143,11 +144,22 @@ TrampolineCompiler::generateForceReturn(
     masm.storePtr(ImmPtr(JSStackFrame::sInvalidPC),
                   Address(JSFrameReg, offsetof(JSStackFrame, savedPC)));
 #endif
 
     masm.ret();
     return true;
 }
 
+#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
+bool
+TrampolineCompiler::generateForceReturnFast(Assembler &masm)
+{
+    // In case of no fast call, when we change the return address,
+    // we need to make sure add esp by 8.
+    masm.addPtr(Imm32(8), Registers::StackPointer);
+    return generateForceReturn(masm);
+}
+#endif
+
 } /* namespace mjit */
 } /* namespace js */
 
--- a/js/src/methodjit/TrampolineCompiler.h
+++ b/js/src/methodjit/TrampolineCompiler.h
@@ -66,16 +66,20 @@ public:
 
 private:
     bool compileTrampoline(void **where, JSC::ExecutablePool **pool,
                            TrampolineGenerator generator);
     
     /* Generators for trampolines. */
     static bool generateForceReturn(Assembler &masm);
 
+#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
+    static bool generateForceReturnFast(Assembler &masm);
+#endif
+
     JSC::ExecutableAllocator *execPool;
     Trampolines *trampolines;
 };
 
 } /* namespace mjit */
 } /* namespace js */
 
 #endif
--- a/js/src/methodjit/TrampolineSUNWX86.s
+++ b/js/src/methodjit/TrampolineSUNWX86.s
@@ -47,21 +47,22 @@ JaegerTrampoline:
     movl %esp, %ebp
     /* Save non-volatile registers. */
     pushl %esi
     pushl %edi
     pushl %ebx
 
     /* Build the JIT frame. Push fields in order, */
     /* then align the stack to form esp == VMFrame. */
-    pushl 20(%ebp)
+    movl  12(%ebp), %ebx                       /* fp */
+    pushl %ebx                                 /* entryFp */
+    pushl 20(%ebp)                             /* inlineCallCount */
     pushl 8(%ebp)
-    pushl 12(%ebp)
-    movl  12(%ebp), %ebx
-    subl $0x1c, %esp
+    pushl %ebx
+    subl $0x18, %esp
 
     /* Jump into the JIT'd code. */
     pushl 16(%ebp)
 
     /* No fastcall for sunstudio. */
     pushl %esp
     call SetVMFrameRegs
     popl  %edx
@@ -128,11 +129,11 @@ throwpoline_exit:
 JaegerFromTracer:
     movl 0x24(%ebx), %edx
     movl 0x28(%ebx), %ecx
     movl 0x38(%ebx), %eax
     /* For Sun Studio there is no fast call. */
     /* We add the stack by 8 before. */
     addl $0x8, %esp
     /* Restore frame regs. */
-    movl 0x20(%esp), %ebx
+    movl 0x1C(%esp), %ebx
     ret
 .size   JaegerFromTracer, . - JaegerFromTracer
--- a/js/src/yarr/pcre/pcre_exec.cpp
+++ b/js/src/yarr/pcre/pcre_exec.cpp
@@ -47,17 +47,17 @@ the JavaScript specification. There are 
 #include <limits.h>
 #include "yarr/jswtfbridge.h"
 #include "yarr/wtf/ASCIICType.h"
 #include "jsarena.h"
 #include "jscntxt.h"
 
 using namespace WTF;
 
-#ifndef WTF_COMPILER_MSVC
+#if !WTF_COMPILER_MSVC && !WTF_COMPILER_SUNPRO
 #define USE_COMPUTED_GOTO_FOR_MATCH_RECURSION
 #endif
 
 /* Note: Webkit sources have USE_COMPUTED_GOTO_FOR_MATCH_OPCODE_LOOP disabled. */
 /* Note: There are hardcoded constants all over the place, but in the port of
  Yarr to TraceMonkey two bytes are added to the OP_BRA* opcodes, so the
  instruction stream now looks like this at the start of a bracket group:
 
--- a/js/src/yarr/yarr/RegexJIT.cpp
+++ b/js/src/yarr/yarr/RegexJIT.cpp
@@ -1405,17 +1405,17 @@ class RegexGenerator : private MacroAsse
 #elif WTF_CPU_X86
         push(X86Registers::ebp);
         move(stackPointerRegister, X86Registers::ebp);
         // TODO: do we need spill registers to fill the output pointer if there are no sub captures?
         push(X86Registers::ebx);
         push(X86Registers::edi);
         push(X86Registers::esi);
         // load output into edi (2 = saved ebp + return address).
-    #if WTF_COMPILER_MSVC
+    #if WTF_COMPILER_MSVC || WTF_COMPILER_SUNPRO
         loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), input);
         loadPtr(Address(X86Registers::ebp, 3 * sizeof(void*)), index);
         loadPtr(Address(X86Registers::ebp, 4 * sizeof(void*)), length);
         loadPtr(Address(X86Registers::ebp, 5 * sizeof(void*)), output);
     #else
         loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), output);
     #endif
 #elif WTF_CPU_ARM
--- a/js/src/yarr/yarr/RegexJIT.h
+++ b/js/src/yarr/yarr/RegexJIT.h
@@ -32,17 +32,17 @@
 #include "assembler/assembler/MacroAssemblerCodeRef.h"
 #include "assembler/jit/ExecutableAllocator.h"
 #include "RegexPattern.h"
 #include "yarr/jswtfbridge.h"
 
 #include "yarr/pcre/pcre.h"
 struct JSRegExp; // temporary, remove when fallback is removed.
 
-#if WTF_CPU_X86 && !WTF_COMPILER_MSVC
+#if WTF_CPU_X86 && !WTF_COMPILER_MSVC && !WTF_COMPILER_SUNPRO
 #define YARR_CALL __attribute__ ((regparm (3)))
 #else
 #define YARR_CALL
 #endif
 
 struct JSContext;
 
 namespace JSC {
@@ -69,17 +69,17 @@ public:
     JSRegExp* getFallback() { return m_fallback; }
     void setFallback(JSRegExp* fallback) { m_fallback = fallback; }
 
     bool operator!() { return (!m_ref.m_code.executableAddress() && !m_fallback); }
     void set(MacroAssembler::CodeRef ref) { m_ref = ref; }
 
     int execute(const UChar* input, unsigned start, unsigned length, int* output)
     {
-        return JS_EXTENSION(reinterpret_cast<RegexJITCode>(m_ref.m_code.executableAddress())(input, start, length, output));
+        return JS_EXTENSION((reinterpret_cast<RegexJITCode>(m_ref.m_code.executableAddress()))(input, start, length, output));
     }
 
 private:
     MacroAssembler::CodeRef m_ref;
     JSRegExp* m_fallback;
 };
 
 void jitCompileRegex(ExecutableAllocator &allocator, RegexCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, int& error, bool &fellBack, bool ignoreCase = false, bool multiline = false);