From 093409a1af0382a565de6859a6386d973090b8c6 Mon Sep 17 00:00:00 2001 From: Nikolay Igotti Date: Tue, 13 Dec 2016 13:24:50 +0300 Subject: [PATCH] Allow binary search for open methods. (#132) --- common/src/hash/headers/Names.h | 2 +- runtime/src/main/cpp/TypeInfo.cpp | 47 +++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/common/src/hash/headers/Names.h b/common/src/hash/headers/Names.h index 520b37c1034..268b06190dd 100644 --- a/common/src/hash/headers/Names.h +++ b/common/src/hash/headers/Names.h @@ -11,7 +11,7 @@ // Generic guideline is that global hash is being used in global persistent // context, while local hashes are more local in scope. // Local hash. -typedef uint64_t LocalHash; +typedef int64_t LocalHash; // Hash of field name. typedef LocalHash FieldNameHash; // Hash of open method name. diff --git a/runtime/src/main/cpp/TypeInfo.cpp b/runtime/src/main/cpp/TypeInfo.cpp index 08c79c6614e..b88aa05dbdc 100644 --- a/runtime/src/main/cpp/TypeInfo.cpp +++ b/runtime/src/main/cpp/TypeInfo.cpp @@ -1,10 +1,52 @@ #include "Assert.h" #include "TypeInfo.h" +// If one shall use binary search when looking up methods and fields. +// TODO: maybe select strategy basing on number of elements. +#define USE_BINARY_SEARCH 0 + extern "C" { +#if USE_BINARY_SEARCH + +int LookupFieldOffset(const TypeInfo* info, FieldNameHash nameSignature) { + int bottom = 0; + int top = info->fieldsCount_ - 1; + + while (bottom <= top) { + int middle = (bottom + top) / 2; + if (info->fields_[middle].nameSignature_ < nameSignature) + bottom = middle + 1; + else if (info->fields_[middle].nameSignature_ == nameSignature) + return info->fields_[middle].fieldOffset_; + else + top = middle - 1; + } + + RuntimeAssert(false, "Unknown field"); + return -1; +} + +void* LookupOpenMethod(const TypeInfo* info, MethodNameHash nameSignature) { + int bottom = 0; + int top = info->openMethodsCount_ - 1; + + while (bottom <= top) { + int middle = (bottom + top) / 2; + if (info->openMethods_[middle].nameSignature_ < nameSignature) + bottom = middle + 1; + else if (info->openMethods_[middle].nameSignature_ == nameSignature) + return info->openMethods_[middle].methodEntryPoint_; + else + top = middle - 1; + } + + RuntimeAssert(false, "Unknown open method"); + return nullptr; +} + +#else int LookupFieldOffset(const TypeInfo* info, FieldNameHash nameSignature) { - // TODO: make it binary search? for (int i = 0; i < info->fieldsCount_; ++i) { if (info->fields_[i].nameSignature_ == nameSignature) { return info->fields_[i].fieldOffset_; @@ -15,7 +57,6 @@ int LookupFieldOffset(const TypeInfo* info, FieldNameHash nameSignature) { } void* LookupOpenMethod(const TypeInfo* info, MethodNameHash nameSignature) { - // TODO: make it binary search? for (int i = 0; i < info->openMethodsCount_; ++i) { if (info->openMethods_[i].nameSignature_ == nameSignature) { return info->openMethods_[i].methodEntryPoint_; @@ -25,4 +66,6 @@ void* LookupOpenMethod(const TypeInfo* info, MethodNameHash nameSignature) { return nullptr; } +#endif + }