[K/N][codegen] Refactored interface calls
Removed old impl for debug builds Fixes https://youtrack.jetbrains.com/issue/KT-44547 as a side effect
This commit is contained in:
@@ -52,7 +52,6 @@ struct ObjCToKotlinMethodAdapter {
|
||||
|
||||
struct KotlinToObjCMethodAdapter {
|
||||
const char* selector;
|
||||
MethodNameHash nameSignature;
|
||||
ClassId interfaceId;
|
||||
int itableSize;
|
||||
int itableIndex;
|
||||
@@ -66,9 +65,6 @@ struct ObjCTypeAdapter {
|
||||
const void * const * kotlinVtable;
|
||||
int kotlinVtableSize;
|
||||
|
||||
const MethodTableRecord* kotlinMethodTable;
|
||||
int kotlinMethodTableSize;
|
||||
|
||||
const InterfaceTableRecord* kotlinItable;
|
||||
int kotlinItableSize;
|
||||
|
||||
@@ -652,7 +648,6 @@ static const TypeInfo* createTypeInfo(
|
||||
const TypeInfo* superType,
|
||||
const KStdVector<const TypeInfo*>& superInterfaces,
|
||||
const KStdVector<VTableElement>& vtable,
|
||||
const KStdVector<MethodTableRecord>& methodTable,
|
||||
const KStdOrderedMap<ClassId, KStdVector<VTableElement>>& interfaceVTables,
|
||||
const InterfaceTableRecord* superItable,
|
||||
int superItableSize,
|
||||
@@ -707,12 +702,6 @@ static const TypeInfo* createTypeInfo(
|
||||
}
|
||||
}
|
||||
|
||||
MethodTableRecord* openMethods_ = konanAllocArray<MethodTableRecord>(methodTable.size());
|
||||
for (size_t i = 0; i < methodTable.size(); ++i) openMethods_[i] = methodTable[i];
|
||||
|
||||
result->openMethods_ = openMethods_;
|
||||
result->openMethodsCount_ = methodTable.size();
|
||||
|
||||
result->packageName_ = nullptr;
|
||||
result->relativeName_ = nullptr; // TODO: add some info.
|
||||
result->writableInfo_ = (WritableTypeInfo*)konanAllocMemory(sizeof(WritableTypeInfo));
|
||||
@@ -777,22 +766,6 @@ static int getVtableSize(const TypeInfo* typeInfo) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void insertOrReplace(KStdVector<MethodTableRecord>& methodTable, MethodNameHash nameSignature, void* entryPoint) {
|
||||
MethodTableRecord record = {nameSignature, entryPoint};
|
||||
|
||||
for (int i = methodTable.size() - 1; i >= 0; --i) {
|
||||
if (methodTable[i].nameSignature_ == nameSignature) {
|
||||
methodTable[i].methodEntryPoint_ = entryPoint;
|
||||
return;
|
||||
} else if (methodTable[i].nameSignature_ < nameSignature) {
|
||||
methodTable.insert(methodTable.begin() + (i + 1), record);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
methodTable.insert(methodTable.begin(), record);
|
||||
}
|
||||
|
||||
static void throwIfCantBeOverridden(Class clazz, const KotlinToObjCMethodAdapter* adapter) {
|
||||
if (adapter->kotlinImpl == nullptr) {
|
||||
NSString* reason;
|
||||
@@ -816,9 +789,6 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co
|
||||
const void * const * superVtable = nullptr;
|
||||
int superVtableSize = getVtableSize(superType);
|
||||
|
||||
const MethodTableRecord* superMethodTable = nullptr;
|
||||
int superMethodTableSize = 0;
|
||||
|
||||
InterfaceTableRecord const* superITable = nullptr;
|
||||
int superITableSize = 0;
|
||||
|
||||
@@ -828,27 +798,17 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co
|
||||
// And if it is abstract, then vtable and method table are not available from TypeInfo,
|
||||
// but present in type adapter instead:
|
||||
superVtable = superTypeAdapter->kotlinVtable;
|
||||
superMethodTable = superTypeAdapter->kotlinMethodTable;
|
||||
superMethodTableSize = superTypeAdapter->kotlinMethodTableSize;
|
||||
superITable = superTypeAdapter->kotlinItable;
|
||||
superITableSize = superTypeAdapter->kotlinItableSize;
|
||||
}
|
||||
|
||||
if (superVtable == nullptr) superVtable = superType->vtable();
|
||||
if (superMethodTable == nullptr) {
|
||||
superMethodTable = superType->openMethods_;
|
||||
superMethodTableSize = superType->openMethodsCount_;
|
||||
}
|
||||
|
||||
KStdVector<const void*> vtable(
|
||||
superVtable,
|
||||
superVtable + superVtableSize
|
||||
);
|
||||
|
||||
KStdVector<MethodTableRecord> methodTable(
|
||||
superMethodTable, superMethodTable + superMethodTableSize
|
||||
);
|
||||
|
||||
if (superITable == nullptr) {
|
||||
superITable = superType->interfaceTable_;
|
||||
superITableSize = superType->interfaceTableSize_;
|
||||
@@ -915,7 +875,6 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co
|
||||
throwIfCantBeOverridden(clazz, adapter);
|
||||
|
||||
itableEqualsSuper = false;
|
||||
insertOrReplace(methodTable, adapter->nameSignature, const_cast<void*>(adapter->kotlinImpl));
|
||||
if (adapter->vtableIndex != -1) vtable[adapter->vtableIndex] = adapter->kotlinImpl;
|
||||
|
||||
if (adapter->itableIndex != -1 && superITable != nullptr)
|
||||
@@ -940,7 +899,6 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co
|
||||
const KotlinToObjCMethodAdapter* adapter = &typeAdapter->reverseAdapters[i];
|
||||
throwIfCantBeOverridden(clazz, adapter);
|
||||
|
||||
insertOrReplace(methodTable, adapter->nameSignature, const_cast<void*>(adapter->kotlinImpl));
|
||||
RuntimeAssert(adapter->vtableIndex == -1, "");
|
||||
|
||||
if (adapter->itableIndex != -1 && superITable != nullptr) {
|
||||
@@ -954,9 +912,8 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co
|
||||
|
||||
// TODO: consider forbidding the class being abstract.
|
||||
|
||||
const TypeInfo* result = createTypeInfo(superType, addedInterfaces, vtable, methodTable,
|
||||
interfaceVTables, superITable, superITableSize, itableEqualsSuper,
|
||||
fieldsInfo);
|
||||
const TypeInfo* result = createTypeInfo(superType, addedInterfaces, vtable, interfaceVTables,
|
||||
superITable, superITableSize, itableEqualsSuper, fieldsInfo);
|
||||
|
||||
// TODO: it will probably never be requested, since such a class can't be instantiated in Kotlin.
|
||||
result->writableInfo_->objCExport.objCClass = clazz;
|
||||
|
||||
@@ -17,44 +17,7 @@
|
||||
#include "KAssert.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 1
|
||||
|
||||
extern "C" {
|
||||
#if USE_BINARY_SEARCH
|
||||
|
||||
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
|
||||
|
||||
void* LookupOpenMethod(const TypeInfo* info, MethodNameHash nameSignature) {
|
||||
for (int i = 0; i < info->openMethodsCount_; ++i) {
|
||||
if (info->openMethods_[i].nameSignature_ == nameSignature) {
|
||||
return info->openMethods_[i].methodEntryPoint_;
|
||||
}
|
||||
}
|
||||
RuntimeAssert(false, "Unknown open method");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Seeks for the specified id. In case of failure returns a valid pointer to some record, never returns nullptr.
|
||||
// It is the caller's responsibility to check if the search has succeeded or not.
|
||||
|
||||
@@ -29,17 +29,6 @@ struct WritableTypeInfo;
|
||||
struct ObjHeader;
|
||||
struct AssociatedObjectTableRecord;
|
||||
|
||||
// Hash of open method name. Must be unique per class/scope (CityHash64 is being used).
|
||||
typedef int64_t MethodNameHash;
|
||||
|
||||
// An element of sorted by hash in-place array representing methods.
|
||||
// For systems where introspection is not needed - only open methods are in
|
||||
// this table.
|
||||
struct MethodTableRecord {
|
||||
MethodNameHash nameSignature_;
|
||||
void* methodEntryPoint_;
|
||||
};
|
||||
|
||||
// Type for runtime representation of Konan object.
|
||||
// Keep in sync with runtimeTypeMap in RTTIGenerator.
|
||||
enum Konan_RuntimeType {
|
||||
@@ -123,9 +112,6 @@ struct TypeInfo {
|
||||
int32_t objOffsetsCount_;
|
||||
const TypeInfo* const* implementedInterfaces_;
|
||||
int32_t implementedInterfacesCount_;
|
||||
// Null for abstract classes and interfaces.
|
||||
const MethodTableRecord* openMethods_;
|
||||
uint32_t openMethodsCount_;
|
||||
int32_t interfaceTableSize_;
|
||||
InterfaceTableRecord const* interfaceTable_;
|
||||
|
||||
@@ -181,14 +167,6 @@ struct TypeInfo {
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// Find open method by its hash. Other methods are resolved in compile-time.
|
||||
// Note, that we use attribute const, which assumes function doesn't
|
||||
// dereference global memory, while this function does. However, it seems
|
||||
// to be safe, as actual result of this computation depends only on 'type_info'
|
||||
// and 'hash' numeric values and doesn't really depends on global memory state
|
||||
// (as TypeInfo is compile time constant and type info pointers are stable).
|
||||
void* LookupOpenMethod(const TypeInfo* info, MethodNameHash nameSignature) RUNTIME_CONST;
|
||||
|
||||
InterfaceTableRecord const* LookupInterfaceTableRecord(InterfaceTableRecord const* interfaceTable,
|
||||
int interfaceTableSize, ClassId interfaceId) RUNTIME_CONST;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user