diff --git a/BUILD b/BUILD index b5efeb2dae..3789b98f42 100644 --- a/BUILD +++ b/BUILD @@ -5,6 +5,7 @@ load( ) load( "//bazel:upb_proto_library.bzl", + "upb_fasttable_enabled", "upb_proto_library", "upb_proto_reflection_library", ) @@ -35,6 +36,12 @@ config_setting( constraint_values = ["@bazel_tools//platforms:windows"], ) +upb_fasttable_enabled( + name = "fasttable_enabled", + build_setting_default = True, + visibility = ["//visibility:public"], +) + # Public C/C++ libraries ####################################################### cc_library( diff --git a/bazel/upb_proto_library.bzl b/bazel/upb_proto_library.bzl index c09cb3d127..6c56293b52 100644 --- a/bazel/upb_proto_library.bzl +++ b/bazel/upb_proto_library.bzl @@ -106,6 +106,28 @@ def _cc_library_func(ctx, name, hdrs, srcs, dep_ccinfos): linking_context = linking_context, ) +# Build setting for whether fasttable code generation is enabled ############### + +_FastTableEnabled = provider( + fields = { + "enabled": "whether fasttable is enabled", + }, +) + +def fasttable_enabled_impl(ctx): + raw_setting = ctx.build_setting_value + + if raw_setting: + # TODO(haberman): check that the target CPU supports fasttable. + pass + + return _FastTableEnabled(enabled = raw_setting) + +upb_fasttable_enabled = rule( + implementation = fasttable_enabled_impl, + build_setting = config.bool(flag = True) +) + # upb_proto_library / upb_proto_reflection_library shared code ################# GeneratedSrcsInfo = provider( @@ -127,6 +149,8 @@ def _compile_upb_protos(ctx, proto_info, proto_sources, ext): srcs = [_generate_output_file(ctx, name, ext + ".c") for name in proto_sources] hdrs = [_generate_output_file(ctx, name, ext + ".h") for name in proto_sources] transitive_sets = proto_info.transitive_descriptor_sets.to_list() + fasttable_enabled = ctx.attr._fasttable_enabled[_FastTableEnabled].enabled + codegen_params = "fasttable:" if fasttable_enabled else "" ctx.actions.run( inputs = depset( direct = [proto_info.direct_descriptor_set], @@ -136,7 +160,7 @@ def _compile_upb_protos(ctx, proto_info, proto_sources, ext): outputs = srcs + hdrs, executable = ctx.executable._protoc, arguments = [ - "--upb_out=" + _get_real_root(srcs[0]), + "--upb_out=" + codegen_params + _get_real_root(srcs[0]), "--plugin=protoc-gen-upb=" + ctx.executable._upbc.path, "--descriptor_set_in=" + ctx.configuration.host_path_separator.join([f.path for f in transitive_sets]), ] + @@ -240,6 +264,7 @@ _upb_proto_library_aspect = aspect( "//:upb", ]), "_ext": attr.string(default = ".upb"), + "_fasttable_enabled": attr.label(default = "//:fasttable_enabled") }), implementation = _upb_proto_library_aspect_impl, provides = [ @@ -295,6 +320,7 @@ _upb_proto_reflection_library_aspect = aspect( ], ), "_ext": attr.string(default = ".upbdefs"), + "_fasttable_enabled": attr.label(default = "//:fasttable_enabled") }), implementation = _upb_proto_reflection_library_aspect_impl, provides = [ diff --git a/cmake/make_cmakelists.py b/cmake/make_cmakelists.py index 3582d0543a..a750717326 100755 --- a/cmake/make_cmakelists.py +++ b/cmake/make_cmakelists.py @@ -141,6 +141,9 @@ class BuildFileFunctions(object): def config_setting(self, **kwargs): pass + def upb_fasttable_enabled(self, **kwargs): + pass + def select(self, arg_dict): return [] diff --git a/upbc/generator.cc b/upbc/generator.cc index b374c4aef9..f34858203e 100644 --- a/upbc/generator.cc +++ b/upbc/generator.cc @@ -883,7 +883,8 @@ std::vector FastDecodeTable(const protobuf::Descriptor* message, return table; } -void WriteSource(const protobuf::FileDescriptor* file, Output& output) { +void WriteSource(const protobuf::FileDescriptor* file, Output& output, + bool fasttable_enabled) { EmitFileWarning(file, output); output( @@ -975,7 +976,13 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output) { output("};\n\n"); } - std::vector table = FastDecodeTable(message, layout); + std::vector table; + uint8_t table_mask = -1; + + if (fasttable_enabled) { + table = FastDecodeTable(message, layout); + table_mask = (table.size() - 1) << 3; + } output("const upb_msglayout $0 = {\n", MessageInit(message)); output(" $0,\n", submsgs_array_ref); @@ -983,7 +990,7 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output) { output(" $0, $1, $2, $3,\n", GetSizeInit(layout.message_size()), field_number_order.size(), "false", // TODO: extendable - (table.size() - 1) << 3 + table_mask ); output(" {\n"); for (const auto& ent : table) { @@ -1120,14 +1127,15 @@ void WriteDefSource(const protobuf::FileDescriptor* file, Output& output) { } bool Generator::Generate(const protobuf::FileDescriptor* file, - const std::string& /* parameter */, + const std::string& parameter, protoc::GeneratorContext* context, std::string* /* error */) const { + bool fasttable_enabled = parameter == "fasttable"; Output h_output(context->Open(HeaderFilename(file->name()))); WriteHeader(file, h_output); Output c_output(context->Open(SourceFilename(file->name()))); - WriteSource(file, c_output); + WriteSource(file, c_output, fasttable_enabled); Output h_def_output(context->Open(DefHeaderFilename(file->name()))); WriteDefHeader(file, h_def_output);