diff options
-rw-r--r-- | Makefile | 553 | ||||
-rw-r--r-- | tests/test_handlers.c | 1 | ||||
-rw-r--r-- | tests/test_vs_proto2.cc | 167 | ||||
-rw-r--r-- | upb/bindings/lua/upb.c | 1 | ||||
-rw-r--r-- | upb/bindings/ruby/extconf.rb | 4 | ||||
-rw-r--r-- | upb/pb/compile_decoder_x64.c | 83 | ||||
-rw-r--r-- | upb/pb/jit_debug_elf_file.s | 6 |
7 files changed, 222 insertions, 593 deletions
@@ -18,41 +18,47 @@ .PHONY: all lib clean tests test benchmarks benchmark descriptorgen .PHONY: clean_leave_profile -# Default rule: just build libupb. -default: lib +# Prevents the deletion of intermediate files. +.SECONDARY: + +UPB_MODULES = upb upb.pb upb.descriptor +UPB_LIBS = $(patsubst %,lib/lib%.a,$(UPB_MODULES)) +UPB_PICLIBS = $(patsubst %,lib/lib%_pic.a,$(UPB_MODULES)) + +# Default rule: build all upb libraries (but no bindings) +default: $(UPB_LIBS) # All: build absolutely everything all: lib tests benchmarks tools/upbc lua python testall: test pythontest -# User-specified CFLAGS. -USER_CFLAGS= -USER_CXXFLAGS= +# Set this to have user-specific flags (especially things like -O0 and -g). +USER_CPPFLAGS= -# If the user doesn't specify an -O setting, we default to -O3, except -# for def which gets -Os. -ifeq (, $(findstring -O, $(USER_CFLAGS))) - USER_CFLAGS += -O3 - DEF_OPT = -Os -endif - -ifneq (, $(findstring DUPB_USE_JIT_X64, $(USER_CFLAGS))) - USE_JIT=true -endif +# Build with "make WITH_JIT=yes" (or anything besides "no") to enable the JIT. +WITH_JIT=no # Basic compiler/flag setup. CC=cc CXX=c++ -CFLAGS=-std=gnu99 -CXXFLAGS=$(USER_CXXFLAGS) -INCLUDE=-Itests -I. -CPPFLAGS=$(INCLUDE) -DNDEBUG -Wall -Wextra -Wno-sign-compare -Wno-unused-private-field $(USER_CFLAGS) +CFLAGS=-std=c99 +CXXFLAGS=-Wno-unused-private-field $(USER_CXXFLAGS) +INCLUDE=-I. +CPPFLAGS=$(INCLUDE) -DNDEBUG -Wall -Wextra -Wno-sign-compare $(USER_CPPFLAGS) LDLIBS=-lpthread upb/libupb.a LUA=lua # 5.1 and 5.2 should both be supported +ifneq ($(WITH_JIT), no) + USE_JIT=true + CPPFLAGS += -DUPB_USE_JIT_X64 +endif + # Build with "make Q=" to see all commands that are being executed. Q=@ +# Function to expand a wildcard pattern recursively. +rwildcard=$(strip $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)$(filter $(subst *,%,$2),$d))) + ifeq ($(Q), @) E=@echo else @@ -68,23 +74,55 @@ install: # Unfortuantely we can't easily generate deps for benchmarks or tests because # of the scheme we use that compiles the same source file multiple times with # different -D options, which can include different header files. -ALLSRC=$(shell find . -name '*.c' -print | grep -v perf-tmp) -deps: Makefile $(ALLSRC) +dep: $(E) Regenerating dependencies for upb/... @set -e @rm -f deps - @for file in $(ALLSRC); do \ + @for file in $$(find . -name '*.c'); do \ gcc -MM $$file -MT $${file%.*}.o $(CPPFLAGS) -I. >> deps 2> /dev/null; \ done -# Source files. ############################################################### +clean_leave_profile: + rm -rf obj lib + rm -f benchmark/google_messages.proto.pb benchmark/google_messages.pb.* benchmarks/b.* benchmarks/*.pb* + rm -f $(TESTS) tests/testmain.o tests/t.* + rm -f tests/test.proto.pb + rm -f upb/descriptor.pb + rm -rf tools/upbc deps + rm -rf upb/bindings/python/build + rm -f upb/bindings/ruby/Makefile + rm -f upb/bindings/ruby/upb.so + rm -f upb/bindings/ruby/mkmf.log + find . | grep dSYM | xargs rm -rf + +clean: clean_leave_profile + rm -rf $(call rwildcard,,*.gcno) $(call rwildcard,,*.gcda) + +# A little bit of Make voodoo: you can call this from the deps of a patterned +# rule like so: +# +# all: lib/libfoo.bar.a +# +# foo_bar_SRCS = a.c b.c +# +# # This will expand into a.o b.o +# lib/lib%.a: $(call make_objs,o) +# gcc -c -o $@ $^ +# +# SECONDEXPANSION: flips on a bit essentially that allows this "seconary +# expansion": it must appear before anything that uses make_objs. +.SECONDEXPANSION: +to_srcs = $(subst .,_,$(1)_SRCS) +pc = % +make_objs = $$(patsubst upb/$$(pc).c,obj/$$(pc).$(1),$$($$(call to_srcs,$$*))) +make_objs_cc = $$(patsubst upb/$$(pc).cc,obj/$$(pc).$(1),$$($$(call to_srcs,$$*))) + -# The core library. -CORE= \ +# Core libraries (ie. not bindings). ############################################################### + +upb_SRCS = \ upb/def.c \ - upb/descriptor/reader.c \ - upb/descriptor/descriptor.upb.c \ upb/handlers.c \ upb/refcounted.c \ upb/shim/shim.c \ @@ -92,104 +130,67 @@ CORE= \ upb/table.c \ upb/upb.c \ -GOOGLEPB= \ - upb/bindings/googlepb/bridge.cc \ - upb/bindings/googlepb/proto2.cc \ +upb_descriptor_SRCS = \ + upb/descriptor/reader.c \ + upb/descriptor/descriptor.upb.c \ -# Library for the protocol buffer format (both text and binary). -PB= \ +upb_pb_SRCS = \ upb/pb/decoder.c \ upb/pb/compile_decoder.c \ upb/pb/glue.c \ upb/pb/varint.c \ upb/pb/textprinter.c \ +# If the JIT is enabled we include its source. +# If Lua is present we can use DynASM to regenerate the .h file. +ifdef USE_JIT +upb_pb_SRCS += upb/pb/compile_decoder_x64.c +obj/pb/compile_decoder_x64.o obj/pb/compile_decoder_x64.lo: upb/pb/compile_decoder_x64.h -# Rules. ####################################################################### - -clean_leave_profile: - rm -rf $(LIBUPB) $(LIBUPB_PIC) - rm -rf $(call rwildcard,,*.o) $(call rwildcard,,*.lo) $(call rwildcard,,*.dSYM) - rm -rf upb/pb/decoder_x64.h - rm -rf benchmark/google_messages.proto.pb benchmark/google_messages.pb.* benchmarks/b.* benchmarks/*.pb* - rm -rf upb/pb/jit_debug_elf_file.o - rm -rf upb/pb/jit_debug_elf_file.h - rm -rf $(TESTS) tests/t.* - rm -rf upb/descriptor.pb - rm -rf tools/upbc deps - rm -rf upb/bindings/lua/upb.so - rm -rf upb/bindings/python/build - rm -rf upb/bindings/ruby/Makefile - rm -rf upb/bindings/ruby/upb.so +upb/pb/compile_decoder_x64.h: upb/pb/compile_decoder_x64.dasc + $(E) DYNASM $< + $(Q) $(LUA) dynasm/dynasm.lua upb/pb/compile_decoder_x64.dasc > upb/pb/compile_decoder_x64.h || (rm upb/pb/compile_decoder_x64.h ; false) +endif -clean: clean_leave_profile - rm -rf $(call rwildcard,,*.gcno) $(call rwildcard,,*.gcda) +upb_json_SRCS = \ + upb/json/typed_printer.c -# Core library (libupb.a). -SRC=$(CORE) $(PB) $(GOOGLEPB) -LIBUPB=upb/libupb.a -LIBUPB_PIC=upb/libupb_pic.a -lib: $(LIBUPB) +# If the user doesn't specify an -O setting, we use -O3 for critical-path +# code and -Os for the rest. +ifeq (, $(findstring -O, $(USER_CFLAGS))) +OPT = -O3 +lib/libupb.a : OPT = -Os +lib/libupb.descriptor.a : OPT = -Os +endif +$(UPB_PICLIBS): lib/lib%_pic.a: $(call make_objs,lo) + $(E) AR $@ + $(Q) mkdir -p lib && ar rcs $@ $^ -OBJ=$(patsubst %.c,%.o,$(SRC)) $(patsubst %.cc,%.o,$(SRC)) -PICOBJ=$(patsubst %.c,%.lo,$(SRC)) $(patsubst %.cc,%.lo,$(SRC)) +$(UPB_LIBS): lib/lib%.a: $(call make_objs,o) + $(E) AR $@ + $(Q) mkdir -p lib && ar rcs $@ $^ -ifdef USE_JIT -PB += upb/pb/compile_decoder_x64.c -upb/pb/compile_decoder_x64.o upb/pb/compile_decoder_x64.lo: upb/pb/compile_decoder_x64.h -endif -$(LIBUPB): $(OBJ) - $(E) AR $(LIBUPB) - $(Q) ar rcs $(LIBUPB) $(OBJ) -$(LIBUPB_PIC): $(PICOBJ) - $(E) AR $(LIBUPB_PIC) - $(Q) ar rcs $(LIBUPB_PIC) $(PICOBJ) - -%.o : %.c +obj/%.o: upb/%.c | $$(@D)/. $(E) CC $< - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + $(Q) $(CC) $(OPT) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< -%.o : %.cc +obj/%.o: upb/%.cc | $$(@D)/. $(E) CXX $< - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $< + $(Q) $(CXX) $(OPT) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< -%.lo : %.c +obj/%.lo: upb/%.c | $$(@D)/. $(E) 'CC -fPIC' $< - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< -fPIC + $(Q) $(CC) $(OPT) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< -fPIC -%.o : %.cc +obj/%.lo: upb/%.cc | $$(@D)/. $(E) CXX $< - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $< -fPIC + $(Q) $(CXX) $(OPT) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< -fPIC -# Override the optimization level for def.o, because it is not in the -# critical path but gets very large when -O3 is used. -upb/def.o: upb/def.c - $(E) CC $< - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) $(DEF_OPT) -c -o $@ $< - -upb/def.lo: upb/def.c - $(E) 'CC -fPIC' $< - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) $(DEF_OPT) -c -o $@ $< -fPIC - -upb/pb/compile_decoder_x64.h: upb/pb/compile_decoder_x64.dasc - $(E) DYNASM $< - $(Q) $(LUA) dynasm/dynasm.lua upb/pb/compile_decoder_x64.dasc > upb/pb/compile_decoder_x64.h || (rm upb/pb/compile_decoder_x64.h ; false) - -ifneq ($(shell uname), Darwin) -upb/pb/jit_debug_elf_file.o: upb/pb/jit_debug_elf_file.s - $(E) GAS $< - $(Q) gcc -c upb/pb/jit_debug_elf_file.s -o upb/pb/jit_debug_elf_file.o - -upb/pb/jit_debug_elf_file.h: upb/pb/jit_debug_elf_file.o - $(E) XXD $< - $(Q) xxd -i < upb/pb/jit_debug_elf_file.o > upb/pb/jit_debug_elf_file.h -upb/pb/compile_decoder_x64.h: upb/pb/jit_debug_elf_file.h -endif - -# Function to expand a wildcard pattern recursively. -rwildcard=$(strip $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)$(filter $(subst *,%,$2),$d))) +# Note: mkdir -p is technically susceptible to races when used with make -j. +%/.: + $(Q) mkdir -p $@ # Regenerating the auto-generated files in upb/. upb/descriptor.pb: upb/descriptor.proto @@ -210,285 +211,165 @@ examples/msg: examples/msg.c $(LIBUPB) # Tests. ####################################################################### -tests/test.proto.pb: tests/test.proto - @# TODO: replace with upbc - protoc tests/test.proto -otests/test.proto.pb +# This section contains only the tests that don't depend on any external +# libraries. -SIMPLE_TESTS= \ - tests/test_def \ +C_TESTS = \ tests/pb/test_varint \ - tests/test_handlers + tests/test_def \ + tests/test_handlers \ -SIMPLE_CXX_TESTS= \ +CC_TESTS = \ tests/pb/test_decoder \ - tests/test_cpp - - -VARIADIC_TESTS= \ - tests/t.test_vs_proto2.googlemessage1 \ - tests/t.test_vs_proto2.googlemessage2 \ + tests/test_cpp \ + tests/test_table \ -TESTS=$(SIMPLE_TESTS) $(SIMPLE_CXX_TESTS) $(VARIADIC_TESTS) tests/test_table - -tests: $(TESTS) $(INTERACTIVE_TESTS) -$(TESTS): $(LIBUPB) -tests/test_def: tests/test.proto.pb +TESTS=$(C_TESTS) $(CC_TESTS) +tests: $(TESTS) tests/testmain.o: tests/testmain.cc $(E) CXX $< $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $< -$(SIMPLE_TESTS): tests/testmain.o -$(SIMPLE_TESTS): % : %.c +$(C_TESTS): % : %.c tests/testmain.o $$(LIBS) $(E) CC $< - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ tests/testmain.o $< $(LIBUPB) + $(Q) $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ tests/testmain.o $< $(LIBS) -$(SIMPLE_CXX_TESTS): tests/testmain.o -$(SIMPLE_CXX_TESTS): % : %.cc +$(CC_TESTS): % : %.cc tests/testmain.o $$(LIBS) $(E) CXX $< - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ tests/testmain.o $< $(LIBUPB) + $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Wno-deprecated -o $@ tests/testmain.o $< $(LIBS) + +# Several of these tests don't actually test these libs, but use them +# incidentally to load a descriptor +LOAD_DESCRIPTOR_LIBS = lib/libupb.pb.a lib/libupb.descriptor.a + +# Specify which libs each test depends on. +tests/pb/test_varint: LIBS = lib/libupb.pb.a lib/libupb.a +tests/test_def: LIBS = $(LOAD_DESCRIPTOR_LIBS) lib/libupb.a +tests/test_handlers: LIBS = lib/libupb.descriptor.a lib/libupb.a +tests/pb/test_decoder: LIBS = lib/libupb.pb.a lib/libupb.a +tests/test_cpp: LIBS = $(LOAD_DESCRIPTOR_LIBS) lib/libupb.a +tests/test_table: LIBS = lib/libupb.a + +tests/test_def: tests/test.proto.pb + +tests/test.proto.pb: tests/test.proto + @# TODO: add .proto file parser to upb so this isn't necessary. + protoc tests/test.proto -otests/test.proto.pb + +VARIADIC_TESTS= \ + tests/t.test_vs_proto2.googlemessage1 \ + tests/t.test_vs_proto2.googlemessage2 \ + +ifeq ($(RUN_UNDER), valgrind) +RUN_UNDER=valgrind --leak-check=full --error-exitcode=1 --track-origins=yes +endif -#VALGRIND=valgrind --leak-check=full --error-exitcode=1 --track-origins=yes -VALGRIND= test: tests @set -e # Abort on error. - @for test in $(SIMPLE_TESTS) $(SIMPLE_CXX_TESTS); do \ + @find tests -perm -u+x -type f | while read test; do \ if [ -x ./$$test ] ; then \ - echo !!! $(VALGRIND) ./$$test; \ - $(VALGRIND) ./$$test tests/test.proto.pb || exit 1; \ + echo "RUN $$test"; \ + $(RUN_UNDER) ./$$test tests/test.proto.pb || exit 1; \ fi \ done; - @$(VALGRIND) ./tests/t.test_vs_proto2.googlemessage1 benchmarks/google_message1.dat || exit 1; - @$(VALGRIND) ./tests/t.test_vs_proto2.googlemessage2 benchmarks/google_message2.dat || exit 1; @echo "All tests passed!" -tests/t.test_vs_proto2.googlemessage1 \ -tests/t.test_vs_proto2.googlemessage2: \ - tests/test_vs_proto2.cc $(LIBUPB) benchmarks/google_messages.proto.pb \ - benchmarks/google_messages.pb.cc - $(E) CXX $< '(benchmarks::SpeedMessage1)' - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o tests/t.test_vs_proto2.googlemessage1 $< \ - -DMESSAGE_NAME=\"benchmarks.SpeedMessage1\" \ - -DMESSAGE_DESCRIPTOR_FILE=\"../benchmarks/google_messages.proto.pb\" \ - -DMESSAGE_FILE=\"../benchmarks/google_message1.dat\" \ - -DMESSAGE_CIDENT="benchmarks::SpeedMessage1" \ - -DMESSAGE_HFILE=\"../benchmarks/google_messages.pb.h\" \ - benchmarks/google_messages.pb.cc tests/testmain.o -lprotobuf -lpthread $(LIBUPB) - $(E) CXX $< '(benchmarks::SpeedMessage2)' - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o tests/t.test_vs_proto2.googlemessage2 $< \ - -DMESSAGE_NAME=\"benchmarks.SpeedMessage2\" \ - -DMESSAGE_DESCRIPTOR_FILE=\"../benchmarks/google_messages.proto.pb\" \ - -DMESSAGE_FILE=\"../benchmarks/google_message2.dat\" \ - -DMESSAGE_CIDENT="benchmarks::SpeedMessage2" \ - -DMESSAGE_HFILE=\"../benchmarks/google_messages.pb.h\" \ - benchmarks/google_messages.pb.cc tests/testmain.o -lprotobuf -lpthread $(LIBUPB) -tests/test_table: tests/test_table.cc - @# Includes <hash_set> which is a deprecated header. - $(E) CXX $< - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -Wno-deprecated -o $@ $< tests/testmain.o $(LIBUPB) -tests/tests: upb/libupb.a +# Google protobuf binding ###################################################### +upb_bindings_googlepb_SRCS = \ + upb/bindings/googlepb/bridge.cc \ + upb/bindings/googlepb/proto2.cc \ -# Benchmarks. ################################################################## +GOOGLEPB_TESTS = \ + tests/bindings/googlepb/test_vs_proto2.googlemessage1 \ + tests/bindings/googlepb/test_vs_proto2.googlemessage2 \ -# Benchmarks -UPB_BENCHMARKS=benchmarks/b.parsestream_googlemessage1.upb_table \ - benchmarks/b.parsestream_googlemessage2.upb_table \ +GOOGLEPB_LIB=lib/libupb.bindings.googlepb.a -ifdef USE_JIT -UPB_BENCHMARKS += \ - benchmarks/b.parsestream_googlemessage1.upb_jit \ - benchmarks/b.parsestream_googlemessage2.upb_jit \ - benchmarks/b.parsetoproto2_googlemessage1.upb_jit \ - benchmarks/b.parsetoproto2_googlemessage2.upb_jit -endif +.PHONY: googlepb clean_googlepb googlepbtest +clean: clean_googlepb +clean_googlepb: + rm -f tests/bindings/googlepb/test_vs_proto2.googlemessage* + rm -f $(GOOGLEPB_LIB) +googlepb: default $(GOOGLEPB_LIB) +googlepbtest: $(GOOGLEPB_TESTS) -BENCHMARKS=$(UPB_BENCHMARKS) \ - benchmarks/b.parsetostruct_googlemessage1.proto2_table \ - benchmarks/b.parsetostruct_googlemessage2.proto2_table \ - benchmarks/b.parsetostruct_googlemessage1.proto2_compiled \ - benchmarks/b.parsetostruct_googlemessage2.proto2_compiled \ - benchmarks/b.parsetoproto2_googlemessage1.upb \ - benchmarks/b.parsetoproto2_googlemessage2.upb - -upb_benchmarks: $(UPB_BENCHMARKS) -benchmarks: $(BENCHMARKS) -upb_benchmark: $(UPB_BENCHMARKS) - @rm -f benchmarks/results - @rm -rf benchmarks/*.dSYM - @for test in benchmarks/b.* ; do ./$$test ; done -benchmark: $(BENCHMARKS) - @rm -f benchmarks/results - @rm -rf benchmarks/*.dSYM - @for test in benchmarks/b.* ; do ./$$test ; done +lib/libupb.bindings.googlepb.a: $(upb_bindings_googlepb_SRCS:upb/%.cc=obj/%.o) + $(E) AR $@ + $(Q) mkdir -p lib && ar rcs $@ $^ +# These generated files live in benchmarks/ but are used by both tests and +# benchmarks. benchmarks/google_messages.proto.pb: benchmarks/google_messages.proto @# TODO: replace with upbc. protoc benchmarks/google_messages.proto -obenchmarks/google_messages.proto.pb - benchmarks/google_messages.pb.cc: benchmarks/google_messages.proto protoc benchmarks/google_messages.proto --cpp_out=. -# This basic idea is useful (varying the benchmarks' setup by recompiling -# several times with different #defines) but the implementation in this -# Makefile is verbose and error-prone. Open to better ideas here. I don't -# want to make these command-line parameters -- it makes it more annoying to -# debug or profile them. - -benchmarks/b.parsetostruct_googlemessage1.upb_table \ -benchmarks/b.parsetostruct_googlemessage2.upb_table: \ - benchmarks/parsetostruct.upb.c $(LIBUPB) benchmarks/google_messages.proto.pb - $(E) 'CC benchmarks/parsetostruct.upb.c (benchmarks.SpeedMessage1, nojit)' - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage1.upb_table $< \ - -DMESSAGE_NAME=\"benchmarks.SpeedMessage1\" \ - -DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ - -DMESSAGE_FILE=\"google_message1.dat\" \ - -DJIT=false $(LIBUPB) - $(E) 'CC benchmarks/parsetostruct.upb.c (benchmarks.SpeedMessage2, nojit)' - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage2.upb_table $< \ - -DMESSAGE_NAME=\"benchmarks.SpeedMessage2\" \ - -DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ - -DMESSAGE_FILE=\"google_message2.dat\" \ - -DJIT=false $(LIBUPB) - -benchmarks/b.parsestream_googlemessage1.upb_table \ -benchmarks/b.parsestream_googlemessage2.upb_table: \ - benchmarks/parsestream.upb.c $(LIBUPB) benchmarks/google_messages.proto.pb - $(E) 'CC benchmarks/parsestream.upb.c (benchmarks.SpeedMessage1, nojit)' - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsestream_googlemessage1.upb_table $< \ - -DMESSAGE_NAME=\"benchmarks.SpeedMessage1\" \ - -DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ - -DMESSAGE_FILE=\"google_message1.dat\" -DJIT=false \ - $(LIBUPB) - $(E) 'CC benchmarks/parsestream.upb.c (benchmarks.SpeedMessage2, nojit)' - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsestream_googlemessage2.upb_table $< \ - -DMESSAGE_NAME=\"benchmarks.SpeedMessage2\" \ - -DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ - -DMESSAGE_FILE=\"google_message2.dat\" -DJIT=false \ - $(LIBUPB) - -ifdef USE_JIT -benchmarks/b.parsetostruct_googlemessage1.upb_jit \ -benchmarks/b.parsetostruct_googlemessage2.upb_jit: \ - benchmarks/parsetostruct.upb.c $(LIBUPB) benchmarks/google_messages.proto.pb - $(E) 'CC benchmarks/parsetostruct.upb.c (benchmarks.SpeedMessage1, jit)' - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage1.upb_jit $< \ - -DMESSAGE_NAME=\"benchmarks.SpeedMessage1\" \ - -DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ - -DMESSAGE_FILE=\"google_message1.dat\" -DJIT=true \ - -DJIT=true $(LIBUPB) - $(E) 'CC benchmarks/parsetostruct.upb.c (benchmarks.SpeedMessage2, jit)' - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage2.upb_jit $< \ - -DMESSAGE_NAME=\"benchmarks.SpeedMessage2\" \ - -DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ - -DMESSAGE_FILE=\"google_message2.dat\" -DJIT=true \ - -DJIT=true $(LIBUPB) - -benchmarks/b.parsestream_googlemessage1.upb_jit \ -benchmarks/b.parsestream_googlemessage2.upb_jit: \ - benchmarks/parsestream.upb.c $(LIBUPB) benchmarks/google_messages.proto.pb - $(E) 'CC benchmarks/parsestream.upb.c (benchmarks.SpeedMessage1, jit)' - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsestream_googlemessage1.upb_jit $< \ +tests/bindings/googlepb/test_vs_proto2.googlemessage1: \ + tests/bindings/googlepb/test_vs_proto2.cc $(LIBUPB) benchmarks/google_messages.proto.pb \ + benchmarks/google_messages.pb.cc + $(E) CXX $< '(benchmarks::SpeedMessage1)' + $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $< \ -DMESSAGE_NAME=\"benchmarks.SpeedMessage1\" \ - -DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ - -DMESSAGE_FILE=\"google_message1.dat\" -DJIT=true \ - $(LIBUPB) - $(E) 'CC benchmarks/parsestream.upb.c (benchmarks.SpeedMessage2, jit)' - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsestream_googlemessage2.upb_jit $< \ - -DMESSAGE_NAME=\"benchmarks.SpeedMessage2\" \ - -DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ - -DMESSAGE_FILE=\"google_message2.dat\" -DJIT=true \ - $(LIBUPB) - -benchmarks/b.parsetoproto2_googlemessage1.upb_jit \ -benchmarks/b.parsetoproto2_googlemessage2.upb_jit: \ - benchmarks/parsetoproto2.upb.cc benchmarks/google_messages.pb.cc $(LIBUPB) benchmarks/google_messages.proto.pb - $(E) 'CXX benchmarks/parsetoproto2.upb.cc (benchmarks.SpeedMessage1, jit)' - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetoproto2_googlemessage1.upb_jit $< \ + -DMESSAGE_DESCRIPTOR_FILE=\"../benchmarks/google_messages.proto.pb\" \ + -DMESSAGE_FILE=\"../benchmarks/google_message1.dat\" \ -DMESSAGE_CIDENT="benchmarks::SpeedMessage1" \ - -DMESSAGE_NAME=\"benchmarks.SpeedMessage1\" \ - -DMESSAGE_FILE=\"google_message1.dat\" \ - -DMESSAGE_HFILE=\"google_messages.pb.h\" \ - -DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" -DJIT=true \ - benchmarks/google_messages.pb.cc -lprotobuf -lpthread $(LIBUPB) - $(E) 'CXX benchmarks/parsetoproto2.upb.cc (benchmarks.SpeedMessage2, jit)' - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetoproto2_googlemessage2.upb_jit $< \ - -DMESSAGE_CIDENT="benchmarks::SpeedMessage2" \ - -DMESSAGE_NAME=\"benchmarks.SpeedMessage2\" \ - -DMESSAGE_FILE=\"google_message2.dat\" \ - -DMESSAGE_HFILE=\"google_messages.pb.h\" -DJIT=true \ - -DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ - benchmarks/google_messages.pb.cc -lprotobuf -lpthread $(LIBUPB) -endif + -DMESSAGE_HFILE=\"../benchmarks/google_messages.pb.h\" \ + benchmarks/google_messages.pb.cc tests/testmain.o -lprotobuf -lpthread \ + lib/libupb.bindings.googlepb.a lib/libupb.pb.a lib/libupb.descriptor.a lib/libupb.a -benchmarks/b.parsetostruct_googlemessage1.proto2_table \ -benchmarks/b.parsetostruct_googlemessage2.proto2_table: \ - benchmarks/parsetostruct.proto2_table.cc benchmarks/google_messages.pb.cc - $(E) 'CXX benchmarks/parsetostruct.proto2_table.cc (benchmarks.SpeedMessage1)' - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage1.proto2_table $< \ - -DMESSAGE_CIDENT="benchmarks::SpeedMessage1" \ - -DMESSAGE_FILE=\"google_message1.dat\" \ - -DMESSAGE_HFILE=\"google_messages.pb.h\" \ - benchmarks/google_messages.pb.cc -lprotobuf -lpthread - $(E) 'CXX benchmarks/parsetostruct.proto2_table.cc (benchmarks.SpeedMessage2)' - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage2.proto2_table $< \ - -DMESSAGE_CIDENT="benchmarks::SpeedMessage2" \ - -DMESSAGE_FILE=\"google_message2.dat\" \ - -DMESSAGE_HFILE=\"google_messages.pb.h\" \ - benchmarks/google_messages.pb.cc -lprotobuf -lpthread - -benchmarks/b.parsetostruct_googlemessage1.proto2_compiled \ -benchmarks/b.parsetostruct_googlemessage2.proto2_compiled: \ - benchmarks/parsetostruct.proto2_compiled.cc benchmarks/google_messages.pb.cc - $(E) 'CXX benchmarks/parsetostruct.proto2_compiled.cc (benchmarks.SpeedMessage1)' - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage1.proto2_compiled $< \ - -DMESSAGE_CIDENT="benchmarks::SpeedMessage1" \ - -DMESSAGE_FILE=\"google_message1.dat\" \ - -DMESSAGE_HFILE=\"google_messages.pb.h\" \ - benchmarks/google_messages.pb.cc -lprotobuf -lpthread - $(E) 'CXX benchmarks/parsetostruct.proto2_compiled.cc (benchmarks.SpeedMessage2)' - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage2.proto2_compiled $< \ - -DMESSAGE_CIDENT="benchmarks::SpeedMessage2" \ - -DMESSAGE_FILE=\"google_message2.dat\" \ - -DMESSAGE_HFILE=\"google_messages.pb.h\" \ - benchmarks/google_messages.pb.cc -lprotobuf -lpthread - -benchmarks/b.parsetoproto2_googlemessage1.upb \ -benchmarks/b.parsetoproto2_googlemessage2.upb: \ - benchmarks/parsetoproto2.upb.cc benchmarks/google_messages.pb.cc $(LIBUPB) benchmarks/google_messages.proto.pb - $(E) 'CXX benchmarks/parsetoproto2.upb.cc (benchmarks.SpeedMessage1, nojit)' - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetoproto2_googlemessage1.upb $< \ - -DMESSAGE_CIDENT="benchmarks::SpeedMessage1" \ - -DMESSAGE_NAME=\"benchmarks.SpeedMessage1\" \ - -DMESSAGE_FILE=\"google_message1.dat\" \ - -DMESSAGE_HFILE=\"google_messages.pb.h\" \ - -DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" -DJIT=false \ - benchmarks/google_messages.pb.cc -lprotobuf -lpthread $(LIBUPB) - $(E) 'CXX benchmarks/parsetoproto2.upb.cc (benchmarks.SpeedMessage2, nojit)' - $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetoproto2_googlemessage2.upb $< \ - -DMESSAGE_CIDENT="benchmarks::SpeedMessage2" \ +tests/bindings/googlepb/test_vs_proto2.googlemessage2: \ + tests/bindings/googlepb/test_vs_proto2.cc $(LIBUPB) benchmarks/google_messages.proto.pb \ + benchmarks/google_messages.pb.cc + $(E) CXX $< '(benchmarks::SpeedMessage2)' + $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $< \ -DMESSAGE_NAME=\"benchmarks.SpeedMessage2\" \ - -DMESSAGE_FILE=\"google_message2.dat\" \ - -DMESSAGE_HFILE=\"google_messages.pb.h\" \ - -DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" -DJIT=false \ - benchmarks/google_messages.pb.cc -lprotobuf -lpthread $(LIBUPB) + -DMESSAGE_DESCRIPTOR_FILE=\"../benchmarks/google_messages.proto.pb\" \ + -DMESSAGE_FILE=\"../benchmarks/google_message2.dat\" \ + -DMESSAGE_CIDENT="benchmarks::SpeedMessage2" \ + -DMESSAGE_HFILE=\"../benchmarks/google_messages.pb.h\" \ + benchmarks/google_messages.pb.cc tests/testmain.o -lprotobuf -lpthread \ + lib/libupb.bindings.googlepb.a lib/libupb.pb.a lib/libupb.descriptor.a lib/libupb.a # Lua extension ################################################################## -LUA_CPPFLAGS = $(strip $(shell pkg-config --silence-errors --cflags lua || pkg-config --silence-errors --cflags lua5.1 || echo '-I/usr/local/include')) ifeq ($(shell uname), Darwin) LUA_LDFLAGS = -undefined dynamic_lookup else LUA_LDFLAGS = endif -LUAEXT=upb/bindings/lua/upb.so -lua: $(LUAEXT) -upb/bindings/lua/upb.so: upb/bindings/lua/upb.c $(LIBUPB_PIC) - $(E) CC bindings/lua/upb.c - $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) $(LUA_CPPFLAGS) -fpic -shared -o $@ $< upb/libupb_pic.a $(LUA_LDFLAGS) +LUAEXTS = \ + upb/bindings/lua/upb.so \ + upb/bindings/lua/upb.pb.so \ + +.PHONY: clean_lua testlua lua +clean: clean_lua +testlua: + LUA_PATH=tests/bindings/lua/?.lua LUA_CPATH=upb/bindings/lua/?.so lua tests/bindings/lua/upb.lua + +clean_lua: + rm -f upb/bindings/lua/upb.lua.h + rm -f upb/bindings/lua/upb.so + rm -f upb/bindings/lua/upb.pb.so + +lua: $(LUAEXTS) + +upb/bindings/lua/upb.lua.h: + $(E) XXD upb/bindings/lua/upb.lua + $(Q) xxd -i < upb/bindings/lua/upb.lua > upb/bindings/lua/upb.lua.h + +upb/bindings/lua/upb.so: upb/bindings/lua/upb.c upb/bindings/lua/upb.lua.h lib/libupb.descriptor_pic.a lib/libupb_pic.a lib/libupb.pb_pic.a + $(E) CC upb/bindings/lua/upb.c + $(Q) $(CC) $(CPPFLAGS) $(CFLAGS) -fpic -shared -o $@ $< lib/libupb.pb_pic.a lib/libupb.descriptor_pic.a lib/libupb_pic.a $(LUA_LDFLAGS) + +upb/bindings/lua/upb.pb.so: upb/bindings/lua/upb.pb.c lib/libupb_pic.a lib/libupb.pb_pic.a + $(E) CC upb/bindings/lua/upb.pb.c + $(Q) $(CC) $(CPPFLAGS) $(CFLAGS) -fpic -shared -o $@ $< $(LUA_LDFLAGS) # Python extension ############################################################# @@ -508,9 +389,9 @@ pythontest: $(PYTHONEXT) RUBY=ruby RUBYEXT=upb/bindings/ruby/upb.so ruby: $(RUBYEXT) -upb/bindings/ruby/Makefile: upb/bindings/ruby/extconf.rb +upb/bindings/ruby/Makefile: upb/bindings/ruby/extconf.rb lib/libupb_pic.a lib/libupb.pb_pic.a lib/libupb.descriptor_pic.a $(E) RUBY upb/bindings/ruby/extconf.rb $(Q) cd upb/bindings/ruby && ruby extconf.rb -$(RUBYEXT): $(LIBUPB_PIC) upb/bindings/ruby/upb.c upb/bindings/ruby/Makefile +$(RUBYEXT): upb/bindings/ruby/upb.c upb/bindings/ruby/Makefile $(E) CC upb/bindings/ruby/upb.c $(Q) cd upb/bindings/ruby && make diff --git a/tests/test_handlers.c b/tests/test_handlers.c index ad59465..951f2c5 100644 --- a/tests/test_handlers.c +++ b/tests/test_handlers.c @@ -18,6 +18,7 @@ static bool startmsg(void *c, const void *hd) { } static void test_error() { + // Test creating handlers of a static msgdef. const upb_symtab *s = upbdefs_google_protobuf_descriptor(&s); upb_handlers *h = upb_handlers_new(upbdefs_google_protobuf_DescriptorProto(s), &h); diff --git a/tests/test_vs_proto2.cc b/tests/test_vs_proto2.cc deleted file mode 100644 index ed44a73..0000000 --- a/tests/test_vs_proto2.cc +++ /dev/null @@ -1,167 +0,0 @@ -/* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2011-2012 Google Inc. See LICENSE for details. - * - * A test that verifies that our results are identical to proto2 for a - * given proto type and input protobuf. - */ - -#define __STDC_LIMIT_MACROS // So we get UINT32_MAX -#include <assert.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/dynamic_message.h> -#include <google/protobuf/message.h> -#include <google/protobuf/text_format.h> -#include <google/protobuf/wire_format_lite.h> -#include <inttypes.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include "benchmarks/google_messages.pb.h" -#include "upb/bindings/googlepb/bridge.h" -#include "upb/def.h" -#include "upb/handlers.h" -#include "upb/pb/decoder.h" -#include "upb/pb/glue.h" -#include "upb/pb/varint.int.h" -#include "upb_test.h" - -void compare_metadata(const google::protobuf::Descriptor* d, - const upb::MessageDef *upb_md) { - ASSERT(d->field_count() == upb_md->field_count()); - for (upb::MessageDef::const_iterator i = upb_md->begin(); i != upb_md->end(); - ++i) { - const upb::FieldDef* upb_f = *i; - const google::protobuf::FieldDescriptor *proto2_f = - d->FindFieldByNumber(upb_f->number()); - ASSERT(upb_f); - ASSERT(proto2_f); - ASSERT(upb_f->number() == proto2_f->number()); - ASSERT(std::string(upb_f->name()) == proto2_f->name()); - ASSERT(upb_f->descriptor_type() == - static_cast<upb::FieldDef::DescriptorType>(proto2_f->type())); - ASSERT(upb_f->IsSequence() == proto2_f->is_repeated()); - } -} - -void print_diff(const google::protobuf::Message& msg1, - const google::protobuf::Message& msg2) { - std::string text_str1; - std::string text_str2; - google::protobuf::TextFormat::PrintToString(msg1, &text_str1); - google::protobuf::TextFormat::PrintToString(msg2, &text_str2); - fprintf(stderr, "str1: %s, str2: %s\n", text_str1.c_str(), text_str2.c_str()); -} - -void parse_and_compare(google::protobuf::Message *msg1, - google::protobuf::Message *msg2, - const upb::Handlers *protomsg_handlers, - const char *str, size_t len, bool allow_jit) { - // Parse to both proto2 and upb. - ASSERT(msg1->ParseFromArray(str, len)); - - upb::pb::CodeCache cache; - ASSERT(cache.set_allow_jit(allow_jit)); - upb::reffed_ptr<const upb::pb::DecoderMethod> decoder_method( - cache.GetDecoderMethod(upb::pb::DecoderMethodOptions(protomsg_handlers))); - - upb::Status status; - upb::pb::Decoder decoder(decoder_method.get(), &status); - upb::Sink protomsg_sink(protomsg_handlers, msg2); - - decoder.ResetOutput(&protomsg_sink); - - msg2->Clear(); - bool ok = upb::BufferSource::PutBuffer(str, len, decoder.input()); - if (!ok) { - fprintf(stderr, "error parsing: %s\n", status.error_message()); - print_diff(*msg1, *msg2); - } - ASSERT(ok); - ASSERT(status.ok()); - - // Would like to just compare the message objects themselves, but - // unfortunately MessageDifferencer is not part of the open-source release of - // proto2, so we compare their serialized strings, which we expect will be - // equivalent. - std::string str1; - std::string str2; - msg1->SerializeToString(&str1); - msg2->SerializeToString(&str2); - if (str1 != str2) { - print_diff(*msg1, *msg2); - } - ASSERT(str1 == str2); - ASSERT(std::string(str, len) == str2); -} - -void test_zig_zag() { - for (uint64_t num = 5; num * 1.5 < UINT64_MAX; num *= 1.5) { - ASSERT(upb_zzenc_64(num) == - google::protobuf::internal::WireFormatLite::ZigZagEncode64(num)); - if (num < UINT32_MAX) { - ASSERT(upb_zzenc_32(num) == - google::protobuf::internal::WireFormatLite::ZigZagEncode32(num)); - } - } - -} - -extern "C" { - -int run_tests(int argc, char *argv[]) -{ - if (argc < 2) { - fprintf(stderr, "Usage: test_vs_proto2 <message file>\n"); - return 1; - } - const char *message_file = argv[1]; - - // Read the message data itself. - size_t len; - const char *str = upb_readfile(message_file, &len); - if(str == NULL) { - fprintf(stderr, "Error reading %s\n", message_file); - return 1; - } - - MESSAGE_CIDENT msg1; - MESSAGE_CIDENT msg2; - - upb::reffed_ptr<const upb::Handlers> h( - upb::googlepb::WriteHandlers::New(msg1)); - - compare_metadata(msg1.GetDescriptor(), h->message_def()); - - // Run twice to test proper object reuse. - parse_and_compare(&msg1, &msg2, h.get(), str, len, false); - parse_and_compare(&msg1, &msg2, h.get(), str, len, true); - parse_and_compare(&msg1, &msg2, h.get(), str, len, false); - parse_and_compare(&msg1, &msg2, h.get(), str, len, true); - - // Test with DynamicMessage. - google::protobuf::DynamicMessageFactory* factory = - new google::protobuf::DynamicMessageFactory; - const google::protobuf::Message* prototype = - factory->GetPrototype(msg1.descriptor()); - google::protobuf::Message* dyn_msg1 = prototype->New(); - google::protobuf::Message* dyn_msg2 = prototype->New(); - h = upb::googlepb::WriteHandlers::New(*dyn_msg1); - parse_and_compare(dyn_msg1, dyn_msg2, h.get(), str, len, false); - parse_and_compare(dyn_msg1, dyn_msg2, h.get(), str, len, true); - delete dyn_msg1; - delete dyn_msg2; - delete factory; - - free((void*)str); - - test_zig_zag(); - - printf("All tests passed, %d assertions.\n", num_assertions); - - google::protobuf::ShutdownProtobufLibrary(); - return 0; -} - -} diff --git a/upb/bindings/lua/upb.c b/upb/bindings/lua/upb.c index dbeb937..f938b26 100644 --- a/upb/bindings/lua/upb.c +++ b/upb/bindings/lua/upb.c @@ -1622,6 +1622,7 @@ static void lupb_sethasbit(lupb_msg *msg, uint32_t hasbit) { static size_t strhandler(void *closure, const void *hd, const char *str, size_t len, const upb_bufhandle *handle) { + UPB_UNUSED(handle); lupb_msg *msg = closure; const lupb_handlerdata *data = hd; lua_State *L = msg->lmd->L; diff --git a/upb/bindings/ruby/extconf.rb b/upb/bindings/ruby/extconf.rb index 67fddba..3637511 100644 --- a/upb/bindings/ruby/extconf.rb +++ b/upb/bindings/ruby/extconf.rb @@ -2,6 +2,8 @@ require 'mkmf' find_header("upb/upb.h", "../../..") or raise "Can't find upb headers" -find_library("upb_pic", "upb_msgdef_new", "../..") or raise "Can't find upb lib" +find_library("upb_pic", "upb_msgdef_new", "../../../lib") or raise "Can't find upb lib" +find_library("upb.pb_pic", "upb_decoder_init", "../../../lib") or raise "Can't find upb.pb lib" +find_library("upb.descriptor_pic", "upb_descreader_init", "../../../lib") or raise "Can't find upb.descriptor lib" $CFLAGS += " -Wall" create_makefile("upb") diff --git a/upb/pb/compile_decoder_x64.c b/upb/pb/compile_decoder_x64.c index 1d8b861..d8af013 100644 --- a/upb/pb/compile_decoder_x64.c +++ b/upb/pb/compile_decoder_x64.c @@ -259,8 +259,6 @@ static int pcofs(jitcompiler *jc) { return jc->pc - jc->group->bytecode; } -static void upb_reg_jit_gdb(jitcompiler *jc); - // Returns a machine code offset corresponding to the given key. // Requires that this key was defined with define_jmptarget. static int machine_code_ofs(jitcompiler *jc, const void *key) { @@ -470,7 +468,6 @@ void upb_pbdecoder_jit(mgroup *group) { MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); dasm_encode(jc, jit_code); mprotect(jit_code, jc->group->jit_size, PROT_EXEC | PROT_READ); - upb_reg_jit_gdb(jc); jc->group->jit_code = (upb_string_handlerfunc *)jit_code; #ifdef UPB_JIT_LOAD_SO @@ -496,84 +493,4 @@ void upb_pbdecoder_freejit(mgroup *group) { munmap(group->jit_code, group->jit_size); } free(group->debug_info); - // TODO: unregister GDB JIT interface. -} - -// To debug JIT-ted code with GDB we need to tell GDB about the JIT-ted code -// at runtime. GDB 7.x+ has defined an interface for doing this, and these -// structure/function defintions are copied out of gdb/jit.h -// -// We need to give GDB an ELF file at runtime describing the symbols we have -// generated. To avoid implementing the ELF format, we generate an ELF file -// at compile-time and compile it in as a character string. We can replace -// a few key constants (address of JIT-ted function and its size) by looking -// for a few magic numbers and doing a dumb string replacement. -// -// Unfortunately this approach is showing its limits; we can only define one -// symbol, and this approach only works with GDB. The .so approach above is -// more reliable. - -#ifndef __APPLE__ -const unsigned char upb_jit_debug_elf_file[] = { -#include "upb/pb/jit_debug_elf_file.h" -}; - -typedef enum { - GDB_JIT_NOACTION = 0, - GDB_JIT_REGISTER, - GDB_JIT_UNREGISTER -} jit_actions_t; - -typedef struct gdb_jit_entry { - struct gdb_jit_entry *next_entry; - struct gdb_jit_entry *prev_entry; - const char *symfile_addr; - uint64_t symfile_size; -} gdb_jit_entry; - -typedef struct { - uint32_t version; - uint32_t action_flag; - gdb_jit_entry *relevant_entry; - gdb_jit_entry *first_entry; -} gdb_jit_descriptor; - -gdb_jit_descriptor __jit_debug_descriptor = {1, GDB_JIT_NOACTION, NULL, NULL}; - -void __attribute__((noinline)) __jit_debug_register_code() { - __asm__ __volatile__(""); } - -static void upb_reg_jit_gdb(jitcompiler *jc) { - // Create debug info. - size_t elf_len = sizeof(upb_jit_debug_elf_file); - jc->group->debug_info = malloc(elf_len); - memcpy(jc->group->debug_info, upb_jit_debug_elf_file, elf_len); - uint64_t *p = (void *)jc->group->debug_info; - for (; (void *)(p + 1) <= (void *)jc->group->debug_info + elf_len; ++p) { - if (*p == 0x12345678) { - *p = (uintptr_t)jc->group->jit_code; - } - if (*p == 0x321) { - *p = jc->group->jit_size; - } - } - - // Register the JIT-ted code with GDB. - gdb_jit_entry *e = malloc(sizeof(gdb_jit_entry)); - e->next_entry = __jit_debug_descriptor.first_entry; - e->prev_entry = NULL; - if (e->next_entry) e->next_entry->prev_entry = e; - e->symfile_addr = jc->group->debug_info; - e->symfile_size = elf_len; - __jit_debug_descriptor.first_entry = e; - __jit_debug_descriptor.relevant_entry = e; - __jit_debug_descriptor.action_flag = GDB_JIT_REGISTER; - __jit_debug_register_code(); -} - -#else - -static void upb_reg_jit_gdb(jitcompiler *jc) { (void)jc; } - -#endif diff --git a/upb/pb/jit_debug_elf_file.s b/upb/pb/jit_debug_elf_file.s deleted file mode 100644 index 2c3d6fb..0000000 --- a/upb/pb/jit_debug_elf_file.s +++ /dev/null @@ -1,6 +0,0 @@ - .file "JIT mcode" - .text -upb_jit_compiled_decoder: - .globl upb_jit_compiled_decoder - .size upb_jit_compiled_decoder, 0x321 - .space 0x321 |