Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

EOS-VM Optimized Compiler #7975

Merged
merged 28 commits into from
Sep 30, 2019
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d60e1c3
EOS-VM Optimized Compiler
spoonincode Jun 14, 2019
bf50619
always set load/store alignment assumption to just 1 byte
spoonincode Sep 24, 2019
a2e90f7
resolve possible exception object leakage
spoonincode Sep 24, 2019
cf3a3dc
fork EOSVMOC OOP helpers before main via linker trick
spoonincode Sep 25, 2019
ae9a6f5
fix some strict aliasing violations
spoonincode Sep 25, 2019
fcc8525
eosio_exit comment and cleanup
spoonincode Sep 25, 2019
579dd5c
fix GCC compile of EOS-VM OC and replace some constants
spoonincode Sep 26, 2019
50aa079
EOS-VM OC licensing updates
spoonincode Sep 26, 2019
bd910a5
resolve possible type punning violation on code cache header
spoonincode Sep 26, 2019
2684ee3
fix spelling error
spoonincode Sep 27, 2019
f087bb2
fix potential error in null string validator
spoonincode Sep 27, 2019
b6cd1e8
cleanup allocator include and be paranoid about size
spoonincode Sep 27, 2019
93607fa
add cstddef include for std:byte, possibly needed on some platforms
spoonincode Sep 27, 2019
5d81389
Merge remote-tracking branch 'origin/develop' into rodeos
spoonincode Sep 27, 2019
4f19ce2
cleanup to EOS-VM OC support post EOS-VM merge
spoonincode Sep 27, 2019
f4f7979
do not fall through after calling the chained SEGV handler
spoonincode Sep 27, 2019
fbfbf58
clean up signal init to not require an explict mutex
spoonincode Sep 27, 2019
2fab726
greatly simplify array_ptr_impl asm
spoonincode Sep 27, 2019
e74700d
add some paranoia around GS usage
spoonincode Sep 27, 2019
ad6d6d2
Merge remote-tracking branch 'origin/develop' into rodeos
spoonincode Sep 27, 2019
df42cfa
clean up error checking throughout the tierup processes
spoonincode Sep 29, 2019
94516fd
executor needs to check its inital map of code
spoonincode Sep 29, 2019
b5b655a
be more explict about testing the alignment of code/data segments
spoonincode Sep 29, 2019
d7ef3b3
make sure EOS-VM OC is given at least 1 thread
spoonincode Sep 29, 2019
65a2ff5
don't leak memfd if memory fails to be ctored
spoonincode Sep 29, 2019
d871028
coalesce executor's per-action cleanup lambda
spoonincode Sep 29, 2019
f838560
be more aggressive on evicting cache when compiler monitor indicates …
spoonincode Sep 30, 2019
25f33f7
bump the code cache header to force invalidation of previous caches
spoonincode Sep 30, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32)
if(LLVM_VERSION_MAJOR VERSION_LESS 7 OR LLVM_VERSION_MAJOR VERSION_GREATER 9)
message(FATAL_ERROR "EOSIO requires an LLVM version 7.0 to 9.0")
endif()

if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
list(APPEND EOSIO_WASM_RUNTIMES eos-vm-oc)
endif()
endif()

if(UNIX)
Expand Down
39 changes: 38 additions & 1 deletion libraries/chain/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,33 @@ if("wavm" IN_LIST EOSIO_WASM_RUNTIMES)
set(CHAIN_WAVM_SOURCES "webassembly/wavm.cpp")
endif()

if("eos-vm-oc" IN_LIST EOSIO_WASM_RUNTIMES)
set(CHAIN_EOSVMOC_SOURCES webassembly/eos-vm-oc/code_cache.cpp
webassembly/eos-vm-oc/executor.cpp
webassembly/eos-vm-oc/memory.cpp
webassembly/eos-vm-oc/intrinsic.cpp
webassembly/eos-vm-oc/LLVMJIT.cpp
webassembly/eos-vm-oc/LLVMEmitIR.cpp
webassembly/eos-vm-oc/compile_monitor.cpp
webassembly/eos-vm-oc/compile_trampoline.cpp
webassembly/eos-vm-oc/ipc_helpers.cpp
webassembly/eos-vm-oc/gs_seg_helpers.c
webassembly/eos-vm-oc.cpp)

if(LLVM_VERSION VERSION_LESS 7.1 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
enable_language(ASM-LLVMWAR)
list(APPEND CHAIN_EOSVMOC_SOURCES webassembly/eos-vm-oc/llvmWARshim.llvmwar)
else()
list(APPEND CHAIN_EOSVMOC_SOURCES webassembly/eos-vm-oc/llvmWARshim.cpp)
endif()

llvm_map_components_to_libnames(LLVM_LIBS support core passes mcjit native orcjit)
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})

option(EOSVMOC_ENABLE_DEVELOPER_OPTIONS "enable developer options for EOS-VM OC" OFF)
endif()

