diff --git a/common.mk b/common.mk index e7468ad61c..e0ca7b2fe0 100644 --- a/common.mk +++ b/common.mk @@ -237,10 +237,6 @@ $(srcdir)/lib/ruby_vm/mjit/instruction.rb: $(tooldir)/insns2vm.rb $(tooldir)/rub $(ECHO) generating $@ $(Q) $(BASERUBY) -Ku $(tooldir)/insns2vm.rb --basedir="$(srcdir)" $(INSNS2VMOPT) $@ -mjit-headers: $(MJIT_SUPPORT)-mjit-headers -no-mjit-headers: PHONY -yes-mjit-headers: mjit_config.h PHONY - mjit.$(OBJEXT): mjit_config.h mjit_config.h: Makefile @@ -248,29 +244,6 @@ mjit_config.h: Makefile mjit-bindgen: $(Q) $(BASERUBY) -rrubygems -C $(srcdir)/tool/mjit bindgen.rb $(CURDIR) -# These rules using MJIT_HEADER_SUFFIX must be in common.mk, not -# Makefile.in, in order to override the macro in defs/universal.mk. - -# Other `-Dxxx`s preceding `-DMJIT_HEADER` will be removed in transform_mjit_header.rb. -# So `-DMJIT_HEADER` should be passed first when rb_mjit_header.h is generated. -$(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time: probes.h vm.$(OBJEXT) \ - $(TIMESTAMPDIR)/$(arch)/.time $(tooldir)/mjit_tabs.rb $(PREP) $(RBCONFIG) - $(ECHO) building $(@F:.time=.h) - $(Q)$(MINIRUBY) $(tooldir)/mjit_tabs.rb "$(MJIT_TABS)" \ - $(CPP) -DMJIT_HEADER $(MJIT_HEADER_FLAGS) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(srcdir)/vm.c $(CPPOUTFLAG)$(@F:.time=.h).new - $(Q) $(IFCHANGE) "--timestamp=$@" $(@F:.time=.h) $(@F:.time=.h).new - -$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).h: $(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time - -$(MJIT_MIN_HEADER:.h=)$(MJIT_HEADER_SUFFIX).h: \ - $(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time \ - $(tooldir)/transform_mjit_header.rb $(PREP) \ - $(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).h - $(ECHO) building $@ - $(Q)$(MINIRUBY) $(tooldir)/transform_mjit_header.rb "$(CC) $(CFLAGS) -w" $(MJIT_HEADER:.h=)$(MJIT_HEADER_ARCH).h $@ - $(Q) $(MAKEDIRS) $(MJIT_HEADER_INSTALL_DIR) - $(Q) $(MAKE_LINK) $@ $(MJIT_HEADER_INSTALL_DIR)/$(@F) - .PHONY: showflags exts enc trans: $(SHOWFLAGS) showflags: @@ -684,8 +657,7 @@ clean-srcs-local:: $(Q)$(RM) parse.c parse.h lex.c enc/trans/newline.c revision.h $(Q)$(RM) id.c id.h probes.dmyh probes.h $(Q)$(RM) encdb.h transdb.h verconf.h ruby-runner.h - $(Q)$(RM) mjit_config.h rb_mjit_header.h - $(Q)$(RM) $(MJIT_MIN_HEADER) $(MJIT_MIN_HEADER:.h=)$(MJIT_HEADER_SUFFIX:%=*).h + $(Q)$(RM) mjit_config.h realclean-srcs-local:: clean-srcs-local $(Q)$(CHDIR) $(srcdir) && $(RM) \ diff --git a/configure.ac b/configure.ac index cc3d4305c3..42b96abbad 100644 --- a/configure.ac +++ b/configure.ac @@ -797,8 +797,6 @@ AS_IF([test "$GCC" = yes], [ [@%:@include ]) ]) - : ${MJIT_HEADER_FLAGS='-P -dD'} - # -fstack-protector AS_CASE(["$target_os"], [emscripten*|wasi*], [ @@ -2933,8 +2931,6 @@ AC_ARG_WITH(mjit-tabs, AC_SUBST(MJIT_TABS)dnl AC_SUBST(DLDFLAGS)dnl AC_SUBST(ARCH_FLAG)dnl -AC_SUBST(MJIT_HEADER_FLAGS)dnl -AC_SUBST(MJIT_HEADER_INSTALL_DIR)dnl AC_SUBST(MJIT_CC)dnl AS_CASE(["$GCC:$target_os"], [yes:aix*], [mjit_std_cflag="-std=gnu99"], @@ -3407,12 +3403,6 @@ AS_CASE(["$target_os"], AC_ARG_ENABLE(multiarch, AS_HELP_STRING([--enable-multiarch], [enable multiarch compatible directories]), [multiarch=], [unset multiarch]) -AS_IF([test ${multiarch+set}], [ - AC_DEFINE(ENABLE_MULTIARCH) - MJIT_HEADER_INSTALL_DIR=include/'${arch}/${RUBY_VERSION_NAME}' -], [ - MJIT_HEADER_INSTALL_DIR=include/'${RUBY_VERSION_NAME}/${arch}' -]) archlibdir='${libdir}/${arch}' sitearchlibdir='${libdir}/${sitearch}' diff --git a/defs/gmake.mk b/defs/gmake.mk index e646968b6f..0c404e04e4 100644 --- a/defs/gmake.mk +++ b/defs/gmake.mk @@ -386,34 +386,6 @@ ifneq ($(filter update-bundled_gems refresh-gems,$(MAKECMDGOALS)),) update-gems: update-bundled_gems endif -ifeq ($(filter 0 1,$(words $(arch_flags))),) -$(foreach x,$(patsubst -arch=%,%,$(arch_flags)), \ - $(eval $$(MJIT_HEADER:.h=)-$(value x).h \ - $$(MJIT_MIN_HEADER:.h=)-$(value x).h \ - $$(TIMESTAMPDIR)/$$(MJIT_HEADER:.h=)-$(value x).time \ - : ARCH_FLAG := -arch $(value x))) - -$(foreach x,$(patsubst -arch=%,%,$(arch_flags)), \ - $(eval $$(MJIT_HEADER:.h=)-$(value x).h: \ - $$(TIMESTAMPDIR)/$$(MJIT_HEADER:.h=)-$(value x).time)) - -mjit_min_headers := $(patsubst -arch=%,$(MJIT_MIN_HEADER:.h=-%.h),$(arch_flags)) -$(MJIT_MIN_HEADER): $(mjit_min_headers) $(PREP) - @ set -e; set $(patsubst -arch=%,%,$(arch_flags)); \ - cd $(@D); h=$(@F:.h=); \ - exec > $(@F).new; \ - echo '#if 0'; \ - for arch; do\ - echo "#elif defined __$${arch}__"; \ - echo "# include \"$$h-$$arch.h\""; \ - done; \ - echo "#else"; echo "# error unsupported platform"; echo "#endif" - $(IFCHANGE) $@ $@.new - $(Q) $(MAKEDIRS) $(MJIT_HEADER_INSTALL_DIR) - $(Q) $(MAKE_LINK) $@ $(MJIT_HEADER_INSTALL_DIR)/$(@F) - -endif - .SECONDARY: update-unicode-files .SECONDARY: update-unicode-auxiliary-files .SECONDARY: update-unicode-ucd-emoji-files diff --git a/defs/universal.mk b/defs/universal.mk deleted file mode 100644 index c34a31b356..0000000000 --- a/defs/universal.mk +++ /dev/null @@ -1,5 +0,0 @@ -arch_flags := $(filter -arch=%,$(subst -arch ,-arch=,$(ARCH_FLAG))) -ifeq ($(filter 0 1,$(words $(arch_flags))),) -override MJIT_HEADER_SUFFIX = -% -override MJIT_HEADER_ARCH = -$(word 2,$(ARCH_FLAG)) -endif diff --git a/ruby-runner.c b/ruby-runner.c index 1e9b560817..d7ce511a85 100644 --- a/ruby-runner.c +++ b/ruby-runner.c @@ -9,10 +9,6 @@ #include "ruby-runner.h" -#ifdef MAKE_MJIT_BUILD_DIR -const char MJIT_HEADER[] = BUILDDIR "/" MJIT_MIN_HEADER; -#else - static void insert_env_path(const char *envname, const char *paths, size_t size, int prepend) { @@ -91,5 +87,3 @@ main(int argc, char **argv) perror(rubypath); return -1; } - -#endif /* MAKE_MJIT_BUILD_DIR */ diff --git a/template/GNUmakefile.in b/template/GNUmakefile.in index 4db4467905..0c7f4e9dd0 100644 --- a/template/GNUmakefile.in +++ b/template/GNUmakefile.in @@ -27,7 +27,6 @@ override UNICODE_TABLES_DEPENDENTS = \ $(UNICODE_TABLES_DATA_FILES)))),\ force,none) -include $(srcdir)/defs/universal.mk -include uncommon.mk include $(srcdir)/defs/gmake.mk diff --git a/template/Makefile.in b/template/Makefile.in index 71b68edbeb..0dd30ca7d1 100644 --- a/template/Makefile.in +++ b/template/Makefile.in @@ -96,20 +96,12 @@ USE_RUBYGEMS = @USE_RUBYGEMS@ USE_RUBYGEMS_ = $(USE_RUBYGEMS:yes=) CPPFLAGS = @CPPFLAGS@ $(USE_RUBYGEMS_:no=-DDISABLE_RUBYGEMS=1) MJIT_SUPPORT = @MJIT_SUPPORT@ -MJIT_HEADER_FLAGS = @MJIT_HEADER_FLAGS@ -MJIT_HEADER_SUFFIX = -MJIT_HEADER_ARCH = -MJIT_HEADER_INSTALL_DIR = @MJIT_HEADER_INSTALL_DIR@ MJIT_CC = @MJIT_CC@ MJIT_CFLAGS = @MJIT_CFLAGS@ MJIT_OPTFLAGS = @MJIT_OPTFLAGS@ MJIT_DEBUGFLAGS = @MJIT_DEBUGFLAGS@ MJIT_LDSHARED = @MJIT_LDSHARED@ MJIT_DLDFLAGS = $(XDLDFLAGS) -MJIT_HEADER = rb_mjit_header.h -MJIT_MIN_HEADER_NAME = rb_mjit_min_header-$(RUBY_PROGRAM_VERSION).h -MJIT_MIN_HEADER = $(MJIT_HEADER_BUILD_DIR)/$(MJIT_MIN_HEADER_NAME) -MJIT_HEADER_BUILD_DIR = $(EXTOUT)/include/$(arch) MJIT_TABS=@MJIT_TABS@ YJIT_SUPPORT=@YJIT_SUPPORT@ YJIT_LIBS=@YJIT_LIBS@ @@ -183,7 +175,6 @@ MAJOR= @MAJOR@ MINOR= @MINOR@ TEENY= @TEENY@ -# here for MJIT_MIN_HEADER_NAME, not in common.mk RUBY_PROGRAM_VERSION = $(MAJOR).$(MINOR).$(TEENY) LIBRUBY_A = @LIBRUBY_A@ @@ -490,17 +481,8 @@ probes.$(OBJEXT): $(srcdir)/probes.d $(DTRACE_REBUILD:yes=probes.stamp) $(Q) $(RM) $@ $(Q) $(DTRACE) -G -C $(INCFLAGS) -s $(srcdir)/probes.d -o $@ $(DTRACE_REBUILD_OBJS) -main: mjit-headers -yes-mjit-headers: $(MJIT_MIN_HEADER) clean-local:: - $(Q)$(RM) \ - $(MJIT_HEADER) $(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX:%=*).h \ - $(MJIT_MIN_HEADER) $(MJIT_MIN_HEADER:.h=)$(MJIT_HEADER_SUFFIX:%=*).h \ - $(MJIT_HEADER_INSTALL_DIR)/rb_mjit_min_header-*.h \ - $(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time mjit_config.h \ - || $(NULLCMD) $(Q)$(RM) -r mjit_build_dir.* - -$(Q) $(RMDIRS) $(MJIT_HEADER_INSTALL_DIR) $(MJIT_HEADER_BUILD_DIR) $(TIMESTAMPDIR) 2> $(NULL) || $(NULLCMD) # DTrace static library hacks described here: # https://marc.info/?l=opensolaris-dtrace-discuss&m=114761203110734&w=4 @@ -669,12 +651,6 @@ mjit_config.h: echo '#define RUBY_MJIT_CONFIG_H 1'; \ echo; \ sep=; \ - echo '#ifdef LOAD_RELATIVE'; \ - quote MJIT_HEADER_INSTALL_DIR "/$(MJIT_HEADER_INSTALL_DIR)"; \ - echo '#else'; \ - quote MJIT_HEADER_INSTALL_DIR "$(rubyarchhdrdir)"; \ - echo '#endif'; \ - quote MJIT_MIN_HEADER_NAME "$(MJIT_MIN_HEADER_NAME)"; \ sep=,; \ quote "MJIT_CC_COMMON " $(MJIT_CC); \ quote "MJIT_CFLAGS MJIT_ARCHFLAG" $(MJIT_CFLAGS); \ @@ -691,10 +667,10 @@ mjit_config.h: } > $@ yes-test-almost yes-test-all programs: mjit_build_dir.$(SOEXT) -mjit_build_dir.$(SOEXT): $(MJIT_MIN_HEADER) $(srcdir)/ruby-runner.c ruby-runner.h +mjit_build_dir.$(SOEXT): $(srcdir)/ruby-runner.c ruby-runner.h $(ECHO) making $@ $(Q) $(DLDSHARED) $(MJIT_DLDFLAGS) $(ARCH_FLAG) $(CFLAGS) $(INCFLAGS) $(CPPFLAGS) \ - -DMAKE_MJIT_BUILD_DIR=1 -DMJIT_MIN_HEADER='"$(MJIT_MIN_HEADER)"' \ + -DMAKE_MJIT_BUILD_DIR=1 \ $(OUTFLAG)$@ $(srcdir)/ruby-runner.c # yes-test-basic: leaked-globals diff --git a/tool/transform_mjit_header.rb b/tool/transform_mjit_header.rb deleted file mode 100644 index 2180236824..0000000000 --- a/tool/transform_mjit_header.rb +++ /dev/null @@ -1,319 +0,0 @@ -# Copyright (C) 2017 Vladimir Makarov, -# This is a script to transform functions to static inline. -# Usage: transform_mjit_header.rb
- -require 'fileutils' -require 'tempfile' - -PROGRAM = File.basename($0, ".*") - -module MJITHeader - ATTR_VALUE_REGEXP = /[^()]|\([^()]*\)/ - ATTR_REGEXP = /__attribute__\s*\(\(#{ATTR_VALUE_REGEXP}*\)\)/ - # Example: - # VALUE foo(int bar) - # VALUE __attribute__ ((foo)) bar(int baz) - # __attribute__ ((foo)) VALUE bar(int baz) - FUNC_HEADER_REGEXP = /\A[^\[{(]*(\s*#{ATTR_REGEXP})*[^\[{(]*\((#{ATTR_REGEXP}|[^()])*\)(\s*#{ATTR_REGEXP})*\s*/ - TARGET_NAME_REGEXP = /\A(rb|ruby|vm|insn|attr|Init)_/ - - # Predefined macros for compilers which are already supported by MJIT. - # We're going to support cl.exe too (WIP) but `cl.exe -E` can't produce macro. - SUPPORTED_CC_MACROS = [ - '__GNUC__', # gcc - '__clang__', # clang - ] - - # These macros are relied on this script's transformation - PREFIXED_MACROS = [ - 'ALWAYS_INLINE', - 'COLDFUNC', - 'inline', - 'RBIMPL_ATTR_COLD', - ] - - # For MinGW's ras.h. Those macros have its name in its definition and can't be preprocessed multiple times. - RECURSIVE_MACROS = %w[ - RASCTRYINFO - RASIPADDR - ] - - IGNORED_FUNCTIONS = [ - 'rb_vm_search_method_slowpath', # This increases the time to compile when inlined. So we use it as external function. - 'rb_equal_opt', # Not used from VM and not compilable - 'ruby_abi_version', - ] - - ALWAYS_INLINED_FUNCTIONS = [ - 'vm_opt_plus', - 'vm_opt_minus', - 'vm_opt_mult', - 'vm_opt_div', - 'vm_opt_mod', - 'vm_opt_neq', - 'vm_opt_lt', - 'vm_opt_le', - 'vm_opt_gt', - 'vm_opt_ge', - 'vm_opt_ltlt', - 'vm_opt_and', - 'vm_opt_or', - 'vm_opt_aref', - 'vm_opt_aset', - 'vm_opt_aref_with', - 'vm_opt_aset_with', - 'vm_opt_not', - ] - - COLD_FUNCTIONS = %w[ - setup_parameters_complex - vm_call_iseq_setup - vm_call_iseq_setup_2 - vm_call_iseq_setup_tailcall - vm_call_method_each_type - vm_ic_update - ] - - # Return start..stop of last decl in CODE ending STOP - def self.find_decl(code, stop) - level = 0 - i = stop - while i = code.rindex(/[;{}]/, i) - if level == 0 && stop != i && decl_found?($&, i) - return decl_start($&, i)..stop - end - case $& - when '}' - level += 1 - when '{' - level -= 1 - end - i -= 1 - end - nil - end - - def self.decl_found?(code, i) - i == 0 || code == ';' || code == '}' - end - - def self.decl_start(code, i) - if i == 0 && code != ';' && code != '}' - 0 - else - i + 1 - end - end - - # Given DECL return the name of it, nil if failed - def self.decl_name_of(decl) - ident_regex = /\w+/ - decl = decl.gsub(/^#.+$/, '') # remove macros - reduced_decl = decl.gsub(ATTR_REGEXP, '') # remove attributes - su1_regex = /{[^{}]*}/ - su2_regex = /{([^{}]|#{su1_regex})*}/ - su3_regex = /{([^{}]|#{su2_regex})*}/ # 3 nested structs/unions is probably enough - reduced_decl.gsub!(su3_regex, '') # remove structs/unions in the header - id_seq_regex = /\s*(?:#{ident_regex}(?:\s+|\s*[*]+\s*))*/ - # Process function header: - match = /\A#{id_seq_regex}(?#{ident_regex})\s*\(/.match(reduced_decl) - return match[:name] if match - # Process non-function declaration: - reduced_decl.gsub!(/\s*=[^;]+(?=;)/, '') # remove initialization - match = /#{id_seq_regex}(?#{ident_regex})/.match(reduced_decl); - return match[:name] if match - nil - end - - # Return true if CC with CFLAGS compiles successfully the current code. - # Use STAGE in the message in case of a compilation failure - def self.check_code!(code, cc, cflags, stage) - with_code(code) do |path| - cmd = "#{cc} #{cflags} #{path}" - out = IO.popen(cmd, err: [:child, :out], &:read) - unless $?.success? - STDERR.puts "error in #{stage} header file:\n#{out}" - exit false - end - end - end - - # Remove unpreprocessable macros - def self.remove_harmful_macros!(code) - code.gsub!(/^#define #{Regexp.union(RECURSIVE_MACROS)} .*$/, '') - end - - # -dD outputs those macros, and it produces redefinition warnings or errors - # This assumes common.mk passes `-DMJIT_HEADER` first when it creates rb_mjit_header.h. - def self.remove_predefined_macros!(code) - code.sub!(/\A(#define [^\n]+|\n)*(#define MJIT_HEADER 1\n)/, '\2') - end - - # Return [macro, others]. But others include PREFIXED_MACROS to be used in code. - def self.separate_macro_and_code(code) - code.lines.partition do |l| - l.start_with?('#') && PREFIXED_MACROS.all? { |m| !l.start_with?("#define #{m}") } - end.map! { |lines| lines.join('') } - end - - def self.write(code, out) - # create with strict permission, then will install proper - # permission - FileUtils.mkdir_p(File.dirname(out), mode: 0700) - File.binwrite("#{out}.new", code, perm: 0600) - FileUtils.mv("#{out}.new", out) - end - - # Note that this checks runruby. This conservatively covers platform names. - def self.windows? - RUBY_PLATFORM =~ /mswin|mingw|msys/ - end - - # If code has macro which only supported compilers predefine, return true. - def self.supported_header?(code) - SUPPORTED_CC_MACROS.any? { |macro| code =~ /^#\s*define\s+#{Regexp.escape(macro)}\b/ } - end - - # This checks if syntax check outputs one of the following messages. - # "error: conflicting types for 'restrict'" - # "error: redefinition of parameter 'restrict'" - # If it's true, this script regards platform as AIX or Solaris and adds -std=c99 as workaround. - def self.conflicting_types?(code, cc, cflags) - with_code(code) do |path| - cmd = "#{cc} #{cflags} #{path}" - out = IO.popen(cmd, err: [:child, :out], &:read) - !$?.success? && - (out.match?(/error: conflicting types for '[^']+'/) || - out.match?(/error: redefinition of parameter '[^']+'/)) - end - end - - def self.with_code(code) - # for `system_header` pragma which can't be in the main file. - Tempfile.open(['', '.h'], mode: File::BINARY) do |f| - f.puts code - f.close - Tempfile.open(['', '.c'], mode: File::BINARY) do |c| - c.puts <
" -end - -if STDOUT.tty? - require_relative 'lib/colorize' - color = Colorize.new -end -cc = ARGV[0] -code = File.binread(ARGV[1]) # Current version of the header file. -outfile = ARGV[2] -cflags = '-S -DMJIT_HEADER -fsyntax-only -Werror=implicit-function-declaration -Werror=implicit-int -Wfatal-errors' - -if !MJITHeader.supported_header?(code) - puts "This compiler (#{cc}) looks not supported for MJIT. Giving up to generate MJIT header." - MJITHeader.write("#error MJIT does not support '#{cc}' yet", outfile) - exit -end - -MJITHeader.remove_predefined_macros!(code) - -if MJITHeader.windows? # transformation is broken on Windows and the platform is not supported - MJITHeader.remove_harmful_macros!(code) - MJITHeader.check_code!(code, cc, cflags, 'initial') - puts "\nSkipped transforming external functions to static on Windows." - MJITHeader.write(code, outfile) - exit -end - -macro, code = MJITHeader.separate_macro_and_code(code) # note: this does not work on MinGW -code = <