diff options
Diffstat (limited to 'gdb/arch/riscv.c')
-rw-r--r-- | gdb/arch/riscv.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/gdb/arch/riscv.c b/gdb/arch/riscv.c index cb715fa..81fd2f2 100644 --- a/gdb/arch/riscv.c +++ b/gdb/arch/riscv.c @@ -18,17 +18,45 @@ #include "common-defs.h" #include "riscv.h" #include <stdlib.h> +#include <unordered_map> #include "../features/riscv/32bit-cpu.c" #include "../features/riscv/64bit-cpu.c" #include "../features/riscv/32bit-fpu.c" #include "../features/riscv/64bit-fpu.c" +/* Wrapper used by std::unordered_map to generate hash for feature set. */ +struct riscv_gdbarch_features_hasher +{ + std::size_t + operator() (const riscv_gdbarch_features &features) const noexcept + { + return features.hash (); + } +}; + +/* Cache of previously seen target descriptions, indexed by the feature set + that created them. */ +static std::unordered_map<riscv_gdbarch_features, + target_desc *, + riscv_gdbarch_features_hasher> riscv_tdesc_cache; + /* See arch/riscv.h. */ const target_desc * riscv_create_target_description (struct riscv_gdbarch_features features) { + /* Have we seen this feature set before? If we have return the same + target description. GDB expects that if two target descriptions are + the same (in content terms) then they will actually be the same + instance. This is important when trying to lookup gdbarch objects as + GDBARCH_LIST_LOOKUP_BY_INFO performs a pointer comparison on target + descriptions to find candidate gdbarch objects. */ + const auto it = riscv_tdesc_cache.find (features); + if (it != riscv_tdesc_cache.end ()) + return it->second; + + /* Now we should create a new target description. */ target_desc *tdesc = allocate_target_description (); #ifndef IN_PROCESS_AGENT @@ -65,5 +93,8 @@ riscv_create_target_description (struct riscv_gdbarch_features features) else if (features.flen == 8) regnum = create_feature_riscv_64bit_fpu (tdesc, regnum); + /* Add to the cache. */ + riscv_tdesc_cache.emplace (features, tdesc); + return tdesc; } |