Merge pull request #2256 from bytecodealliance/main

Merge branch main into dev/exce_handling
This commit is contained in:
Wenyong Huang 2023-06-13 14:00:17 +08:00 committed by GitHub
commit 31f4cabe27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
117 changed files with 5209 additions and 577 deletions

View File

@ -76,7 +76,7 @@ jobs:
with:
os: "ubuntu-22.04"
arch: "X86"
build_wamrc:
needs:
[build_llvm_libraries_on_ubuntu_2004, build_llvm_libraries_on_ubuntu_2204]
@ -117,84 +117,6 @@ jobs:
cmake --build . --config Release --parallel 4
working-directory: wamr-compiler
build_iwasm_linux_gcc4_8:
runs-on: ubuntu-latest
container:
image: ubuntu:14.04
strategy:
matrix:
make_options_run_mode: [
# Running mode
$CLASSIC_INTERP_BUILD_OPTIONS,
$FAST_INTERP_BUILD_OPTIONS,
$FAST_JIT_BUILD_OPTIONS,
]
make_options_feature: [
# Features
"-DWAMR_BUILD_CUSTOM_NAME_SECTION=1",
"-DWAMR_BUILD_DEBUG_AOT=1",
"-DWAMR_BUILD_DEBUG_INTERP=1",
"-DWAMR_BUILD_DUMP_CALL_STACK=1",
"-DWAMR_BUILD_LIB_PTHREAD=1",
"-DWAMR_BUILD_LIB_WASI_THREADS=1",
"-DWAMR_BUILD_LOAD_CUSTOM_SECTION=1",
"-DWAMR_BUILD_MINI_LOADER=1",
"-DWAMR_BUILD_MEMORY_PROFILING=1",
"-DWAMR_BUILD_MULTI_MODULE=1",
"-DWAMR_BUILD_PERF_PROFILING=1",
"-DWAMR_BUILD_REF_TYPES=1",
"-DWAMR_BUILD_SIMD=1",
"-DWAMR_BUILD_TAIL_CALL=1",
"-DWAMR_DISABLE_HW_BOUND_CHECK=1",
]
exclude:
# uncompatiable feature and platform
# uncompatiable mode and feature
# MULTI_MODULE only on INTERP mode
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
# SIMD only on JIT/AOT mode
- make_options_run_mode: $CLASSIC_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_SIMD=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_SIMD=1"
# DEBUG_INTERP only on CLASSIC INTERP mode
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_INTERP=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_INTERP=1"
# DEBUG_AOT only on JIT/AOT mode
- make_options_run_mode: $CLASSIC_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1"
# TODO: DEBUG_AOT on JIT
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1"
# MINI_LOADER only on INTERP mode
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
steps:
- name: checkout
uses: actions/checkout@v3
- name: Install dependencies
run: apt update && apt install -y make g++-4.8 gcc-4.8 wget git
- name: Install cmake
run: |
wget https://github.com/Kitware/CMake/releases/download/v3.26.1/cmake-3.26.1-linux-x86_64.tar.gz -O cmake.tar.gz
tar xzf cmake.tar.gz
cp cmake-3.26.1-linux-x86_64/bin/cmake /usr/local/bin
cp -r cmake-3.26.1-linux-x86_64/share/cmake-3.26/ /usr/local/share/
- name: Build iwasm
run: |
mkdir build && cd build
cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }} -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8
cmake --build . --config Release --parallel 4
working-directory: product-mini/platforms/linux
build_iwasm:
needs:
[build_llvm_libraries_on_ubuntu_2004, build_llvm_libraries_on_ubuntu_2204]
@ -342,7 +264,6 @@ jobs:
strategy:
fail-fast: false
matrix:
sanitizer: ["", "ubsan"]
make_options: [
# Running mode
$AOT_BUILD_OPTIONS,
@ -400,14 +321,14 @@ jobs:
if: (!endsWith(matrix.make_options, '_INTERP_BUILD_OPTIONS'))
run: |
mkdir build && cd build
cmake -DSANITIZER="${{matrix.sanitizer}}" ..
cmake ..
cmake --build . --config Release --parallel 4
working-directory: wamr-compiler
- name: Build Sample [wasm-c-api]
run: |
VERBOSE=1
cmake -S . -B build ${{ matrix.make_options }} -DSANITIZER="${{matrix.sanitizer}}"
cmake -S . -B build ${{ matrix.make_options }}
cmake --build build --config Release --parallel 4
ctest --test-dir build --output-on-failure
working-directory: samples/wasm-c-api
@ -515,6 +436,7 @@ jobs:
]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04, ubuntu-22.04]
running_mode:

View File

@ -94,7 +94,7 @@ jobs:
- name: Install RISC-V Compilers
if: contains(matrix.nuttx_board_config, 'risc-v')
run: |
curl -L https://static.dev.sifive.com/dev-tools/freedom-tools/v2020.12/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz > riscv.tar.gz
curl -L -k https://static.dev.sifive.com/dev-tools/freedom-tools/v2020.12/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz > riscv.tar.gz
tar xvf riscv.tar.gz
echo "$PWD/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin" >> $GITHUB_PATH

View File

@ -51,6 +51,7 @@ env:
AOT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_LAZY_JIT=0"
CLASSIC_INTERP_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=0 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_LAZY_JIT=0"
FAST_INTERP_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=0 -DWAMR_BUILD_FAST_INTERP=1 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_LAZY_JIT=0"
FAST_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_JIT=1 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_LAZY_JIT=1"
LLVM_LAZY_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=1"
LLVM_EAGER_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=0"
@ -70,6 +71,7 @@ jobs:
$AOT_BUILD_OPTIONS,
$CLASSIC_INTERP_BUILD_OPTIONS,
$FAST_INTERP_BUILD_OPTIONS,
$FAST_JIT_BUILD_OPTIONS,
# Running modes unsupported
#$LLVM_LAZY_JIT_BUILD_OPTIONS,
#$LLVM_EAGER_JIT_BUILD_OPTIONS,
@ -127,124 +129,43 @@ jobs:
mkdir build && cd build
cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }}
cmake --build . --config Release --parallel 4
cd ../enclave-sample
make
working-directory: product-mini/platforms/${{ matrix.platform }}
build_wamrc:
needs: [build_llvm_libraries]
run_samples_file:
needs: [build_iwasm, build_llvm_libraries]
runs-on: ${{ matrix.os }}
strategy:
matrix:
iwasm_make_options_run_mode: [
# Running modes supported
$AOT_BUILD_OPTIONS,
$CLASSIC_INTERP_BUILD_OPTIONS,
$FAST_INTERP_BUILD_OPTIONS,
$FAST_JIT_BUILD_OPTIONS,
# Running modes unsupported
#$LLVM_LAZY_JIT_BUILD_OPTIONS,
#$LLVM_EAGER_JIT_BUILD_OPTIONS,
]
os: [ubuntu-20.04]
wasi_sdk_release:
[
"https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz",
]
wabt_release:
[
"https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz",
]
iwasm_make_options_feature: [
# Features to be tested: IPFS
"-DWAMR_BUILD_SGX_IPFS=1",
]
platform: [linux-sgx]
include:
- os: ubuntu-20.04
llvm_cache_key: ${{ needs.build_llvm_libraries.outputs.cache_key }}
steps:
- name: install SGX SDK and necessary libraries
run: |
mkdir -p /opt/intel
cd /opt/intel
wget https://download.01.org/intel-sgx/sgx-linux/2.15/distro/ubuntu20.04-server/sgx_linux_x64_sdk_2.15.100.3.bin
chmod +x sgx_linux_x64_sdk_2.15.100.3.bin
echo 'yes' | ./sgx_linux_x64_sdk_2.15.100.3.bin
echo 'deb [arch=amd64] https://download.01.org/intel-sgx/sgx_repo/ubuntu focal main' | sudo tee /etc/apt/sources.list.d/intel-sgx.list
wget -qO - https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | sudo apt-key add -
sudo apt update
sudo apt install -y libsgx-launch libsgx-urts
source /opt/intel/sgxsdk/environment
- name: checkout
uses: actions/checkout@v3
- name: Get LLVM libraries
id: retrieve_llvm_libs
uses: actions/cache@v3
with:
path: |
./core/deps/llvm/build/bin
./core/deps/llvm/build/include
./core/deps/llvm/build/lib
./core/deps/llvm/build/libexec
./core/deps/llvm/build/share
key: ${{ matrix.llvm_cache_key }}
- name: Quit if cache miss
if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true'
run: echo "::error::can not get prebuilt llvm libraries" && exit 1
- name: Build wamrc
run: |
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
working-directory: wamr-compiler
build_samples_wasm_c_api:
needs: [build_iwasm]
runs-on: ${{ matrix.os }}
strategy:
matrix:
make_options: [
# Running modes supported
$CLASSIC_INTERP_BUILD_OPTIONS,
$FAST_INTERP_BUILD_OPTIONS,
# Running modes unsupported
#$LLVM_EAGER_JIT_BUILD_OPTIONS,
#$LLVM_LAZY_JIT_BUILD_OPTIONS,
#$AOT_BUILD_OPTIONS,
]
os: [ubuntu-20.04]
wasi_sdk_release:
[
"https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz",
]
wabt_release:
[
"https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz",
]
steps:
- name: checkout
uses: actions/checkout@v3
- name: download and install wabt
run: |
cd /opt
sudo wget ${{ matrix.wabt_release }}
sudo tar -xzf wabt-1.0.31-*.tar.gz
sudo mv wabt-1.0.31 wabt
- name: install SGX SDK and necessary libraries
run: |
mkdir -p /opt/intel
cd /opt/intel
wget https://download.01.org/intel-sgx/sgx-linux/2.15/distro/ubuntu20.04-server/sgx_linux_x64_sdk_2.15.100.3.bin
chmod +x sgx_linux_x64_sdk_2.15.100.3.bin
echo 'yes' | ./sgx_linux_x64_sdk_2.15.100.3.bin
echo 'deb [arch=amd64] https://download.01.org/intel-sgx/sgx_repo/ubuntu focal main' | sudo tee /etc/apt/sources.list.d/intel-sgx.list
wget -qO - https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | sudo apt-key add -
sudo apt update
sudo apt install -y libsgx-launch libsgx-urts
source /opt/intel/sgxsdk/environment
- name: Build Sample [wasm-c-api]
run: |
cmake -S . -B build ${{ matrix.make_options }}
cmake --build build --config Release --parallel 4
ctest --test-dir build
working-directory: samples/wasm-c-api
build_samples_others:
needs: [build_iwasm]
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04]
wasi_sdk_release:
[
"https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz",
]
wabt_release:
[
"https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz",
]
steps:
- name: checkout
uses: actions/checkout@v3
@ -290,13 +211,38 @@ jobs:
wget -qO - https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | sudo apt-key add -
sudo apt update
sudo apt install -y libsgx-launch libsgx-urts
source /opt/intel/sgxsdk/environment
- name: Build Sample [basic]
- name: Build iwasm for testing samples
run: |
cd samples/basic
./build.sh
./run.sh
mkdir build && cd build
cmake .. ${{ matrix.iwasm_make_options_run_mode }} ${{ matrix.iwasm_make_options_feature }}
cmake --build . --config Release --parallel 4
cd ../enclave-sample
make
working-directory: product-mini/platforms/${{ matrix.platform }}
- name: Get LLVM libraries
if: matrix.iwasm_make_options_run_mode == '$AOT_BUILD_OPTIONS'
id: retrieve_llvm_libs
uses: actions/cache@v3
with:
path: |
./core/deps/llvm/build/bin
./core/deps/llvm/build/include
./core/deps/llvm/build/lib
./core/deps/llvm/build/libexec
./core/deps/llvm/build/share
key: ${{ matrix.llvm_cache_key }}
fail-on-cache-miss: true
- name: Build wamrc only for testing samples in aot mode
if: matrix.iwasm_make_options_run_mode == '$AOT_BUILD_OPTIONS'
run: |
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
cp wamrc `pwd`/../../product-mini/platforms/${{ matrix.platform }}/enclave-sample
working-directory: wamr-compiler
- name: Build Sample [file]
run: |
@ -304,62 +250,46 @@ jobs:
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./src/iwasm -f wasm-app/file.wasm -d .
cp wasm-app/file.wasm `pwd`/../../../product-mini/platforms/${{ matrix.platform }}/enclave-sample
- name: Build Sample [multi-thread]
- name: Test Sample [file] in non-aot mode
if: matrix.iwasm_make_options_run_mode != '$AOT_BUILD_OPTIONS'
run: |
cd samples/multi-thread
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./iwasm wasm-apps/test.wasm
source /opt/intel/sgxsdk/environment
./iwasm --dir=. file.wasm
working-directory: product-mini/platforms/${{ matrix.platform }}/enclave-sample
- name: Build Sample [multi-module]
- name: Test Sample [file] in aot mode
if: matrix.iwasm_make_options_run_mode == '$AOT_BUILD_OPTIONS'
run: |
cd samples/multi-module
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./multi_module
- name: Build Sample [spawn-thread]
run: |
cd samples/spawn-thread
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./spawn_thread
- name: Build Sample [ref-types]
run: |
cd samples/ref-types
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./hello
- name: Build Sample [wasi-threads]
run: |
cd samples/wasi-threads
mkdir build && cd build
cmake -DWASI_SYSROOT=`pwd`/../../../core/deps/wasi-libc/sysroot ..
cmake --build . --config Release --parallel 4
./iwasm wasm-apps/no_pthread.wasm
source /opt/intel/sgxsdk/environment
./wamrc -sgx -o file.aot file.wasm
./iwasm --dir=. file.aot
working-directory: product-mini/platforms/${{ matrix.platform }}/enclave-sample
spec_test_default:
needs: [build_iwasm, build_llvm_libraries, build_wamrc]
needs: [build_iwasm, build_llvm_libraries]
runs-on: ubuntu-20.04
strategy:
matrix:
running_mode: ["classic-interp", "fast-interp", "aot"]
test_option: ["-x -p -s spec -b -P", "-x -p -s spec -S -b -P"]
running_mode: ["classic-interp", "fast-interp", "aot", "fast-jit"]
test_option: ["-x -p -s spec -b -P", "-x -p -s spec -S -b -P", "-x -p -s spec -X -b -P"]
llvm_cache_key: ["${{ needs.build_llvm_libraries.outputs.cache_key }}"]
# classic-interp and fast-interp don't support simd
exclude:
# classic-interp, fast-interp and fast-jit don't support simd
- running_mode: "classic-interp"
test_option: "-x -p -s spec -S -b -P"
- running_mode: "fast-interp"
test_option: "-x -p -s spec -S -b -P"
- running_mode: "fast-jit"
test_option: "-x -p -s spec -S -b -P"
# classic-interp, fast-interp and fast jit don't support XIP
- running_mode: "classic-interp"
test_option: "-x -p -s spec -X -b -P"
- running_mode: "fast-interp"
test_option: "-x -p -s spec -X -b -P"
- running_mode: "fast-jit"
test_option: "-x -p -s spec -X -b -P"
steps:
- name: checkout

622
.github/workflows/nightly_run.yml vendored Normal file
View File

@ -0,0 +1,622 @@
# Copyright (C) 2023 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
name: nightly_run
on:
# midnight UTC
schedule:
- cron: "0 0 * * *"
# allow to be triggered manually
workflow_dispatch:
# Cancel any in-flight jobs for the same PR/branch so there's only one active
# at a time
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
# For BUILD
AOT_BUILD_OPTIONS: " -DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_FAST_JIT=0 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_LAZY_JIT=0"
CLASSIC_INTERP_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=0 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_JIT=0 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_LAZY_JIT=0"
FAST_INTERP_BUILD_OPTIONS: " -DWAMR_BUILD_AOT=0 -DWAMR_BUILD_FAST_INTERP=1 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_JIT=0 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_LAZY_JIT=0"
FAST_JIT_BUILD_OPTIONS: " -DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_FAST_JIT=1 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_LAZY_JIT=0"
LLVM_LAZY_JIT_BUILD_OPTIONS: " -DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_FAST_JIT=0 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=1"
LLVM_EAGER_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_FAST_JIT=0 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=0"
MULTI_TIER_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_JIT=1 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=1"
# For Spec Test
DEFAULT_TEST_OPTIONS: "-s spec -b -P"
MULTI_MODULES_TEST_OPTIONS: "-s spec -b -M -P"
SIMD_TEST_OPTIONS: "-s spec -b -S -P"
THREADS_TEST_OPTIONS: "-s spec -b -p -P"
X86_32_TARGET_TEST_OPTIONS: "-m x86_32 -P"
WASI_TEST_OPTIONS: "-s wasi_certification -w"
jobs:
build_llvm_libraries_on_ubuntu_2004:
uses: ./.github/workflows/build_llvm_libraries.yml
with:
os: "ubuntu-20.04"
arch: "X86"
build_llvm_libraries_on_ubuntu_2204:
uses: ./.github/workflows/build_llvm_libraries.yml
with:
os: "ubuntu-22.04"
arch: "X86"
build_wamrc:
needs:
[build_llvm_libraries_on_ubuntu_2004, build_llvm_libraries_on_ubuntu_2204]
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-20.04
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}
- os: ubuntu-22.04
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
steps:
- name: checkout
uses: actions/checkout@v3
# since jobs.id can't contain the dot character
# it is hard to use `format` to assemble the cache key
- name: Get LLVM libraries
id: retrieve_llvm_libs
uses: actions/cache@v3
with:
path: |
./core/deps/llvm/build/bin
./core/deps/llvm/build/include
./core/deps/llvm/build/lib
./core/deps/llvm/build/libexec
./core/deps/llvm/build/share
key: ${{ matrix.llvm_cache_key }}
- name: Quit if cache miss
if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true'
run: echo "::error::can not get prebuilt llvm libraries" && exit 1
- name: Build wamrc
run: |
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
working-directory: wamr-compiler
build_iwasm:
needs:
[build_llvm_libraries_on_ubuntu_2004, build_llvm_libraries_on_ubuntu_2204]
runs-on: ${{ matrix.os }}
strategy:
matrix:
make_options_run_mode: [
# Running mode
$AOT_BUILD_OPTIONS,
$CLASSIC_INTERP_BUILD_OPTIONS,
$FAST_INTERP_BUILD_OPTIONS,
$FAST_JIT_BUILD_OPTIONS,
$LLVM_LAZY_JIT_BUILD_OPTIONS,
$LLVM_EAGER_JIT_BUILD_OPTIONS,
$MULTI_TIER_JIT_BUILD_OPTIONS,
]
make_options_feature: [
# Features
"-DWAMR_BUILD_CUSTOM_NAME_SECTION=1",
"-DWAMR_BUILD_DEBUG_AOT=1",
"-DWAMR_BUILD_DEBUG_INTERP=1",
"-DWAMR_BUILD_DUMP_CALL_STACK=1",
"-DWAMR_BUILD_LIB_PTHREAD=1",
"-DWAMR_BUILD_LIB_WASI_THREADS=1",
"-DWAMR_BUILD_LOAD_CUSTOM_SECTION=1",
"-DWAMR_BUILD_MINI_LOADER=1",
"-DWAMR_BUILD_MEMORY_PROFILING=1",
"-DWAMR_BUILD_MULTI_MODULE=1",
"-DWAMR_BUILD_PERF_PROFILING=1",
"-DWAMR_BUILD_REF_TYPES=1",
"-DWAMR_BUILD_SIMD=1",
"-DWAMR_BUILD_TAIL_CALL=1",
"-DWAMR_DISABLE_HW_BOUND_CHECK=1",
]
os: [ubuntu-20.04, ubuntu-22.04]
platform: [android, linux]
exclude:
# uncompatiable feature and platform
# uncompatiable mode and feature
# MULTI_MODULE only on INTERP mode
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
- make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
- make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
# SIMD only on JIT/AOT mode
- make_options_run_mode: $CLASSIC_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_SIMD=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_SIMD=1"
# DEBUG_INTERP only on CLASSIC INTERP mode
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_INTERP=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_INTERP=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_INTERP=1"
- make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_INTERP=1"
- make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_INTERP=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_INTERP=1"
# DEBUG_AOT only on JIT/AOT mode
- make_options_run_mode: $CLASSIC_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1"
# TODO: DEBUG_AOT on JIT
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1"
- make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1"
- make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1"
# MINI_LOADER only on INTERP mode
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
- make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
- make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
# Fast-JIT and Multi-Tier-JIT mode don't support android(X86-32)
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
platform: android
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
platform: android
# only test andorid on ubuntu latest
- os: ubuntu-20.04
platform: android
include:
- os: ubuntu-20.04
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}
- os: ubuntu-22.04
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
steps:
- name: checkout
uses: actions/checkout@v3
# only download llvm cache when needed
- name: Get LLVM libraries
id: retrieve_llvm_libs
if: endsWith(matrix.make_options_run_mode, '_JIT_BUILD_OPTIONS')
uses: actions/cache@v3
with:
path: |
./core/deps/llvm/build/bin
./core/deps/llvm/build/include
./core/deps/llvm/build/lib
./core/deps/llvm/build/libexec
./core/deps/llvm/build/share
key: ${{ matrix.llvm_cache_key }}
- name: Quit if cache miss
if: endsWith(matrix.make_options_run_mode, '_JIT_BUILD_OPTIONS') && (steps.retrieve_llvm_libs.outputs.cache-hit != 'true')
run: echo "::error::can not get prebuilt llvm libraries" && exit 1
- name: Build iwasm
run: |
mkdir build && cd build
cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }}
cmake --build . --config Release --parallel 4
working-directory: product-mini/platforms/${{ matrix.platform }}
build_iwasm_linux_gcc4_8:
runs-on: ubuntu-latest
container:
image: ubuntu:14.04
strategy:
matrix:
make_options_run_mode: [
# Running mode
$CLASSIC_INTERP_BUILD_OPTIONS,
$FAST_INTERP_BUILD_OPTIONS,
$FAST_JIT_BUILD_OPTIONS,
]
make_options_feature: [
# Features
"-DWAMR_BUILD_CUSTOM_NAME_SECTION=1",
"-DWAMR_BUILD_DEBUG_AOT=1",
"-DWAMR_BUILD_DEBUG_INTERP=1",
"-DWAMR_BUILD_DUMP_CALL_STACK=1",
"-DWAMR_BUILD_LIB_PTHREAD=1",
"-DWAMR_BUILD_LIB_WASI_THREADS=1",
"-DWAMR_BUILD_LOAD_CUSTOM_SECTION=1",
"-DWAMR_BUILD_MINI_LOADER=1",
"-DWAMR_BUILD_MEMORY_PROFILING=1",
"-DWAMR_BUILD_MULTI_MODULE=1",
"-DWAMR_BUILD_PERF_PROFILING=1",
"-DWAMR_BUILD_REF_TYPES=1",
"-DWAMR_BUILD_SIMD=1",
"-DWAMR_BUILD_TAIL_CALL=1",
"-DWAMR_DISABLE_HW_BOUND_CHECK=1",
]
exclude:
# uncompatiable feature and platform
# uncompatiable mode and feature
# MULTI_MODULE only on INTERP mode
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
# SIMD only on JIT/AOT mode
- make_options_run_mode: $CLASSIC_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_SIMD=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_SIMD=1"
# DEBUG_INTERP only on CLASSIC INTERP mode
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_INTERP=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_INTERP=1"
# DEBUG_AOT only on JIT/AOT mode
- make_options_run_mode: $CLASSIC_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1"
# TODO: DEBUG_AOT on JIT
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1"
# MINI_LOADER only on INTERP mode
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
steps:
- name: checkout
uses: actions/checkout@v3
- name: Install dependencies
run: apt update && apt install -y make g++-4.8 gcc-4.8 wget git
- name: Install cmake
run: |
wget https://github.com/Kitware/CMake/releases/download/v3.26.1/cmake-3.26.1-linux-x86_64.tar.gz -O cmake.tar.gz
tar xzf cmake.tar.gz
cp cmake-3.26.1-linux-x86_64/bin/cmake /usr/local/bin
cp -r cmake-3.26.1-linux-x86_64/share/cmake-3.26/ /usr/local/share/
- name: Build iwasm
run: |
mkdir build && cd build
cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }} -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8
cmake --build . --config Release --parallel 4
working-directory: product-mini/platforms/linux
build_samples_wasm_c_api:
needs:
[
build_iwasm,
build_llvm_libraries_on_ubuntu_2004,
build_llvm_libraries_on_ubuntu_2204,
build_wamrc,
]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
sanitizer: ["", "ubsan", "asan"]
make_options: [
# Running mode
$AOT_BUILD_OPTIONS,
$CLASSIC_INTERP_BUILD_OPTIONS,
$FAST_INTERP_BUILD_OPTIONS,
$FAST_JIT_BUILD_OPTIONS,
$LLVM_LAZY_JIT_BUILD_OPTIONS,
$LLVM_EAGER_JIT_BUILD_OPTIONS,
$MULTI_TIER_JIT_BUILD_OPTIONS,
]
os: [ubuntu-20.04, ubuntu-22.04]
wasi_sdk_release:
[
"https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz",
]
wabt_release:
[
"https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz",
]
include:
- os: ubuntu-20.04
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}
- os: ubuntu-22.04
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
exclude:
- make_options: $MULTI_TIER_JIT_BUILD_OPTIONS
sanitizer: asan
steps:
- name: checkout
uses: actions/checkout@v3
- name: Get LLVM libraries
id: retrieve_llvm_libs
if: (!endsWith(matrix.make_options, '_INTERP_BUILD_OPTIONS'))
uses: actions/cache@v3
with:
path: |
./core/deps/llvm/build/bin
./core/deps/llvm/build/include
./core/deps/llvm/build/lib
./core/deps/llvm/build/libexec
./core/deps/llvm/build/share
key: ${{ matrix.llvm_cache_key }}
- name: Quit if cache miss
if: (!endsWith(matrix.make_options, '_INTERP_BUILD_OPTIONS')) && (steps.retrieve_llvm_libs.outputs.cache-hit != 'true')
run: echo "::error::can not get prebuilt llvm libraries" && exit 1
- name: download and install wabt
run: |
cd /opt
sudo wget ${{ matrix.wabt_release }}
sudo tar -xzf wabt-1.0.31-*.tar.gz
sudo mv wabt-1.0.31 wabt
- name: Build wamrc
if: (!endsWith(matrix.make_options, '_INTERP_BUILD_OPTIONS'))
run: |
mkdir build && cd build
cmake -D WAMR_BUILD_SANITIZER="${{matrix.sanitizer}}" ..
cmake --build . --config Release --parallel 4
working-directory: wamr-compiler
- name: Build Sample [wasm-c-api]
run: |
VERBOSE=1
cmake -S . -B build ${{ matrix.make_options }} -D WAMR_BUILD_SANITIZER="${{matrix.sanitizer}}"
cmake --build build --config Release --parallel 4
ctest --test-dir build --output-on-failure
working-directory: samples/wasm-c-api
build_samples_others:
needs: [build_iwasm]
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, ubuntu-22.04]
wasi_sdk_release:
[
"https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz",
]
wabt_release:
[
"https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz",
]
steps:
- name: checkout
uses: actions/checkout@v3
- name: download and install wasi-sdk
run: |
cd /opt
sudo wget ${{ matrix.wasi_sdk_release }}
sudo tar -xzf wasi-sdk-*.tar.gz
sudo mv wasi-sdk-20.0 wasi-sdk
- name: download and install wabt
run: |
cd /opt
sudo wget ${{ matrix.wabt_release }}
sudo tar -xzf wabt-1.0.31-*.tar.gz
sudo mv wabt-1.0.31 wabt
- name: Build Sample [basic]
run: |
cd samples/basic
./build.sh
./run.sh
- name: Build Sample [file]
run: |
cd samples/file
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./src/iwasm -f wasm-app/file.wasm -d .
- name: Build Sample [multi-thread]
run: |
cd samples/multi-thread
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./iwasm wasm-apps/test.wasm
- name: Build Sample [multi-module]
run: |
cd samples/multi-module
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./multi_module
- name: Build Sample [spawn-thread]
run: |
cd samples/spawn-thread
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./spawn_thread
- name: Build Sample [ref-types]
run: |
cd samples/ref-types
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./hello
- name: Build Sample [simple]
run: |
./build.sh -p host-interp
python3 ./sample_test_run.py $(pwd)/out
exit $?
working-directory: ./samples/simple
- name: Build Sample [wasi-threads]
run: |
cd samples/wasi-threads
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./iwasm wasm-apps/no_pthread.wasm
test:
needs:
[
build_iwasm,
build_llvm_libraries_on_ubuntu_2004,
build_llvm_libraries_on_ubuntu_2204,
build_wamrc,
]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04, ubuntu-22.04]
sanitizer: ["", "ubsan", "asan"]
running_mode:
[
"classic-interp",
"fast-interp",
"jit",
"aot",
"fast-jit",
"multi-tier-jit",
]
test_option:
[
$DEFAULT_TEST_OPTIONS,
$MULTI_MODULES_TEST_OPTIONS,
$SIMD_TEST_OPTIONS,
$THREADS_TEST_OPTIONS,
$WASI_TEST_OPTIONS,
]
wasi_sdk_release:
[
"https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz",
]
include:
- os: ubuntu-20.04
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}
ubuntu_version: "20.04"
- os: ubuntu-22.04
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
ubuntu_version: "22.04"
exclude:
# uncompatiable modes and features
- os: ubuntu-20.04
sanitizer: asan
# asan works only for aot now
- running_mode: "classic-interp"
sanitizer: asan
- running_mode: "fast-interp"
sanitizer: asan
- running_mode: "jit"
sanitizer: asan
- running_mode: "fast-jit"
sanitizer: asan
- running_mode: "multi-tier-jit"
sanitizer: asan
# classic-interp and fast-interp don't support simd
- running_mode: "classic-interp"
test_option: $SIMD_TEST_OPTIONS
- running_mode: "fast-interp"
test_option: $SIMD_TEST_OPTIONS
# aot and jit don't support multi module
- running_mode: "aot"
test_option: $MULTI_MODULES_TEST_OPTIONS
- running_mode: "jit"
test_option: $MULTI_MODULES_TEST_OPTIONS
# fast-jit doesn't support multi module, simd
- running_mode: "fast-jit"
test_option: $MULTI_MODULES_TEST_OPTIONS
- running_mode: "fast-jit"
test_option: $SIMD_TEST_OPTIONS
# multi-tier-jit doesn't support multi module, simd
- running_mode: "multi-tier-jit"
test_option: $MULTI_MODULES_TEST_OPTIONS
- running_mode: "multi-tier-jit"
test_option: $SIMD_TEST_OPTIONS
steps:
- name: checkout
uses: actions/checkout@v3
- name: download and install wasi-sdk
if: matrix.test_option == '$WASI_TEST_OPTIONS'
run: |
cd /opt
sudo wget ${{ matrix.wasi_sdk_release }}
sudo tar -xzf wasi-sdk-*.tar.gz
sudo mv wasi-sdk-20.0 wasi-sdk
- name: set env variable(if llvm are used)
if: matrix.running_mode == 'aot' || matrix.running_mode == 'jit' || matrix.running_mode == 'multi-tier-jit'
run: echo "USE_LLVM=true" >> $GITHUB_ENV
- name: set env variable(if x86_32 test needed)
if: >
(matrix.test_option == '$DEFAULT_TEST_OPTIONS' || matrix.test_option == '$THREADS_TEST_OPTIONS'
|| matrix.test_option == '$WASI_TEST_OPTIONS')
&& matrix.running_mode != 'fast-jit' && matrix.running_mode != 'jit' && matrix.running_mode != 'multi-tier-jit'
run: echo "TEST_ON_X86_32=true" >> $GITHUB_ENV
- name: set sanitizer
run: echo "WAMR_BUILD_SANITIZER=${{ matrix.sanitizer }}" >> $GITHUB_ENV
#only download llvm libraries in jit and aot mode
- name: Get LLVM libraries
if: env.USE_LLVM == 'true'
id: retrieve_llvm_libs
uses: actions/cache@v3
with:
path: |
./core/deps/llvm/build/bin
./core/deps/llvm/build/include
./core/deps/llvm/build/lib
./core/deps/llvm/build/libexec
./core/deps/llvm/build/share
key: ${{ matrix.llvm_cache_key }}
- name: Quit if cache miss
if: env.USE_LLVM == 'true' && steps.retrieve_llvm_libs.outputs.cache-hit != 'true'
run: echo "::error::can not get prebuilt llvm libraries" && exit 1
- name: install jq JSON processor
if: matrix.running_mode == 'aot' && matrix.test_option == '$WASI_TEST_OPTIONS'
run: sudo apt-get update && sudo apt install -y jq
- name: Build WASI thread tests
if: matrix.test_option == '$WASI_TEST_OPTIONS'
run: bash build.sh
working-directory: ./core/iwasm/libraries/lib-wasi-threads/test/
- name: build socket api tests
if: matrix.test_option == '$WASI_TEST_OPTIONS'
run: bash build.sh
working-directory: ./core/iwasm/libraries/lib-socket/test/
- name: run tests
timeout-minutes: 10
run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites
#only install x32 support libraries when to run x86_32 cases
- name: install x32 support libraries
if: env.TEST_ON_X86_32 == 'true'
run:
# Add another apt repository as some packages cannot
# be downloaded with the github default repository
sudo curl -sSL https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc &&
sudo apt-add-repository https://packages.microsoft.com/ubuntu/${{ matrix.ubuntu_version }}/prod &&
sudo apt-get update &&
sudo apt install -y g++-multilib lib32gcc-9-dev
- name: run tests x86_32
timeout-minutes: 10
if: env.TEST_ON_X86_32 == 'true'
run: ./test_wamr.sh ${{ env.X86_32_TARGET_TEST_OPTIONS }} ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites

