Temporary patch to enable rethinkdb build on ppc64le until rethinkdb 2.4 release. * Changes: Files: configure, blocker_pool.cc, context_switching.cc, build.mk, args.hpp, cluster.cc Changes were backported from rethinkdb to add support for ppc64le Files: v8.sh Backported changes to enable v8 build on ppc64le (as version 3.30.33.16 did not have support) Files: js_job.cc Changes related with upgrade of v8 on ppc64le and API break ---------- --- ./configure +++ ./configure @@ -84,6 +84,8 @@ arm*) var_append LDFLAGS -ldl final_warning="ARM support is still experimental" ;; + ppc64le|powerpc64le|powerpc64el) + final_warning="PowerPC support is still experimental" ;; *) error "unsupported architecture: $MACHINE" esac --- ./src/arch/io/blocker_pool.cc +++ ./src/arch/io/blocker_pool.cc @@ -93,12 +93,19 @@ // The coroutine stack size should be enough for blocker pool stacks. Right // now that's 128 KB. + #if defined (__powerpc64__) + static_assert(COROUTINE_STACK_SIZE == 262144, + "Expecting COROUTINE_STACK_SIZE to be 262144. If you changed " + "it, please double-check whether the value is appropriate for " + "blocker pool threads."); + #else static_assert(COROUTINE_STACK_SIZE == 131072, "Expecting COROUTINE_STACK_SIZE to be 131072. If you changed " "it, please double-check whether the value is appropriate for " "blocker pool threads."); // Disregard failure -- we'll just use the default stack size if this somehow // fails. + #endif UNUSED int ignored_res = pthread_attr_setstacksize(&attr, COROUTINE_STACK_SIZE); res = pthread_create(&threads[i], &attr, --- ./src/arch/runtime/context_switching.cc +++ ./src/arch/runtime/context_switching.cc @@ -101,6 +101,8 @@ #elif defined(__arm__) /* We must preserve r4, r5, r6, r7, r8, r9, r10, and r11. Because we have to store the LR (r14) in swapcontext as well, we also store r12 in swapcontext to keep the stack double-word-aligned. However, we already accounted for both of those by decrementing sp twice above (once for r14 and once for r12, say). */ sp -= 8; +#elif defined (__powerpc64__) + sp -= 20; // r14-r31, toc, cr. #else #error "Unsupported architecture." #endif @@ -262,7 +264,7 @@ } asm( -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined (__powerpc64__) // We keep the i386, x86_64, and ARM stuff interleaved in order to enforce commonality. #if defined(__x86_64__) #if defined(__LP64__) || defined(__LLP64__) @@ -281,6 +283,8 @@ /* `current_pointer_out` is in `%rdi`. `dest_pointer` is in `%rsi`. */ #elif defined(__arm__) /* `current_pointer_out` is in `r0`. `dest_pointer` is in `r1` */ +#elif defined(__powerpc64__) + /* `current_pointer_out` is in `r3`. `dest_pointer` is in `r4` */ #endif /* Save preserved registers (the return address is already on the stack). */ @@ -302,6 +306,31 @@ "push {r12}\n" "push {r14}\n" "push {r4-r11}\n" +#elif defined(__powerpc64__) + "addi 1, 1, -(21*8)\n" + "std 2, (8*0)(1)\n" + "std 14, (8*1)(1)\n" + "std 15, (8*2)(1)\n" + "std 16, (8*3)(1)\n" + "std 17, (8*4)(1)\n" + "std 18, (8*5)(1)\n" + "std 19, (8*6)(1)\n" + "std 20, (8*7)(1)\n" + "std 21, (8*8)(1)\n" + "std 22, (8*9)(1)\n" + "std 23, (8*10)(1)\n" + "std 24, (8*11)(1)\n" + "std 25, (8*12)(1)\n" + "std 26, (8*13)(1)\n" + "std 27, (8*14)(1)\n" + "std 28, (8*15)(1)\n" + "std 29, (8*16)(1)\n" + "std 30, (8*17)(1)\n" + "std 31, (8*18)(1)\n" + "mfcr 0\n" + "std 0, (8*19)(1)\n" + "mflr 0\n" + "std 0, (8*20)(1)\n" #endif /* Save old stack pointer. */ @@ -316,6 +345,8 @@ #elif defined(__arm__) /* On ARM, the first argument is in `r0`. `r13` is the stack pointer. */ "str r13, [r0]\n" +#elif defined(__powerpc64__) + "std 1, 0(3)\n" #endif /* Load the new stack pointer and the preserved registers. */ @@ -330,6 +361,8 @@ #elif defined(__arm__) /* On ARM, the second argument is in `r1` */ "mov r13, r1\n" +#elif defined(__powerpc64__) + "mr 1, 4\n" #endif #if defined(__i386__) @@ -348,6 +381,31 @@ "pop {r4-r11}\n" "pop {r14}\n" "pop {r12}\n" +#elif defined(__powerpc64__) + "ld 2, (8*0)(1)\n" + "ld 14, (8*1)(1)\n" + "ld 15, (8*2)(1)\n" + "ld 16, (8*3)(1)\n" + "ld 17, (8*4)(1)\n" + "ld 18, (8*5)(1)\n" + "ld 19, (8*6)(1)\n" + "ld 20, (8*7)(1)\n" + "ld 21, (8*8)(1)\n" + "ld 22, (8*9)(1)\n" + "ld 23, (8*10)(1)\n" + "ld 24, (8*11)(1)\n" + "ld 25, (8*12)(1)\n" + "ld 26, (8*13)(1)\n" + "ld 27, (8*14)(1)\n" + "ld 28, (8*15)(1)\n" + "ld 29, (8*16)(1)\n" + "ld 30, (8*17)(1)\n" + "ld 31, (8*18)(1)\n" + "ld 0, (8*19)(1)\n" + "mtcr 0\n" + "ld 0, (8*20)(1)\n" + "mtlr 0\n" + "addi 1, 1, (8*21)\n" #endif #if defined(__i386__) || defined(__x86_64__) @@ -360,6 +418,8 @@ /* Above, we popped `LR` (`r14`) off the stack, so the bx instruction will jump to the correct return address. */ "bx r14\n" +#elif defined(__powerpc64__) + "blr\n" #endif #else --- ./src/build.mk +++ ./src/build.mk @@ -54,6 +54,10 @@ ifeq ($(OS),Linux) RT_LDFLAGS += -Wl,--no-as-needed + ifeq ($(GCC_ARCH),ppc64le) + RT_CXXFLAGS += "-DV8_NEEDS_BUFFER_ALLOCATOR" + RT_LDFLAGS += -no-pie + endif endif ifeq ($(STATICFORCE),1) @@ -167,7 +171,11 @@ else # ifeq ($(DEBUG),1) # use -fno-strict-aliasing to not break things # march=native used to break the serializer - RT_CXXFLAGS += -O3 -DNDEBUG -fno-strict-aliasing # -march=native + ifeq ($(GCC_ARCH),ppc64le) + RT_CXXFLAGS += -O1 -DNDEBUG -fno-strict-aliasing + else + RT_CXXFLAGS += -O3 -DNDEBUG -fno-strict-aliasing # -march=native + endif ifeq ($(NO_OMIT_FRAME_POINTER),1) RT_CXXFLAGS += -fno-omit-frame-pointer endif --- ./src/config/args.hpp +++ ./src/config/args.hpp @@ -151,7 +151,11 @@ // block infos. #define LBA_RECONSTRUCTION_BATCH_SIZE 1024 +#if defined (__powerpc64__) +#define COROUTINE_STACK_SIZE 262144 +#else #define COROUTINE_STACK_SIZE 131072 +#endif /** --- ./src/rpc/connectivity/cluster.cc +++ ./src/rpc/connectivity/cluster.cc @@ -103,7 +103,7 @@ return false; } -#if defined (__x86_64__) || defined (_WIN64) +#if defined (__x86_64__) || defined (_WIN64) || defined (__powerpc64__) const std::string connectivity_cluster_t::cluster_arch_bitsize("64bit"); #elif defined (__i386__) || defined(__arm__) const std::string connectivity_cluster_t::cluster_arch_bitsize("32bit"); --- ./mk/support/pkg/v8.sh +++ ./mk/support/pkg/v8.sh @@ -1,13 +1,44 @@ - -version=3.30.33.16-patched2 # See http://omahaproxy.appspot.com/ for the current stable/beta/dev versions of v8 -src_url=http://commondatastorage.googleapis.com/chromium-browser-official/v8-${version/-patched2/}.tar.bz2 +ARCH=`uname -m` +if [[ "$ARCH" == "ppc64le" ]]; then + # 4.7 has no source distribution, making it harder to build on Linux + version=4.7.80.23 + + pkg_fetch () { + pkg_make_tmp_fetch_dir + + # These steps are inspired by the official docs: + # https://github.com/v8/v8/wiki/Using%20Git + # with a few additional steps to get an exact version instead of HEAD + git clone --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git "$tmp_dir/depot_tools" + PATH="$tmp_dir/depot_tools:$PATH" + in_dir "$tmp_dir" gclient config --unmanaged https://chromium.googlesource.com/v8/v8.git + in_dir "$tmp_dir" git clone https://chromium.googlesource.com/v8/v8.git + v8_commit=`in_dir "$tmp_dir/v8" git rev-parse refs/tags/$version` + in_dir "$tmp_dir" gclient sync --revision v8@$v8_commit || true + find "$tmp_dir" -depth -name .git -exec rm -rf {} \; + rm -rf "$src_dir" + mv "$tmp_dir/v8" "$src_dir" + + sed -i "s/ucontext->uc_mcontext.regs->nip/ucontext->uc_mcontext.gp_regs[32]/g" "$src_dir/src/profiler/sampler.cc" + sed -i "s/ucontext->uc_mcontext.regs->gpr\[PT_R1\]/ucontext->uc_mcontext.gp_regs[1]/g" "$src_dir/src/profiler/sampler.cc" + sed -i "s/ucontext->uc_mcontext.regs->gpr\[PT_R31\]/ucontext->uc_mcontext.gp_regs[31]/g" "$src_dir/src/profiler/sampler.cc" + + pkg_remove_tmp_fetch_dir + } +else + version=3.30.33.16-patched2 + src_url=http://commondatastorage.googleapis.com/chromium-browser-official/v8-${version/-patched2/}.tar.bz2 +fi + pkg_install-include () { pkg_copy_src_to_build - in_dir "$build_dir" patch -fp1 < "$pkg_dir"/patch/v8_2-HandleScope-protected.patch - + if [[ "$ARCH" != "ppc64le" ]]; then + in_dir "$build_dir" patch -fp1 < "$pkg_dir"/patch/v8_2-HandleScope-protected.patch + fi + rm -rf "$install_dir/include" mkdir -p "$install_dir/include" cp -RL "$build_dir/include/." "$install_dir/include" @@ -29,7 +60,10 @@ pkg_install () { pkg_copy_src_to_build - in_dir "$build_dir" patch -fp1 < "$pkg_dir"/patch/v8_2-HandleScope-protected.patch + + if [[ "$ARCH" != "ppc64le" ]]; then + in_dir "$build_dir" patch -fp1 < "$pkg_dir"/patch/v8_2-HandleScope-protected.patch + fi sed -i.bak '/unittests/d;/cctest/d' "$build_dir/build/all.gyp" # don't build the tests mkdir -p "$install_dir/lib" if [[ "$OS" = Darwin ]]; then @@ -44,6 +78,7 @@ i?86) arch=ia32 ;; x86_64) arch=x64 ;; arm*) arch=arm; arch_gypflags=$raspberry_pi_gypflags ;; + ppc64le*|powerpc*) arch=ppc64 ;; *) arch=native ;; esac mode=release @@ -58,10 +93,21 @@ pkg_link-flags () { # These are the necessary libraries recommended by the docs: # https://developers.google.com/v8/get_started#hello - for lib in libv8_{base,libbase,snapshot,libplatform}; do - echo "$install_dir/lib/$lib.a" - done - for lib in libicu{i18n,uc,data}; do - echo "$install_dir/lib/$lib.a" - done + if [[ "$ARCH" == "ppc64le" ]]; then + for lib in libv8_{base,libbase,nosnapshot,libplatform}; do + echo "$install_dir/lib/$lib.a" + done + for lib in libicu{i18n,uc,data}; do + echo "$install_dir/lib/$lib.a" + done + echo "-licui18n -licuuc -ldl -lexecinfo" + + else + for lib in libv8_{base,libbase,snapshot,libplatform}; do + echo "$install_dir/lib/$lib.a" + done + for lib in libicu{i18n,uc,data}; do + echo "$install_dir/lib/$lib.a" + done + fi } --- ./src/extproc/js_job.cc +++ ./src/extproc/js_job.cc files_v8/js_job.cc @@ -56,7 +56,12 @@ platform.init(v8::platform::CreateDefaultPlatform()); v8::V8::InitializePlatform(platform.get()); v8::V8::Initialize(); +#ifdef __powerpc64__ + v8::Isolate::CreateParams params; + isolate_ = v8::Isolate::New(params); +#else isolate_ = v8::Isolate::New(); +#endif isolate_->Enter(); }