## SORT .cpp by most likely to change / break compile
add_library( eosio_chain
merkle.cpp
Expand Down Expand Up @@ -56,6 +83,7 @@ add_library( eosio_chain

${CHAIN_WAVM_SOURCES}
webassembly/wabt.cpp
${CHAIN_EOSVMOC_SOURCES}

# get_config.cpp
#
Expand All @@ -76,7 +104,7 @@ add_library( eosio_chain
)

target_link_libraries( eosio_chain fc chainbase Logging IR WAST WASM Runtime
softfloat builtins wabt
softfloat builtins wabt ${LLVM_LIBS}
)
target_include_directories( eosio_chain
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include"
Expand All @@ -85,12 +113,21 @@ target_include_directories( eosio_chain
"${CMAKE_BINARY_DIR}/libraries/wabt"
)

if("eos-vm-oc" IN_LIST EOSIO_WASM_RUNTIMES)
target_link_libraries(eosio_chain "-Wl,-wrap=main")
endif()

foreach(RUNTIME ${EOSIO_WASM_RUNTIMES})
string(TOUPPER "${RUNTIME}" RUNTIMEUC)
string(REPLACE "-" "_" RUNTIMEUC ${RUNTIMEUC})
target_compile_definitions(eosio_chain PUBLIC "EOSIO_${RUNTIMEUC}_RUNTIME_ENABLED")
endforeach()

if(EOSVMOC_ENABLE_DEVELOPER_OPTIONS)
message(WARNING "EOS-VM OC Developer Options are enabled; these are NOT supported")
target_compile_definitions(eosio_chain PUBLIC EOSIO_EOS_VM_OC_DEVELOPER)
endif()

install( TARGETS eosio_chain
RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ struct controller_impl {
cfg.reversible_cache_size, false, cfg.db_map_mode, cfg.db_hugepage_paths ),
blog( cfg.blocks_dir ),
fork_db( cfg.state_dir ),
wasmif( cfg.wasm_runtime, db ),
wasmif( cfg.wasm_runtime, cfg.eosvmoc_tierup, db, cfg.state_dir, cfg.eosvmoc_config ),
resource_limits( db ),
authorization( s, db ),
protocol_features( std::move(pfs) ),
Expand Down
3 changes: 3 additions & 0 deletions libraries/chain/include/eosio/chain/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <eosio/chain/account_object.hpp>
#include <eosio/chain/snapshot.hpp>
#include <eosio/chain/protocol_feature_manager.hpp>
#include <eosio/chain/webassembly/eos-vm-oc/config.hpp>

namespace chainbase {
class database;
Expand Down Expand Up @@ -82,6 +83,8 @@ namespace eosio { namespace chain {
bool disable_all_subjective_mitigations = false; //< for testing purposes only

wasm_interface::vm_type wasm_runtime = chain::config::default_wasm_runtime;
eosvmoc::config eosvmoc_config;
bool eosvmoc_tierup = false;

db_read_mode read_mode = db_read_mode::SPECULATIVE;
validation_mode block_validation_mode = validation_mode::FULL;
Expand Down
8 changes: 5 additions & 3 deletions libraries/chain/include/eosio/chain/wasm_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace eosio { namespace chain {
class apply_context;
class wasm_runtime_interface;
class controller;
namespace eosvmoc { struct config; }

struct wasm_exit {
int32_t code = 0;
Expand Down Expand Up @@ -73,10 +74,11 @@ namespace eosio { namespace chain {
public:
enum class vm_type {
wavm,
wabt
wabt,
eos_vm_oc
};

wasm_interface(vm_type vm, const chainbase::database& db);
wasm_interface(vm_type vm, bool eosvmoc_tierup, const chainbase::database& d, const boost::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config);
~wasm_interface();

//call before dtor to skip what can be minutes of dtor overhead with some runtimes; can cause leaks
Expand Down Expand Up @@ -108,4 +110,4 @@ namespace eosio{ namespace chain {
std::istream& operator>>(std::istream& in, wasm_interface::vm_type& runtime);
}}

FC_REFLECT_ENUM( eosio::chain::wasm_interface::vm_type, (wavm)(wabt) )
FC_REFLECT_ENUM( eosio::chain::wasm_interface::vm_type, (wavm)(wabt)(eos_vm_oc) )
55 changes: 50 additions & 5 deletions libraries/chain/include/eosio/chain/wasm_interface_private.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
#include <eosio/chain/wasm_interface.hpp>
#include <eosio/chain/webassembly/wavm.hpp>
#include <eosio/chain/webassembly/wabt.hpp>
#ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED
#include <eosio/chain/webassembly/eos-vm-oc.hpp>
#else
#define _REGISTER_EOSVMOC_INTRINSIC(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)
#endif
#include <eosio/chain/webassembly/runtime_interface.hpp>
#include <eosio/chain/wasm_eosio_injection.hpp>
#include <eosio/chain/transaction_context.hpp>
Expand All @@ -24,6 +29,8 @@ using boost::multi_index_container;

namespace eosio { namespace chain {

namespace eosvmoc { struct config; }

struct wasm_interface_impl {
struct wasm_cache_entry {
digest_type code_hash;
Expand All @@ -37,15 +44,35 @@ namespace eosio { namespace chain {
struct by_first_block_num;
struct by_last_block_num;

wasm_interface_impl(wasm_interface::vm_type vm, const chainbase::database& d) : db(d) {
#ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED
struct eosvmoc_tier {
eosvmoc_tier(const boost::filesystem::path& d, const eosvmoc::config& c, const chainbase::database& db) : cc(d, c, db), exec(cc) {}
eosvmoc::code_cache_async cc;
eosvmoc::executor exec;
eosvmoc::memory mem;
};
#endif

wasm_interface_impl(wasm_interface::vm_type vm, bool eosvmoc_tierup, const chainbase::database& d, const boost::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config) : db(d), wasm_runtime_time(vm) {
#ifdef EOSIO_WAVM_RUNTIME_ENABLED
if(vm == wasm_interface::vm_type::wavm)
runtime_interface = std::make_unique<webassembly::wavm::wavm_runtime>();
#endif
if(vm == wasm_interface::vm_type::wabt)
runtime_interface = std::make_unique<webassembly::wabt_runtime::wabt_runtime>();
#ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED
if(vm == wasm_interface::vm_type::eos_vm_oc)
runtime_interface = std::make_unique<webassembly::eosvmoc::eosvmoc_runtime>(data_dir, eosvmoc_config, d);
#endif
if(!runtime_interface)
EOS_THROW(wasm_exception, "${r} wasm runtime not supported on this platform and/or configuration", ("r", vm));

#ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED
if(eosvmoc_tierup) {
EOS_ASSERT(vm != wasm_interface::vm_type::eos_vm_oc, wasm_exception, "You can't use EOS-VM OC as the base runtime when tier up is activated");
eosvmoc.emplace(data_dir, eosvmoc_config, d);
}
#endif
}

~wasm_interface_impl() {
Expand Down Expand Up @@ -84,7 +111,13 @@ namespace eosio { namespace chain {

void current_lib(uint32_t lib) {
//anything last used before or on the LIB can be evicted
wasm_instantiation_cache.get<by_last_block_num>().erase(wasm_instantiation_cache.get<by_last_block_num>().begin(), wasm_instantiation_cache.get<by_last_block_num>().upper_bound(lib));
const auto first_it = wasm_instantiation_cache.get<by_last_block_num>().begin();
const auto last_it = wasm_instantiation_cache.get<by_last_block_num>().upper_bound(lib);
#ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED
if(eosvmoc) for(auto it = first_it; it != last_it; it++)
eosvmoc->cc.free_code(it->code_hash, it->vm_version);
#endif
wasm_instantiation_cache.get<by_last_block_num>().erase(first_it, last_it);
}

const std::unique_ptr<wasm_instantiated_module_interface>& get_instantiated_module( const digest_type& code_hash, const uint8_t& vm_type,
Expand Down Expand Up @@ -125,8 +158,14 @@ namespace eosio { namespace chain {
EOS_ASSERT(false, wasm_serialization_error, e.message.c_str());
}

wasm_injections::wasm_binary_injection<true> injector(module);
injector.inject();
if(wasm_runtime_time == wasm_interface::vm_type::wabt || wasm_runtime_time == wasm_interface::vm_type::wavm) {
wasm_injections::wasm_binary_injection<true> injector(module);
injector.inject();
}
else {
wasm_injections::wasm_binary_injection<false> injector(module);
injector.inject();
}

std::vector<U8> bytes;
try {
Expand All @@ -140,7 +179,7 @@ namespace eosio { namespace chain {
}

wasm_instantiation_cache.modify(it, [&](auto& c) {
c.module = runtime_interface->instantiate_module((const char*)bytes.data(), bytes.size(), parse_initial_memory(module));
c.module = runtime_interface->instantiate_module((const char*)bytes.data(), bytes.size(), parse_initial_memory(module), code_hash, vm_type, vm_version);
});
}
return it->module;
Expand All @@ -166,6 +205,11 @@ namespace eosio { namespace chain {
wasm_cache_index wasm_instantiation_cache;

const chainbase::database& db;
const wasm_interface::vm_type wasm_runtime_time;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/_time/_type/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is N/A after merging from develop


#ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED
fc::optional<eosvmoc_tier> eosvmoc;
#endif
};

#define _ADD_PAREN_1(...) ((__VA_ARGS__)) _ADD_PAREN_2
Expand All @@ -176,6 +220,7 @@ namespace eosio { namespace chain {

#define _REGISTER_INTRINSIC_EXPLICIT(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
_REGISTER_WAVM_INTRINSIC(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
_REGISTER_EOSVMOC_INTRINSIC(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
_REGISTER_WABT_INTRINSIC(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)

#define _REGISTER_INTRINSIC4(CLS, MOD, METHOD, WASM_SIG, NAME, SIG)\
Expand Down
Loading