View File

@ -52,7 +52,7 @@ jobs:
- name: Install RISC-V Compilers
if: contains(matrix.nuttx_board_config, 'risc-v')
run: |
curl -L https://static.dev.sifive.com/dev-tools/freedom-tools/v2020.12/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz > riscv.tar.gz
curl -L -k https://static.dev.sifive.com/dev-tools/freedom-tools/v2020.12/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz > riscv.tar.gz
tar xvf riscv.tar.gz
echo "$PWD/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin" >> $GITHUB_PATH

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
.cache
.clangd
.vs
.vscode
.venv

View File

@ -16,6 +16,7 @@ WAMR project reused some components from other open source project:
- **asmjit**: for the Fast JIT x86-64 codegen implementation
- **zydis**: for the Fast JIT x86-64 codegen implementation
- **NuttX ELF headers**: used in core/iwasm/aot/debug/elf_parser.c
- **Dhrystone**: for the test benchmakr dhrystone
The WAMR fast interpreter is a clean room development. We would acknowledge the inspirations by [WASM3](https://github.com/wasm3/wasm3) open source project for the approach of pre-calculated oprand stack location.
@ -35,6 +36,7 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
| asmjit | unspecified | unspecified | https://github.com/asmjit/asmjit | |
| zydis | unspecified | e14a07895136182a5b53e181eec3b1c6e0b434de | https://github.com/zyantific/zydis | |
| NuttX ELF headers | 72313301e23f9c2de969fb64b9a0f67bb4c284df | 10.3.0 | https://github.com/apache/incubator-nuttx | |
| Dhrystone | 2.1 | 2.1 | https://fossies.org/linux/privat/old/ | |
## Licenses
@ -81,15 +83,19 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
[LICENSE](./tests/wamr-test-suites/spec-test-script/LICENSE)
### libuv
[LICENSE](./core/iwasm/libraries/libc-uvwasi/LICENSE_LIBUV)
### uvwasi
[LICENSE](./core/iwasm/libraries/libc-uvwasi/LICENSE_UVWASI)
### asmjit
[LICENSE](./core/iwasm/fast-jit/cg/LICENSE_ASMJIT)
### zydis
[LICENSE](./core/iwasm/fast-jit/cg/LICENSE_ZYDIS)
### NuttX ELF headers
@ -97,3 +103,7 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
[LICENSE](./core/iwasm/aot/debug/LICENSE_NUTTX)
[NOTICE](./core/iwasm/aot/debug/NOTICE_NUTTX)
### Dhrystone
[LICENSE](./tests/benchmarks/dhrystone/LICENSE)

View File

@ -77,6 +77,7 @@ The following platforms are supported, click each link below for how to build iw
- [Blog: Introduction to WAMR running modes](https://bytecodealliance.github.io/wamr.dev/blog/introduction-to-wamr-running-modes/)
- [Memory usage tunning](./doc/memory_tune.md): the memory model and how to tune the memory usage
- [Memory usage profiling](./doc/build_wamr.md#enable-memory-profiling-experiment): how to profile the memory usage
- [Performance tunning](./doc/perf_tune.md): how to tune the performance
- [Benchmarks](./tests/benchmarks): checkout these links for how to run the benchmarks: [PolyBench](./tests/benchmarks/polybench), [CoreMark](./tests/benchmarks/coremark), [Sightglass](./tests/benchmarks/sightglass), [JetStream2](./tests/benchmarks/jetstream)
- [Performance and footprint data](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/Performance): the performance and footprint data

View File

@ -1,3 +1,42 @@
## WAMR-1.2.2
### Breaking Changes
### New Features
- Implement Fast JIT multi-threading feature (#2134)
### Bug Fixes
- Update request.ts wasm_response_send signature (#2122)
- Fix ems allocator unaligned memory access on riscv64 (#2140)
- libc_wasi_wrapper.c: Fix min func issue for size_t < 8 bytes on some platforms (#2152)
- Fix three multi-threading and wasm-c-api-imports issues (#2173)
- Fix build polybench benchmark error with wasi-sdk-19.0 (#2187)
- Fix wamr-ide debugger ignoring launch config (#2155)
### Enhancements
- Add test for validating linear memory size updates (#2078)
- Update Zephyr docs to remove unsupported west subcommand (#2128)
- Update messages/comments to refer the new place of the version definition (#2133)
- build_wamr_lldb.yml: sync lldb build options between ubuntu and macos (#2132)
- build_wamr_vscode_ext.yml: vsce publish only on the official repo (#2130)
- VSCode-Extension: Download lldb built for ubuntu 20.04 (#2139)
- Avoid re-installing if Tensorflow is already installed for WASI-NN (#2148)
- wamrc: Add --stack-usage option (#2158)
- Fix URL in language-bindings/python/README.md (#2166)
- Fix URL in embed_wamr.md (#2165)
- Fix URL in README.md (#2168)
- Return error when exception was raised after main thread finishes (#2169)
- wasi-nn: Add external delegation to support several NPU/GPU (#2162)
- Update document for iwasm/wamrc dependent packages (#2183)
- Use a manual flag to disable clock_nanosleep on the unsupported platforms (#2176)
- Fix compile warnings on windows platform (#2208)
### Others
- CI: Add ubsan checks to samples/wasm-c-api (#2147)
- CI: More precise trigger paths for github actions (#2157)
---
## WAMR-1.2.1
### Breaking Changes

View File

@ -61,7 +61,7 @@ def build_llvm(llvm_dir, platform, backends, projects, use_clang=False, extra_fl
"-DLLVM_ENABLE_IDE:BOOL=OFF",
"-DLLVM_ENABLE_LIBEDIT=OFF",
"-DLLVM_ENABLE_TERMINFO:BOOL=OFF",
"-DLLVM_ENABLE_ZLIB:BOOL=OFF",
"-DLLVM_ENABLE_ZLIB:BOOL=ON",
"-DLLVM_INCLUDE_BENCHMARKS:BOOL=OFF",
"-DLLVM_INCLUDE_DOCS:BOOL=OFF",
"-DLLVM_INCLUDE_EXAMPLES:BOOL=OFF",

View File

@ -127,6 +127,28 @@ else ()
unset (LLVM_AVAILABLE_LIBS)
endif ()
# Sanitizers
set(WAMR_BUILD_SANITIZER $ENV{WAMR_BUILD_SANITIZER})
if (NOT DEFINED WAMR_BUILD_SANITIZER)
set(WAMR_BUILD_SANITIZER "")
elseif (WAMR_BUILD_SANITIZER STREQUAL "ubsan")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all -fno-sanitize=alignment" )
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined")
elseif (WAMR_BUILD_SANITIZER STREQUAL "asan")
if (NOT WAMR_BUILD_JIT EQUAL 1)
set (ASAN_OPTIONS "verbosity=2 debug=true ")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fno-omit-frame-pointer -fsanitize=address -fno-sanitize-recover=all" )
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
endif()
elseif (WAMR_BUILD_SANITIZER STREQUAL "tsan")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fno-omit-frame-pointer -fsanitize=thread -fno-sanitize-recover=all" )
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
elseif (NOT (WAMR_BUILD_SANITIZER STREQUAL "") )
message(SEND_ERROR "Unsupported sanitizer: ${WAMR_BUILD_SANITIZER}")
endif()
########################################
message ("-- Build Configurations:")
@ -370,3 +392,11 @@ if ("$ENV{COLLECT_CODE_COVERAGE}" STREQUAL "1" OR COLLECT_CODE_COVERAGE EQUAL 1)
add_definitions (-DCOLLECT_CODE_COVERAGE)
message (" Collect code coverage enabled")
endif ()
if (WAMR_BUILD_STATIC_PGO EQUAL 1)
add_definitions (-DWASM_ENABLE_STATIC_PGO=1)
message (" AOT static PGO enabled")
endif ()
if (WAMR_DISABLE_WRITE_GS_BASE EQUAL 1)
add_definitions (-DWASM_DISABLE_WRITE_GS_BASE=1)
message (" Write linear memory base addr to x86 GS register disabled")
endif ()

View File

@ -1 +1 @@
requests==2.28.2
requests==2.31.0

View File

@ -449,4 +449,15 @@
#define WASM_ENABLE_WASM_CACHE 0
#endif
#ifndef WASM_ENABLE_STATIC_PGO
#define WASM_ENABLE_STATIC_PGO 0
#endif
/* Disable writing linear memory base address to GS segment register,
by default only in linux x86-64, linear memory base addr is written
to GS segment register before calling wasm/aot function. */
#ifndef WASM_DISABLE_WRITE_GS_BASE
#define WASM_DISABLE_WRITE_GS_BASE 0
#endif
#endif /* end of _CONFIG_H_ */

View File

@ -1430,8 +1430,28 @@ destroy_object_data_sections(AOTObjectDataSection *data_sections,
uint32 i;
AOTObjectDataSection *data_section = data_sections;
for (i = 0; i < data_section_count; i++, data_section++)
if (data_section->data)
if (data_section->data) {
#if WASM_ENABLE_STATIC_PGO != 0
if (!strncmp(data_section->name, "__llvm_prf_data", 15)) {
LLVMProfileData *data = (LLVMProfileData *)data_section->data;
if (data->values) {
uint32 num_value_sites =
data->num_value_sites[0] + data->num_value_sites[1];
uint32 j;
for (j = 0; j < num_value_sites; j++) {
ValueProfNode *node = data->values[j], *node_next;
while (node) {
node_next = node->next;
wasm_runtime_free(node);
node = node_next;
}
}
wasm_runtime_free(data->values);
}
}
#endif
os_munmap(data_section->data, data_section->size);
}
wasm_runtime_free(data_sections);
}
@ -1900,6 +1920,8 @@ str2uint64(const char *buf, uint64 *p_res)
return true;
}
#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative offset to GOT */
static bool
do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
char *error_buf, uint32 error_buf_size)
@ -1937,6 +1959,14 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
bh_memcpy_s(symbol, symbol_len, relocation->symbol_name, symbol_len);
symbol[symbol_len] = '\0';
#if WASM_ENABLE_STATIC_PGO != 0
if (!strcmp(symbol, "__llvm_profile_runtime")
|| !strcmp(symbol, "__llvm_profile_register_function")
|| !strcmp(symbol, "__llvm_profile_register_names_function")) {
continue;
}
#endif
if (!strncmp(symbol, AOT_FUNC_PREFIX, strlen(AOT_FUNC_PREFIX))) {
p = symbol + strlen(AOT_FUNC_PREFIX);
if (*p == '\0'
@ -1945,7 +1975,26 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
"invalid import symbol %s", symbol);
goto check_symbol_fail;
}
#if (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) \
&& !defined(BH_PLATFORM_WINDOWS)
if (relocation->relocation_type == R_X86_64_GOTPCREL) {
GOTItem *got_item = module->got_item_list;
uint32 got_item_idx = 0;
while (got_item) {
if (got_item->func_idx == func_index)
break;
got_item_idx++;
got_item = got_item->next;
}
/* Calculate `GOT + G` */
symbol_addr = module->got_func_ptrs + got_item_idx;
}
else
symbol_addr = module->func_ptrs[func_index];
#else
symbol_addr = module->func_ptrs[func_index];
#endif
}
else if (!strcmp(symbol, ".text")) {
symbol_addr = module->code;
@ -1956,7 +2005,13 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
/* ".rodata.cst4/8/16/.." */
|| !strncmp(symbol, ".rodata.cst", strlen(".rodata.cst"))
/* ".rodata.strn.m" */
|| !strncmp(symbol, ".rodata.str", strlen(".rodata.str"))) {
|| !strncmp(symbol, ".rodata.str", strlen(".rodata.str"))
#if WASM_ENABLE_STATIC_PGO != 0
|| !strncmp(symbol, "__llvm_prf_cnts", 15)
|| !strncmp(symbol, "__llvm_prf_data", 15)
|| !strncmp(symbol, "__llvm_prf_names", 16)
#endif
) {
symbol_addr = get_data_section_addr(module, symbol, NULL);
if (!symbol_addr) {
set_error_buf_v(error_buf, error_buf_size,
@ -2088,6 +2143,14 @@ do_data_relocation(AOTModule *module, AOTRelocationGroup *group,
else if (!strcmp(group->section_name, ".rdata")) {
data_section_name = group->section_name;
}
#if WASM_ENABLE_STATIC_PGO != 0
else if (!strncmp(group->section_name, ".rel__llvm_prf_data", 19)) {
data_section_name = group->section_name + strlen(".rel");
}
else if (!strncmp(group->section_name, ".rela__llvm_prf_data", 20)) {
data_section_name = group->section_name + strlen(".rela");
}
#endif
else {
set_error_buf(error_buf, error_buf_size,
"invalid data relocation section name");
@ -2107,6 +2170,49 @@ do_data_relocation(AOTModule *module, AOTRelocationGroup *group,
if (!strcmp(symbol, ".text")) {
symbol_addr = module->code;
}
#if WASM_ENABLE_STATIC_PGO != 0
else if (!strncmp(symbol, AOT_FUNC_PREFIX, strlen(AOT_FUNC_PREFIX))) {
char *p = symbol + strlen(AOT_FUNC_PREFIX);
uint32 func_index;
if (*p == '\0'
|| (func_index = (uint32)atoi(p)) > module->func_count) {
set_error_buf_v(error_buf, error_buf_size,
"invalid relocation symbol %s", symbol);
return false;
}
symbol_addr = module->func_ptrs[func_index];
}
else if (!strcmp(symbol, "__llvm_prf_cnts")) {
uint32 j;
for (j = 0; j < module->data_section_count; j++) {
if (!strncmp(module->data_sections[j].name, symbol, 15)) {
bh_assert(relocation->relocation_addend + sizeof(uint64)
<= module->data_sections[j].size);
symbol_addr = module->data_sections[j].data;
break;
}
}
if (j == module->data_section_count) {
set_error_buf_v(error_buf, error_buf_size,
"invalid relocation symbol %s", symbol);
return false;
}
}
else if (!strncmp(symbol, "__llvm_prf_cnts", 15)) {
uint32 j;
for (j = 0; j < module->data_section_count; j++) {
if (!strcmp(module->data_sections[j].name, symbol)) {
symbol_addr = module->data_sections[j].data;
break;
}
}
if (j == module->data_section_count) {
set_error_buf_v(error_buf, error_buf_size,
"invalid relocation symbol %s", symbol);
return false;
}
}
#endif /* end of WASM_ENABLE_STATIC_PGO != 0 */
else {
set_error_buf_v(error_buf, error_buf_size,
"invalid relocation symbol %s", symbol);
@ -2154,7 +2260,7 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
{
AOTRelocationGroup *groups = NULL, *group;
uint32 symbol_count = 0;
uint32 group_count = 0, i, j;
uint32 group_count = 0, i, j, got_item_count = 0;
uint64 size;
uint32 *symbol_offsets, total_string_len;
uint8 *symbol_buf, *symbol_buf_end;
@ -2216,6 +2322,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
for (j = 0; j < relocation_count; j++) {
AOTRelocation relocation = { 0 };
char group_name_buf[128] = { 0 };
char symbol_name_buf[128] = { 0 };
uint32 symbol_index, offset32;
int32 addend32;
uint16 symbol_name_len;
@ -2244,10 +2352,10 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
symbol_name_len = *(uint16 *)symbol_name;
symbol_name += sizeof(uint16);
char group_name_buf[128] = { 0 };
char symbol_name_buf[128] = { 0 };
memcpy(group_name_buf, group_name, group_name_len);
memcpy(symbol_name_buf, symbol_name, symbol_name_len);
bh_memcpy_s(group_name_buf, (uint32)sizeof(group_name_buf),
group_name, group_name_len);
bh_memcpy_s(symbol_name_buf, (uint32)sizeof(symbol_name_buf),
symbol_name, symbol_name_len);
if ((group_name_len == strlen(".text")
|| (module->is_indirect_mode
@ -2309,6 +2417,139 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
}
#endif /* end of defined(BH_PLATFORM_WINDOWS) */
#if (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) \
&& !defined(BH_PLATFORM_WINDOWS)
buf = symbol_buf_end;
read_uint32(buf, buf_end, group_count);
/* Resolve the relocations of type R_X86_64_GOTPCREL */
for (i = 0; i < group_count; i++) {
uint32 name_index, relocation_count;
uint16 group_name_len;
uint8 *group_name;
/* section name address is 4 bytes aligned. */
buf = (uint8 *)align_ptr(buf, sizeof(uint32));
read_uint32(buf, buf_end, name_index);
if (name_index >= symbol_count) {
set_error_buf(error_buf, error_buf_size,
"symbol index out of range");
goto fail;
}
group_name = symbol_buf + symbol_offsets[name_index];
group_name_len = *(uint16 *)group_name;
group_name += sizeof(uint16);
read_uint32(buf, buf_end, relocation_count);
for (j = 0; j < relocation_count; j++) {
AOTRelocation relocation = { 0 };
char group_name_buf[128] = { 0 };
char symbol_name_buf[128] = { 0 };
uint32 symbol_index;
uint16 symbol_name_len;
uint8 *symbol_name;
/* relocation offset and addend */
buf += sizeof(void *) * 2;
read_uint32(buf, buf_end, relocation.relocation_type);
read_uint32(buf, buf_end, symbol_index);
if (symbol_index >= symbol_count) {
set_error_buf(error_buf, error_buf_size,
"symbol index out of range");
goto fail;
}
symbol_name = symbol_buf + symbol_offsets[symbol_index];
symbol_name_len = *(uint16 *)symbol_name;
symbol_name += sizeof(uint16);
bh_memcpy_s(group_name_buf, (uint32)sizeof(group_name_buf),
group_name, group_name_len);
bh_memcpy_s(symbol_name_buf, (uint32)sizeof(symbol_name_buf),
symbol_name, symbol_name_len);
if (relocation.relocation_type == R_X86_64_GOTPCREL
&& !strncmp(symbol_name_buf, AOT_FUNC_PREFIX,
strlen(AOT_FUNC_PREFIX))) {
uint32 func_idx =
atoi(symbol_name_buf + strlen(AOT_FUNC_PREFIX));
GOTItem *got_item = module->got_item_list;
if (func_idx >= module->func_count) {
set_error_buf(error_buf, error_buf_size,
"func index out of range");
goto fail;
}
while (got_item) {
if (got_item->func_idx == func_idx)
break;
got_item = got_item->next;
}
if (!got_item) {
/* Create the got item and append to the list */
got_item = wasm_runtime_malloc(sizeof(GOTItem));
if (!got_item) {
set_error_buf(error_buf, error_buf_size,
"allocate memory failed");
goto fail;
}
got_item->func_idx = func_idx;
got_item->next = NULL;
if (!module->got_item_list) {
module->got_item_list = module->got_item_list_end =
got_item;
}
else {
module->got_item_list_end->next = got_item;
module->got_item_list_end = got_item;
}
got_item_count++;
}
}
}
}
if (got_item_count) {
GOTItem *got_item = module->got_item_list;
uint32 got_item_idx = 0;
map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE;
/* aot code and data in x86_64 must be in range 0 to 2G due to
relocation for R_X86_64_32/32S/PC32 */
map_flags = MMAP_MAP_32BIT;
/* Create the GOT for func_ptrs, note that it is different from
the .got section of a dynamic object file */
size = (uint64)sizeof(void *) * got_item_count;
if (size > UINT32_MAX
|| !(module->got_func_ptrs =
os_mmap(NULL, (uint32)size, map_prot, map_flags))) {
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
goto fail;
}
while (got_item) {
module->got_func_ptrs[got_item_idx++] =
module->func_ptrs[got_item->func_idx];
got_item = got_item->next;
}
module->got_item_count = got_item_count;
}
#else
(void)got_item_count;
#endif /* (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) && \
!defined(BH_PLATFORM_WINDOWS) */
buf = symbol_buf_end;
read_uint32(buf, buf_end, group_count);
@ -2889,6 +3130,16 @@ load(const uint8 *buf, uint32 size, AOTModule *module, char *error_buf,
module->code and will be destroyed in aot_unload() */
destroy_sections(section_list, false);
}
#if 0
{
uint32 i;
for (i = 0; i < module->func_count; i++) {
os_printf("AOT func %u, addr: %p\n", i, module->func_ptrs[i]);
}
}
#endif
return ret;
fail:
return false;
@ -2984,9 +3235,27 @@ aot_unload(AOTModule *module)
}
#endif
#if (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) \
&& !defined(BH_PLATFORM_WINDOWS)
{
GOTItem *got_item = module->got_item_list, *got_item_next;
if (module->got_func_ptrs) {
os_munmap(module->got_func_ptrs,
sizeof(void *) * module->got_item_count);
}
while (got_item) {
got_item_next = got_item->next;
wasm_runtime_free(got_item);
got_item = got_item_next;
}
}
#endif
if (module->data_sections)
destroy_object_data_sections(module->data_sections,
module->data_section_count);
#if WASM_ENABLE_DEBUG_AOT != 0
jit_code_entry_destroy(module->elf_hdr);
#endif
@ -3033,3 +3302,23 @@ aot_get_custom_section(const AOTModule *module, const char *name, uint32 *len)
return NULL;
}
#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION */
#if WASM_ENABLE_STATIC_PGO != 0
void
aot_exchange_uint16(uint8 *p_data)
{
return exchange_uint16(p_data);
}
void
aot_exchange_uint32(uint8 *p_data)
{
return exchange_uint32(p_data);
}
void
aot_exchange_uint64(uint8 *p_data)
{
return exchange_uint64(p_data);
}
#endif

View File

@ -121,6 +121,14 @@ typedef struct {
REG_SYM(aot_intrinsic_i32_rem_s), \
REG_SYM(aot_intrinsic_i32_rem_u), \
#if WASM_ENABLE_STATIC_PGO != 0
#define REG_LLVM_PGO_SYM() \
{ "__llvm_profile_instrument_target", llvm_profile_instrument_target }, \
{ "__llvm_profile_instrument_memop", llvm_profile_instrument_memop },
#else
#define REG_LLVM_PGO_SYM()
#endif
#define REG_COMMON_SYMBOLS \
REG_SYM(aot_set_exception_with_id), \
REG_SYM(aot_invoke_native), \
@ -150,6 +158,7 @@ typedef struct {
REG_REF_TYPES_SYM() \
REG_AOT_TRACE_SYM() \
REG_INTRINSIC_SYM() \
REG_LLVM_PGO_SYM() \
#define CHECK_RELOC_OFFSET(data_size) do { \
if (!check_reloc_offset(target_section_size, \

View File

@ -1015,6 +1015,15 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst,
}
}
#if defined(os_writegsbase)
{
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
if (memory_inst)
/* write base addr of linear memory to GS segment register */
os_writegsbase(memory_inst->memory_data);
}
#endif
/* Execute start function for both main insance and sub instance */
if (module->start_function) {
AOTFunctionInstance start_func = { 0 };
@ -1453,6 +1462,15 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
}
argc = func_type->param_cell_num;
#if defined(os_writegsbase)
{
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
if (memory_inst)
/* write base addr of linear memory to GS segment register */
os_writegsbase(memory_inst->memory_data);
}
#endif
/* func pointer was looked up previously */
bh_assert(function->u.func.func_ptr != NULL);
@ -2779,12 +2797,14 @@ aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len)
/* function name not exported, print number instead */
if (frame.func_name_wp == NULL) {
line_length = snprintf(line_buf, sizeof(line_buf), "#%02d $f%d\n",
n, frame.func_index);
line_length =
snprintf(line_buf, sizeof(line_buf),
"#%02" PRIu32 " $f%" PRIu32 "\n", n, frame.func_index);
}
else {
line_length = snprintf(line_buf, sizeof(line_buf), "#%02d %s\n", n,
frame.func_name_wp);
line_length =
snprintf(line_buf, sizeof(line_buf), "#%02" PRIu32 " %s\n", n,
frame.func_name_wp);
}
if (line_length >= sizeof(line_buf)) {
@ -2834,3 +2854,520 @@ aot_dump_perf_profiling(const AOTModuleInstance *module_inst)
}
}
#endif /* end of WASM_ENABLE_PERF_PROFILING */
#if WASM_ENABLE_STATIC_PGO != 0
/* indirect call target */
#define IPVK_IndirectCallTarget 0
/* memory intrinsic functions size */
#define IPVK_MemOPSize 1
#define IPVK_First IPVK_IndirectCallTarget
#define IPVK_Last IPVK_MemOPSize
#define INSTR_PROF_DEFAULT_NUM_VAL_PER_SITE 24
#define INSTR_PROF_MAX_NUM_VAL_PER_SITE 255
static int hasNonDefaultValsPerSite = 0;
static uint32 VPMaxNumValsPerSite = INSTR_PROF_DEFAULT_NUM_VAL_PER_SITE;
static bool
cmpxchg_ptr(void **ptr, void *old_val, void *new_val)
{
#if defined(os_atomic_cmpxchg)
return os_atomic_cmpxchg(ptr, &old_val, new_val);
#else
/* TODO: add lock when thread-manager is enabled */
void *read = *ptr;
if (read == old_val) {
*ptr = new_val;
return true;
}
return false;
#endif
}
static int
allocateValueProfileCounters(LLVMProfileData *Data)
{
ValueProfNode **Mem;
uint64 NumVSites = 0, total_size;
uint32 VKI;
/* When dynamic allocation is enabled, allow tracking the max number of
values allowed. */
if (!hasNonDefaultValsPerSite)
VPMaxNumValsPerSite = INSTR_PROF_MAX_NUM_VAL_PER_SITE;
for (VKI = IPVK_First; VKI <= IPVK_Last; ++VKI)
NumVSites += Data->num_value_sites[VKI];
/* If NumVSites = 0, calloc is allowed to return a non-null pointer. */
bh_assert(NumVSites > 0 && "NumVSites can't be zero");
total_size = (uint64)sizeof(ValueProfNode *) * NumVSites;
if (total_size > UINT32_MAX
|| !(Mem = (ValueProfNode **)wasm_runtime_malloc((uint32)total_size))) {
return 0;
}
memset(Mem, 0, (uint32)total_size);
if (!cmpxchg_ptr((void **)&Data->values, NULL, Mem)) {
wasm_runtime_free(Mem);
return 0;
}
return 1;
}
static ValueProfNode *
allocateOneNode(void)
{
ValueProfNode *Node;
Node = wasm_runtime_malloc((uint32)sizeof(ValueProfNode));
if (Node)
memset(Node, 0, sizeof(ValueProfNode));
return Node;
}
static void
instrumentTargetValueImpl(uint64 TargetValue, void *Data, uint32 CounterIndex,
uint64 CountValue)
{
ValueProfNode **ValueCounters;
ValueProfNode *PrevVNode = NULL, *MinCountVNode = NULL, *CurVNode;
LLVMProfileData *PData = (LLVMProfileData *)Data;
uint64 MinCount = UINT64_MAX;
uint8 VDataCount = 0;
bool success = false;
if (!PData)
return;
if (!CountValue)
return;
if (!PData->values) {
if (!allocateValueProfileCounters(PData))
return;
}
ValueCounters = (ValueProfNode **)PData->values;
CurVNode = ValueCounters[CounterIndex];
while (CurVNode) {
if (TargetValue == CurVNode->value) {
CurVNode->count += CountValue;
return;
}
if (CurVNode->count < MinCount) {
MinCount = CurVNode->count;
MinCountVNode = CurVNode;
}
PrevVNode = CurVNode;
CurVNode = CurVNode->next;
++VDataCount;
}
if (VDataCount >= VPMaxNumValsPerSite) {
if (MinCountVNode->count <= CountValue) {
CurVNode = MinCountVNode;
CurVNode->value = TargetValue;
CurVNode->count = CountValue;
}
else
MinCountVNode->count -= CountValue;
return;
}
CurVNode = allocateOneNode();
if (!CurVNode)
return;
CurVNode->value = TargetValue;
CurVNode->count += CountValue;
if (!ValueCounters[CounterIndex]) {
success =
cmpxchg_ptr((void **)&ValueCounters[CounterIndex], NULL, CurVNode);
}
else if (PrevVNode && !PrevVNode->next) {
success = cmpxchg_ptr((void **)&PrevVNode->next, 0, CurVNode);
}
if (!success) {
wasm_runtime_free(CurVNode);
}
}
void
llvm_profile_instrument_target(uint64 target_value, void *data,
uint32 counter_idx)
{
instrumentTargetValueImpl(target_value, data, counter_idx, 1);
}
static inline uint32
popcount64(uint64 u)
{
uint32 ret = 0;
while (u) {
u = (u & (u - 1));
ret++;
}
return ret;
}
static inline uint32
clz64(uint64 type)
{
uint32 num = 0;
if (type == 0)
return 64;
while (!(type & 0x8000000000000000LL)) {
num++;
type <<= 1;
}
return num;
}
/* Map an (observed) memop size value to the representative value of its range.
For example, 5 -> 5, 22 -> 17, 99 -> 65, 256 -> 256, 1001 -> 513. */
static uint64
InstrProfGetRangeRepValue(uint64 Value)
{
if (Value <= 8)
/* The first ranges are individually tracked. Use the value as is. */
return Value;
else if (Value >= 513)
/* The last range is mapped to its lowest value. */
return 513;
else if (popcount64(Value) == 1)
/* If it's a power of two, use it as is. */
return Value;
else
/* Otherwise, take to the previous power of two + 1. */
return (((uint64)1) << (64 - clz64(Value) - 1)) + 1;
}
void
llvm_profile_instrument_memop(uint64 target_value, void *data,
uint32 counter_idx)
{
uint64 rep_value = InstrProfGetRangeRepValue(target_value);
instrumentTargetValueImpl(rep_value, data, counter_idx, 1);
}
static uint32
get_pgo_prof_data_size(AOTModuleInstance *module_inst, uint32 *p_num_prof_data,
uint32 *p_num_prof_counters, uint32 *p_padding_size,
uint32 *p_prof_counters_size, uint32 *p_prof_names_size,
uint32 *p_value_counters_size, uint8 **p_prof_names)
{
AOTModule *module = (AOTModule *)module_inst->module;
LLVMProfileData *prof_data;
uint8 *prof_names = NULL;
uint32 num_prof_data = 0, num_prof_counters = 0, padding_size, i;
uint32 prof_counters_size = 0, prof_names_size = 0;
uint32 total_size, total_size_wo_value_counters;
for (i = 0; i < module->data_section_count; i++) {
if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
bh_assert(module->data_sections[i].size == sizeof(LLVMProfileData));
num_prof_data++;
prof_data = (LLVMProfileData *)module->data_sections[i].data;
num_prof_counters += prof_data->num_counters;
}
else if (!strncmp(module->data_sections[i].name, "__llvm_prf_cnts",
15)) {
prof_counters_size += module->data_sections[i].size;
}
else if (!strncmp(module->data_sections[i].name, "__llvm_prf_names",
16)) {
prof_names_size = module->data_sections[i].size;
prof_names = module->data_sections[i].data;
}
}
if (prof_counters_size != num_prof_counters * sizeof(uint64))
return 0;
total_size = sizeof(LLVMProfileRawHeader)
+ num_prof_data * sizeof(LLVMProfileData_64)
+ prof_counters_size + prof_names_size;
padding_size = sizeof(uint64) - (prof_names_size % sizeof(uint64));
if (padding_size != sizeof(uint64))
total_size += padding_size;
/* Total size excluding value counters */
total_size_wo_value_counters = total_size;
for (i = 0; i < module->data_section_count; i++) {
if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
uint32 j, k, num_value_sites, num_value_nodes;
ValueProfNode **values, *value_node;
prof_data = (LLVMProfileData *)module->data_sections[i].data;
values = prof_data->values;
if (prof_data->num_value_sites[0] > 0
|| prof_data->num_value_sites[1] > 0) {
/* TotalSize (uint32) and NumValueKinds (uint32) */
total_size += 8;
for (j = 0; j < 2; j++) {
if ((num_value_sites = prof_data->num_value_sites[j]) > 0) {
/* ValueKind (uint32) and NumValueSites (uint32) */
total_size += 8;
/* (Value + Counter) group counts of each value site,
each count is one byte */
total_size += align_uint(num_value_sites, 8);
if (values) {
for (k = 0; k < num_value_sites; k++) {
num_value_nodes = 0;
value_node = *values;
while (value_node) {
num_value_nodes++;
value_node = value_node->next;
}
if (num_value_nodes) {
/* (Value + Counter) groups */
total_size += num_value_nodes * 8 * 2;
}
values++;
}
}
}
}
}
}
}
if (p_num_prof_data)
*p_num_prof_data = num_prof_data;
if (p_num_prof_counters)
*p_num_prof_counters = num_prof_counters;
if (p_padding_size)
*p_padding_size = padding_size;
if (p_prof_counters_size)
*p_prof_counters_size = prof_counters_size;
if (p_prof_names_size)
*p_prof_names_size = prof_names_size;
if (p_value_counters_size)
*p_value_counters_size = total_size - total_size_wo_value_counters;
if (p_prof_names)
*p_prof_names = prof_names;
return total_size;
}
uint32
aot_get_pgo_prof_data_size(AOTModuleInstance *module_inst)
{
return get_pgo_prof_data_size(module_inst, NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
}
static union {
int a;
char b;
} __ue = { .a = 1 };
#define is_little_endian() (__ue.b == 1)
uint32
aot_dump_pgo_prof_data_to_buf(AOTModuleInstance *module_inst, char *buf,
uint32 len)
{
AOTModule *module = (AOTModule *)module_inst->module;
LLVMProfileRawHeader prof_header = { 0 };
LLVMProfileData *prof_data;
uint8 *prof_names = NULL;
uint32 num_prof_data = 0, num_prof_counters = 0, padding_size, i;
uint32 prof_counters_size = 0, prof_names_size = 0;
uint32 value_counters_size = 0, value_counters_size_backup = 0;
uint32 total_size, size;
int64 counters_delta, offset_counters;
total_size = get_pgo_prof_data_size(module_inst, &num_prof_data,
&num_prof_counters, &padding_size,
&prof_counters_size, &prof_names_size,
&value_counters_size, &prof_names);
if (len < total_size)
return 0;
value_counters_size_backup = value_counters_size;
value_counters_size = 0;
prof_header.counters_delta = counters_delta =
sizeof(LLVMProfileData_64) * num_prof_data;
offset_counters = 0;
for (i = 0; i < module->data_section_count; i++) {
if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
prof_data = (LLVMProfileData *)module->data_sections[i].data;
prof_data->offset_counters = counters_delta + offset_counters;
offset_counters += prof_data->num_counters * sizeof(uint64);
counters_delta -= sizeof(LLVMProfileData_64);
}
}
prof_header.magic = 0xFF6C70726F667281LL;
/* Version 8 */
prof_header.version = 0x0000000000000008LL;
/* with VARIANT_MASK_IR_PROF (IR Instrumentation) */
prof_header.version |= 0x1ULL << 56;
/* with VARIANT_MASK_MEMPROF (Memory Profile) */
prof_header.version |= 0x1ULL << 62;
prof_header.num_prof_data = num_prof_data;
prof_header.num_prof_counters = num_prof_counters;
prof_header.names_size = prof_names_size;
prof_header.value_kind_last = 1;
if (!is_little_endian()) {
aot_exchange_uint64((uint8 *)&prof_header.magic);
aot_exchange_uint64((uint8 *)&prof_header.version);
aot_exchange_uint64((uint8 *)&prof_header.num_prof_data);
aot_exchange_uint64((uint8 *)&prof_header.num_prof_counters);
aot_exchange_uint64((uint8 *)&prof_header.names_size);
aot_exchange_uint64((uint8 *)&prof_header.counters_delta);
aot_exchange_uint64((uint8 *)&prof_header.value_kind_last);
}
size = sizeof(LLVMProfileRawHeader);
bh_memcpy_s(buf, size, &prof_header, size);
buf += size;
for (i = 0; i < module->data_section_count; i++) {
if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
LLVMProfileData_64 *prof_data_64 = (LLVMProfileData_64 *)buf;
/* Convert LLVMProfileData to LLVMProfileData_64, the pointer width
in the output file is alawys 8 bytes */
prof_data = (LLVMProfileData *)module->data_sections[i].data;
prof_data_64->func_md5 = prof_data->func_md5;
prof_data_64->func_hash = prof_data->func_hash;
prof_data_64->offset_counters = prof_data->offset_counters;
prof_data_64->func_ptr = prof_data->func_ptr;
prof_data_64->values = (uint64)(uintptr_t)prof_data->values;
prof_data_64->num_counters = prof_data->num_counters;
prof_data_64->num_value_sites[0] = prof_data->num_value_sites[0];
prof_data_64->num_value_sites[1] = prof_data->num_value_sites[1];
if (!is_little_endian()) {
aot_exchange_uint64((uint8 *)&prof_data_64->func_hash);
aot_exchange_uint64((uint8 *)&prof_data_64->offset_counters);
aot_exchange_uint64((uint8 *)&prof_data_64->offset_counters);
aot_exchange_uint64((uint8 *)&prof_data_64->func_ptr);
aot_exchange_uint64((uint8 *)&prof_data_64->values);
aot_exchange_uint32((uint8 *)&prof_data_64->num_counters);
aot_exchange_uint16((uint8 *)&prof_data_64->num_value_sites[0]);
aot_exchange_uint16((uint8 *)&prof_data_64->num_value_sites[1]);
}
buf += sizeof(LLVMProfileData_64);
}
}
for (i = 0; i < module->data_section_count; i++) {
if (!strncmp(module->data_sections[i].name, "__llvm_prf_cnts", 15)) {
size = module->data_sections[i].size;
bh_memcpy_s(buf, size, module->data_sections[i].data, size);
buf += size;
}
}
if (prof_names && prof_names_size > 0) {
size = prof_names_size;
bh_memcpy_s(buf, size, prof_names, size);
buf += size;
padding_size = sizeof(uint64) - (prof_names_size % sizeof(uint64));
if (padding_size != sizeof(uint64)) {
char padding_buf[8] = { 0 };
bh_memcpy_s(buf, padding_size, padding_buf, padding_size);
buf += padding_size;
}
}
for (i = 0; i < module->data_section_count; i++) {
if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
uint32 j, k, num_value_sites, num_value_nodes;
ValueProfNode **values, **values_tmp, *value_node;
prof_data = (LLVMProfileData *)module->data_sections[i].data;
values = values_tmp = prof_data->values;
if (prof_data->num_value_sites[0] > 0
|| prof_data->num_value_sites[1] > 0) {
uint32 *buf_total_size = (uint32 *)buf;
buf += 4; /* emit TotalSize later */
*(uint32 *)buf = (prof_data->num_value_sites[0] > 0
&& prof_data->num_value_sites[1] > 0)
? 2
: 1;
if (!is_little_endian())
aot_exchange_uint32((uint8 *)buf);
buf += 4;
for (j = 0; j < 2; j++) {
if ((num_value_sites = prof_data->num_value_sites[j]) > 0) {
/* ValueKind */
*(uint32 *)buf = j;
if (!is_little_endian())
aot_exchange_uint32((uint8 *)buf);
buf += 4;
/* NumValueSites */
*(uint32 *)buf = num_value_sites;
if (!is_little_endian())
aot_exchange_uint32((uint8 *)buf);
buf += 4;
for (k = 0; k < num_value_sites; k++) {
num_value_nodes = 0;
if (values_tmp) {
value_node = *values_tmp;
while (value_node) {
num_value_nodes++;
value_node = value_node->next;
}
values_tmp++;
}
bh_assert(num_value_nodes < 255);
*(uint8 *)buf++ = (uint8)num_value_nodes;
}
if (num_value_sites % 8) {
buf += 8 - (num_value_sites % 8);
}
for (k = 0; k < num_value_sites; k++) {
if (values) {
value_node = *values;
while (value_node) {
*(uint64 *)buf = value_node->value;
if (!is_little_endian())
aot_exchange_uint64((uint8 *)buf);
buf += 8;
*(uint64 *)buf = value_node->count;
if (!is_little_endian())
aot_exchange_uint64((uint8 *)buf);
buf += 8;
value_node = value_node->next;
}
values++;
}
}
}
}
/* TotalSize */
*(uint32 *)buf_total_size =
(uint8 *)buf - (uint8 *)buf_total_size;
if (!is_little_endian())
aot_exchange_uint64((uint8 *)buf_total_size);
value_counters_size += (uint8 *)buf - (uint8 *)buf_total_size;
}
}
}
bh_assert(value_counters_size == value_counters_size_backup);
(void)value_counters_size_backup;
return total_size;
}
#endif /* end of WASM_ENABLE_STATIC_PGO != 0 */

View File

@ -41,6 +41,10 @@ typedef struct AOTObjectDataSection {
char *name;
uint8 *data;
uint32 size;
#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
bool is_name_allocated;
bool is_data_allocated;
#endif
} AOTObjectDataSection;
/* Relocation info */
@ -51,6 +55,9 @@ typedef struct AOTRelocation {
char *symbol_name;
/* index in the symbol offset field */
uint32 symbol_index;
#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
bool is_symbol_name_allocated;
#endif
} AOTRelocation;
/* Relocation Group */
@ -60,6 +67,9 @@ typedef struct AOTRelocationGroup {
uint32 name_index;
uint32 relocation_count;
AOTRelocation *relocations;
#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
bool is_section_name_allocated;
#endif
} AOTRelocationGroup;
/* AOT function instance */
@ -108,6 +118,13 @@ typedef struct AOTUnwindInfo {
#define PLT_ITEM_SIZE 12
#endif
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
typedef struct GOTItem {
uint32 func_idx;
struct GOTItem *next;
} GOTItem, *GOTItemList;
#endif
typedef struct AOTModule {
uint32 module_type;
@ -204,6 +221,13 @@ typedef struct AOTModule {
bool rtl_func_table_registered;
#endif
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
uint32 got_item_count;
GOTItemList got_item_list;
GOTItemList got_item_list_end;
void **got_func_ptrs;
#endif
/* data sections in AOT object file, including .data, .rodata
and .rodata.cstN. */
AOTObjectDataSection *data_sections;
@ -294,6 +318,54 @@ typedef struct AOTFrame {
#endif
} AOTFrame;
#if WASM_ENABLE_STATIC_PGO != 0
typedef struct LLVMProfileRawHeader {
uint64 magic;
uint64 version;
uint64 binary_ids_size;
uint64 num_prof_data;
uint64 padding_bytes_before_counters;
uint64 num_prof_counters;
uint64 padding_bytes_after_counters;
uint64 names_size;
uint64 counters_delta;
uint64 names_delta;
uint64 value_kind_last;
} LLVMProfileRawHeader;
typedef struct ValueProfNode {
uint64 value;
uint64 count;
struct ValueProfNode *next;
} ValueProfNode;
/* The profiling data of data sections created by aot compiler and
used when profiling, the width of pointer can be 8 bytes (64-bit)
or 4 bytes (32-bit) */
typedef struct LLVMProfileData {
uint64 func_md5;
uint64 func_hash;
uint64 offset_counters;
uintptr_t func_ptr;
ValueProfNode **values;
uint32 num_counters;
uint16 num_value_sites[2];
} LLVMProfileData;
/* The profiling data for writting to the output file, the width of
pointer is 8 bytes suppose we always use wamrc and llvm-profdata
with 64-bit mode */
typedef struct LLVMProfileData_64 {
uint64 func_md5;
uint64 func_hash;
uint64 offset_counters;
uint64 func_ptr;
uint64 values;
uint32 num_counters;
uint16 num_value_sites[2];
} LLVMProfileData_64;
#endif /* end of WASM_ENABLE_STATIC_PGO != 0 */
/**
* Load a AOT module from aot file buffer
* @param buf the byte buffer which contains the AOT file data
@ -564,6 +636,32 @@ aot_dump_perf_profiling(const AOTModuleInstance *module_inst);
const uint8 *
aot_get_custom_section(const AOTModule *module, const char *name, uint32 *len);
#if WASM_ENABLE_STATIC_PGO != 0
void
llvm_profile_instrument_target(uint64 target_value, void *data,
uint32 counter_idx);
void
llvm_profile_instrument_memop(uint64 target_value, void *data,
uint32 counter_idx);
uint32
aot_get_pgo_prof_data_size(AOTModuleInstance *module_inst);
uint32
aot_dump_pgo_prof_data_to_buf(AOTModuleInstance *module_inst, char *buf,
uint32 len);
void
aot_exchange_uint16(uint8 *p_data);
void
aot_exchange_uint32(uint8 *p_data);
void
aot_exchange_uint64(uint8 *p_data);
#endif /* end of WASM_ENABLE_STATIC_PGO != 0 */
#ifdef __cplusplus
} /* end of extern "C" */
#endif

View File

@ -8,6 +8,9 @@
#define R_386_32 1 /* Direct 32 bit */
#define R_386_PC32 2 /* PC relative 32 bit */
#define R_386_PLT32 4 /* 32-bit address ProcedureLinkageTable */
#define R_386_TLS_GD_32 \
24 /* Direct 32 bit for general dynamic \
thread local data */
#if !defined(_WIN32) && !defined(_WIN32_)
/* clang-format off */
@ -110,6 +113,9 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
{
switch (reloc_type) {
case R_386_32:
#if WASM_ENABLE_STATIC_PGO != 0
case R_386_TLS_GD_32:
#endif
{
intptr_t value;

View File

@ -6,11 +6,13 @@
#include "aot_reloc.h"
#if !defined(BH_PLATFORM_WINDOWS)
#define R_X86_64_64 1 /* Direct 64 bit */
#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
#define R_X86_64_PLT32 4 /* 32 bit PLT address */
#define R_X86_64_32 10 /* Direct 32 bit zero extended */
#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
#define R_X86_64_64 1 /* Direct 64 bit */
#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
#define R_X86_64_PLT32 4 /* 32 bit PLT address */
#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative offset to GOT */
#define R_X86_64_32 10 /* Direct 32 bit zero extended */
#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
#define R_X86_64_PC64 24 /* PC relative 64 bit */
#else
#ifndef IMAGE_REL_AMD64_ADDR64
#define IMAGE_REL_AMD64_ADDR64 1 /* The 64-bit VA of the relocation target */
@ -164,6 +166,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
#endif
#if !defined(BH_PLATFORM_WINDOWS)
case R_X86_64_PC32:
case R_X86_64_GOTPCREL: /* GOT + G has been calculated as symbol_addr */
{
intptr_t target_addr = (intptr_t) /* S + A - P */
((uintptr_t)symbol_addr + reloc_addend
@ -182,6 +185,16 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
*(int32 *)(target_section_addr + reloc_offset) = (int32)target_addr;
break;
}
case R_X86_64_PC64:
{
intptr_t target_addr = (intptr_t) /* S + A - P */
((uintptr_t)symbol_addr + reloc_addend
- (uintptr_t)(target_section_addr + reloc_offset));
CHECK_RELOC_OFFSET(sizeof(int64));
*(int64 *)(target_section_addr + reloc_offset) = (int64)target_addr;
break;
}
case R_X86_64_32:
case R_X86_64_32S:
{

View File

@ -624,6 +624,11 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
#endif
#endif
#if defined(os_writegsbase)
/* write base addr of linear memory to GS segment register */
os_writegsbase(memory_data_new);
#endif
return ret;
}
#else
@ -756,4 +761,4 @@ wasm_get_linear_memory_size(WASMMemoryInstance *memory, void *node)
#endif
return linear_mem_size;
}
#endif
#endif

View File

@ -130,7 +130,7 @@ static JitCompOptions jit_options = { 0 };
#endif
#if WASM_ENABLE_JIT != 0
static LLVMJITOptions llvm_jit_options = { 3, 3 };
static LLVMJITOptions llvm_jit_options = { 3, 3, 0 };
#endif
static RunningMode runtime_running_mode = Mode_Default;
@ -554,6 +554,7 @@ wasm_runtime_full_init(RuntimeInitArgs *init_args)
#if WASM_ENABLE_JIT != 0
llvm_jit_options.size_level = init_args->llvm_jit_size_level;
llvm_jit_options.opt_level = init_args->llvm_jit_opt_level;
llvm_jit_options.segue_flags = init_args->segue_flags;
#endif
if (!wasm_runtime_env_init()) {
@ -4212,6 +4213,12 @@ static V128FuncPtr invokeNative_V128 = (V128FuncPtr)(uintptr_t)invokeNative;
|| defined(BUILD_TARGET_RISCV64_LP64) */
#endif /* end of defined(_WIN32) || defined(_WIN32_) */
/* ASAN is not designed to work with custom stack unwind or other low-level \
things. > Ignore a function that does some low-level magic. (e.g. walking \
through the thread's stack bypassing the frame boundaries) */
#if defined(__GNUC__)
__attribute__((no_sanitize_address))
#endif
bool
wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
const WASMType *func_type, const char *signature,
@ -5026,6 +5033,33 @@ wasm_runtime_dump_call_stack_to_buf(wasm_exec_env_t exec_env, char *buf,
}
#endif /* end of WASM_ENABLE_DUMP_CALL_STACK */
#if WASM_ENABLE_STATIC_PGO != 0
uint32
wasm_runtime_get_pgo_prof_data_size(WASMModuleInstanceCommon *module_inst)
{
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
AOTModuleInstance *aot_inst = (AOTModuleInstance *)module_inst;
return aot_get_pgo_prof_data_size(aot_inst);
}
#endif
return 0;
}
uint32
wasm_runtime_dump_pgo_prof_data_to_buf(WASMModuleInstanceCommon *module_inst,
char *buf, uint32 len)
{
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
AOTModuleInstance *aot_inst = (AOTModuleInstance *)module_inst;
return aot_dump_pgo_prof_data_to_buf(aot_inst, buf, len);
}
#endif
return 0;
}
#endif /* end of WASM_ENABLE_STATIC_PGO != 0 */
bool
wasm_runtime_get_table_elem_type(const WASMModuleCommon *module_comm,
uint32 table_idx, uint8 *out_elem_type,

View File

@ -420,6 +420,7 @@ typedef struct wasm_frame_t {
typedef struct LLVMJITOptions {
uint32 opt_level;
uint32 size_level;
uint32 segue_flags;
} LLVMJITOptions;
#endif

View File

@ -384,7 +384,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
/* unit of timeout is nsec, convert it to usec */
timeout_left = (uint64)timeout / 1000;
timeout_1sec = 1e6;
timeout_1sec = (uint64)1e6;
while (1) {
if (timeout < 0) {

View File

@ -239,6 +239,13 @@ check_type_compatible(uint8 src_type, uint8 dst_type)
#define FUNC_REF_TYPE comp_ctx->basic_types.funcref_type
#define EXTERN_REF_TYPE comp_ctx->basic_types.externref_type
#define INT8_PTR_TYPE_GS comp_ctx->basic_types.int8_ptr_type_gs
#define INT16_PTR_TYPE_GS comp_ctx->basic_types.int16_ptr_type_gs
#define INT32_PTR_TYPE_GS comp_ctx->basic_types.int32_ptr_type_gs
#define INT64_PTR_TYPE_GS comp_ctx->basic_types.int64_ptr_type_gs
#define F32_PTR_TYPE_GS comp_ctx->basic_types.float32_ptr_type_gs
#define F64_PTR_TYPE_GS comp_ctx->basic_types.float64_ptr_type_gs
#define I32_CONST(v) LLVMConstInt(I32_TYPE, v, true)
#define I64_CONST(v) LLVMConstInt(I64_TYPE, v, true)
#define F32_CONST(v) LLVMConstReal(F32_TYPE, v)
@ -272,6 +279,7 @@ check_type_compatible(uint8 src_type, uint8 dst_type)
#define V128_TYPE comp_ctx->basic_types.v128_type
#define V128_PTR_TYPE comp_ctx->basic_types.v128_ptr_type
#define V128_PTR_TYPE_GS comp_ctx->basic_types.v128_ptr_type_gs
#define V128_i8x16_TYPE comp_ctx->basic_types.i8x16_vec_type
#define V128_i16x8_TYPE comp_ctx->basic_types.i16x8_vec_type
#define V128_i32x4_TYPE comp_ctx->basic_types.i32x4_vec_type

View File

@ -111,6 +111,8 @@ typedef struct AOTSymbolList {
/* AOT object data */
typedef struct AOTObjectData {
AOTCompContext *comp_ctx;
LLVMMemoryBufferRef mem_buf;
LLVMBinaryRef binary;
@ -119,6 +121,12 @@ typedef struct AOTObjectData {
void *text;
uint32 text_size;
void *text_unlikely;
uint32 text_unlikely_size;
void *text_hot;
uint32 text_hot_size;
/* literal data and size */
void *literal;
uint32 literal_size;
@ -558,8 +566,10 @@ get_init_data_section_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
static uint32
get_text_section_size(AOTObjectData *obj_data)
{
return (sizeof(uint32) + obj_data->literal_size + obj_data->text_size + 3)
& ~3;
return sizeof(uint32) + align_uint(obj_data->literal_size, 4)
+ align_uint(obj_data->text_size, 4)
+ align_uint(obj_data->text_unlikely_size, 4)
+ align_uint(obj_data->text_hot_size, 4);
}
static uint32
@ -1702,12 +1712,28 @@ aot_emit_text_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
EMIT_U32(AOT_SECTION_TYPE_TEXT);
EMIT_U32(section_size);
EMIT_U32(obj_data->literal_size);
if (obj_data->literal_size > 0)
EMIT_BUF(obj_data->literal, obj_data->literal_size);
EMIT_BUF(obj_data->text, obj_data->text_size);
while (offset & 3)
EMIT_BUF(&placeholder, 1);
if (obj_data->literal_size > 0) {
EMIT_BUF(obj_data->literal, obj_data->literal_size);
while (offset & 3)
EMIT_BUF(&placeholder, 1);
}
if (obj_data->text_size > 0) {
EMIT_BUF(obj_data->text, obj_data->text_size);
while (offset & 3)
EMIT_BUF(&placeholder, 1);
}
if (obj_data->text_unlikely_size > 0) {
EMIT_BUF(obj_data->text_unlikely, obj_data->text_unlikely_size);
while (offset & 3)
EMIT_BUF(&placeholder, 1);
}
if (obj_data->text_hot_size > 0) {
EMIT_BUF(obj_data->text_hot, obj_data->text_hot_size);
while (offset & 3)
EMIT_BUF(&placeholder, 1);
}
if (offset - *p_offset != section_size + sizeof(uint32) * 2) {
aot_set_last_error("emit text section failed.");
@ -2211,11 +2237,23 @@ aot_resolve_text(AOTObjectData *obj_data)
}
while (
!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
if ((name = (char *)LLVMGetSectionName(sec_itr))
&& !strcmp(name, ".text")) {
obj_data->text = (char *)LLVMGetSectionContents(sec_itr);
obj_data->text_size = (uint32)LLVMGetSectionSize(sec_itr);
break;
if ((name = (char *)LLVMGetSectionName(sec_itr))) {
if (!strcmp(name, ".text")) {
obj_data->text = (char *)LLVMGetSectionContents(sec_itr);
obj_data->text_size = (uint32)LLVMGetSectionSize(sec_itr);
}
else if (!strcmp(name, ".text.unlikely.")) {
obj_data->text_unlikely =
(char *)LLVMGetSectionContents(sec_itr);
obj_data->text_unlikely_size =
(uint32)LLVMGetSectionSize(sec_itr);
}
else if (!strcmp(name, ".text.hot.")) {
obj_data->text_hot =
(char *)LLVMGetSectionContents(sec_itr);
obj_data->text_hot_size =
(uint32)LLVMGetSectionSize(sec_itr);
}
}
LLVMMoveToNextSection(sec_itr);
}
@ -2253,7 +2291,8 @@ static bool
get_relocations_count(LLVMSectionIteratorRef sec_itr, uint32 *p_count);
static bool
is_data_section(LLVMSectionIteratorRef sec_itr, char *section_name)
is_data_section(AOTObjectData *obj_data, LLVMSectionIteratorRef sec_itr,
char *section_name)
{
uint32 relocation_count = 0;
@ -2265,7 +2304,11 @@ is_data_section(LLVMSectionIteratorRef sec_itr, char *section_name)
|| !strncmp(section_name, ".rodata.str", strlen(".rodata.str"))
|| (!strcmp(section_name, ".rdata")
&& get_relocations_count(sec_itr, &relocation_count)
&& relocation_count > 0));
&& relocation_count > 0)
|| (obj_data->comp_ctx->enable_llvm_pgo
&& (!strncmp(section_name, "__llvm_prf_cnts", 15)
|| !strncmp(section_name, "__llvm_prf_data", 15)
|| !strncmp(section_name, "__llvm_prf_names", 16))));
}
static bool
@ -2281,7 +2324,7 @@ get_object_data_sections_count(AOTObjectData *obj_data, uint32 *p_count)
}
while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
if ((name = (char *)LLVMGetSectionName(sec_itr))
&& (is_data_section(sec_itr, name))) {
&& (is_data_section(obj_data, sec_itr, name))) {
count++;
}
LLVMMoveToNextSection(sec_itr);
@ -2306,6 +2349,9 @@ aot_resolve_object_data_sections(AOTObjectData *obj_data)
}
if (sections_count > 0) {
uint32 llvm_prf_cnts_idx = 0, llvm_prf_data_idx = 0;
char buf[32];
size = (uint32)sizeof(AOTObjectDataSection) * sections_count;
if (!(data_section = obj_data->data_sections =
wasm_runtime_malloc(size))) {
@ -2322,10 +2368,46 @@ aot_resolve_object_data_sections(AOTObjectData *obj_data)
while (
!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
if ((name = (char *)LLVMGetSectionName(sec_itr))
&& (is_data_section(sec_itr, name))) {
&& (is_data_section(obj_data, sec_itr, name))) {
data_section->name = name;
data_section->data = (uint8 *)LLVMGetSectionContents(sec_itr);
data_section->size = (uint32)LLVMGetSectionSize(sec_itr);
if (obj_data->comp_ctx->enable_llvm_pgo
&& !strcmp(name, "__llvm_prf_cnts")) {
snprintf(buf, sizeof(buf), "%s%u", name,
llvm_prf_cnts_idx++);
size = strlen(buf) + 1;
if (!(data_section->name = wasm_runtime_malloc(size))) {
aot_set_last_error(
"allocate memory for data section name failed.");
return false;
}
bh_memcpy_s(data_section->name, size, buf, size);
data_section->is_name_allocated = true;
}
else if (obj_data->comp_ctx->enable_llvm_pgo
&& !strcmp(name, "__llvm_prf_data")) {
snprintf(buf, sizeof(buf), "%s%u", name,
llvm_prf_data_idx++);
size = strlen(buf) + 1;
if (!(data_section->name = wasm_runtime_malloc(size))) {
aot_set_last_error(
"allocate memory for data section name failed.");
return false;
}
bh_memcpy_s(data_section->name, size, buf, size);
data_section->is_name_allocated = true;
}
if (obj_data->comp_ctx->enable_llvm_pgo
&& !strcmp(name, "__llvm_prf_names")) {
data_section->data = (uint8 *)aot_compress_aot_func_names(
obj_data->comp_ctx, &data_section->size);
data_section->is_data_allocated = true;
}
else {
data_section->data =
(uint8 *)LLVMGetSectionContents(sec_itr);
data_section->size = (uint32)LLVMGetSectionSize(sec_itr);
}
data_section++;
}
LLVMMoveToNextSection(sec_itr);
@ -2365,9 +2447,36 @@ aot_resolve_functions(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
&& str_starts_with(name, prefix)) {
func_index = (uint32)atoi(name + strlen(prefix));
if (func_index < obj_data->func_count) {
LLVMSectionIteratorRef contain_section;
char *contain_section_name;
func = obj_data->funcs + func_index;
func->func_name = name;
func->text_offset = LLVMGetSymbolAddress(sym_itr);
if (!(contain_section = LLVMObjectFileCopySectionIterator(
obj_data->binary))) {
aot_set_last_error("llvm get section iterator failed.");
LLVMDisposeSymbolIterator(sym_itr);
return false;
}
LLVMMoveToContainingSection(contain_section, sym_itr);
contain_section_name =
(char *)LLVMGetSectionName(contain_section);
LLVMDisposeSectionIterator(contain_section);
if (!strcmp(contain_section_name, ".text.unlikely.")) {
func->text_offset = align_uint(obj_data->text_size, 4)
+ LLVMGetSymbolAddress(sym_itr);
}
else if (!strcmp(contain_section_name, ".text.hot.")) {
func->text_offset =
align_uint(obj_data->text_size, 4)
+ align_uint(obj_data->text_unlikely_size, 4)
+ LLVMGetSymbolAddress(sym_itr);
}
else {
func->text_offset = LLVMGetSymbolAddress(sym_itr);
}
}
}
LLVMMoveToNextSymbol(sym_itr);
@ -2478,9 +2587,86 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data,
}
/* set relocation fields */
relocation->relocation_offset = offset;
relocation->relocation_type = (uint32)type;
relocation->symbol_name = (char *)LLVMGetSymbolName(rel_sym);
relocation->relocation_offset = offset;
if (!strcmp(group->section_name, ".rela.text.unlikely.")
|| !strcmp(group->section_name, ".rel.text.unlikely.")) {
relocation->relocation_offset += align_uint(obj_data->text_size, 4);
}
else if (!strcmp(group->section_name, ".rela.text.hot.")
|| !strcmp(group->section_name, ".rel.text.hot.")) {
relocation->relocation_offset +=
align_uint(obj_data->text_size, 4)
+ align_uint(obj_data->text_unlikely_size, 4);
}
if (!strcmp(relocation->symbol_name, ".text.unlikely.")) {
relocation->symbol_name = ".text";
relocation->relocation_addend += align_uint(obj_data->text_size, 4);
}
if (!strcmp(relocation->symbol_name, ".text.hot.")) {
relocation->symbol_name = ".text";
relocation->relocation_addend +=
align_uint(obj_data->text_size, 4)
+ align_uint(obj_data->text_unlikely_size, 4);
}
if (obj_data->comp_ctx->enable_llvm_pgo
&& (!strcmp(relocation->symbol_name, "__llvm_prf_cnts")
|| !strcmp(relocation->symbol_name, "__llvm_prf_data"))) {
LLVMSectionIteratorRef sec_itr;
char buf[32], *section_name;
uint32 prof_section_idx = 0;
if (!(sec_itr =
LLVMObjectFileCopySectionIterator(obj_data->binary))) {
aot_set_last_error("llvm get section iterator failed.");
LLVMDisposeSymbolIterator(rel_sym);
goto fail;
}
while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary,
sec_itr)) {
section_name = (char *)LLVMGetSectionName(sec_itr);
if (section_name
&& !strcmp(section_name, relocation->symbol_name)) {
if (LLVMGetSectionContainsSymbol(sec_itr, rel_sym))
break;
prof_section_idx++;
}
LLVMMoveToNextSection(sec_itr);
}
LLVMDisposeSectionIterator(sec_itr);
if (!strcmp(group->section_name, ".rela.text")
|| !strcmp(group->section_name, ".rel.text")) {
snprintf(buf, sizeof(buf), "%s%u", relocation->symbol_name,
prof_section_idx);
size = strlen(buf) + 1;
if (!(relocation->symbol_name = wasm_runtime_malloc(size))) {
aot_set_last_error(
"allocate memory for relocation symbol name failed.");
LLVMDisposeSymbolIterator(rel_sym);
goto fail;
}
bh_memcpy_s(relocation->symbol_name, size, buf, size);
relocation->is_symbol_name_allocated = true;
}
else if (!strncmp(group->section_name, ".rela__llvm_prf_data", 20)
|| !strncmp(group->section_name, ".rel__llvm_prf_data",
19)) {
snprintf(buf, sizeof(buf), "%s%u", relocation->symbol_name,
prof_section_idx);
size = strlen(buf) + 1;
if (!(relocation->symbol_name = wasm_runtime_malloc(size))) {
aot_set_last_error(
"allocate memory for relocation symbol name failed.");
LLVMDisposeSymbolIterator(rel_sym);
goto fail;
}
bh_memcpy_s(relocation->symbol_name, size, buf, size);
relocation->is_symbol_name_allocated = true;
}
}
/* for ".LCPIxxx", ".LJTIxxx", ".LBBxxx" and switch lookup table
* relocation, transform the symbol name to real section name and set
@ -2525,10 +2711,14 @@ fail:
}
static bool
is_relocation_section_name(char *section_name)
is_relocation_section_name(AOTObjectData *obj_data, char *section_name)
{
return (!strcmp(section_name, ".rela.text")
|| !strcmp(section_name, ".rel.text")
|| !strcmp(section_name, ".rela.text.unlikely.")
|| !strcmp(section_name, ".rel.text.unlikely.")
|| !strcmp(section_name, ".rela.text.hot.")
|| !strcmp(section_name, ".rel.text.hot.")
|| !strcmp(section_name, ".rela.literal")
|| !strcmp(section_name, ".rela.data")
|| !strcmp(section_name, ".rel.data")
@ -2536,6 +2726,9 @@ is_relocation_section_name(char *section_name)
|| !strcmp(section_name, ".rel.sdata")
|| !strcmp(section_name, ".rela.rodata")
|| !strcmp(section_name, ".rel.rodata")
|| (obj_data->comp_ctx->enable_llvm_pgo
&& (!strcmp(section_name, ".rela__llvm_prf_data")
|| !strcmp(section_name, ".rel__llvm_prf_data")))
/* ".rela.rodata.cst4/8/16/.." */
|| !strncmp(section_name, ".rela.rodata.cst",
strlen(".rela.rodata.cst"))
@ -2545,14 +2738,15 @@ is_relocation_section_name(char *section_name)
}
static bool
is_relocation_section(LLVMSectionIteratorRef sec_itr)
is_relocation_section(AOTObjectData *obj_data, LLVMSectionIteratorRef sec_itr)
{
uint32 count = 0;
char *name = (char *)LLVMGetSectionName(sec_itr);
if (name) {
if (is_relocation_section_name(name))
if (is_relocation_section_name(obj_data, name))
return true;
else if ((!strcmp(name, ".text") || !strcmp(name, ".rdata"))
else if ((!strcmp(name, ".text") || !strcmp(name, ".text.unlikely.")
|| !strcmp(name, ".text.hot.") || !strcmp(name, ".rdata"))
&& get_relocations_count(sec_itr, &count) && count > 0)
return true;
}
@ -2570,7 +2764,7 @@ get_relocation_groups_count(AOTObjectData *obj_data, uint32 *p_count)
return false;
}
while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
if (is_relocation_section(sec_itr)) {
if (is_relocation_section(obj_data, sec_itr)) {
count++;
}
LLVMMoveToNextSection(sec_itr);
@ -2586,7 +2780,7 @@ aot_resolve_object_relocation_groups(AOTObjectData *obj_data)
{
LLVMSectionIteratorRef sec_itr;
AOTRelocationGroup *relocation_group;
uint32 group_count;
uint32 group_count, llvm_prf_data_idx = 0;
char *name;
uint32 size;
@ -2612,14 +2806,50 @@ aot_resolve_object_relocation_groups(AOTObjectData *obj_data)
return false;
}
while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
if (is_relocation_section(sec_itr)) {
if (is_relocation_section(obj_data, sec_itr)) {
name = (char *)LLVMGetSectionName(sec_itr);
relocation_group->section_name = name;
if (obj_data->comp_ctx->enable_llvm_pgo
&& (!strcmp(name, ".rela__llvm_prf_data")
|| !strcmp(name, ".rel__llvm_prf_data"))) {
char buf[32];
snprintf(buf, sizeof(buf), "%s%u", name, llvm_prf_data_idx);
size = strlen(buf) + 1;
if (!(relocation_group->section_name =
wasm_runtime_malloc(size))) {
aot_set_last_error(
"allocate memory for section name failed.");
LLVMDisposeSectionIterator(sec_itr);
return false;
}
bh_memcpy_s(relocation_group->section_name, size, buf, size);
relocation_group->is_section_name_allocated = true;
}
if (!aot_resolve_object_relocation_group(obj_data, relocation_group,
sec_itr)) {
LLVMDisposeSectionIterator(sec_itr);
return false;
}
if (obj_data->comp_ctx->enable_llvm_pgo
&& (!strcmp(name, ".rela__llvm_prf_data")
|| !strcmp(name, ".rel__llvm_prf_data"))) {
llvm_prf_data_idx++;
}
if (!strcmp(relocation_group->section_name, ".rela.text.unlikely.")
|| !strcmp(relocation_group->section_name, ".rela.text.hot.")) {
relocation_group->section_name = ".rela.text";
}
else if (!strcmp(relocation_group->section_name,
".rel.text.unlikely.")
|| !strcmp(relocation_group->section_name,
".rel.text.hot.")) {
relocation_group->section_name = ".rel.text";
}
relocation_group++;
}
LLVMMoveToNextSection(sec_itr);
@ -2633,12 +2863,21 @@ static void
destroy_relocation_groups(AOTRelocationGroup *relocation_groups,
uint32 relocation_group_count)
{
uint32 i;
uint32 i, j;
AOTRelocationGroup *relocation_group = relocation_groups;
for (i = 0; i < relocation_group_count; i++, relocation_group++)
if (relocation_group->relocations)
for (i = 0; i < relocation_group_count; i++, relocation_group++) {
if (relocation_group->relocations) {
for (j = 0; j < relocation_group->relocation_count; j++) {
if (relocation_group->relocations[j].is_symbol_name_allocated)
wasm_runtime_free(
relocation_group->relocations[j].symbol_name);
}
wasm_runtime_free(relocation_group->relocations);
}
if (relocation_group->is_section_name_allocated)
wasm_runtime_free(relocation_group->section_name);
}
wasm_runtime_free(relocation_groups);
}
@ -2664,8 +2903,20 @@ aot_obj_data_destroy(AOTObjectData *obj_data)
LLVMDisposeMemoryBuffer(obj_data->mem_buf);
if (obj_data->funcs)
wasm_runtime_free(obj_data->funcs);
if (obj_data->data_sections)
if (obj_data->data_sections) {
uint32 i;
for (i = 0; i < obj_data->data_sections_count; i++) {
if (obj_data->data_sections[i].name
&& obj_data->data_sections[i].is_name_allocated) {
wasm_runtime_free(obj_data->data_sections[i].name);
}
if (obj_data->data_sections[i].data
&& obj_data->data_sections[i].is_data_allocated) {
wasm_runtime_free(obj_data->data_sections[i].data);
}
}
wasm_runtime_free(obj_data->data_sections);
}
if (obj_data->relocation_groups)
destroy_relocation_groups(obj_data->relocation_groups,
obj_data->relocation_group_count);
@ -2688,6 +2939,7 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
return false;
}
memset(obj_data, 0, sizeof(AOTObjectData));
obj_data->comp_ctx = comp_ctx;
bh_print_time("Begin to emit object file");
if (comp_ctx->external_llc_compiler || comp_ctx->external_asm_compiler) {
@ -2821,8 +3073,8 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
if (!aot_resolve_target_info(comp_ctx, obj_data)
|| !aot_resolve_text(obj_data) || !aot_resolve_literal(obj_data)
|| !aot_resolve_object_data_sections(obj_data)
|| !aot_resolve_object_relocation_groups(obj_data)
|| !aot_resolve_functions(comp_ctx, obj_data))
|| !aot_resolve_functions(comp_ctx, obj_data)
|| !aot_resolve_object_relocation_groups(obj_data))
goto fail;
return obj_data;

View File

@ -868,10 +868,6 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
#if LLVM_VERSION_MAJOR >= 14
LLVMTypeRef llvm_func_type;
#endif
bool recursive_call =
(func_ctx == func_ctxes[func_idx - import_func_count]) ? true
: false;
if (comp_ctx->is_indirect_mode) {
LLVMTypeRef func_ptr_type;
@ -971,7 +967,7 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Check whether there was exception thrown when executing
the function */
if (!tail_call && !recursive_call && comp_ctx->enable_bound_check
if (!tail_call && comp_ctx->enable_bound_check
&& !check_exception_thrown(comp_ctx, func_ctx))
goto fail;
}

View File

@ -81,7 +81,7 @@ get_memory_curr_page_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
LLVMValueRef
aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 offset, uint32 bytes)
uint32 offset, uint32 bytes, bool enable_segue)
{
LLVMValueRef offset_const = I32_CONST(offset);
LLVMValueRef addr, maddr, offset1, cmp1, cmp2, cmp;
@ -162,11 +162,20 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* inside memory space */
offset1 = I32_CONST((uint32)mem_offset);
CHECK_LLVM_CONST(offset1);
if (!(maddr = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE,
mem_base_addr, &offset1, 1,
"maddr"))) {
aot_set_last_error("llvm build add failed.");
goto fail;
if (!enable_segue) {
if (!(maddr = LLVMBuildInBoundsGEP2(comp_ctx->builder,
INT8_TYPE, mem_base_addr,
&offset1, 1, "maddr"))) {
aot_set_last_error("llvm build add failed.");
goto fail;
}
}
else {
if (!(maddr = LLVMBuildIntToPtr(comp_ctx->builder, offset1,
INT8_PTR_TYPE_GS, "maddr"))) {
aot_set_last_error("llvm build IntToPtr failed.");
goto fail;
}
}
return maddr;
}
@ -244,11 +253,29 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
}
/* maddr = mem_base_addr + offset1 */
if (!(maddr = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE,
if (!enable_segue) {
/* maddr = mem_base_addr + offset1 */
if (!(maddr =
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE,
mem_base_addr, &offset1, 1, "maddr"))) {
aot_set_last_error("llvm build add failed.");
goto fail;
aot_set_last_error("llvm build add failed.");
goto fail;
}
}
else {
LLVMValueRef maddr_base;
if (!(maddr_base = LLVMBuildIntToPtr(comp_ctx->builder, addr,
INT8_PTR_TYPE_GS, "maddr_base"))) {
aot_set_last_error("llvm build int to ptr failed.");
goto fail;
}
if (!(maddr = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE,
maddr_base, &offset_const, 1,
"maddr"))) {
aot_set_last_error("llvm build inboundgep failed.");
goto fail;
}
}
return maddr;
fail:
@ -388,13 +415,18 @@ aot_compile_op_i32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
{
LLVMValueRef maddr, value = NULL;
LLVMTypeRef data_type;
bool enable_segue = comp_ctx->enable_segue_i32_load;
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes)))
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes,
enable_segue)))
return false;
switch (bytes) {
case 4:
BUILD_PTR_CAST(INT32_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT32_PTR_TYPE);
else
BUILD_PTR_CAST(INT32_PTR_TYPE_GS);
#if WASM_ENABLE_SHARED_MEMORY != 0
if (atomic)
BUILD_ATOMIC_LOAD(align, I32_TYPE);
@ -405,11 +437,17 @@ aot_compile_op_i32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
case 2:
case 1:
if (bytes == 2) {
BUILD_PTR_CAST(INT16_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT16_PTR_TYPE);
else
BUILD_PTR_CAST(INT16_PTR_TYPE_GS);
data_type = INT16_TYPE;
}
else {
BUILD_PTR_CAST(INT8_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT8_PTR_TYPE);
else
BUILD_PTR_CAST(INT8_PTR_TYPE_GS);
data_type = INT8_TYPE;
}
@ -447,13 +485,18 @@ aot_compile_op_i64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
{
LLVMValueRef maddr, value = NULL;
LLVMTypeRef data_type;
bool enable_segue = comp_ctx->enable_segue_i64_load;
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes)))
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes,
enable_segue)))
return false;
switch (bytes) {
case 8:
BUILD_PTR_CAST(INT64_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT64_PTR_TYPE);
else
BUILD_PTR_CAST(INT64_PTR_TYPE_GS);
#if WASM_ENABLE_SHARED_MEMORY != 0
if (atomic)
BUILD_ATOMIC_LOAD(align, I64_TYPE);
@ -465,15 +508,24 @@ aot_compile_op_i64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
case 2:
case 1:
if (bytes == 4) {
BUILD_PTR_CAST(INT32_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT32_PTR_TYPE);
else
BUILD_PTR_CAST(INT32_PTR_TYPE_GS);
data_type = I32_TYPE;
}
else if (bytes == 2) {
BUILD_PTR_CAST(INT16_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT16_PTR_TYPE);
else
BUILD_PTR_CAST(INT16_PTR_TYPE_GS);
data_type = INT16_TYPE;
}
else {
BUILD_PTR_CAST(INT8_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT8_PTR_TYPE);
else
BUILD_PTR_CAST(INT8_PTR_TYPE_GS);
data_type = INT8_TYPE;
}
@ -509,12 +561,18 @@ aot_compile_op_f32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset)
{
LLVMValueRef maddr, value;
bool enable_segue = comp_ctx->enable_segue_f32_load;
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, 4)))
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, 4,
enable_segue)))
return false;
BUILD_PTR_CAST(F32_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(F32_PTR_TYPE);
else
BUILD_PTR_CAST(F32_PTR_TYPE_GS);
BUILD_LOAD(F32_TYPE);
PUSH_F32(value);
return true;
fail:
@ -526,12 +584,18 @@ aot_compile_op_f64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset)
{
LLVMValueRef maddr, value;
bool enable_segue = comp_ctx->enable_segue_f64_load;
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, 8)))
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, 8,
enable_segue)))
return false;
BUILD_PTR_CAST(F64_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(F64_PTR_TYPE);
else
BUILD_PTR_CAST(F64_PTR_TYPE_GS);
BUILD_LOAD(F64_TYPE);
PUSH_F64(value);
return true;
fail:
@ -543,22 +607,33 @@ aot_compile_op_i32_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset, uint32 bytes, bool atomic)
{
LLVMValueRef maddr, value;
bool enable_segue = comp_ctx->enable_segue_i32_store;
POP_I32(value);
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes)))
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes,
enable_segue)))
return false;
switch (bytes) {
case 4:
BUILD_PTR_CAST(INT32_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT32_PTR_TYPE);
else
BUILD_PTR_CAST(INT32_PTR_TYPE_GS);
break;
case 2:
BUILD_PTR_CAST(INT16_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT16_PTR_TYPE);
else
BUILD_PTR_CAST(INT16_PTR_TYPE_GS);
BUILD_TRUNC(value, INT16_TYPE);
break;
case 1:
BUILD_PTR_CAST(INT8_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT8_PTR_TYPE);
else
BUILD_PTR_CAST(INT8_PTR_TYPE_GS);
BUILD_TRUNC(value, INT8_TYPE);
break;
default:
@ -582,26 +657,40 @@ aot_compile_op_i64_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset, uint32 bytes, bool atomic)
{
LLVMValueRef maddr, value;
bool enable_segue = comp_ctx->enable_segue_i64_store;
POP_I64(value);
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes)))
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes,
enable_segue)))
return false;
switch (bytes) {
case 8:
BUILD_PTR_CAST(INT64_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT64_PTR_TYPE);
else
BUILD_PTR_CAST(INT64_PTR_TYPE_GS);
break;
case 4:
BUILD_PTR_CAST(INT32_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT32_PTR_TYPE);
else
BUILD_PTR_CAST(INT32_PTR_TYPE_GS);
BUILD_TRUNC(value, I32_TYPE);
break;
case 2:
BUILD_PTR_CAST(INT16_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT16_PTR_TYPE);
else
BUILD_PTR_CAST(INT16_PTR_TYPE_GS);
BUILD_TRUNC(value, INT16_TYPE);
break;
case 1:
BUILD_PTR_CAST(INT8_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT8_PTR_TYPE);
else
BUILD_PTR_CAST(INT8_PTR_TYPE_GS);
BUILD_TRUNC(value, INT8_TYPE);
break;
default:
@ -625,13 +714,18 @@ aot_compile_op_f32_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset)
{
LLVMValueRef maddr, value;
bool enable_segue = comp_ctx->enable_segue_f32_store;
POP_F32(value);
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, 4)))
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, 4,
enable_segue)))
return false;
BUILD_PTR_CAST(F32_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(F32_PTR_TYPE);
else
BUILD_PTR_CAST(F32_PTR_TYPE_GS);
BUILD_STORE();
return true;
fail:
@ -643,13 +737,18 @@ aot_compile_op_f64_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset)
{
LLVMValueRef maddr, value;
bool enable_segue = comp_ctx->enable_segue_f64_store;
POP_F64(value);
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, 8)))
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, 8,
enable_segue)))
return false;
BUILD_PTR_CAST(F64_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(F64_PTR_TYPE);
else
BUILD_PTR_CAST(F64_PTR_TYPE_GS);
BUILD_STORE();
return true;
fail:
@ -1140,13 +1239,19 @@ aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 offset, uint32 bytes)
{
LLVMValueRef maddr, value, result;
bool enable_segue = (op_type == VALUE_TYPE_I32)
? comp_ctx->enable_segue_i32_load
&& comp_ctx->enable_segue_i32_store
: comp_ctx->enable_segue_i64_load
&& comp_ctx->enable_segue_i64_store;
if (op_type == VALUE_TYPE_I32)
POP_I32(value);
else
POP_I64(value);
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes)))
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes,
enable_segue)))
return false;
if (!check_memory_alignment(comp_ctx, func_ctx, maddr, align))
@ -1154,19 +1259,31 @@ aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
switch (bytes) {
case 8:
BUILD_PTR_CAST(INT64_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT64_PTR_TYPE);
else
BUILD_PTR_CAST(INT64_PTR_TYPE_GS);
break;
case 4:
BUILD_PTR_CAST(INT32_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT32_PTR_TYPE);
else
BUILD_PTR_CAST(INT32_PTR_TYPE_GS);
if (op_type == VALUE_TYPE_I64)
BUILD_TRUNC(value, I32_TYPE);
break;
case 2:
BUILD_PTR_CAST(INT16_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT16_PTR_TYPE);
else
BUILD_PTR_CAST(INT16_PTR_TYPE_GS);
BUILD_TRUNC(value, INT16_TYPE);
break;
case 1:
BUILD_PTR_CAST(INT8_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT8_PTR_TYPE);
else
BUILD_PTR_CAST(INT8_PTR_TYPE_GS);
BUILD_TRUNC(value, INT8_TYPE);
break;
default:
@ -1208,6 +1325,11 @@ aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
uint32 align, uint32 offset, uint32 bytes)
{
LLVMValueRef maddr, value, expect, result;
bool enable_segue = (op_type == VALUE_TYPE_I32)
? comp_ctx->enable_segue_i32_load
&& comp_ctx->enable_segue_i32_store
: comp_ctx->enable_segue_i64_load
&& comp_ctx->enable_segue_i64_store;
if (op_type == VALUE_TYPE_I32) {
POP_I32(value);
@ -1218,7 +1340,8 @@ aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
POP_I64(expect);
}
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes)))
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes,
enable_segue)))
return false;
if (!check_memory_alignment(comp_ctx, func_ctx, maddr, align))
@ -1226,22 +1349,34 @@ aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
switch (bytes) {
case 8:
BUILD_PTR_CAST(INT64_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT64_PTR_TYPE);
else
BUILD_PTR_CAST(INT64_PTR_TYPE_GS);
break;
case 4:
BUILD_PTR_CAST(INT32_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT32_PTR_TYPE);
else
BUILD_PTR_CAST(INT32_PTR_TYPE_GS);
if (op_type == VALUE_TYPE_I64) {
BUILD_TRUNC(value, I32_TYPE);
BUILD_TRUNC(expect, I32_TYPE);
}
break;
case 2:
BUILD_PTR_CAST(INT16_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT16_PTR_TYPE);
else
BUILD_PTR_CAST(INT16_PTR_TYPE_GS);
BUILD_TRUNC(value, INT16_TYPE);
BUILD_TRUNC(expect, INT16_TYPE);
break;
case 1:
BUILD_PTR_CAST(INT8_PTR_TYPE);
if (!enable_segue)
BUILD_PTR_CAST(INT8_PTR_TYPE);
else
BUILD_PTR_CAST(INT8_PTR_TYPE_GS);
BUILD_TRUNC(value, INT8_TYPE);
BUILD_TRUNC(expect, INT8_TYPE);
break;
@ -1318,7 +1453,8 @@ aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
CHECK_LLVM_CONST(is_wait64);
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes)))
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes,
false)))
return false;
if (!check_memory_alignment(comp_ctx, func_ctx, maddr, align))
@ -1393,7 +1529,8 @@ aot_compiler_op_atomic_notify(AOTCompContext *comp_ctx,
POP_I32(count);
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes)))
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes,
false)))
return false;
if (!check_memory_alignment(comp_ctx, func_ctx, maddr, align))

View File

@ -53,7 +53,7 @@ aot_compile_op_f64_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMValueRef
aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 offset, uint32 bytes);
uint32 offset, uint32 bytes, bool enable_segue);
bool
aot_compile_op_memory_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);

View File

@ -112,7 +112,7 @@ static bool
compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 global_idx, bool is_set, bool is_aux_stack)
{
AOTCompData *comp_data = comp_ctx->comp_data;
const AOTCompData *comp_data = comp_ctx->comp_data;
uint32 import_global_count = comp_data->import_global_count;
uint32 global_base_offset;
uint32 global_offset;

View File

@ -15,7 +15,7 @@
#endif
LLVMTypeRef
wasm_type_to_llvm_type(AOTLLVMTypes *llvm_types, uint8 wasm_type)
wasm_type_to_llvm_type(const AOTLLVMTypes *llvm_types, uint8 wasm_type)
{
switch (wasm_type) {
case VALUE_TYPE_I32:
@ -42,8 +42,8 @@ wasm_type_to_llvm_type(AOTLLVMTypes *llvm_types, uint8 wasm_type)
* Add LLVM function
*/
static LLVMValueRef
aot_add_llvm_func(AOTCompContext *comp_ctx, LLVMModuleRef module,
AOTFuncType *aot_func_type, uint32 func_index,
aot_add_llvm_func(const AOTCompContext *comp_ctx, LLVMModuleRef module,
const AOTFuncType *aot_func_type, uint32 func_index,
LLVMTypeRef *p_func_type)
{
LLVMValueRef func = NULL;
@ -177,8 +177,9 @@ free_block_memory(AOTBlock *block)
* Create first AOTBlock, or function block for the function
*/
static AOTBlock *
aot_create_func_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFunc *func, AOTFuncType *aot_func_type)
aot_create_func_block(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const AOTFunc *func,
const AOTFuncType *aot_func_type)
{
AOTBlock *aot_block;
uint32 param_count = aot_func_type->param_count,
@ -266,7 +267,8 @@ create_argv_buf(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
}
static bool
create_native_stack_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
create_native_stack_bound(const AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx)
{
LLVMValueRef stack_bound_offset = I32_FOUR, stack_bound_addr;
@ -288,7 +290,8 @@ create_native_stack_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
}
static bool
create_native_stack_top_min(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
create_native_stack_top_min(const AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx)
{
LLVMValueRef offset = I32_NINE;
@ -303,7 +306,7 @@ create_native_stack_top_min(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
}
static bool
create_aux_stack_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
create_aux_stack_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{
LLVMValueRef aux_stack_bound_offset = I32_SIX, aux_stack_bound_addr;
LLVMValueRef aux_stack_bottom_offset = I32_SEVEN, aux_stack_bottom_addr;
@ -355,7 +358,7 @@ create_aux_stack_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
}
static bool
create_native_symbol(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
create_native_symbol(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{
LLVMValueRef native_symbol_offset = I32_EIGHT, native_symbol_addr;
@ -384,8 +387,9 @@ create_native_symbol(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
}
static bool
create_local_variables(AOTCompData *comp_data, AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFunc *func)
create_local_variables(const AOTCompData *comp_data,
const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
const AOTFunc *func)
{
AOTFuncType *aot_func_type = comp_data->func_types[func->func_type_index];
char local_name[32];
@ -475,7 +479,7 @@ create_local_variables(AOTCompData *comp_data, AOTCompContext *comp_ctx,
}
static bool
create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMTypeRef int8_ptr_type, uint32 func_index)
{
LLVMValueRef offset, mem_info_base;
@ -807,7 +811,7 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
static bool
create_cur_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
create_cur_exception(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{
LLVMValueRef offset;
@ -823,7 +827,8 @@ create_cur_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
}
static bool
create_func_type_indexes(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
create_func_type_indexes(const AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx)
{
LLVMValueRef offset, func_type_indexes_ptr;
LLVMTypeRef int32_ptr_type;
@ -861,7 +866,7 @@ create_func_type_indexes(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
}
static bool
create_func_ptrs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
create_func_ptrs(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{
LLVMValueRef offset;
@ -903,7 +908,7 @@ create_func_ptrs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
* Create function compiler context
*/
static AOTFuncContext *
aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
aot_create_func_context(const AOTCompData *comp_data, AOTCompContext *comp_ctx,
AOTFunc *func, uint32 func_index)
{
AOTFuncContext *func_ctx;
@ -1059,7 +1064,7 @@ aot_destroy_func_contexts(AOTFuncContext **func_ctxes, uint32 count)
* Create function compiler contexts
*/
static AOTFuncContext **
aot_create_func_contexts(AOTCompData *comp_data, AOTCompContext *comp_ctx)
aot_create_func_contexts(const AOTCompData *comp_data, AOTCompContext *comp_ctx)
{
AOTFuncContext **func_ctxes;
uint64 size;
@ -1127,6 +1132,28 @@ aot_set_llvm_basic_types(AOTLLVMTypes *basic_types, LLVMContextRef context)
basic_types->v128_type = basic_types->i64x2_vec_type;
basic_types->v128_ptr_type = LLVMPointerType(basic_types->v128_type, 0);
basic_types->int8_ptr_type_gs =
LLVMPointerType(basic_types->int8_type, 256);
basic_types->int16_ptr_type_gs =
LLVMPointerType(basic_types->int16_type, 256);
basic_types->int32_ptr_type_gs =
LLVMPointerType(basic_types->int32_type, 256);
basic_types->int64_ptr_type_gs =
LLVMPointerType(basic_types->int64_type, 256);
basic_types->float32_ptr_type_gs =
LLVMPointerType(basic_types->float32_type, 256);
basic_types->float64_ptr_type_gs =
LLVMPointerType(basic_types->float64_type, 256);
basic_types->v128_ptr_type_gs =
LLVMPointerType(basic_types->v128_type, 256);
if (!basic_types->int8_ptr_type_gs || !basic_types->int16_ptr_type_gs
|| !basic_types->int32_ptr_type_gs || !basic_types->int64_ptr_type_gs
|| !basic_types->float32_ptr_type_gs
|| !basic_types->float64_ptr_type_gs
|| !basic_types->v128_ptr_type_gs) {
return false;
}
basic_types->i1x2_vec_type = LLVMVectorType(basic_types->int1_type, 2);
basic_types->funcref_type = LLVMInt32TypeInContext(context);
@ -1536,7 +1563,7 @@ aot_compiler_destroy(void)
}
AOTCompContext *
aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
{
AOTCompContext *comp_ctx, *ret = NULL;
LLVMTargetRef target;
@ -1643,6 +1670,12 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
if (option->disable_llvm_lto)
comp_ctx->disable_llvm_lto = true;
if (option->enable_llvm_pgo)
comp_ctx->enable_llvm_pgo = true;
if (option->use_prof_file)
comp_ctx->use_prof_file = option->use_prof_file;
if (option->enable_stack_estimation)
comp_ctx->enable_stack_estimation = true;
@ -2007,6 +2040,7 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
os_printf("Create AoT compiler with:\n");
os_printf(" target: %s\n", comp_ctx->target_arch);
os_printf(" target cpu: %s\n", cpu);
os_printf(" target triple: %s\n", triple_norm);
os_printf(" cpu features: %s\n", features);
os_printf(" opt level: %d\n", opt_level);
os_printf(" size level: %d\n", size_level);
@ -2025,6 +2059,8 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
break;
}
LLVMSetTarget(comp_ctx->module, triple_norm);
if (!LLVMTargetHasTargetMachine(target)) {
snprintf(buf, sizeof(buf),
"no target machine for this target (%s).", triple_norm);
@ -2065,6 +2101,37 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
}
}
triple = LLVMGetTargetMachineTriple(comp_ctx->target_machine);
if (!triple) {
aot_set_last_error("get target machine triple failed.");
goto fail;
}
if (strstr(triple, "linux") && !strcmp(comp_ctx->target_arch, "x86_64")) {
if (option->segue_flags) {
if (option->segue_flags & (1 << 0))
comp_ctx->enable_segue_i32_load = true;
if (option->segue_flags & (1 << 1))
comp_ctx->enable_segue_i64_load = true;
if (option->segue_flags & (1 << 2))
comp_ctx->enable_segue_f32_load = true;
if (option->segue_flags & (1 << 3))
comp_ctx->enable_segue_f64_load = true;
if (option->segue_flags & (1 << 4))
comp_ctx->enable_segue_v128_load = true;
if (option->segue_flags & (1 << 8))
comp_ctx->enable_segue_i32_store = true;
if (option->segue_flags & (1 << 9))
comp_ctx->enable_segue_i64_store = true;
if (option->segue_flags & (1 << 10))
comp_ctx->enable_segue_f32_store = true;
if (option->segue_flags & (1 << 11))
comp_ctx->enable_segue_f64_store = true;
if (option->segue_flags & (1 << 12))
comp_ctx->enable_segue_v128_store = true;
}
}
LLVMDisposeMessage(triple);
if (option->enable_simd && strcmp(comp_ctx->target_arch, "x86_64") != 0
&& strncmp(comp_ctx->target_arch, "aarch64", 7) != 0) {
/* Disable simd if it isn't supported by target arch */
@ -2098,6 +2165,7 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
aot_set_last_error("create LLVM target data layout failed.");
goto fail;
}
LLVMSetModuleDataLayout(comp_ctx->module, target_data_ref);
comp_ctx->pointer_size = LLVMPointerSize(target_data_ref);
LLVMDisposeTargetData(target_data_ref);
@ -2768,3 +2836,23 @@ aot_load_const_from_table(AOTCompContext *comp_ctx, LLVMValueRef base,
(void)const_type;
return const_value;
}
bool
aot_set_cond_br_weights(AOTCompContext *comp_ctx, LLVMValueRef cond_br,
int32 weights_true, int32 weights_false)
{
LLVMMetadataRef md_nodes[3], meta_data;
LLVMValueRef meta_data_as_value;
md_nodes[0] = LLVMMDStringInContext2(comp_ctx->context, "branch_weights",
strlen("branch_weights"));
md_nodes[1] = LLVMValueAsMetadata(I32_CONST(weights_true));
md_nodes[2] = LLVMValueAsMetadata(I32_CONST(weights_false));
meta_data = LLVMMDNodeInContext2(comp_ctx->context, md_nodes, 3);
meta_data_as_value = LLVMMetadataAsValue(comp_ctx->context, meta_data);
LLVMSetMetadata(cond_br, 2, meta_data_as_value);
return true;
}

View File

@ -154,8 +154,6 @@ typedef struct AOTFuncContext {
AOTFunc *aot_func;
LLVMValueRef func;
LLVMTypeRef func_type;
/* LLVM module for this function, note that in LAZY JIT mode,
each aot function belongs to an individual module */
LLVMModuleRef module;
AOTBlockStack block_stack;
@ -214,6 +212,14 @@ typedef struct AOTLLVMTypes {
LLVMTypeRef f32x4_vec_type;
LLVMTypeRef f64x2_vec_type;
LLVMTypeRef int8_ptr_type_gs;
LLVMTypeRef int16_ptr_type_gs;
LLVMTypeRef int32_ptr_type_gs;
LLVMTypeRef int64_ptr_type_gs;
LLVMTypeRef float32_ptr_type_gs;
LLVMTypeRef float64_ptr_type_gs;
LLVMTypeRef v128_ptr_type_gs;
LLVMTypeRef i1x2_vec_type;
LLVMTypeRef meta_data_type;
@ -275,7 +281,7 @@ typedef struct AOTLLVMConsts {
* Compiler context
*/
typedef struct AOTCompContext {
AOTCompData *comp_data;
const AOTCompData *comp_data;
/* LLVM variables required to emit LLVM IR */
LLVMContextRef context;
@ -341,6 +347,25 @@ typedef struct AOTCompContext {
/* Disable LLVM link time optimization */
bool disable_llvm_lto;
/* Enable LLVM PGO (Profile-Guided Optimization) */
bool enable_llvm_pgo;
/* Use profile file collected by LLVM PGO */
char *use_prof_file;
/* Enable to use segument register as the base addr
of linear memory for load/store operations */
bool enable_segue_i32_load;
bool enable_segue_i64_load;
bool enable_segue_f32_load;
bool enable_segue_f64_load;
bool enable_segue_v128_load;
bool enable_segue_i32_store;
bool enable_segue_i64_store;
bool enable_segue_f32_store;
bool enable_segue_f64_store;
bool enable_segue_v128_store;
/* Whether optimize the JITed code */
bool optimize;
@ -407,12 +432,15 @@ typedef struct AOTCompOption {
bool enable_aux_stack_frame;
bool disable_llvm_intrinsics;
bool disable_llvm_lto;
bool enable_llvm_pgo;
bool enable_stack_estimation;
char *use_prof_file;
uint32 opt_level;
uint32 size_level;
uint32 output_format;
uint32 bounds_checks;
uint32 stack_bounds_checks;
uint32 segue_flags;
char **custom_sections;
uint32 custom_sections_count;
const char *stack_usage_file;
@ -425,7 +453,7 @@ void
aot_compiler_destroy(void);
AOTCompContext *
aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option);
aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option);
void
aot_destroy_comp_context(AOTCompContext *comp_ctx);
@ -464,7 +492,7 @@ void
aot_block_destroy(AOTBlock *block);
LLVMTypeRef
wasm_type_to_llvm_type(AOTLLVMTypes *llvm_types, uint8 wasm_type);
wasm_type_to_llvm_type(const AOTLLVMTypes *llvm_types, uint8 wasm_type);
bool
aot_checked_addr_list_add(AOTFuncContext *func_ctx, uint32 local_idx,
@ -519,6 +547,13 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module);
void
aot_handle_llvm_errmsg(const char *string, LLVMErrorRef err);
char *
aot_compress_aot_func_names(AOTCompContext *comp_ctx, uint32 *p_size);
bool
aot_set_cond_br_weights(AOTCompContext *comp_ctx, LLVMValueRef cond_br,
int32 weights_true, int32 weights_false);
#ifdef __cplusplus
} /* end of extern "C" */
#endif

View File

@ -5,6 +5,8 @@
#include <llvm/Passes/StandardInstrumentations.h>
#include <llvm/Support/Error.h>
#include <llvm/ADT/None.h>
#include <llvm/ADT/Optional.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/ADT/Twine.h>
#include <llvm/ADT/Triple.h>
@ -44,6 +46,7 @@
#if LLVM_VERSION_MAJOR >= 12
#include <llvm/Analysis/AliasAnalysis.h>
#endif
#include <llvm/ProfileData/InstrProf.h>
#include <cstring>
#include "../aot/aot_runtime.h"
@ -232,14 +235,26 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
PTO.SLPVectorization = true;
PTO.LoopUnrolling = true;
Optional<PGOOptions> PGO = None;
if (comp_ctx->enable_llvm_pgo) {
/* Disable static counter allocation for value profiler,
it will be allocated by runtime */
const char *argv[] = { "", "-vp-static-alloc=false" };
cl::ParseCommandLineOptions(2, argv);
PGO = PGOOptions("", "", "", PGOOptions::IRInstr);
}
else if (comp_ctx->use_prof_file) {
PGO = PGOOptions(comp_ctx->use_prof_file, "", "", PGOOptions::IRUse);
}
#ifdef DEBUG_PASS
PassInstrumentationCallbacks PIC;
PassBuilder PB(TM, PTO, None, &PIC);
PassBuilder PB(TM, PTO, PGO, &PIC);
#else
#if LLVM_VERSION_MAJOR == 12
PassBuilder PB(false, TM, PTO);
PassBuilder PB(false, TM, PTO, PGO);
#else
PassBuilder PB(TM, PTO);
PassBuilder PB(TM, PTO, PGO);
#endif
#endif
@ -334,8 +349,20 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
FPM.addPass(SLPVectorizerPass());
FPM.addPass(LoadStoreVectorizerPass());
if (comp_ctx->enable_llvm_pgo || comp_ctx->use_prof_file) {
/* LICM pass: loop invariant code motion, attempting to remove
as much code from the body of a loop as possible. Experiments
show it is good to enable it when pgo is enabled. */
#if LLVM_VERSION_MAJOR >= 15
LICMOptions licm_opt;
FPM.addPass(
createFunctionToLoopPassAdaptor(LICMPass(licm_opt), true));
#else
FPM.addPass(createFunctionToLoopPassAdaptor(LICMPass(), true));
#endif
}
/*
FPM.addPass(createFunctionToLoopPassAdaptor(LICMPass()));
FPM.addPass(createFunctionToLoopPassAdaptor(LoopRotatePass()));
FPM.addPass(createFunctionToLoopPassAdaptor(SimpleLoopUnswitchPass()));
*/
@ -344,9 +371,10 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
if (!disable_llvm_lto) {
/* Apply LTO for AOT mode */
if (comp_ctx->comp_data->func_count >= 10)
/* Adds the pre-link optimizations if the func count
is large enough */
if (comp_ctx->comp_data->func_count >= 10
|| comp_ctx->enable_llvm_pgo || comp_ctx->use_prof_file)
/* Add the pre-link optimizations if the func count
is large enough or PGO is enabled */
MPM.addPass(PB.buildLTOPreLinkDefaultPipeline(OL));
else
MPM.addPass(PB.buildLTODefaultPipeline(OL, NULL));
@ -358,3 +386,34 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
MPM.run(*M, MAM);
}
char *
aot_compress_aot_func_names(AOTCompContext *comp_ctx, uint32 *p_size)
{
std::vector<std::string> NameStrs;
std::string Result;
char buf[32], *compressed_str;
uint32 compressed_str_len, i;
for (i = 0; i < comp_ctx->func_ctx_count; i++) {
snprintf(buf, sizeof(buf), "%s%d", AOT_FUNC_PREFIX, i);
std::string str(buf);
NameStrs.push_back(str);
}
if (collectPGOFuncNameStrings(NameStrs, true, Result)) {
aot_set_last_error("collect pgo func name strings failed");
return NULL;
}
compressed_str_len = Result.size();
if (!(compressed_str = (char *)wasm_runtime_malloc(compressed_str_len))) {
aot_set_last_error("allocate memory failed");
return NULL;
}
bh_memcpy_s(compressed_str, compressed_str_len, Result.c_str(),
compressed_str_len);
*p_size = compressed_str_len;
return compressed_str;
}

View File

@ -4,7 +4,13 @@
*/
#include <llvm-c/TargetMachine.h>
#include <llvm/ADT/None.h>
#include <llvm/ADT/Optional.h>
#if LLVM_VERSION_MAJOR >= 14
#include <llvm/MC/TargetRegistry.h>
#else
#include <llvm/Support/TargetRegistry.h>
#endif
#include <llvm/Target/TargetMachine.h>
#include "bh_assert.h"

View File

@ -8,6 +8,8 @@
#include "llvm-c/OrcEE.h"
#include "llvm-c/TargetMachine.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"

View File

@ -114,7 +114,7 @@ destroy_dwarf_extractor(dwar_extractor_handle_t handle)
}
LLVMMetadataRef
dwarf_gen_file_info(AOTCompContext *comp_ctx)
dwarf_gen_file_info(const AOTCompContext *comp_ctx)
{
dwar_extractor *extractor;
int units_number;
@ -191,7 +191,7 @@ dwarf_gen_mock_vm_info(AOTCompContext *comp_ctx)
#endif
LLVMMetadataRef
dwarf_gen_comp_unit_info(AOTCompContext *comp_ctx)
dwarf_gen_comp_unit_info(const AOTCompContext *comp_ctx)
{
dwar_extractor *extractor;
int units_number;
@ -257,7 +257,7 @@ lldb_get_basic_type_encoding(BasicType basic_type)
}
static LLVMMetadataRef
lldb_type_to_type_dbi(AOTCompContext *comp_ctx, SBType &type)
lldb_type_to_type_dbi(const AOTCompContext *comp_ctx, SBType &type)
{
LLVMMetadataRef type_info = NULL;
BasicType basic_type = type.GetBasicType();
@ -282,8 +282,9 @@ lldb_type_to_type_dbi(AOTCompContext *comp_ctx, SBType &type)
}
static LLVMMetadataRef
lldb_function_to_function_dbi(AOTCompContext *comp_ctx, SBSymbolContext &sc,
AOTFuncContext *func_ctx)
lldb_function_to_function_dbi(const AOTCompContext *comp_ctx,
SBSymbolContext &sc,
const AOTFuncContext *func_ctx)
{
SBFunction function(sc.GetFunction());
const char *function_name = function.GetName();
@ -388,7 +389,8 @@ lldb_function_to_function_dbi(AOTCompContext *comp_ctx, SBSymbolContext &sc,
}
LLVMMetadataRef
dwarf_gen_func_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
dwarf_gen_func_info(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx)
{
LLVMMetadataRef func_info = NULL;
dwar_extractor *extractor;
@ -417,8 +419,8 @@ dwarf_gen_func_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
}
void
dwarf_get_func_name(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
char *name, int len)
dwarf_get_func_name(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, char *name, int len)
{
LLVMMetadataRef func_info = NULL;
dwar_extractor *extractor;
@ -448,8 +450,8 @@ dwarf_get_func_name(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
LLVMMetadataRef
dwarf_gen_location(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint64_t vm_offset)
dwarf_gen_location(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, uint64_t vm_offset)
{
LLVMMetadataRef location_info = NULL;
dwar_extractor *extractor;
@ -487,7 +489,8 @@ dwarf_gen_location(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
LLVMMetadataRef
dwarf_gen_func_ret_location(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
dwarf_gen_func_ret_location(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx)
{
LLVMMetadataRef func_info = NULL;
dwar_extractor *extractor;

View File

@ -30,24 +30,26 @@ dwar_extractor_handle_t
create_dwarf_extractor(aot_comp_data_t comp_data, char *file_name);
LLVMMetadataRef
dwarf_gen_file_info(AOTCompContext *comp_ctx);
dwarf_gen_file_info(const AOTCompContext *comp_ctx);
LLVMMetadataRef
dwarf_gen_comp_unit_info(AOTCompContext *comp_ctx);
dwarf_gen_comp_unit_info(const AOTCompContext *comp_ctx);
LLVMMetadataRef
dwarf_gen_func_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
dwarf_gen_func_info(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx);
LLVMMetadataRef
dwarf_gen_location(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint64_t vm_offset);
dwarf_gen_location(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, uint64_t vm_offset);
LLVMMetadataRef
dwarf_gen_func_ret_location(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
dwarf_gen_func_ret_location(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx);
void
dwarf_get_func_name(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
char *name, int len);
dwarf_get_func_name(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, char *name, int len);
#ifdef __cplusplus
}

View File

@ -14,12 +14,12 @@
static LLVMValueRef
simd_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 align,
uint32 offset, uint32 data_length, LLVMTypeRef ptr_type,
LLVMTypeRef data_type)
LLVMTypeRef data_type, bool enable_segue)
{
LLVMValueRef maddr, data;
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset,
data_length))) {
data_length, enable_segue))) {
HANDLE_FAILURE("aot_check_memory_overflow");
return NULL;
}
@ -44,10 +44,12 @@ bool
aot_compile_simd_v128_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset)
{
bool enable_segue = comp_ctx->enable_segue_v128_load;
LLVMTypeRef v128_ptr_type = enable_segue ? V128_PTR_TYPE_GS : V128_PTR_TYPE;
LLVMValueRef result;
if (!(result = simd_load(comp_ctx, func_ctx, align, offset, 16,
V128_PTR_TYPE, V128_TYPE))) {
v128_ptr_type, V128_TYPE, enable_segue))) {
return false;
}
@ -75,6 +77,7 @@ aot_compile_simd_load_extend(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMVectorType(I32_TYPE, 2), LLVMVectorType(I32_TYPE, 2),
};
LLVMTypeRef sub_vector_type, sub_vector_ptr_type;
bool enable_segue = comp_ctx->enable_segue_v128_load;
bh_assert(opcode_index < 6);
@ -82,13 +85,15 @@ aot_compile_simd_load_extend(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* to vector ptr type */
if (!sub_vector_type
|| !(sub_vector_ptr_type = LLVMPointerType(sub_vector_type, 0))) {
|| !(sub_vector_ptr_type =
LLVMPointerType(sub_vector_type, enable_segue ? 256 : 0))) {
HANDLE_FAILURE("LLVMPointerType");
return false;
}
if (!(sub_vector = simd_load(comp_ctx, func_ctx, align, offset, 8,
sub_vector_ptr_type, sub_vector_type))) {
if (!(sub_vector =
simd_load(comp_ctx, func_ctx, align, offset, 8,
sub_vector_ptr_type, sub_vector_type, enable_segue))) {
return false;
}
@ -118,6 +123,9 @@ aot_compile_simd_load_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMValueRef element, result;
LLVMTypeRef element_ptr_types[] = { INT8_PTR_TYPE, INT16_PTR_TYPE,
INT32_PTR_TYPE, INT64_PTR_TYPE };
LLVMTypeRef element_ptr_types_gs[] = { INT8_PTR_TYPE_GS, INT16_PTR_TYPE_GS,
INT32_PTR_TYPE_GS,
INT64_PTR_TYPE_GS };
LLVMTypeRef element_data_types[] = { INT8_TYPE, INT16_TYPE, I32_TYPE,
I64_TYPE };
uint32 data_lengths[] = { 1, 2, 4, 8 };
@ -133,13 +141,16 @@ aot_compile_simd_load_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVM_CONST(i32x4_zero),
LLVM_CONST(i32x2_zero),
};
bool enable_segue = comp_ctx->enable_segue_v128_load;
bh_assert(opcode_index < 4);
if (!(element = simd_load(comp_ctx, func_ctx, align, offset,
data_lengths[opcode_index],
element_ptr_types[opcode_index],
element_data_types[opcode_index]))) {
if (!(element = simd_load(
comp_ctx, func_ctx, align, offset, data_lengths[opcode_index],
comp_ctx->enable_segue_v128_load
? element_ptr_types_gs[opcode_index]
: element_ptr_types[opcode_index],
element_data_types[opcode_index], enable_segue))) {
return false;
}
@ -170,11 +181,15 @@ aot_compile_simd_load_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 data_lengths[] = { 1, 2, 4, 8 };
LLVMTypeRef element_ptr_types[] = { INT8_PTR_TYPE, INT16_PTR_TYPE,
INT32_PTR_TYPE, INT64_PTR_TYPE };
LLVMTypeRef element_ptr_types_gs[] = { INT8_PTR_TYPE_GS, INT16_PTR_TYPE_GS,
INT32_PTR_TYPE_GS,
INT64_PTR_TYPE_GS };
LLVMTypeRef element_data_types[] = { INT8_TYPE, INT16_TYPE, I32_TYPE,
I64_TYPE };
LLVMTypeRef vector_types[] = { V128_i8x16_TYPE, V128_i16x8_TYPE,
V128_i32x4_TYPE, V128_i64x2_TYPE };
LLVMValueRef lane = simd_lane_id_to_llvm_value(comp_ctx, lane_id);
bool enable_segue = comp_ctx->enable_segue_v128_load;
bh_assert(opcode_index < 4);
@ -183,10 +198,12 @@ aot_compile_simd_load_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false;
}
if (!(element = simd_load(comp_ctx, func_ctx, align, offset,
data_lengths[opcode_index],
element_ptr_types[opcode_index],
element_data_types[opcode_index]))) {
if (!(element = simd_load(
comp_ctx, func_ctx, align, offset, data_lengths[opcode_index],
comp_ctx->enable_segue_v128_load
? element_ptr_types_gs[opcode_index]
: element_ptr_types[opcode_index],
element_data_types[opcode_index], enable_segue))) {
return false;
}
@ -207,6 +224,8 @@ aot_compile_simd_load_zero(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 opcode_index = opcode - SIMD_v128_load32_zero;
uint32 data_lengths[] = { 4, 8 };
LLVMTypeRef element_ptr_types[] = { INT32_PTR_TYPE, INT64_PTR_TYPE };
LLVMTypeRef element_ptr_types_gs[] = { INT32_PTR_TYPE_GS,
INT64_PTR_TYPE_GS };
LLVMTypeRef element_data_types[] = { I32_TYPE, I64_TYPE };
LLVMValueRef zero[] = {
LLVM_CONST(i32x4_vec_zero),
@ -222,13 +241,16 @@ aot_compile_simd_load_zero(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVM_CONST(i32_six) },
{ LLVM_CONST(i32_zero), LLVM_CONST(i32_two) },
};
bool enable_segue = comp_ctx->enable_segue_v128_load;
bh_assert(opcode_index < 2);
if (!(element = simd_load(comp_ctx, func_ctx, align, offset,
data_lengths[opcode_index],
element_ptr_types[opcode_index],
element_data_types[opcode_index]))) {
if (!(element = simd_load(
comp_ctx, func_ctx, align, offset, data_lengths[opcode_index],
comp_ctx->enable_segue_v128_load
? element_ptr_types_gs[opcode_index]
: element_ptr_types[opcode_index],
element_data_types[opcode_index], enable_segue))) {
return false;
}
@ -260,12 +282,12 @@ aot_compile_simd_load_zero(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
static bool
simd_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 align,
uint32 offset, uint32 data_length, LLVMValueRef value,
LLVMTypeRef value_ptr_type)
LLVMTypeRef value_ptr_type, bool enable_segue)
{
LLVMValueRef maddr, result;
if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset,
data_length)))
data_length, enable_segue)))
return false;
if (!(maddr = LLVMBuildBitCast(comp_ctx->builder, maddr, value_ptr_type,
@ -288,12 +310,14 @@ bool
aot_compile_simd_v128_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset)
{
bool enable_segue = comp_ctx->enable_segue_v128_store;
LLVMTypeRef v128_ptr_type = enable_segue ? V128_PTR_TYPE_GS : V128_PTR_TYPE;
LLVMValueRef value;
POP_V128(value);
return simd_store(comp_ctx, func_ctx, align, offset, 16, value,
V128_PTR_TYPE);
v128_ptr_type, enable_segue);
fail:
return false;
}
@ -307,10 +331,14 @@ aot_compile_simd_store_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 data_lengths[] = { 1, 2, 4, 8 };
LLVMTypeRef element_ptr_types[] = { INT8_PTR_TYPE, INT16_PTR_TYPE,
INT32_PTR_TYPE, INT64_PTR_TYPE };
LLVMTypeRef element_ptr_types_gs[] = { INT8_PTR_TYPE_GS, INT16_PTR_TYPE_GS,
INT32_PTR_TYPE_GS,
INT64_PTR_TYPE_GS };
uint32 opcode_index = opcode - SIMD_v128_store8_lane;
LLVMTypeRef vector_types[] = { V128_i8x16_TYPE, V128_i16x8_TYPE,
V128_i32x4_TYPE, V128_i64x2_TYPE };
LLVMValueRef lane = simd_lane_id_to_llvm_value(comp_ctx, lane_id);
bool enable_segue = comp_ctx->enable_segue_v128_store;
bh_assert(opcode_index < 4);
@ -327,5 +355,7 @@ aot_compile_simd_store_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return simd_store(comp_ctx, func_ctx, align, offset,
data_lengths[opcode_index], element,
element_ptr_types[opcode_index]);
enable_segue ? element_ptr_types_gs[opcode_index]
: element_ptr_types[opcode_index],
enable_segue);
}

View File

@ -55,12 +55,15 @@ typedef struct AOTCompOption {
bool enable_aux_stack_frame;
bool disable_llvm_intrinsics;
bool disable_llvm_lto;
bool enable_llvm_pgo;
bool enable_stack_estimation;
char *use_prof_file;
uint32_t opt_level;
uint32_t size_level;
uint32_t output_format;
uint32_t bounds_checks;
uint32_t stack_bounds_checks;
uint32_t segue_flags;
char **custom_sections;
uint32_t custom_sections_count;
const char *stack_usage_file;

View File

@ -167,6 +167,8 @@ typedef struct RuntimeInitArgs {
/* LLVM JIT opt and size level */
uint32_t llvm_jit_opt_level;
uint32_t llvm_jit_size_level;
/* Segue optimization flags for LLVM JIT */
uint32_t segue_flags;
} RuntimeInitArgs;
#ifndef WASM_VALKIND_T_DEFINED
@ -1329,6 +1331,30 @@ WASM_RUNTIME_API_EXTERN uint32_t
wasm_runtime_dump_call_stack_to_buf(wasm_exec_env_t exec_env, char *buf,
uint32_t len);
/**
* Get the size required to store the LLVM PGO profile data
*
* @param module_inst the WASM module instance
*
* @return size required to store the contents, 0 means error
*/
WASM_RUNTIME_API_EXTERN uint32_t
wasm_runtime_get_pgo_prof_data_size(wasm_module_inst_t module_inst);
/**
* Dump the LLVM PGO profile data to buffer
*
* @param module_inst the WASM module instance
* @param buf buffer to store the dumped content
* @param len length of the buffer
*
* @return bytes dumped to the buffer, 0 means error and data in buf
* may be invalid
*/
WASM_RUNTIME_API_EXTERN uint32_t
wasm_runtime_dump_pgo_prof_data_to_buf(wasm_module_inst_t module_inst,
char *buf, uint32_t len);
/**
* Get a custom section by name
*
@ -1351,20 +1377,21 @@ WASM_RUNTIME_API_EXTERN void
wasm_runtime_get_version(uint32_t *major, uint32_t *minor, uint32_t *patch);
/**
* Check whether an import func `(import <module_name> <func_name> (func ...))` is linked or not
* with runtime registered natvie functions
* Check whether an import func `(import <module_name> <func_name> (func ...))`
* is linked or not with runtime registered natvie functions
*/
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_is_import_func_linked(const char *module_name,
const char *func_name);
/**
* Check whether an import global `(import <module_name> <global_name> (global ...))` is linked or not
* with runtime registered natvie globals
* Check whether an import global `(import <module_name> <global_name> (global ...))`
* is linked or not with runtime registered natvie globals
*/
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_is_import_global_linked(const char *module_name,
const char *global_name);
/* clang-format on */
#ifdef __cplusplus

View File

@ -270,7 +270,7 @@ local_copysignf(float x, float y)
{
union {
float f;
uint32_t i;
uint32 i;
} ux = { x }, uy = { y };
ux.i &= 0x7fffffff;
ux.i |= uy.i & 0x80000000;
@ -282,9 +282,9 @@ local_copysign(double x, double y)
{
union {
double f;
uint64_t i;
uint64 i;
} ux = { x }, uy = { y };
ux.i &= -1ULL / 2;
ux.i &= UINT64_MAX / 2;
ux.i |= uy.i & 1ULL << 63;
return ux.f;
}
@ -4002,6 +4002,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
#if WASM_ENABLE_FAST_JIT != 0
/* ASAN is not designed to work with custom stack unwind or other low-level \
things. > Ignore a function that does some low-level magic. (e.g. walking \
through the thread's stack bypassing the frame boundaries) */
#if defined(__GNUC__)
__attribute__((no_sanitize_address))
#endif
static void
fast_jit_call_func_bytecode(WASMModuleInstance *module_inst,
WASMExecEnv *exec_env,
@ -4241,6 +4247,15 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
wasm_exec_env_set_cur_frame(exec_env, frame);
#if defined(os_writegsbase)
{
WASMMemoryInstance *memory_inst = wasm_get_default_memory(module_inst);
if (memory_inst)
/* write base addr of linear memory to GS segment register */
os_writegsbase(memory_inst->memory_data);
}
#endif
if (function->is_import_func) {
#if WASM_ENABLE_MULTI_MODULE != 0
if (function->import_module_inst) {

View File

@ -232,7 +232,7 @@ local_copysignf(float x, float y)
{
union {
float f;
uint32_t i;
uint32 i;
} ux = { x }, uy = { y };
ux.i &= 0x7fffffff;
ux.i |= uy.i & 0x80000000;
@ -244,9 +244,9 @@ local_copysign(double x, double y)
{
union {
double f;
uint64_t i;
uint64 i;
} ux = { x }, uy = { y };
ux.i &= -1ULL / 2;
ux.i &= UINT64_MAX / 2;
ux.i |= uy.i & 1ULL << 63;
return ux.f;
}
@ -3995,6 +3995,15 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
wasm_exec_env_set_cur_frame(exec_env, frame);
#if defined(os_writegsbase)
{
WASMMemoryInstance *memory_inst = wasm_get_default_memory(module_inst);
if (memory_inst)
/* write base addr of linear memory to GS segment register */
os_writegsbase(memory_inst->memory_data);
}
#endif
if (function->is_import_func) {
#if WASM_ENABLE_MULTI_MODULE != 0
if (function->import_module_inst) {

View File

@ -3000,7 +3000,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
if (module->function_count == 0)
return true;
#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_LLVM_JIT != 0
#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_LAZY_JIT != 0
if (os_mutex_init(&module->tierup_wait_lock) != 0) {
set_error_buf(error_buf, error_buf_size, "init jit tierup lock failed");
return false;
@ -3035,6 +3035,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
llvm_jit_options = wasm_runtime_get_llvm_jit_options();
option.opt_level = llvm_jit_options.opt_level;
option.size_level = llvm_jit_options.size_level;
option.segue_flags = llvm_jit_options.segue_flags;
#if WASM_ENABLE_BULK_MEMORY != 0
option.enable_bulk_memory = true;

View File

@ -1843,7 +1843,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
if (module->function_count == 0)
return true;
#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_LLVM_JIT != 0
#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_LAZY_JIT != 0
if (os_mutex_init(&module->tierup_wait_lock) != 0) {
set_error_buf(error_buf, error_buf_size, "init jit tierup lock failed");
return false;
@ -1876,6 +1876,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
option.is_jit_mode = true;
option.opt_level = llvm_jit_options.opt_level;
option.size_level = llvm_jit_options.size_level;
option.segue_flags = llvm_jit_options.segue_flags;
#if WASM_ENABLE_BULK_MEMORY != 0
option.enable_bulk_memory = true;

View File

@ -3048,12 +3048,14 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env, bool print, char *buf,
/* function name not exported, print number instead */
if (frame.func_name_wp == NULL) {
line_length = snprintf(line_buf, sizeof(line_buf), "#%02d $f%d\n",
n, frame.func_index);
line_length =
snprintf(line_buf, sizeof(line_buf),
"#%02" PRIu32 " $f%" PRIu32 "\n", n, frame.func_index);
}
else {
line_length = snprintf(line_buf, sizeof(line_buf), "#%02d %s\n", n,
frame.func_name_wp);
line_length =
snprintf(line_buf, sizeof(line_buf), "#%02" PRIu32 " %s\n", n,
frame.func_name_wp);
}
if (line_length >= sizeof(line_buf)) {

View File

@ -561,7 +561,6 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
#if WASM_ENABLE_LIBC_WASI != 0
WASIContext *wasi_ctx;
#endif
CApiFuncImport **new_c_api_func_imports = NULL;
bh_assert(module);
bh_assert(module_inst);

View File

@ -56,11 +56,13 @@ typedef struct WASIContext *wasi_ctx_t;
wasi_ctx_t
wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst);
#if WASM_ENABLE_THREAD_MGR != 0
static inline uint64_t
min_uint64(uint64_t a, uint64_t b)
{
return a > b ? b : a;
}
#endif
static inline uint32_t
min_uint32(uint32_t a, uint32_t b)

View File

@ -41,7 +41,7 @@
#endif
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__EMSCRIPTEN__) \
&& !defined(ESP_PLATFORM)
&& !defined(ESP_PLATFORM) && !defined(DISABLE_CLOCK_NANOSLEEP)
#define CONFIG_HAS_CLOCK_NANOSLEEP 1
#else
#define CONFIG_HAS_CLOCK_NANOSLEEP 0

View File

@ -8,7 +8,7 @@ project (iwasm)
set (CMAKE_VERBOSE_MAKEFILE OFF)
# Reset default linker flags
set (CMAKE_C_STANDARD 99)
set (CMAKE_CXX_STANDARD 14)
set (CMAKE_CXX_STANDARD 17)
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")

View File

@ -564,6 +564,7 @@ gc_realloc_vo_internal(void *vheap, void *ptr, gc_size_t size, const char *file,
os_mutex_unlock(&heap->lock);
return NULL;
}
hmu_mark_pinuse(hmu_next);
}
os_mutex_unlock(&heap->lock);
return obj_old;

View File

@ -214,13 +214,16 @@ set_hmu_normal_node_next(hmu_normal_node_t *node, hmu_normal_node_t *next)
#if defined(_MSC_VER)
__pragma(pack(push, 1));
#define __attr_packed
#define __attr_aligned(a)
#elif defined(__GNUC__) || defined(__clang__)
#define __attr_packed __attribute__((packed))
#define __attr_aligned(a) __attribute__((aligned(a)))
#else
#error "packed attribute isn't used to define struct hmu_tree_node"
#endif
#else /* else of UINTPTR_MAX == UINT64_MAX */
#define __attr_packed
#define __attr_aligned(a)
#endif
typedef struct hmu_tree_node {
@ -229,7 +232,7 @@ typedef struct hmu_tree_node {
struct hmu_tree_node *right;
struct hmu_tree_node *parent;
gc_size_t size;
} __attr_packed hmu_tree_node_t;
} __attr_packed __attr_aligned(4) hmu_tree_node_t;
#if UINTPTR_MAX == UINT64_MAX
#if defined(_MSC_VER)

View File

@ -492,6 +492,12 @@ destroy_stack_guard_pages()
}
#endif /* end of WASM_DISABLE_STACK_HW_BOUND_CHECK == 0 */
/* ASAN is not designed to work with custom stack unwind or other low-level \
things. > Ignore a function that does some low-level magic. (e.g. walking \
through the thread's stack bypassing the frame boundaries) */
#if defined(__GNUC__)
__attribute__((no_sanitize_address))
#endif
static void
mask_signals(int how)
{
@ -506,6 +512,12 @@ mask_signals(int how)
static os_thread_local_attribute struct sigaction prev_sig_act_SIGSEGV;
static os_thread_local_attribute struct sigaction prev_sig_act_SIGBUS;
/* ASAN is not designed to work with custom stack unwind or other low-level \
things. > Ignore a function that does some low-level magic. (e.g. walking \
through the thread's stack bypassing the frame boundaries) */
#if defined(__GNUC__)
__attribute__((no_sanitize_address))
#endif
static void
signal_callback(int sig_num, siginfo_t *sig_info, void *sig_ucontext)
{

View File

@ -130,6 +130,7 @@ os_thread_exit(void *retval);
#define os_memory_order_release memory_order_release
#define os_memory_order_seq_cst memory_order_seq_cst
#define os_atomic_thread_fence atomic_thread_fence
#define os_atomic_cmpxchg atomic_compare_exchange_strong
#endif
#endif /* end of os_atomic_thread_fence */

View File

@ -63,6 +63,22 @@ typedef sem_t korp_sem;
#define bh_socket_t int
#if WASM_DISABLE_WRITE_GS_BASE == 0
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
#define os_writegsbase(base_addr) \
do { \
uint64 __gs_value = (uint64)(uintptr_t)base_addr; \
asm volatile("wrgsbase %0" ::"r"(__gs_value) : "memory"); \
} while (0)
#if 0
/* _writegsbase_u64 also works, but need to add -mfsgsbase flag for gcc */
#include <immintrin.h>
#define os_writegsbase(base_addr) \
_writegsbase_u64(((uint64)(uintptr_t)base_addr))
#endif
#endif
#endif
#if WASM_DISABLE_HW_BOUND_CHECK == 0
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \

View File

@ -26,6 +26,7 @@
#include <malloc.h>
#include <process.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <basetsd.h>

View File

@ -5,7 +5,7 @@ set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
add_definitions(-DBH_PLATFORM_WINDOWS)
add_definitions(-DHAVE_STRUCT_TIMESPEC)
add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS)
include_directories(${PLATFORM_SHARED_DIR})
include_directories(${PLATFORM_SHARED_DIR}/../include)

View File

@ -7,5 +7,5 @@
#define _WAMR_VERSION_H_
#define WAMR_VERSION_MAJOR 1
#define WAMR_VERSION_MINOR 2
#define WAMR_VERSION_PATCH 1
#define WAMR_VERSION_PATCH 2
#endif

View File

@ -98,7 +98,7 @@ cmake -DWAMR_BUILD_PLATFORM=linux -DWAMR_BUILD_TARGET=ARM
#### **Disable boundary check with hardware trap**
- **WAMR_DISABLE_HW_BOUND_CHECK**=1/0, default to enable if not set and supported by platform
> Note: by default only platform linux/darwin/android/windows/vxworks 64-bit will enable the boundary check with hardware trap feature, and the wamrc tool will generate AOT code without boundary check instructions in all 64-bit targets except SGX to improve performance. The boundary check includes linear memory access boundary and native stack access boundary, if `WAMR_DISABLE_STACK_HW_BOUND_CHECK` below isn't set.
> Note: by default only platform [linux/darwin/android/windows/vxworks 64-bit](https://github.com/bytecodealliance/wasm-micro-runtime/blob/5fb5119239220b0803e7045ca49b0a29fe65e70e/core/shared/platform/linux/platform_internal.h#L81) will enable the boundary check with hardware trap feature, for 32-bit platforms it's automatically disabled even when the flag is set to 0, and the wamrc tool will generate AOT code without boundary check instructions in all 64-bit targets except SGX to improve performance. The boundary check includes linear memory access boundary and native stack access boundary, if `WAMR_DISABLE_STACK_HW_BOUND_CHECK` below isn't set.
#### **Disable native stack boundary check with hardware trap**
- **WAMR_DISABLE_STACK_HW_BOUND_CHECK**=1/0, default to enable if not set and supported by platform, same as `WAMR_DISABLE_HW_BOUND_CHECK`.
@ -198,6 +198,13 @@ Currently we only profile the memory consumption of module, module_instance and
- **WAMR_BUILD_STACK_GUARD_SIZE**=n, default to N/A if not set.
> Note: By default, the stack guard size is 1K (1024) or 24K (if uvwasi enabled).
### **Disable the writing linear memory base address to x86 GS segment register
- **WAMR_DISABLE_WRITE_GS_BASE**=1/0, default to enable if not set and supported by platform
> Note: by default only platform [linux x86-64](https://github.com/bytecodealliance/wasm-micro-runtime/blob/5fb5119239220b0803e7045ca49b0a29fe65e70e/core/shared/platform/linux/platform_internal.h#L67) will enable this feature, for 32-bit platforms it's automatically disabled even when the flag is set to 0. In linux x86-64, writing the linear memory base address to x86 GS segment register may be used to speedup the linear memory access for LLVM AOT/JIT, when `--enable-segue=[<flags>]` option is added for `wamrc` or `iwasm`.
### **Enable running PGO(Profile-Guided Optimization) instrumented AOT file**
- **WAMR_BUILD_STATIC_PGO**=1/0, default to disable if not set
**Combination of configurations:**
We can combine the configurations. For example, if we want to disable interpreter, enable AOT and WASI, we can run command:

View File

@ -394,7 +394,7 @@ Examples: wamrc -o test.aot test.wasm
### Usage example
``` bash
WAMRC_LLC_COMPILER=<path/to/your/compiler/driver> ./wamrc -o test.aot test.wasm
WAMRC_LLC_COMPILER=/usr/local/opt/llvm@14/bin/clang WAMRC_LLC_FLAGS="--target=x86_64-pc-linux-gnu -mcmodel=medium -c -O3" ./wamrc -o test.aot test.wasm
```
> Note: `wamrc` will verify whether the specified file exists and executable. If verification failed, `wamrc` will report a warning and fallback to normal pipeline. Since the verification is based on file, you **must specify the absolute path to the binary** even if it's in `$PATH`
@ -403,6 +403,8 @@ WAMRC_LLC_COMPILER=<path/to/your/compiler/driver> ./wamrc -o test.aot test.wasm
> Note: the `LLC` and `ASM` in the env name just means this compiler will be used to compile the `LLVM IR file`/`assembly file` to object file, usually passing the compiler driver is the simplest way. (e.g. for LLVM toolchain, you don't need to pass `/usr/bin/llc`, using `/usr/bin/clang` is OK)
> Note: You might need to set `WAMRC_LLC_FLAGS`/`WAMRC_ASM_FLAGS` to match whatever the `wamrc` command would automatically do. In the above example, `-mcmodel=medium` corresponds to `wamrc --size-level=1`, which is the default of `wamrc` on macOS.
Run WASM app in WAMR mini product build
=======================================

74
doc/perf_tune.md Normal file
View File

@ -0,0 +1,74 @@
# Tune the performance of running wasm/aot file
Normally there are some methods to tune the performance:
## 1. Use `wasm-opt` tool
Download the [binaryen release](https://github.com/WebAssembly/binaryen/releases), and use the `wasm-opt` tool in it to optimize the wasm file, for example:
```bash
wasm-opt -O4 -o test_opt.wasm test.wasm
```
## 2. Enable `simd128` option when compiling wasm source files
WebAssembly [128-bit SIMD](https://github.com/WebAssembly/simd) is supported by WAMR on x86-64 and aarch64 targets, enabling it when compiling wasm source files may greatly improve the performance. For [wasi-sdk](https://github.com/WebAssembly/wasi-sdk) and [emsdk](https://github.com/emscripten-core/emsdk), please add `-msimd128` flag for `clang` and `emcc/em++`:
```bash
/opt/wasi-sdk/bin/clang -msimd128 -O3 -o <wasm_file> <c/c++ source files>
emcc -msimd128 -O3 -o <wasm_file> <c/c++ source files>
```
## 3. Enable segue optimization for wamrc when generating the aot file
[Segue](https://plas2022.github.io/files/pdf/SegueColorGuard.pdf) is an optimization technology which uses x86 segment register to store the WebAssembly linear memory base address, so as to remove most of the cost of SFI (Software-based Fault Isolation) base addition and free up a general purpose register, by this way it may:
- Improve the performance of JIT/AOT
- Reduce the footprint of JIT/AOT, the JIT/AOT code generated is smaller
- Reduce the compilation time of JIT/AOT
Currently it is supported on linux x86-64, developer can use `--enable-segue=[<flags>]` for wamrc:
```bash
wamrc --enable-segue -o aot_file wasm_file
# or
wamrc --enable-segue=[<flags>] -o aot_file wasm_file
```
`flags` can be: i32.load, i64.load, f32.load, f64.load, v128.load, i32.store, i64.store, f32.store, f64.store and v128.store, use comma to separate them, e.g. `--enable-segue=i32.load,i64.store`, and `--enable-segue` means all flags are added.
> Note: Normally for most cases, using `--enable-segue` is enough, but for some cases, using `--enable-segue=<flags>` may be better, for example for CoreMark benchmark, `--enable-segue=i32.store` may lead to better performance than `--enable-segue`.
## 4. Enable segue optimization for iwasm when running wasm file
Similar to segue optimization for wamrc, run:
``` bash
iwasm --enable-segue wasm_file (iwasm is built with llvm-jit enabled)
# or
iwasm --enable-segue=[<flags>] wasm_file
```
## 5. Use the AOT static PGO method
LLVM PGO (Profile-Guided Optimization) allows the compiler to better optimize code for how it actually runs. WAMR supports AOT static PGO, currently it is tested on Linux x86-64 and x86-32. The basic steps are:
1. Use `wamrc --enable-llvm-pgo -o <aot_file_of_pgo> <wasm_file>` to generate an instrumented aot file.
2. Compile iwasm with `cmake -DWAMR_BUILD_STATIC_PGO=1` and run `iwasm --gen-prof-file=<raw_profile_file> <aot_file_of_pgo>` to generate the raw profile file.
> Note: Directly dumping raw profile data to file system may be unsupported in some environments, developer can dump the profile data into memory buffer instead and try outputting it through network (e.g. uart or socket):
```C
uint32_t
wasm_runtime_get_pgo_prof_data_size(wasm_module_inst_t module_inst);
uint32_t
wasm_runtime_dump_pgo_prof_data_to_buf(wasm_module_inst_t module_inst, char *buf, uint32_t len);
```
3. Install or compile `llvm-profdata` toolrefer to [here](../tests/benchmarks/README.md#install-llvm-profdata) for the details.
4. Run `llvm-profdata merge -output=<profile_file> <raw_profile_file>` to merge the raw profile file into the profile file.
5. Run `wamrc --use-prof-file=<profile_file> -o <aot_file> <wasm_file>` to generate the optimized aot file.
6. Run the optimized aot_file: `iwasm <aot_file>`.
Developer can refer to the `test_pgo.sh` files under each benchmark folder for more details, e.g. [test_pgo.sh](../tests/benchmarks/coremark/test_pgo.sh) of CoreMark benchmark.

View File

@ -4,6 +4,8 @@ The WAMR Python package contains a set of high-level bindings for WAMR API and W
## Installation
* **Notice**: This python package need python >= `3.9`.
To Install from local source tree in _development mode_ run the following command,
```bash

View File

@ -62,4 +62,5 @@ setup(
'install': PreInstallCommand,
'egg_info': PreEggInfoCommand,
},
python_requires='>=3.9'
)

View File

@ -1,5 +1,7 @@
# WARM API
* **Notice**: The python package `wamr.wamrapi.wamr` need python >= `3.9`.
## Setup
### Pre-requisites

0
language-bindings/python/wamr-api/samples/compile.sh Normal file → Executable file
View File

View File

@ -34,7 +34,7 @@ if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif ()
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
if (NOT DEFINED WAMR_BUILD_INTERP)
# Enable Interpreter by default

View File

@ -34,7 +34,7 @@ if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif ()
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
if (NOT DEFINED WAMR_BUILD_INTERP)
# Enable Interpreter by default

View File

@ -41,7 +41,7 @@ if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif ()
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
if (NOT DEFINED WAMR_BUILD_INTERP)
# Enable Interpreter by default

View File

@ -89,6 +89,11 @@ if (NOT DEFINED WAMR_BUILD_SGX_IPFS)
set (WAMR_BUILD_SGX_IPFS 0)
endif ()
if (NOT DEFINED WAMR_BUILD_STATIC_PGO)
# Disable static PGO by default
set (WAMR_BUILD_STATIC_PGO 0)
endif ()
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11 -ffunction-sections -fdata-sections \
-Wall -Wno-unused-parameter -Wno-pedantic \
@ -107,6 +112,18 @@ add_custom_command (
add_custom_target (vmlib_untrusted ALL DEPENDS libvmlib_untrusted.a)
if ((WAMR_BUILD_STATIC_PGO EQUAL 1) AND (WAMR_BUILD_AOT EQUAL 1))
execute_process(
COMMAND bash -c "sed -i -E 's/^WAMR_BUILD_STATIC_PGO = 0/WAMR_BUILD_STATIC_PGO = 1/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Makefile"
OUTPUT_VARIABLE cmdOutput
)
else()
execute_process(
COMMAND bash -c "sed -i -E 's/^WAMR_BUILD_STATIC_PGO = 1/WAMR_BUILD_STATIC_PGO = 0/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Makefile"
OUTPUT_VARIABLE cmdOutput
)
endif()
if (DEFINED WAMR_BUILD_GLOBAL_HEAP_POOL)
execute_process(
COMMAND bash -c "sed -i -E 's/^WAMR_BUILD_GLOBAL_HEAP_POOL = .*/WAMR_BUILD_GLOBAL_HEAP_POOL = ${WAMR_BUILD_GLOBAL_HEAP_POOL}/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Makefile"

View File

@ -232,6 +232,9 @@ print_help()
printf(" for example:\n");
printf(" --addr-pool=1.2.3.4/15,2.3.4.5/16\n");
printf(" --max-threads=n Set maximum thread number per cluster, default is 4\n");
#if WASM_ENABLE_STATIC_PGO != 0
printf(" --gen-prof-file=<path> Generate LLVM PGO (Profile-Guided Optimization) profile file\n");
#endif
printf(" --version Show version information\n");
return 1;
}
@ -294,6 +297,10 @@ typedef enum EcallCmd {
CMD_SET_WASI_ARGS, /* wasm_runtime_set_wasi_args() */
CMD_SET_LOG_LEVEL, /* bh_log_set_verbose_level() */
CMD_GET_VERSION, /* wasm_runtime_get_version() */
#if WASM_ENABLE_STATIC_PGO != 0
CMD_GET_PGO_PROF_BUF_SIZE, /* wasm_runtime_get_pro_prof_data_size() */
CMD_DUMP_PGO_PROF_BUF_DATA, /* wasm_runtime_dump_pgo_prof_data_to_buf() */
#endif
} EcallCmd;
static void
@ -598,6 +605,64 @@ get_version(uint64_t *major, uint64_t *minor, uint64_t *patch)
*patch = ecall_args[2];
}
#if WASM_ENABLE_STATIC_PGO != 0
static void
dump_pgo_prof_data(void *module_inst, const char *path)
{
char *buf;
uint32_t len;
FILE *file;
uint64_t ecall_args[1];
ecall_args[0] = (uint64_t)(uintptr_t)module_inst;
if (SGX_SUCCESS
!= ecall_handle_command(g_eid, CMD_GET_PGO_PROF_BUF_SIZE,
(uint8_t *)ecall_args, sizeof(ecall_args))) {
printf("Call ecall_handle_command() failed.\n");
return;
}
if (!(len = ecall_args[0])) {
printf("failed to get LLVM PGO profile data size\n");
return;
}
if (!(buf = (char *)malloc(len))) {
printf("allocate memory failed\n");
return;
}
uint64_t ecall_args_2[3];
ecall_args_2[0] = (uint64_t)(uintptr_t)module_inst;
ecall_args_2[1] = (uint64_t)(uintptr_t)buf;
ecall_args_2[2] = len;
if (SGX_SUCCESS
!= ecall_handle_command(g_eid, CMD_DUMP_PGO_PROF_BUF_DATA,
(uint8_t *)ecall_args_2,
sizeof(ecall_args_2))) {
printf("Call ecall_handle_command() failed.\n");
free(buf);
return;
}
if (!(len = ecall_args_2[0])) {
printf("failed to dump LLVM PGO profile data\n");
free(buf);
return;
}
if (!(file = fopen(path, "wb"))) {
printf("failed to create file %s", path);
free(buf);
return;
}
fwrite(buf, len, 1, file);
fclose(file);
free(buf);
printf("LLVM raw profile file %s was generated.\n", path);
}
#endif
int
main(int argc, char *argv[])
{
@ -619,6 +684,9 @@ main(int argc, char *argv[])
const char *addr_pool[8] = { NULL };
uint32_t addr_pool_size = 0;
uint32_t max_thread_num = 4;
#if WASM_ENABLE_STATIC_PGO != 0
const char *gen_prof_file = NULL;
#endif
if (enclave_init(&g_eid) < 0) {
std::cout << "Fail to initialize enclave." << std::endl;
@ -718,6 +786,13 @@ main(int argc, char *argv[])
return print_help();
max_thread_num = atoi(argv[0] + 14);
}
#if WASM_ENABLE_STATIC_PGO != 0
else if (!strncmp(argv[0], "--gen-prof-file=", 16)) {
if (argv[0][16] == '\0')
return print_help();
gen_prof_file = argv[0] + 16;
}
#endif
else if (!strncmp(argv[0], "--version", 9)) {
uint64_t major = 0, minor = 0, patch = 0;
get_version(&major, &minor, &patch);
@ -779,6 +854,11 @@ main(int argc, char *argv[])
else
app_instance_main(wasm_module_inst, argc, argv);
#if WASM_ENABLE_STATIC_PGO != 0
if (gen_prof_file)
dump_pgo_prof_data(wasm_module_inst, gen_prof_file);
#endif
ret = 0;
/* Deinstantiate module */
@ -836,7 +916,7 @@ wamr_pal_create_process(struct wamr_pal_create_process_args *args)
int stdoutfd = -1;
int stderrfd = -1;
int argc = 2;
const int argc = 2;
char *argv[argc] = { (char *)"./iwasm", (char *)args->argv[0] };
uint8_t *wasm_files_buf = NULL;

View File

@ -49,6 +49,10 @@ typedef enum EcallCmd {
CMD_SET_WASI_ARGS, /* wasm_runtime_set_wasi_args() */
CMD_SET_LOG_LEVEL, /* bh_log_set_verbose_level() */
CMD_GET_VERSION, /* wasm_runtime_get_version() */
#if WASM_ENABLE_STATIC_PGO != 0
CMD_GET_PGO_PROF_BUF_SIZE, /* wasm_runtime_get_pro_prof_data_size() */
CMD_DUMP_PGO_PROF_BUF_DATA, /* wasm_runtime_dump_pgo_prof_data_to_buf() */
#endif
} EcallCmd;
typedef struct EnclaveModule {
@ -597,6 +601,36 @@ handle_cmd_get_version(uint64 *args, uint32 argc)
args[2] = patch;
}
#if WASM_ENABLE_STATIC_PGO != 0
static void
handle_cmd_get_pgo_prof_buf_size(uint64 *args, int32 argc)
{
wasm_module_inst_t module_inst = *(wasm_module_inst_t *)args;
uint32 buf_len;
bh_assert(argc == 1);
buf_len = wasm_runtime_get_pgo_prof_data_size(module_inst);
args[0] = buf_len;
}
static void
handle_cmd_get_pro_prof_buf_data(uint64 *args, int32 argc)
{
uint64 *args_org = args;
wasm_module_inst_t module_inst = *(wasm_module_inst_t *)args++;
char *buf = *(char **)args++;
uint32 len = *(uint32 *)args++;
uint32 bytes_dumped;
bh_assert(argc == 3);
bytes_dumped =
wasm_runtime_dump_pgo_prof_data_to_buf(module_inst, buf, len);
args_org[0] = bytes_dumped;
}
#endif
void
ecall_handle_command(unsigned cmd, unsigned char *cmd_buf,
unsigned cmd_buf_size)
@ -647,6 +681,14 @@ ecall_handle_command(unsigned cmd, unsigned char *cmd_buf,
case CMD_GET_VERSION:
handle_cmd_get_version(args, argc);
break;
#if WASM_ENABLE_STATIC_PGO != 0
case CMD_GET_PGO_PROF_BUF_SIZE:
handle_cmd_get_pgo_prof_buf_size(args, argc);
break;
case CMD_DUMP_PGO_PROF_BUF_DATA:
handle_cmd_get_pro_prof_buf_data(args, argc);
break;
#endif
default:
LOG_ERROR("Unknown command %d\n", cmd);
break;

View File

@ -15,6 +15,7 @@ WAMR_BUILD_SGX_IPFS = 0
WAMR_BUILD_LIB_RATS = 0
WAMR_BUILD_GLOBAL_HEAP_POOL = 0
WAMR_BUILD_GLOBAL_HEAP_SIZE = 10485760
WAMR_BUILD_STATIC_PGO = 0
VMLIB_BUILD_DIR ?= $(CURDIR)/../build
LIB_RATS_SRC ?= $(VMLIB_BUILD_DIR)/_deps/librats-build
@ -65,7 +66,7 @@ ifeq ($(WAMR_BUILD_LIB_RATS), 1)
App_Include_Paths += -I$(LIB_RATS_INCLUDE_DIR)
endif
App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths) -DWASM_ENABLE_STATIC_PGO=$(WAMR_BUILD_STATIC_PGO)
# Three configuration modes - Debug, prerelease, release
# Debug - Macro DEBUG enabled.
@ -134,7 +135,7 @@ ifeq ($(WAMR_BUILD_LIB_RATS), 1)
Enclave_Include_Paths += -I$(LIB_RATS_INCLUDE_DIR) -I$(SGX_SSL)/include
endif
Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths) -DWASM_GLOBAL_HEAP_SIZE=$(WAMR_BUILD_GLOBAL_HEAP_SIZE) -DWASM_ENABLE_GLOBAL_HEAP_POOL=$(WAMR_BUILD_GLOBAL_HEAP_POOL) -DWASM_ENABLE_LIB_RATS=$(WAMR_BUILD_LIB_RATS)
Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths) -DWASM_GLOBAL_HEAP_SIZE=$(WAMR_BUILD_GLOBAL_HEAP_SIZE) -DWASM_ENABLE_GLOBAL_HEAP_POOL=$(WAMR_BUILD_GLOBAL_HEAP_POOL) -DWASM_ENABLE_LIB_RATS=$(WAMR_BUILD_LIB_RATS) -DWASM_ENABLE_STATIC_PGO=$(WAMR_BUILD_STATIC_PGO)
ifeq ($(SPEC_TEST), 1)
Enclave_C_Flags += -DWASM_ENABLE_SPEC_TEST=1
else

View File

@ -16,7 +16,7 @@ set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
set (CMAKE_C_STANDARD 99)
set (CMAKE_CXX_STANDARD 14)
set (CMAKE_CXX_STANDARD 17)
# Set WAMR_BUILD_TARGET, currently values supported:
# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]",
@ -135,24 +135,6 @@ if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mindirect-branch-register")
# UNDEFINED BEHAVIOR, refer to https://en.cppreference.com/w/cpp/language/ub
if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT WAMR_BUILD_JIT EQUAL 1)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined \
-fno-sanitize=bounds,bounds-strict,alignment \
-fno-sanitize-recover")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined \
-fno-sanitize=bounds,bounds-strict,alignment \
-fno-sanitize-recover")
endif()
else ()
# UNDEFINED BEHAVIOR, refer to https://en.cppreference.com/w/cpp/language/ub
if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT WAMR_BUILD_JIT EQUAL 1)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined \
-fno-sanitize=bounds,alignment \
-fno-sanitize-recover")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined \
-fno-sanitize=bounds,alignment \
-fno-sanitize-recover")
endif()
endif ()
endif ()

View File

@ -54,6 +54,14 @@ print_help()
#if WASM_ENABLE_JIT != 0
printf(" --llvm-jit-size-level=n Set LLVM JIT size level, default is 3\n");
printf(" --llvm-jit-opt-level=n Set LLVM JIT optimization level, default is 3\n");
#if defined(os_writegsbase)
printf(" --enable-segue[=<flags>] Enable using segment register GS as the base address of\n");
printf(" linear memory, which may improve performance, flags can be:\n");
printf(" i32.load, i64.load, f32.load, f64.load, v128.load,\n");
printf(" i32.store, i64.store, f32.store, f64.store, v128.store\n");
printf(" Use comma to separate, e.g. --enable-segue=i32.load,i64.store\n");
printf(" and --enable-segue means all flags are added.\n");
#endif
#endif
printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
" that runs commands in the form of \"FUNC ARG...\"\n");
@ -89,6 +97,9 @@ print_help()
#if WASM_ENABLE_DEBUG_INTERP != 0
printf(" -g=ip:port Set the debug sever address, default is debug disabled\n");
printf(" if port is 0, then a random port will be used\n");
#endif
#if WASM_ENABLE_STATIC_PGO != 0
printf(" --gen-prof-file=<path> Generate LLVM PGO (Profile-Guided Optimization) profile file\n");
#endif
printf(" --version Show version information\n");
return 1;
@ -117,13 +128,13 @@ app_instance_func(wasm_module_inst_t module_inst, const char *func_name)
}
/**
* Split a space separated strings into an array of strings
* Split a string into an array of strings
* Returns NULL on failure
* Memory must be freed by caller
* Based on: http://stackoverflow.com/a/11198630/471795
*/
static char **
split_string(char *str, int *count)
split_string(char *str, int *count, const char *delimer)
{
char **res = NULL, **res1;
char *p;
@ -131,7 +142,7 @@ split_string(char *str, int *count)
/* split string and append tokens to 'res' */
do {
p = strtok(str, " ");
p = strtok(str, delimer);
str = NULL;
res1 = res;
res = (char **)realloc(res1, sizeof(char *) * (uint32)(idx + 1));
@ -180,7 +191,7 @@ app_instance_repl(wasm_module_inst_t module_inst)
printf("exit repl mode\n");
break;
}
app_argv = split_string(cmd, &app_argc);
app_argv = split_string(cmd, &app_argc, " ");
if (app_argv == NULL) {
LOG_ERROR("Wasm prepare param failed: split string failed.\n");
break;
@ -195,6 +206,59 @@ app_instance_repl(wasm_module_inst_t module_inst)
return NULL;
}
#if WASM_ENABLE_JIT != 0
static uint32
resolve_segue_flags(char *str_flags)
{
uint32 segue_flags = 0;
int32 flag_count, i;
char **flag_list;
flag_list = split_string(str_flags, &flag_count, ",");
if (flag_list) {
for (i = 0; i < flag_count; i++) {
if (!strcmp(flag_list[i], "i32.load")) {
segue_flags |= 1 << 0;
}
else if (!strcmp(flag_list[i], "i64.load")) {
segue_flags |= 1 << 1;
}
else if (!strcmp(flag_list[i], "f32.load")) {
segue_flags |= 1 << 2;
}
else if (!strcmp(flag_list[i], "f64.load")) {
segue_flags |= 1 << 3;
}
else if (!strcmp(flag_list[i], "v128.load")) {
segue_flags |= 1 << 4;
}
else if (!strcmp(flag_list[i], "i32.store")) {
segue_flags |= 1 << 8;
}
else if (!strcmp(flag_list[i], "i64.store")) {
segue_flags |= 1 << 9;
}
else if (!strcmp(flag_list[i], "f32.store")) {
segue_flags |= 1 << 10;
}
else if (!strcmp(flag_list[i], "f64.store")) {
segue_flags |= 1 << 11;
}
else if (!strcmp(flag_list[i], "v128.store")) {
segue_flags |= 1 << 12;
}
else {
/* invalid flag */
segue_flags = (uint32)-1;
break;
}
}
free(flag_list);
}
return segue_flags;
}
#endif /* end of WASM_ENABLE_JIT != 0 */
#if WASM_ENABLE_LIBC_WASI != 0
static bool
validate_env_str(char *env)
@ -352,6 +416,44 @@ moudle_destroyer(uint8 *buffer, uint32 size)
static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
#endif
#if WASM_ENABLE_STATIC_PGO != 0
static void
dump_pgo_prof_data(wasm_module_inst_t module_inst, const char *path)
{
char *buf;
uint32 len;
FILE *file;
if (!(len = wasm_runtime_get_pgo_prof_data_size(module_inst))) {
printf("failed to get LLVM PGO profile data size\n");
return;
}
if (!(buf = wasm_runtime_malloc(len))) {
printf("allocate memory failed\n");
return;
}
if (len != wasm_runtime_dump_pgo_prof_data_to_buf(module_inst, buf, len)) {
printf("failed to dump LLVM PGO profile data\n");
wasm_runtime_free(buf);
return;
}
if (!(file = fopen(path, "wb"))) {
printf("failed to create file %s", path);
wasm_runtime_free(buf);
return;
}
fwrite(buf, len, 1, file);
fclose(file);
wasm_runtime_free(buf);
printf("LLVM raw profile file %s was generated.\n", path);
}
#endif
int
main(int argc, char *argv[])
{
@ -367,6 +469,7 @@ main(int argc, char *argv[])
#if WASM_ENABLE_JIT != 0
uint32 llvm_jit_size_level = 3;
uint32 llvm_jit_opt_level = 3;
uint32 segue_flags = 0;
#endif
wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL;
@ -398,6 +501,9 @@ main(int argc, char *argv[])
char *ip_addr = NULL;
int instance_port = 0;
#endif
#if WASM_ENABLE_STATIC_PGO != 0
const char *gen_prof_file = NULL;
#endif
/* Process options. */
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
@ -487,7 +593,16 @@ main(int argc, char *argv[])
llvm_jit_opt_level = 3;
}
}
#endif
else if (!strcmp(argv[0], "--enable-segue")) {
/* all flags are enabled */
segue_flags = 0x1F1F;
}
else if (!strncmp(argv[0], "--enable-segue=", 15)) {
segue_flags = resolve_segue_flags(argv[0] + 15);
if (segue_flags == (uint32)-1)
return print_help();
}
#endif /* end of WASM_ENABLE_JIT != 0 */
#if WASM_ENABLE_LIBC_WASI != 0
else if (!strncmp(argv[0], "--dir=", 6)) {
if (argv[0][6] == '\0')
@ -592,6 +707,13 @@ main(int argc, char *argv[])
return print_help();
ip_addr = argv[0] + 3;
}
#endif
#if WASM_ENABLE_STATIC_PGO != 0
else if (!strncmp(argv[0], "--gen-prof-file=", 16)) {
if (argv[0][16] == '\0')
return print_help();
gen_prof_file = argv[0] + 16;
}
#endif
else if (!strncmp(argv[0], "--version", 9)) {
uint32 major, minor, patch;
@ -632,6 +754,7 @@ main(int argc, char *argv[])
#if WASM_ENABLE_JIT != 0
init_args.llvm_jit_size_level = llvm_jit_size_level;
init_args.llvm_jit_opt_level = llvm_jit_opt_level;
init_args.segue_flags = segue_flags;
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0
@ -754,6 +877,12 @@ main(int argc, char *argv[])
}
#endif
#if WASM_ENABLE_STATIC_PGO != 0 && WASM_ENABLE_AOT != 0
if (get_package_type(wasm_file_buf, wasm_file_size) == Wasm_Module_AoT
&& gen_prof_file)
dump_pgo_prof_data(wasm_module_inst, gen_prof_file);
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0
fail4:
#endif

View File

@ -102,7 +102,6 @@ include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WINSOCK_DEPRECATED_NO_WARNINGS")
if (NOT MINGW)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")

View File

@ -0,0 +1,22 @@
# Copyright (C) 2023 Midokura Japan KK. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 3.0)
project(mem_allocator_create)
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
if(APPLE)
add_definitions(-DBH_PLATFORM_DARWIN)
endif()
set(WAMR_BUILD_INTERP 1)
set(WAMR_BUILD_LIBC_BUILTIN 0)
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../..)
include(${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
add_executable(mem_alloc_test main.c)
target_link_libraries(mem_alloc_test vmlib -lm -lpthread)

View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2023 Midokura Japan KK. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "mem_alloc.h"
char store[1000];
int
main(int argc, char **argv)
{
mem_allocator_t a = mem_allocator_create(store, sizeof(store));
uint8_t *p;
uint8_t *p2;
p = mem_allocator_malloc(a, 256);
printf("%p\n", p);
if (p == NULL) {
exit(1);
}
p = mem_allocator_realloc(a, p, 256 + 12);
printf("%p\n", p);
if (p == NULL) {
exit(1);
}
/*
* write some values to confuse the ems allocator.
*
* hmu = p + 256
* hmu_set_ut(hmu, HMU_FC)
* hmu_set_size(hmu, 256)
* hmu_set_free_size(hmu)
*/
*(uint32_t *)(p + 256) = (1 << 30) | 0x20;
*(uint32_t *)(p + 256 + 12 - 4) = 12;
p2 = mem_allocator_malloc(a, 256);
printf("%p\n", p2);
if (p2 == NULL) {
exit(1);
}
mem_allocator_free(a, p2);
p2 = mem_allocator_malloc(a, 256);
printf("%p\n", p2);
if (p2 == NULL) {
exit(1);
}
mem_allocator_free(a, p2);
mem_allocator_free(a, p);
}

View File

@ -142,8 +142,8 @@ set_and_cmp(wasm_exec_env_t exec_env, wasm_module_inst_t inst, int32 i,
wasm_set_externref(exec_env, inst, i, externref);
local_set_externref(i, externref);
wasm_get_externref(exec_env, inst, 0, &wasm_externref);
if (!local_chk_externref(exec_env, 0, wasm_externref)) {
wasm_get_externref(exec_env, inst, i, &wasm_externref);
if (!local_chk_externref(exec_env, i, wasm_externref)) {
printf("#%d, In host language world Wasm Externref 0x%lx Vs. Native "
"Externref 0x%lx FAILED\n",
i, wasm_externref, externref);

View File

@ -16,7 +16,7 @@ if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
################ runtime settings ################
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
@ -87,15 +87,6 @@ endif()
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
if (NOT DEFINED SANITIZER)
set(SANITIZER "")
elseif (SANITIZER STREQUAL "ubsan")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O2 -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all -fno-sanitize=alignment" )
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined")
elseif (NOT (SANITIZER STREQUAL "") )
message(SEND_ERROR "Unsupported sanitizer: ${SANITIZER}")
endif()
add_library(vmlib STATIC ${WAMR_RUNTIME_LIB_SOURCE})
if (MSVC)
target_compile_definitions(vmlib PRIVATE WASM_API_EXTERN=)

View File

@ -6,7 +6,7 @@
},
"displayName": "WAMR-IDE",
"description": "An Integrated Development Environment for WASM",
"version": "1.1.2",
"version": "1.2.1",
"engines": {
"vscode": "^1.59.0"
},

View File

@ -7,52 +7,33 @@ import * as vscode from 'vscode';
import * as os from 'os';
export class WasmDebugConfigurationProvider
implements vscode.DebugConfigurationProvider
{
/* default port set as 1234 */
private port = 1234;
private hostPath!: string;
private providerPromise: Thenable<vscode.DebugConfiguration> | undefined =
undefined;
implements vscode.DebugConfigurationProvider {
private wasmDebugConfig = {
type: 'wamr-debug',
name: 'Attach',
request: 'attach',
stopOnEntry: true,
initCommands: os.platform() === 'win32' || os.platform() === 'darwin' ?
/* linux and windows has different debug configuration */
['platform select remote-linux'] :
undefined,
attachCommands: [
/* default port 1234 */
'process connect -p wasm connect://127.0.0.1:1234',
]
};
private wasmDebugConfig!: vscode.DebugConfiguration;
public resolveDebugConfiguration(
_: vscode.WorkspaceFolder | undefined,
debugConfiguration: vscode.DebugConfiguration,
): vscode.ProviderResult<vscode.DebugConfiguration> {
public resolveDebugConfiguration():
| Thenable<vscode.DebugConfiguration>
| undefined {
if (!this.providerPromise) {
this.providerPromise = Promise.resolve(this.wasmDebugConfig);
return this.providerPromise;
}
return this.providerPromise;
}
this.wasmDebugConfig = {
...this.wasmDebugConfig,
...debugConfiguration
};
public setDebugConfig(hostPath: string, port: number): void {
this.port = port;
this.hostPath = hostPath;
/* linux and windows has different debug configuration */
if (os.platform() === 'win32' || os.platform() === 'darwin') {
this.wasmDebugConfig = {
type: 'wamr-debug',
name: 'Attach',
request: 'attach',
['stopOnEntry']: true,
['initCommands']: ['platform select remote-linux'],
['attachCommands']: [
'process connect -p wasm connect://127.0.0.1:' + port + '',
],
};
} else if (os.platform() === 'linux') {
this.wasmDebugConfig = {
type: 'wamr-debug',
name: 'Attach',
request: 'attach',
['stopOnEntry']: true,
['attachCommands']: [
'process connect -p wasm connect://127.0.0.1:' + port + '',
],
};
}
return this.wasmDebugConfig;
}
public getDebugConfig(): vscode.DebugConfiguration {

View File

@ -171,7 +171,6 @@ export async function activate(context: vscode.ExtensionContext) {
/* register debug configuration */
wasmDebugConfigProvider = new WasmDebugConfigurationProvider();
wasmDebugConfigProvider.setDebugConfig(currentPrjDir, 1234);
vscode.debug.registerDebugConfigurationProvider(
'wamr-debug',

View File

@ -0,0 +1,62 @@
# WAMR test benchmarks
This folder contains test benchmarks for wamr.
## Build and Run
Refer to the `README.md` under each folder for how to build and run the benchmark.
## Install `llvm-profdata`
The tool `llvm-profdata` is used when running the `test_pgo.sh` script under the benchmark folder. There are two ways to install it:
1. Refer to https://apt.llvm.org/, e.g. in Ubuntu 20.04, add lines below to /etc/apt/source.list
```bash
deb http://apt.llvm.org/focal/ llvm-toolchain-focal main
deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal main
# 15
deb http://apt.llvm.org/focal/ llvm-toolchain-focal-15 main
deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-15 main
```
Then run `sudo apt update`, `sudo apt install llvm`. And after installing:
```bash
cd /usr/bin
sudo ln -s llvm-profdata-15 llvm-profdata
```
2. Build manually
```bash
git clone --depth 1 --branch release/15.x https://github.com/llvm/llvm-project.git
cd llvm-project
mkdir build && cd build
cmake ../llvm \
-DCMAKE_BUILD_TYPE:STRING="Release" \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DLLVM_APPEND_VC_REV:BOOL=ON \
-DLLVM_BUILD_EXAMPLES:BOOL=OFF \
-DLLVM_BUILD_LLVM_DYLIB:BOOL=OFF \
-DLLVM_BUILD_TESTS:BOOL=OFF \
-DLLVM_CCACHE_BUILD:BOOL=ON \
-DLLVM_ENABLE_BINDINGS:BOOL=OFF \
-DLLVM_ENABLE_IDE:BOOL=OFF \
-DLLVM_ENABLE_LIBEDIT=OFF \
-DLLVM_ENABLE_TERMINFO:BOOL=OFF \
-DLLVM_ENABLE_ZLIB:BOOL=ON \
-DLLVM_INCLUDE_BENCHMARKS:BOOL=OFF \
-DLLVM_INCLUDE_DOCS:BOOL=OFF \
-DLLVM_INCLUDE_EXAMPLES:BOOL=OFF \
-DLLVM_INCLUDE_UTILS:BOOL=OFF \
-DLLVM_INCLUDE_TESTS:BOOL=OFF \
-DLLVM_BUILD_TESTS:BOOL=OFF \
-DLLVM_OPTIMIZED_TABLEGEN:BOOL=ON \
-DLLVM_ENABLE_LIBXML2:BOOL=OFF \
-DLLVM_TARGETS_TO_BUILD:STRING="X86" \
-DLLVM_INCLUDE_TOOLS:BOOL=ON \
-G'Ninja'
ninja -j 8
# tool `llvm-profdata` is generated under this folder.
```

View File

@ -17,3 +17,9 @@ And then run `./build.sh` to build the source code, file `coremark.exe`, `corema
# Running
Run `./run.sh` to test the benchmark, the native mode, iwasm aot mode and iwasm interpreter mode will be tested respectively.
Run `./test_pgo.sh` to test the benchmark with AOT static PGO (Profile-Guided Optimization) enabled, please refer [here](../README.md#install-llvm-profdata) to install tool `llvm-profdata` and build `iwasm` with `cmake -DWAMR_BUILD_STATIC_PGO=1`.
- For Linux, build `iwasm` with `cmake -DWAMR_BUILD_STATIC_PGO=1`, then run `./test_pgo.sh` to test the benchmark with AOT static PGO (Profile-Guided Optimization) enabled.
- For Linux-sgx, similarly, build `iwasm` with `cmake -DWAMR_BUILD_STATIC_PGO=1`, then `make` in the directory `enclave-sample`. And run `./test_pgo.sh --sgx` to test the benchmark.

View File

@ -3,6 +3,8 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
PLATFORM=$(uname -s | tr A-Z a-z)
WAMRC="../../../wamr-compiler/build/wamrc"
if [ ! -d coremark ]; then
@ -32,4 +34,9 @@ cd ..
echo "Compile coremark.wasm to coremark.aot .."
${WAMRC} -o coremark.aot coremark.wasm
if [[ ${PLATFORM} == "linux" ]]; then
echo "Compile coremark.wasm to coremark_segue.aot .."
${WAMRC} --enable-segue -o coremark_segue.aot coremark.wasm
fi
echo "Done"

View File

@ -3,14 +3,21 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
IWASM="../../../product-mini/platforms/linux/build/iwasm"
PLATFORM=$(uname -s | tr A-Z a-z)
IWASM="../../../product-mini/platforms/${PLATFORM}/build/iwasm"
WAMRC="../../../wamr-compiler/build/wamrc"
echo "Run coremark with native .."
./coremark.exe
echo "Run coremark with iwasm mode .."
echo "Run coremark with iwasm aot mode .."
${IWASM} coremark.aot
echo "Run coremakr with iwasm interpreter .."
if [[ ${PLATFORM} == "linux" ]]; then
echo "Run coremark with iwasm aot-segue mode .."
${IWASM} coremark_segue.aot
fi
echo "Run coremark with iwasm interpreter mode .."
${IWASM} coremark.wasm

View File

@ -0,0 +1,55 @@
#!/bin/sh
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
PLATFORM=$(uname -s | tr A-Z a-z)
if [ "$1" = "--sgx" ] && [ "$PLATFORM" = "linux" ]; then
IWASM="../../../product-mini/platforms/${PLATFORM}-sgx/enclave-sample/iwasm"
WAMRC="../../../wamr-compiler/build/wamrc -sgx"
else
IWASM="../../../product-mini/platforms/${PLATFORM}/build/iwasm"
WAMRC="../../../wamr-compiler/build/wamrc"
fi
if [ ! -e "coremark.wasm" ]; then
echo "coremark.wasm doesn't exist, please run build.sh first"
exit
fi
echo ""
echo "Compile coremark.wasm to coremark.aot .."
${WAMRC} -o coremark.aot coremark.wasm
echo ""
echo "Compile coremark.wasm to coremark_pgo.aot .."
${WAMRC} --enable-llvm-pgo -o coremark_pgo.aot coremark.wasm
echo ""
echo "Run coremark_pgo.aot to generate the raw profile data .."
${IWASM} --gen-prof-file=coremark.profraw coremark_pgo.aot
echo ""
echo "Merge the raw profile data to coremark.profdata .."
rm -f coremark.profdata && llvm-profdata merge -output=coremark.profdata coremark.profraw
echo ""
echo "Compile coremark.wasm to coremark_opt.aot with the profile data .."
${WAMRC} --use-prof-file=coremark.profdata -o coremark_opt.aot coremark.wasm
echo ""
echo "Run the coremark native"
./coremark.exe
echo ""
echo "Run the original aot file coremark.aot"
${IWASM} coremark.aot
echo ""
echo "Run the PGO optimized aot file coremark_opt.aot"
${IWASM} coremark_opt.aot
# Show the profile data:
# llvm-profdata show --all-functions --detailed-summary --binary-ids --counts \
# --hot-func-list --memop-sizes --show-prof-sym-list coremark.profraw

View File

@ -0,0 +1,7 @@
Dhrystone
------------------------------------------------------------------------------
There is no explicit license defined. They were originally
written in ADA by Reinhold P. Weicker and translated to C by Rick Richardson .
The source obtained from the following site:
https://fossies.org/linux/privat/old/dhrystone-2.1.tar.gz

View File

@ -0,0 +1,24 @@
#!/bin/bash
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
PLATFORM=$(uname -s | tr A-Z a-z)
WAMRC_CMD=$PWD/../../../wamr-compiler/build/wamrc
echo "===> compile dhrystone src to dhrystone_native"
gcc -O3 -o dhrystone_native src/dhry_1.c src/dhry_2.c -I include
echo "===> compile dhrystone src to dhrystone.wasm"
/opt/wasi-sdk/bin/clang -O3 \
-o dhrystone.wasm src/dhry_1.c src/dhry_2.c -I include \
-Wl,--export=__heap_base -Wl,--export=__data_end
echo "===> compile dhrystone.wasm to dhrystone.aot"
${WAMRC_CMD} -o dhrystone.aot dhrystone.wasm
if [[ ${PLATFORM} == "linux" ]]; then
echo "===> compile dhrystone.wasm to dhrystone_segue.aot"
${WAMRC_CMD} --enable-segue -o dhrystone_segue.aot dhrystone.wasm
fi

View File

@ -0,0 +1,306 @@
/*
**************************************************************************
* DHRYSTONE 2.1 BENCHMARK PC VERSION
**************************************************************************
*
* "DHRYSTONE" Benchmark Program
* -----------------------------
*
* Version: C, Version 2.1
*
* File: dhry.h (part 1 of 3)
*
* Date: May 25, 1988
*
* Author: Reinhold P. Weicker
* Siemens AG, AUT E 51
* Postfach 3220
* 8520 Erlangen
* Germany (West)
* Phone: [+49]-9131-7-20330
* (8-17 Central European Time)
* Usenet: ..!mcsun!unido!estevax!weicker
*
* Original Version (in Ada) published in
* "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
* pp. 1013 - 1030, together with the statistics
* on which the distribution of statements etc. is based.
*
* In this C version, the following C library functions are used:
* - strcpy, strcmp (inside the measurement loop)
* - printf, scanf (outside the measurement loop)
* In addition, Berkeley UNIX system calls "times ()" or "time ()"
* are used for execution time measurement. For measurements
* on other systems, these calls have to be changed.
*
* Collection of Results:
* Reinhold Weicker (address see above) and
*
* Rick Richardson
* PC Research. Inc.
* 94 Apple Orchard Drive
* Tinton Falls, NJ 07724
* Phone: (201) 389-8963 (9-17 EST)
* Usenet: ...!uunet!pcrat!rick
*
* Please send results to Rick Richardson and/or Reinhold Weicker.
* Complete information should be given on hardware and software used.
* Hardware information includes: Machine type, CPU, type and size
* of caches; for microprocessors: clock frequency, memory speed
* (number of wait states).
* Software information includes: Compiler (and runtime library)
* manufacturer and version, compilation switches, OS version.
* The Operating System version may give an indication about the
* compiler; Dhrystone itself performs no OS calls in the measurement
* loop.
*
* The complete output generated by the program should be mailed
* such that at least some checks for correctness can be made.
*
**************************************************************************
*
* This version has changes made by Roy Longbottom to conform to a common
* format for a series of standard benchmarks for PCs:
*
* Running time greater than 5 seconds due to inaccuracy of the PC clock.
*
* Automatic adjustment of run time, no manually inserted parameters.
*
* Initial display of calibration times to confirm linearity.
*
* Display of results within one screen (or at a slow speed as the test
* progresses) so that it can be seen to have run successfully.
*
* Facilities to type in details of system used etc.
*
* All results and details appended to a results file.
*
*
* Roy Longbottom
* 101323.2241@compuserve.com
*
**************************************************************************
*
* For details of history, changes, other defines, benchmark construction
* statistics see official versions from ftp.nosc.mil/pub/aburto where
* the latest table of results (dhry.tbl) are available. See also
* netlib@ornl.gov
*
**************************************************************************
*
* Defines: The following "Defines" are possible:
* -DREG=register (default: Not defined)
* As an approximation to what an average C programmer
* might do, the "register" storage class is applied
* (if enabled by -DREG=register)
* - for local variables, if they are used (dynamically)
* five or more times
* - for parameters if they are used (dynamically)
* six or more times
* Note that an optimal "register" strategy is
* compiler-dependent, and that "register" declarations
* do not necessarily lead to faster execution.
* -DNOSTRUCTASSIGN (default: Not defined)
* Define if the C compiler does not support
* assignment of structures.
* -DNOENUMS (default: Not defined)
* Define if the C compiler does not support
* enumeration types.
***************************************************************************
*
* Compilation model and measurement (IMPORTANT):
*
* This C version of Dhrystone consists of three files:
* - dhry.h (this file, containing global definitions and comments)
* - dhry_1.c (containing the code corresponding to Ada package Pack_1)
* - dhry_2.c (containing the code corresponding to Ada package Pack_2)
*
* The following "ground rules" apply for measurements:
* - Separate compilation
* - No procedure merging
* - Otherwise, compiler optimizations are allowed but should be indicated
* - Default results are those without register declarations
* See the companion paper "Rationale for Dhrystone Version 2" for a more
* detailed discussion of these ground rules.
*
* For 16-Bit processors (e.g. 80186, 80286), times for all compilation
* models ("small", "medium", "large" etc.) should be given if possible,
* together with a definition of these models for the compiler system used.
*
**************************************************************************
* Examples of Pentium Results
*
* Dhrystone Benchmark Version 2.1 (Language: C)
*
* Month run 4/1996
* PC model Escom
* CPU Pentium
* Clock MHz 100
* Cache 256K
* Options Neptune chipset
* OS/DOS Windows 95
* Compiler Watcom C/ C++ 10.5 Win386
* OptLevel -otexan -zp8 -fp5 -5r
* Run by Roy Longbottom
* From UK
* Mail 101323.2241@compuserve.com
*
* Final values (* implementation-dependent):
*
* Int_Glob: O.K. 5
* Bool_Glob: O.K. 1
* Ch_1_Glob: O.K. A
* Ch_2_Glob: O.K. B
* Arr_1_Glob[8]: O.K. 7
* Arr_2_Glob8/7: O.K. 1600010
* Ptr_Glob->
* Ptr_Comp: * 98008
* Discr: O.K. 0
* Enum_Comp: O.K. 2
* Int_Comp: O.K. 17
* Str_Comp: O.K. DHRYSTONE PROGRAM, SOME STRING
* Next_Ptr_Glob->
* Ptr_Comp: * 98008 same as above
* Discr: O.K. 0
* Enum_Comp: O.K. 1
* Int_Comp: O.K. 18
* Str_Comp: O.K. DHRYSTONE PROGRAM, SOME STRING
* Int_1_Loc: O.K. 5
* Int_2_Loc: O.K. 13
* Int_3_Loc: O.K. 7
* Enum_Loc: O.K. 1
* Str_1_Loc: O.K. DHRYSTONE PROGRAM, 1'ST STRING
* Str_2_Loc: O.K. DHRYSTONE PROGRAM, 2'ND STRING
*
* Register option Selected.
*
* Microseconds 1 loop: 4.53
* Dhrystones / second: 220690
* VAX MIPS rating: 125.61
*
*
* Dhrystone Benchmark Version 2.1 (Language: C)
*
* Month run 4/1996
* PC model Escom
* CPU Pentium
* Clock MHz 100
* Cache 256K
* Options Neptune chipset
* OS/DOS Windows 95
* Compiler Watcom C/ C++ 10.5 Win386
* OptLevel No optimisation
* Run by Roy Longbottom
* From UK
* Mail 101323.2241@compuserve.com
*
* Final values (* implementation-dependent):
*
* Int_Glob: O.K. 5
* Bool_Glob: O.K. 1
* Ch_1_Glob: O.K. A
* Ch_2_Glob: O.K. B
* Arr_1_Glob[8]: O.K. 7
* Arr_2_Glob8/7: O.K. 320010
* Ptr_Glob->
* Ptr_Comp: * 98004
* Discr: O.K. 0
* Enum_Comp: O.K. 2
* Int_Comp: O.K. 17
* Str_Comp: O.K. DHRYSTONE PROGRAM, SOME STRING
* Next_Ptr_Glob->
* Ptr_Comp: * 98004 same as above
* Discr: O.K. 0
* Enum_Comp: O.K. 1
* Int_Comp: O.K. 18
* Str_Comp: O.K. DHRYSTONE PROGRAM, SOME STRING
* Int_1_Loc: O.K. 5
* Int_2_Loc: O.K. 13
* Int_3_Loc: O.K. 7
* Enum_Loc: O.K. 1
* Str_1_Loc: O.K. DHRYSTONE PROGRAM, 1'ST STRING
* Str_2_Loc: O.K. DHRYSTONE PROGRAM, 2'ND STRING
*
* Register option Not selected.
*
* Microseconds 1 loop: 20.06
* Dhrystones / second: 49844
* VAX MIPS rating: 28.37
*
**************************************************************************
*/
/* Compiler and system dependent definitions: */
#ifndef TIME
#define TIMES
#endif
/* Use times(2) time function unless */
/* explicitly defined otherwise */
#ifdef TIMES
/* #include <sys/types.h>
#include <sys/times.h> */
/* for "times" */
#endif
#define Mic_secs_Per_Second 1000000.0
/* Berkeley UNIX C returns process times in seconds/HZ */
#ifdef NOSTRUCTASSIGN
#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
#else
#define structassign(d, s) d = s
#endif
#ifdef NOENUM
#define Ident_1 0
#define Ident_2 1
#define Ident_3 2
#define Ident_4 3
#define Ident_5 4
typedef int Enumeration;
#else
typedef enum { Ident_1, Ident_2, Ident_3, Ident_4, Ident_5 } Enumeration;
#endif
/* for boolean and enumeration types in Ada, Pascal */
/* General definitions: */
#include <stdio.h>
#include <string.h>
/* for strcpy, strcmp */
#define Null 0
/* Value of a Null pointer */
#define true 1
#define false 0
typedef int One_Thirty;
typedef int One_Fifty;
typedef char Capital_Letter;
typedef int Boolean;
typedef char Str_30[31];
typedef int Arr_1_Dim[50];
typedef int Arr_2_Dim[50][50];
typedef struct record {
struct record *Ptr_Comp;
Enumeration Discr;
union {
struct {
Enumeration Enum_Comp;
int Int_Comp;
char Str_Comp[31];
} var_1;
struct {
Enumeration E_Comp_2;
char Str_2_Comp[31];
} var_2;
struct {
char Ch_1_Comp;
char Ch_2_Comp;
} var_3;
} variant;
} Rec_Type, *Rec_Pointer;

View File

@ -0,0 +1,19 @@
#!/bin/bash
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
PLATFORM=$(uname -s | tr A-Z a-z)
readonly IWASM_CMD="../../../product-mini/platforms/${PLATFORM}/build/iwasm"
echo "============> run dhrystone native"
./dhrystone_native
echo "============> run dhrystone.aot"
${IWASM_CMD} dhrystone.aot
if [[ ${PLATFORM} == "linux" ]]; then
echo "============> run dhrystone_segue.aot"
${IWASM_CMD} dhrystone_segue.aot
fi

View File

@ -0,0 +1,485 @@
/*
*************************************************************************
*
* "DHRYSTONE" Benchmark Program
* -----------------------------
*
* Version: C, Version 2.1
*
* File: dhry_1.c (part 2 of 3)
*
* Date: May 25, 1988
*
* Author: Reinhold P. Weicker
*
*************************************************************************
*/
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include "dhry.h"
/* Global Variables: */
Rec_Pointer Ptr_Glob, Next_Ptr_Glob;
int Int_Glob;
Boolean Bool_Glob;
char Ch_1_Glob, Ch_2_Glob;
int Arr_1_Glob[50];
int Arr_2_Glob[50][50];
Enumeration
Func_1(Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val);
/*
forward declaration necessary since Enumeration may not simply be int
*/
#ifndef ROPT
#define REG
/* REG becomes defined as empty */
/* i.e. no register variables */
#else
#define REG register
#endif
void
Proc_1(REG Rec_Pointer Ptr_Val_Par);
void
Proc_2(One_Fifty *Int_Par_Ref);
void
Proc_3(Rec_Pointer *Ptr_Ref_Par);
void
Proc_4();
void
Proc_5();
void
Proc_6(Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par);
void
Proc_7(One_Fifty Int_1_Par_Val, One_Fifty Int_2_Par_Val,
One_Fifty *Int_Par_Ref);
void
Proc_8(Arr_1_Dim Arr_1_Par_Ref, Arr_2_Dim Arr_2_Par_Ref, int Int_1_Par_Val,
int Int_2_Par_Val);
Boolean
Func_2(Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref);
/* variables for time measurement: */
#define Too_Small_Time 2
/* Measurements should last at least 2 seconds */
#define BILLION 1000000000L
#define MILLION 1000000
struct timespec Begin_Time, End_Time;
double User_Time;
double Microseconds, Dhrystones_Per_Second, Vax_Mips;
/* end of variables for time measurement */
int
main(int argc, char *argv[])
/*****/
/* main program, corresponds to procedures */
/* Main and Proc_0 in the Ada version */
{
One_Fifty Int_1_Loc;
REG One_Fifty Int_2_Loc;
One_Fifty Int_3_Loc;
REG char Ch_Index;
Enumeration Enum_Loc;
Str_30 Str_1_Loc;
Str_30 Str_2_Loc;
REG int Run_Index;
REG int Number_Of_Runs;
int endit, count = 10;
char general[9][80] = { " " };
/***********************************************************************
* Change for compiler and optimisation used *
***********************************************************************/
Next_Ptr_Glob = (Rec_Pointer)malloc(sizeof(Rec_Type));
Ptr_Glob = (Rec_Pointer)malloc(sizeof(Rec_Type));
Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
Ptr_Glob->Discr = Ident_1;
Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
Ptr_Glob->variant.var_1.Int_Comp = 40;
strcpy(Ptr_Glob->variant.var_1.Str_Comp, "DHRYSTONE PROGRAM, SOME STRING");
strcpy(Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
Arr_2_Glob[8][7] = 10;
/* Was missing in published program. Without this statement, */
/* Arr_2_Glob [8][7] would have an undefined value. */
/* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
/* overflow may occur for this array element. */
printf("\n");
printf("Dhrystone Benchmark, Version 2.1 (Language: C or C++)\n");
printf("\n");
Number_Of_Runs = 5000;
do {
Number_Of_Runs = Number_Of_Runs * 2;
count = count - 1;
Arr_2_Glob[8][7] = 10;
/***************/
/* Start timer */
/***************/
clock_gettime(CLOCK_MONOTONIC, &Begin_Time);
for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) {
Proc_5();
Proc_4();
/* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
Int_1_Loc = 2;
Int_2_Loc = 3;
strcpy(Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
Enum_Loc = Ident_2;
Bool_Glob = !Func_2(Str_1_Loc, Str_2_Loc);
/* Bool_Glob == 1 */
while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
{
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
/* Int_3_Loc == 7 */
Proc_7(Int_1_Loc, Int_2_Loc, &Int_3_Loc);
/* Int_3_Loc == 7 */
Int_1_Loc += 1;
} /* while */
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
Proc_8(Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
/* Int_Glob == 5 */
Proc_1(Ptr_Glob);
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
/* loop body executed twice */
{
if (Enum_Loc == Func_1(Ch_Index, 'C'))
/* then, not executed */
{
Proc_6(Ident_1, &Enum_Loc);
strcpy(Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
Int_2_Loc = Run_Index;
Int_Glob = Run_Index;
}
}
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
Int_2_Loc = Int_2_Loc * Int_1_Loc;
Int_1_Loc = Int_2_Loc / Int_3_Loc;
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
/* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
Proc_2(&Int_1_Loc);
/* Int_1_Loc == 5 */
} /* loop "for Run_Index" */
/**************/
/* Stop timer */
/**************/
clock_gettime(CLOCK_MONOTONIC, &End_Time);
User_Time = (End_Time.tv_sec - Begin_Time.tv_sec) * MILLION
+ (End_Time.tv_nsec - Begin_Time.tv_nsec) / 1000;
User_Time = User_Time / MILLION; /* convert to seconds */
printf("%ld runs %lf seconds \n", (long)Number_Of_Runs, User_Time);
if (User_Time > 5.0) {
count = 0;
}
else {
if (User_Time < 0.1) {
Number_Of_Runs = Number_Of_Runs * 5;
}
}
} /* calibrate/run do while */
while (count > 0);
printf("\n");
printf("Final values (* implementation-dependent):\n");
printf("\n");
printf("Int_Glob: ");
if (Int_Glob == 5)
printf("O.K. ");
else
printf("WRONG ");
printf("%d ", Int_Glob);
printf("Bool_Glob: ");
if (Bool_Glob == 1)
printf("O.K. ");
else
printf("WRONG ");
printf("%d\n", Bool_Glob);
printf("Ch_1_Glob: ");
if (Ch_1_Glob == 'A')
printf("O.K. ");
else
printf("WRONG ");
printf("%c ", Ch_1_Glob);
printf("Ch_2_Glob: ");
if (Ch_2_Glob == 'B')
printf("O.K. ");
else
printf("WRONG ");
printf("%c\n", Ch_2_Glob);
printf("Arr_1_Glob[8]: ");
if (Arr_1_Glob[8] == 7)
printf("O.K. ");
else
printf("WRONG ");
printf("%d ", Arr_1_Glob[8]);
printf("Arr_2_Glob8/7: ");
if (Arr_2_Glob[8][7] == Number_Of_Runs + 10)
printf("O.K. ");
else
printf("WRONG ");
printf("%10d\n", Arr_2_Glob[8][7]);
printf("Ptr_Glob-> ");
printf(" Ptr_Comp: * %p\n", Ptr_Glob->Ptr_Comp);
printf(" Discr: ");
if (Ptr_Glob->Discr == 0)
printf("O.K. ");
else
printf("WRONG ");
printf("%d ", Ptr_Glob->Discr);
printf("Enum_Comp: ");
if (Ptr_Glob->variant.var_1.Enum_Comp == 2)
printf("O.K. ");
else
printf("WRONG ");
printf("%d\n", Ptr_Glob->variant.var_1.Enum_Comp);
printf(" Int_Comp: ");
if (Ptr_Glob->variant.var_1.Int_Comp == 17)
printf("O.K. ");
else
printf("WRONG ");
printf("%d ", Ptr_Glob->variant.var_1.Int_Comp);
printf("Str_Comp: ");
if (strcmp(Ptr_Glob->variant.var_1.Str_Comp,
"DHRYSTONE PROGRAM, SOME STRING")
== 0)
printf("O.K. ");
else
printf("WRONG ");
printf("%s\n", Ptr_Glob->variant.var_1.Str_Comp);
printf("Next_Ptr_Glob-> ");
printf(" Ptr_Comp: * %p", Next_Ptr_Glob->Ptr_Comp);
printf(" same as above\n");
printf(" Discr: ");
if (Next_Ptr_Glob->Discr == 0)
printf("O.K. ");
else
printf("WRONG ");
printf("%d ", Next_Ptr_Glob->Discr);
printf("Enum_Comp: ");
if (Next_Ptr_Glob->variant.var_1.Enum_Comp == 1)
printf("O.K. ");
else
printf("WRONG ");
printf("%d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
printf(" Int_Comp: ");
if (Next_Ptr_Glob->variant.var_1.Int_Comp == 18)
printf("O.K. ");
else
printf("WRONG ");
printf("%d ", Next_Ptr_Glob->variant.var_1.Int_Comp);
printf("Str_Comp: ");
if (strcmp(Next_Ptr_Glob->variant.var_1.Str_Comp,
"DHRYSTONE PROGRAM, SOME STRING")
== 0)
printf("O.K. ");
else
printf("WRONG ");
printf("%s\n", Next_Ptr_Glob->variant.var_1.Str_Comp);
printf("Int_1_Loc: ");
if (Int_1_Loc == 5)
printf("O.K. ");
else
printf("WRONG ");
printf("%d ", Int_1_Loc);
printf("Int_2_Loc: ");
if (Int_2_Loc == 13)
printf("O.K. ");
else
printf("WRONG ");
printf("%d\n", Int_2_Loc);
printf("Int_3_Loc: ");
if (Int_3_Loc == 7)
printf("O.K. ");
else
printf("WRONG ");
printf("%d ", Int_3_Loc);
printf("Enum_Loc: ");
if (Enum_Loc == 1)
printf("O.K. ");
else
printf("WRONG ");
printf("%d\n", Enum_Loc);
printf("Str_1_Loc: ");
if (strcmp(Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING") == 0)
printf("O.K. ");
else
printf("WRONG ");
printf("%s\n", Str_1_Loc);
printf("Str_2_Loc: ");
if (strcmp(Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING") == 0)
printf("O.K. ");
else
printf("WRONG ");
printf("%s\n", Str_2_Loc);
printf("\n");
if (User_Time < Too_Small_Time) {
printf("Measured time too small to obtain meaningful results\n");
printf("Please increase number of runs\n");
printf("\n");
}
else {
Microseconds = User_Time * Mic_secs_Per_Second / (double)Number_Of_Runs;
Dhrystones_Per_Second = (double)Number_Of_Runs / User_Time;
Vax_Mips = Dhrystones_Per_Second / 1757.0;
printf("Microseconds for one run through Dhrystone: ");
printf("%lf \n", Microseconds);
printf("Dhrystones per Second: ");
printf("%lf \n", Dhrystones_Per_Second);
printf("VAX MIPS rating = ");
printf("%lf \n", Vax_Mips);
printf("\n");
}
free(Next_Ptr_Glob);
free(Ptr_Glob);
return 1;
}
void
Proc_1(REG Rec_Pointer Ptr_Val_Par)
/******************/
/* executed once */
{
REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
/* == Ptr_Glob_Next */
/* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
/* corresponds to "rename" in Ada, "with" in Pascal */
structassign(*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
Ptr_Val_Par->variant.var_1.Int_Comp = 5;
Next_Record->variant.var_1.Int_Comp = Ptr_Val_Par->variant.var_1.Int_Comp;
Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
Proc_3(&Next_Record->Ptr_Comp);
/* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
== Ptr_Glob->Ptr_Comp */
if (Next_Record->Discr == Ident_1)
/* then, executed */
{
Next_Record->variant.var_1.Int_Comp = 6;
Proc_6(Ptr_Val_Par->variant.var_1.Enum_Comp,
&Next_Record->variant.var_1.Enum_Comp);
Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
Proc_7(Next_Record->variant.var_1.Int_Comp, 10,
&Next_Record->variant.var_1.Int_Comp);
}
else { /* not executed */
structassign(*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
}
} /* Proc_1 */
void
Proc_2(One_Fifty *Int_Par_Ref)
/******************/
/* executed once */
/* *Int_Par_Ref == 1, becomes 4 */
{
One_Fifty Int_Loc;
Enumeration Enum_Loc;
Int_Loc = *Int_Par_Ref + 10;
do /* executed once */
if (Ch_1_Glob == 'A')
/* then, executed */
{
Int_Loc -= 1;
*Int_Par_Ref = Int_Loc - Int_Glob;
Enum_Loc = Ident_1;
} /* if */
while (Enum_Loc != Ident_1); /* true */
} /* Proc_2 */
void
Proc_3(Rec_Pointer *Ptr_Ref_Par)
/******************/
/* executed once */
/* Ptr_Ref_Par becomes Ptr_Glob */
{
if (Ptr_Glob != Null)
/* then, executed */
*Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
Proc_7(10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
} /* Proc_3 */
void
Proc_4() /* without parameters */
/*******/
/* executed once */
{
Boolean Bool_Loc;
Bool_Loc = Ch_1_Glob == 'A';
Bool_Glob = Bool_Loc | Bool_Glob;
Ch_2_Glob = 'B';
} /* Proc_4 */
void
Proc_5() /* without parameters */
/*******/
/* executed once */
{
Ch_1_Glob = 'A';
Bool_Glob = false;
} /* Proc_5 */
/* Procedure for the assignment of structures, */
/* if the C compiler doesn't support this feature */
#ifdef NOSTRUCTASSIGN
memcpy(d, s, l) register char *d;
register char *s;
register int l;
{
while (l--)
*d++ = *s++;
}
#endif

View File

@ -0,0 +1,187 @@
/*
*************************************************************************
*
* "DHRYSTONE" Benchmark Program
* -----------------------------
*
* Version: C, Version 2.1
*
* File: dhry_2.c (part 3 of 3)
*
* Date: May 25, 1988
*
* Author: Reinhold P. Weicker
*
*************************************************************************
*/
#include "dhry.h"
#ifndef REG
#define REG
/* REG becomes defined as empty */
/* i.e. no register variables */
#else
#define REG register
#endif
extern int Int_Glob;
extern char Ch_1_Glob;
Boolean
Func_3(Enumeration Enum_Par_Val);
void
Proc_6(Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
/*********************************/
/* executed once */
/* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
{
*Enum_Ref_Par = Enum_Val_Par;
if (!Func_3(Enum_Val_Par))
/* then, not executed */
*Enum_Ref_Par = Ident_4;
switch (Enum_Val_Par) {
case Ident_1:
*Enum_Ref_Par = Ident_1;
break;
case Ident_2:
if (Int_Glob > 100)
/* then */
*Enum_Ref_Par = Ident_1;
else
*Enum_Ref_Par = Ident_4;
break;
case Ident_3: /* executed */
*Enum_Ref_Par = Ident_2;
break;
case Ident_4:
break;
case Ident_5:
*Enum_Ref_Par = Ident_3;
break;
} /* switch */
} /* Proc_6 */
void
Proc_7(One_Fifty Int_1_Par_Val, One_Fifty Int_2_Par_Val, One_Fifty *Int_Par_Ref)
/**********************************************/
/* executed three times */
/* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
/* Int_Par_Ref becomes 7 */
/* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
/* Int_Par_Ref becomes 17 */
/* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
/* Int_Par_Ref becomes 18 */
{
One_Fifty Int_Loc;
Int_Loc = Int_1_Par_Val + 2;
*Int_Par_Ref = Int_2_Par_Val + Int_Loc;
} /* Proc_7 */
void
Proc_8(Arr_1_Dim Arr_1_Par_Ref, Arr_2_Dim Arr_2_Par_Ref, int Int_1_Par_Val,
int Int_2_Par_Val)
/*********************************************************************/
/* executed once */
/* Int_Par_Val_1 == 3 */
/* Int_Par_Val_2 == 7 */
{
REG One_Fifty Int_Index;
REG One_Fifty Int_Loc;
Int_Loc = Int_1_Par_Val + 5;
Arr_1_Par_Ref[Int_Loc] = Int_2_Par_Val;
Arr_1_Par_Ref[Int_Loc + 1] = Arr_1_Par_Ref[Int_Loc];
Arr_1_Par_Ref[Int_Loc + 30] = Int_Loc;
for (Int_Index = Int_Loc; Int_Index <= Int_Loc + 1; ++Int_Index)
Arr_2_Par_Ref[Int_Loc][Int_Index] = Int_Loc;
Arr_2_Par_Ref[Int_Loc][Int_Loc - 1] += 1;
Arr_2_Par_Ref[Int_Loc + 20][Int_Loc] = Arr_1_Par_Ref[Int_Loc];
Int_Glob = 5;
} /* Proc_8 */
Enumeration
Func_1(Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val)
/*************************************************/
/* executed three times */
/* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
/* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
/* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
{
Capital_Letter Ch_1_Loc;
Capital_Letter Ch_2_Loc;
Ch_1_Loc = Ch_1_Par_Val;
Ch_2_Loc = Ch_1_Loc;
if (Ch_2_Loc != Ch_2_Par_Val)
/* then, executed */
return (Ident_1);
else /* not executed */
{
Ch_1_Glob = Ch_1_Loc;
return (Ident_2);
}
} /* Func_1 */
Boolean
Func_2(Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref)
/*************************************************/
/* executed once */
/* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
/* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
{
REG One_Thirty Int_Loc;
Capital_Letter Ch_Loc;
Int_Loc = 2;
while (Int_Loc <= 2) /* loop body executed once */
if (Func_1(Str_1_Par_Ref[Int_Loc], Str_2_Par_Ref[Int_Loc + 1])
== Ident_1)
/* then, executed */
{
Ch_Loc = 'A';
Int_Loc += 1;
} /* if, while */
if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
/* then, not executed */
Int_Loc = 7;
if (Ch_Loc == 'R')
/* then, not executed */
return (true);
else /* executed */
{
if (strcmp(Str_1_Par_Ref, Str_2_Par_Ref) > 0)
/* then, not executed */
{
Int_Loc += 7;
Int_Glob = Int_Loc;
return (true);
}
else /* executed */
return (false);
} /* if Ch_Loc */
} /* Func_2 */
Boolean
Func_3(Enumeration Enum_Par_Val)
/***************************/
/* executed once */
/* Enum_Par_Val == Ident_3 */
{
Enumeration Enum_Loc;
Enum_Loc = Enum_Par_Val;
if (Enum_Loc == Ident_3)
/* then, executed */
return (true);
else /* not executed */
return (false);
} /* Func_3 */

View File

@ -0,0 +1,55 @@
#!/bin/sh
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
PLATFORM=$(uname -s | tr A-Z a-z)
if [ "$1" = "--sgx" ] && [ "$PLATFORM" = "linux" ]; then
IWASM="../../../product-mini/platforms/${PLATFORM}-sgx/enclave-sample/iwasm"
WAMRC="../../../wamr-compiler/build/wamrc -sgx"
else
IWASM="../../../product-mini/platforms/${PLATFORM}/build/iwasm"
WAMRC="../../../wamr-compiler/build/wamrc"
fi
if [ ! -e "dhrystone.wasm" ]; then
echo "dhrystone.wasm doesn't exist, please run build.sh first"
exit
fi
echo ""
echo "Compile dhrystone.wasm to dhrystone.aot .."
${WAMRC} -o dhrystone.aot dhrystone.wasm
echo ""
echo "Compile dhrystone.wasm to dhrystone_pgo.aot .."
${WAMRC} --enable-llvm-pgo -o dhrystone_pgo.aot dhrystone.wasm
echo ""
echo "Run dhrystone_pgo.aot to generate the raw profile data .."
${IWASM} --gen-prof-file=dhrystone.profraw dhrystone_pgo.aot
echo ""
echo "Merge the raw profile data to dhrystone.profdata .."
rm -f dhrystone.profdata && llvm-profdata merge -output=dhrystone.profdata dhrystone.profraw
echo ""
echo "Compile dhrystone.wasm to dhrystone_opt.aot with the profile data .."
${WAMRC} --use-prof-file=dhrystone.profdata -o dhrystone_opt.aot dhrystone.wasm
echo ""
echo "Run the dhrystone native"
./dhrystone_native
echo ""
echo "Run the original aot file dhrystone.aot"
${IWASM} dhrystone.aot
echo ""
echo "Run the PGO optimized aot file dhrystone_opt.aot"
${IWASM} dhrystone_opt.aot
# Show the profile data:
# llvm-profdata show --all-functions --detailed-summary --binary-ids --counts \
# --hot-func-list --memop-sizes --show-prof-sym-list dhrystone.profraw

View File

@ -27,3 +27,9 @@ And then run `./build.sh` to build the source code, the folder `out` will be cre
# Running
Run `./run_aot.sh` to test the benchmark, the native mode and iwasm aot mode will be tested for each workload, and the file `report.txt` will be generated.
Run `./test_pgo.sh` to test the benchmark with AOT static PGO (Profile-Guided Optimization) enabled, please refer [here](../README.md#install-llvm-profdata) to install tool `llvm-profdata` and build `iwasm` with `cmake -DWAMR_BUILD_STATIC_PGO=1`.
- For Linux, build `iwasm` with `cmake -DWAMR_BUILD_STATIC_PGO=1`, then run `./test_pgo.sh` to test the benchmark with AOT static PGO (Profile-Guided Optimization) enabled.
- For Linux-sgx, similarly, build `iwasm` with `cmake -DWAMR_BUILD_STATIC_PGO=1`, then `make` in the directory `enclave-sample`. And run `./test_pgo.sh --sgx` to test the benchmark.

View File

@ -3,27 +3,45 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
source /opt/emsdk/emsdk_env.sh
PLATFORM=$(uname -s | tr A-Z a-z)
OUT_DIR=$PWD/out
WAMRC_CMD=$PWD/../../../wamr-compiler/build/wamrc
mkdir -p jetstream
mkdir -p tsf-src
mkdir -p ${OUT_DIR}
if [[ $1 != "--no-simd" ]];then
NATIVE_SIMD_FLAGS="-msse2 -msse3 -msse4"
WASM_SIMD_FLAGS="-msimd128 -msse2 -msse3 -msse4"
else
NATIVE_SIMD_FLAGS=""
WASM_SIMD_FLAGS=""
fi
cd jetstream
echo "Download source files .."
wget https://browserbench.org/JetStream/wasm/gcc-loops.cpp
wget https://browserbench.org/JetStream/wasm/quicksort.c
wget https://browserbench.org/JetStream/wasm/HashSet.cpp
wget https://browserbench.org/JetStream/simple/float-mm.c
wget -N https://browserbench.org/JetStream/wasm/gcc-loops.cpp
wget -N https://browserbench.org/JetStream/wasm/quicksort.c
wget -N https://browserbench.org/JetStream/wasm/HashSet.cpp
wget -N https://browserbench.org/JetStream/simple/float-mm.c
patch -p1 < ../jetstream.patch
if [[ $? != 0 ]]; then
exit
fi
echo "Patch source files .."
patch -p1 -N < ../jetstream.patch
echo "Build gcc-loops with g++ .."
g++ -O3 -msse2 -msse3 -msse4 -o ${OUT_DIR}/gcc-loops_native gcc-loops.cpp
g++ -O3 ${NATIVE_SIMD_FLAGS} -o ${OUT_DIR}/gcc-loops_native gcc-loops.cpp
echo "Build gcc-loops with em++ .."
em++ -O3 -s STANDALONE_WASM=1 -msimd128 \
em++ -O3 -s STANDALONE_WASM=1 ${WASM_SIMD_FLAGS} \
-s INITIAL_MEMORY=1048576 \
-s TOTAL_STACK=32768 \
-s "EXPORTED_FUNCTIONS=['_main']" \
@ -33,11 +51,16 @@ em++ -O3 -s STANDALONE_WASM=1 -msimd128 \
echo "Compile gcc-loops.wasm to gcc-loops.aot"
${WAMRC_CMD} -o ${OUT_DIR}/gcc-loops.aot ${OUT_DIR}/gcc-loops.wasm
if [[ ${PLATFORM} == "linux" ]]; then
echo "Compile gcc-loops.wasm to gcc-loops_segue.aot"
${WAMRC_CMD} --enable-segue -o ${OUT_DIR}/gcc-loops_segue.aot ${OUT_DIR}/gcc-loops.wasm
fi
echo "Build quicksort with gcc .."
gcc -O3 -msse2 -msse3 -msse4 -o ${OUT_DIR}/quicksort_native quicksort.c
gcc -O3 ${NATIVE_SIMD_FLAGS} -o ${OUT_DIR}/quicksort_native quicksort.c
echo "Build quicksort with emcc .."
emcc -O3 -s STANDALONE_WASM=1 -msimd128 \
emcc -O3 -s STANDALONE_WASM=1 ${WASM_SIMD_FLAGS} \
-s INITIAL_MEMORY=1048576 \
-s TOTAL_STACK=32768 \
-s "EXPORTED_FUNCTIONS=['_main']" \
@ -46,12 +69,17 @@ emcc -O3 -s STANDALONE_WASM=1 -msimd128 \
echo "Compile quicksort.wasm to quicksort.aot"
${WAMRC_CMD} -o ${OUT_DIR}/quicksort.aot ${OUT_DIR}/quicksort.wasm
if [[ ${PLATFORM} == "linux" ]]; then
echo "Compile quicksort.wasm to quicksort_segue.aot"
${WAMRC_CMD} --enable-segue -o ${OUT_DIR}/quicksort_segue.aot ${OUT_DIR}/quicksort.wasm
fi
echo "Build HashSet with g++ .."
g++ -O3 -msse2 -msse3 -msse4 -o ${OUT_DIR}/HashSet_native HashSet.cpp \
g++ -O3 ${NATIVE_SIMD_FLAGS} -o ${OUT_DIR}/HashSet_native HashSet.cpp \
-lstdc++
echo "Build HashSet with em++ .."
em++ -O3 -s STANDALONE_WASM=1 -msimd128 \
em++ -O3 -s STANDALONE_WASM=1 ${WASM_SIMD_FLAGS} \
-s INITIAL_MEMORY=1048576 \
-s TOTAL_STACK=32768 \
-s "EXPORTED_FUNCTIONS=['_main']" \
@ -60,11 +88,16 @@ em++ -O3 -s STANDALONE_WASM=1 -msimd128 \
echo "Compile HashSet.wasm to HashSet.aot"
${WAMRC_CMD} -o ${OUT_DIR}/HashSet.aot ${OUT_DIR}/HashSet.wasm
if [[ ${PLATFORM} == "linux" ]]; then
echo "Compile HashSet.wasm to HashSet_segue.aot"
${WAMRC_CMD} --enable-segue -o ${OUT_DIR}/HashSet_segue.aot ${OUT_DIR}/HashSet.wasm
fi
echo "Build float-mm with gcc .."
gcc -O3 -msse2 -msse3 -msse4 -o ${OUT_DIR}/float-mm_native float-mm.c
gcc -O3 ${NATIVE_SIMD_FLAGS} -o ${OUT_DIR}/float-mm_native float-mm.c
echo "Build float-mm with emcc .."
emcc -O3 -s STANDALONE_WASM=1 -msimd128 \
emcc -O3 -s STANDALONE_WASM=1 ${WASM_SIMD_FLAGS} \
-s INITIAL_MEMORY=1048576 \
-s TOTAL_STACK=32768 \
-s "EXPORTED_FUNCTIONS=['_main']" \
@ -72,3 +105,70 @@ emcc -O3 -s STANDALONE_WASM=1 -msimd128 \
echo "Compile float-mm.wasm to float-mm.aot"
${WAMRC_CMD} -o ${OUT_DIR}/float-mm.aot ${OUT_DIR}/float-mm.wasm
if [[ ${PLATFORM} == "linux" ]]; then
echo "Compile float-mm.wasm to float-mm_segue.aot"
${WAMRC_CMD} --enable-segue -o ${OUT_DIR}/float-mm_segue.aot ${OUT_DIR}/float-mm.wasm
fi
cd ../tsf-src
tsf_srcs="tsf_asprintf.c tsf_buffer.c tsf_error.c tsf_reflect.c tsf_st.c \
tsf_type.c tsf_io.c tsf_native.c tsf_generator.c tsf_st_typetable.c \
tsf_parser.c tsf_buf_writer.c tsf_buf_reader.c tsf_primitive.c \
tsf_type_table.c tsf_copier.c tsf_destructor.c tsf_gpc_code_gen.c \
gpc_code_gen_util.c gpc_threaded.c gpc_intable.c gpc_instruction.c \
gpc_program.c gpc_proto.c gpc_stack_height.c tsf_serial_in_man.c \
tsf_serial_out_man.c tsf_type_in_map.c tsf_type_out_map.c \
tsf_stream_file_input.c tsf_stream_file_output.c tsf_sort.c \
tsf_version.c tsf_named_type.c tsf_io_utils.c tsf_zip_attr.c \
tsf_zip_reader.c tsf_zip_writer.c tsf_zip_abstract.c tsf_limits.c \
tsf_ra_type_man.c tsf_adaptive_reader.c tsf_sha1.c tsf_sha1_writer.c \
tsf_fsdb.c tsf_fsdb_protocol.c tsf_define_helpers.c tsf_ir.c \
tsf_ir_different.c tsf_ir_speed.c"
tsf_files="${tsf_srcs} config.h gpc_worklist.h \
tsf_config_stub.h tsf.h tsf_internal.h tsf_region.h tsf_types.h \
gpc.h tsf_atomics.h tsf_define_helpers.h tsf_indent.h tsf_inttypes.h \
tsf_serial_protocol.h tsf_util.h gpc_int_common.h tsf_build_defines.h \
tsf_format.h tsf_internal_config.h tsf_ir_different.h tsf_sha1.h \
tsf_zip_abstract.h gpc_internal.h tsf_config.h tsf_fsdb_protocol.h \
tsf_internal_config_stub.h tsf_ir.h tsf_st.h \
gpc_instruction_dispatch.gen gpc_instruction_stack_effects.gen \
gpc_instruction_to_string.gen gpc_instruction_size.gen \
gpc_instruction_static_size.gen gpc_interpreter.gen"
echo "Download tsf source files .."
for t in ${tsf_files}
do
wget -N "https://browserbench.org/JetStream/wasm/TSF/${t}"
if [[ $? != 0 ]]; then
exit
fi
done
patch -p1 -N < ../tsf.patch
echo "Build tsf with gcc .."
gcc \
-o ${OUT_DIR}/tsf_native -O3 ${NATIVE_SIMD_FLAGS} \
-I. -DTSF_BUILD_SYSTEM=1 \
${tsf_srcs} -lm
echo "Build tsf standalone with wasi-sdk .."
/opt/wasi-sdk/bin/clang -O3 ${WASM_SIMD_FLAGS} -z stack-size=1048576 \
-Wl,--initial-memory=52428800 \
-Wl,--export=main \
-Wl,--export=__heap_base,--export=__data_end \
-I. -DTSF_BUILD_SYSTEM=1 \
-Wl,--allow-undefined \
-o ${OUT_DIR}/tsf.wasm \
${tsf_srcs}
echo "Compile tsf.wasm to tsf.aot"
${WAMRC_CMD} -o ${OUT_DIR}/tsf.aot ${OUT_DIR}/tsf.wasm
if [[ ${PLATFORM} == "linux" ]]; then
echo "Compile tsf.wasm to tsf_segue.aot"
${WAMRC_CMD} --enable-segue -o ${OUT_DIR}/tsf_segue.aot ${OUT_DIR}/tsf.wasm
fi

View File

@ -1,15 +1,18 @@
diff -urN jetstream-org/HashSet.cpp jetstream/HashSet.cpp
--- jetstream-org/HashSet.cpp 2020-10-30 04:12:42.000000000 +0800
+++ jetstream/HashSet.cpp 2022-01-24 17:11:08.619831711 +0800
@@ -24,6 +24,7 @@
--- jetstream-org/HashSet.cpp 2020-10-30 04:12:42.000000000 +0800
+++ jetstream/HashSet.cpp 2022-01-24 17:11:08.619831711 +0800
@@ -22,8 +22,10 @@
#include <algorithm>
#include <memory>
+#include <limits>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/time.h>
// Compile with: xcrun clang++ -o HashSet HashSet.cpp -O2 -W -framework Foundation -licucore -std=c++11 -fvisibility=hidden -DNDEBUG=1
@@ -76,7 +77,7 @@
@@ -76,7 +78,7 @@
inline ToType bitwise_cast(FromType from)
{
typename std::remove_const<ToType>::type to { };
@ -17,4 +20,4 @@ diff -urN jetstream-org/HashSet.cpp jetstream/HashSet.cpp
+ memcpy(&to, &from, sizeof(to));
return to;
}

View File

@ -3,6 +3,8 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
PLATFORM=$(uname -s | tr A-Z a-z)
CUR_DIR=$PWD
OUT_DIR=$CUR_DIR/out
REPORT=$CUR_DIR/report.txt
@ -13,7 +15,7 @@ IWASM_CMD=$CUR_DIR/../../../product-mini/platforms/${PLATFORM}/build/iwasm
BENCH_NAME_MAX_LEN=20
JETSTREAM_CASES="gcc-loops quicksort HashSet float-mm"
JETSTREAM_CASES="gcc-loops HashSet tsf float-mm quicksort"
rm -f $REPORT
touch $REPORT
@ -34,7 +36,11 @@ echo "Start to run cases, the result is written to report.txt"
#run benchmarks
cd $OUT_DIR
echo -en "\t\t\t\t\t native\tiwasm-aot\n" >> $REPORT
if [[ ${PLATFORM} == "linux" ]]; then
echo -en "\t\t\t\t\t native\tiwasm-aot\tiwasm-aot-segue\n" >> $REPORT
else
echo -en "\t\t\t\t\t native\tiwasm-aot\n" >> $REPORT
fi
for t in $JETSTREAM_CASES
do
@ -46,7 +52,13 @@ do
echo "run $t with iwasm aot .."
echo -en "\t" >> $REPORT
$TIME -f "real-%e-time" $IWASM_CMD ${t}.aot 2>&1 | grep "real-.*-time" | awk -F '-' '{ORS=""; print $2}' >> $REPORT
$TIME -f "real-%e-time" $IWASM_CMD --dir=. ${t}.aot 2>&1 | grep "real-.*-time" | awk -F '-' '{ORS=""; print $2}' >> $REPORT
if [[ ${PLATFORM} == "linux" ]]; then
echo "run $t with iwasm aot segue .."
echo -en "\t" >> $REPORT
$TIME -f "real-%e-time" $IWASM_CMD --dir=. ${t}_segue.aot 2>&1 | grep "real-.*-time" | awk -F '-' '{ORS=""; print $2}' >> $REPORT
fi
echo -en "\n" >> $REPORT
done

View File

@ -0,0 +1,92 @@
#!/bin/bash
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
CUR_DIR=$PWD
OUT_DIR=$CUR_DIR/out
REPORT=$CUR_DIR/report.txt
TIME=/usr/bin/time
PLATFORM=$(uname -s | tr A-Z a-z)
if [ "$1" = "--sgx" ] && [ "$PLATFORM" = "linux" ]; then
IWASM_CMD="$CUR_DIR/../../../product-mini/platforms/${PLATFORM}-sgx/enclave-sample/iwasm"
WAMRC_CMD="$CUR_DIR/../../../wamr-compiler/build/wamrc -sgx"
else
IWASM_CMD="$CUR_DIR/../../../product-mini/platforms/${PLATFORM}/build/iwasm"
WAMRC_CMD="$CUR_DIR/../../../wamr-compiler/build/wamrc"
fi
BENCH_NAME_MAX_LEN=20
JETSTREAM_CASES="gcc-loops HashSet tsf float-mm quicksort"
rm -f $REPORT
touch $REPORT
function print_bench_name()
{
name=$1
echo -en "$name" >> $REPORT
name_len=${#name}
if [ $name_len -lt $BENCH_NAME_MAX_LEN ]
then
spaces=$(( $BENCH_NAME_MAX_LEN - $name_len ))
for i in $(eval echo "{1..$spaces}"); do echo -n " " >> $REPORT; done
fi
}
pushd $OUT_DIR > /dev/null 2>&1
for t in $JETSTREAM_CASES
do
if [ ! -e "${t}.wasm" ]; then
echo "${t}.wasm doesn't exist, please run build.sh first"
exit
fi
echo ""
echo "Compile ${t}.wasm to ${t}.aot .."
${WAMRC_CMD} -o ${t}.aot ${t}.wasm
echo ""
echo "Compile ${t}.wasm to ${t}_pgo.aot .."
${WAMRC_CMD} --enable-llvm-pgo -o ${t}_pgo.aot ${t}.wasm
echo ""
echo "Run ${t}_pgo.aot to generate the raw profile data .."
${IWASM_CMD} --gen-prof-file=${t}.profraw --dir=. ${t}_pgo.aot
echo ""
echo "Merge the raw profile data to ${t}.profdata .."
rm -f ${t}.profdata && llvm-profdata merge -output=${t}.profdata ${t}.profraw
echo ""
echo "Compile ${t}.wasm to ${t}_opt.aot with the profile data .."
${WAMRC_CMD} --use-prof-file=${t}.profdata -o ${t}_opt.aot ${t}.wasm
done
popd > /dev/null 2>&1
echo "Start to run cases, the result is written to report.txt"
#run benchmarks
cd $OUT_DIR
echo -en "\t\t\t\t\t native\tiwasm-aot\tiwasm-aot-pgo\n" >> $REPORT
for t in $JETSTREAM_CASES
do
print_bench_name $t
echo "run $t with native .."
echo -en "\t" >> $REPORT
$TIME -f "real-%e-time" ./${t}_native 2>&1 | grep "real-.*-time" | awk -F '-' '{ORS=""; print $2}' >> $REPORT
echo "run $t with iwasm aot .."
echo -en "\t" >> $REPORT
$TIME -f "real-%e-time" $IWASM_CMD --dir=. ${t}.aot 2>&1 | grep "real-.*-time" | awk -F '-' '{ORS=""; print $2}' >> $REPORT
echo "run $t with iwasm aot opt .."
echo -en "\t" >> $REPORT
$TIME -f "real-%e-time" $IWASM_CMD --dir=. ${t}_opt.aot 2>&1 | grep "real-.*-time" | awk -F '-' '{ORS=""; print $2}' >> $REPORT
echo -en "\n" >> $REPORT
done

View File

@ -0,0 +1,24 @@
diff -urN tsf-src-org/tsf_internal.h tsf-src/tsf_internal.h
--- tsf-src-org/tsf_internal.h 2023-03-31 10:49:45.000000000 +0800
+++ tsf-src/tsf_internal.h 2023-05-11 08:18:35.000000000 +0800
@@ -429,6 +429,7 @@
#endif
tsf_fsdb_connection_t *connection;
#endif
+ uint32_t __padding;
} remote;
} u;
tsf_limits_t *limits;
diff -urN tsf-src-org/tsf_ir_speed.c tsf-src/tsf_ir_speed.c
--- tsf-src-org/tsf_ir_speed.c 2023-03-31 10:49:45.000000000 +0800
+++ tsf-src/tsf_ir_speed.c 2023-05-11 08:18:35.000000000 +0800
@@ -63,6 +63,9 @@
Program_t *program;
unsigned elementIndex;
+ if (!(programIndex % 100))
+ printf("##programIndex: %u\n", programIndex);
+
CS(program = tsf_region_create(sizeof(Program_t)));
program->globals.len = numDecls + numDefns;

View File

@ -18,6 +18,12 @@ And then run `./build.sh` to build the source code, the libsodium source code wi
Run `./run_aot.sh` to test the benchmark, the native mode and iwasm aot mode will be tested respectively.
Run `./test_pgo.sh` to test the benchmark with AOT static PGO (Profile-Guided Optimization) enabled, please refer [here](../README.md#install-llvm-profdata) to install tool `llvm-profdata` and build `iwasm` with `cmake -DWAMR_BUILD_STATIC_PGO=1`.
- For Linux, build `iwasm` with `cmake -DWAMR_BUILD_STATIC_PGO=1`, then run `./test_pgo.sh` to test the benchmark with AOT static PGO (Profile-Guided Optimization) enabled.
- For Linux-sgx, similarly, build `iwasm` with `cmake -DWAMR_BUILD_STATIC_PGO=1`, then `make` in the directory `enclave-sample`. And run `./test_pgo.sh --sgx` to test the benchmark.
# Others
Refer to [Performance of WebAssembly runtimes in 2023](https://00f.net/2023/01/04/webassembly-benchmark-2023) for more about the performance comparison of wasm runtimes on running the libsodium benchmarks.

View File

@ -16,6 +16,8 @@ libsodium_CASES="aead_aes256gcm2 aead_aes256gcm aead_chacha20poly13052 aead_chac
sodium_utils3 sodium_utils sodium_version stream2 stream3 stream4 stream verify1 \
xchacha20"
PLATFORM=$(uname -s | tr A-Z a-z)
readonly WAMRC_CMD=$PWD/../../../wamr-compiler/build/wamrc
readonly OUT_DIR=$PWD/libsodium/zig-out/bin
@ -34,9 +36,16 @@ zig build -Drelease-fast -Denable_benchmarks=true -Dtarget=wasm32-wasi
for case in ${libsodium_CASES}
do
${WAMRC_CMD} -o ${OUT_DIR}/${case}.aot ${OUT_DIR}/${case}.wasm
if [ "$?" != 0 ]; then
echo -e "Error while compiling ${case}.wasm to ${case}.aot"
exit
fi
if [[ ${PLATFORM} == "linux" ]]; then
${WAMRC_CMD} --enable-segue -o ${OUT_DIR}/${case}_segue.aot ${OUT_DIR}/${case}.wasm
if [ "$?" != 0 ]; then
echo -e "Error while compiling ${case}.wasm to ${case}_segue.aot"
exit
fi
fi
done

Some files were not shown because too many files have changed in this diff Show More